Posts Tagged ‘lisp’

find hyperlinks with lisp

October 23, 2010

here is a quick-and-dirty script to extract all the unique links from a web page.

it uses cl-ppcre to extract the hyperlinks-like strings from a target string. tested using drakma as web client.

(asdf:oos 'asdf:load-op :drakma)
(asdf:oos 'asdf:load-op :cl-ppcre)

(defparameter *url-re* "href\ *=\ *['\"](\\S+)['\"]")

(defun find-links (str)
  (let ((urls '()))
    (ppcre:do-register-groups
      (u) (*url-re* str nil :start 0 :sharedp t)
      (pushnew u urls :test #'equalp))
  (nreverse urls)))

(print
  (find-links (drakma:http-request "https://lbolla.wordpress.com")))

there are 139 links on this page…

Advertisements

lisp threading example

October 23, 2010

today I wanted to experiment with threads in lisp (sbcl, in particular).

here is a trivial example of how to access a shared resource (a closure, keeping a list of integers), from a set of *nt* threads.

(use-package :sb-thread)

;; number of threads
(defparameter *nt* 10)

;; threads
(defvar *threads* '())

;; mutex to use with shared resource accessed by the threads
(defvar *a-mutex* (make-mutex :name "acc-lock"))

;; shared closure accessed by the threads
(let ((x '()))
  (defun acc (v)
    (with-mutex (*a-mutex*)
                (push v x)))
  (defun get-acc ()
    x))

;; print the shared resource
(print (get-acc))

;; wait for all the threads to return
(mapcar #'join-thread
        ;; run the threads
        (loop :for i :below *nt*   
              ;; bind i to x so it is local to the thread
              :collect (let ((x i))
                        (make-thread #'(lambda ()
                                         ;; body of the thread
                                         (sleep (random 2))
                                         (acc x))
                                     :name x))))

;; print the shared resource
(print (get-acc))

it can’t get much simpler than that…

simple wordpress api lisp client

August 4, 2010

I like old things, therefore I started to learn Lisp.

there isn’t a better way to learn than by doing, so I tried to implement a client for the wordpress api. the result, even if not complete yet, it’s so elegant that I’d like to share it.

(require 's-xml-rpc)

(defpackage :wp 
  (:use :cl :cl-user :s-xml-rpc))

(in-package :wp)

(defparameter +interfaces+ 
  '((get-blogs "wp.getUsersBlogs" username password)
    (get-tags "wp.getTags" blog-id username password)
    (get-comment-count "wp.getCommentCount" blog-id username password post-id)
    (get-post-status-list "wp.getPostStatusList" blog-id username password)
    (get-page-status-list "wp.getPageStatusList" blog-id username password)
    (get-page-templates "wp.getPageTemplates" blog-id username password)
    (get-options "wp.getOptions" blog-id username password)
    (delete-comment "wp.deleteComment" blog-id username password comment-id)
    (get-comment-status-list "wp.getCommentStatusList" blog-id username password)
    (get-page "wp.getPage" blog-id page-id username password)
    (get-pages "wp.getPages" blog-id username password)
    (get-page-list "wp.getPageList" blog-id username password)
    (delete-page "wp.deletePage" blog-id username password page-id)
    (get-authors "wp.getAuthors" blog-id username password)
    (get-categories "wp.getCategories" blog-id username password)
    (delete-category "wp.deleteCategory" blog-id username password category-id)
    (suggest-categories "wp.suggestCategories" blog-id username password category max-results)
    (get-comment "wp.getComment" blog-id username password comment-id))
  "Interface definition to WP services")

(defun defunwp (params) 
  (destructuring-bind (name service &rest rest) params
    (setf (fdefinition name) (compile nil `(lambda (host ,@rest &optional (url "/xmlrpc.php")) 
                                             (block ,name 
                                                    (xml-rpc-call 
                                                      (encode-xml-rpc-call ,service ,@rest)
                                                      :host host
                                                      :url url)))))
    name))

(mapcar #'(lambda (interface) (export (defunwp interface))) +interfaces+)

it uses the s-xml-rpc package and I’ve tested it with SBCL.

example usage is as follows:

* (wp:get-blogs "username.wordpress.com" "your-username" "your-password") ; returns the list of blogs for the user
* (wp:get-pages "username.wordpress.com" your-blog-id "your-username" "your-password") ; returns the list of pages

and so on (see wp::+interfaces+ for function names and required params).

enjoy!