;;; identica-friends.el --- ;; ;; Filename: identica-friends.el ;; Description: A library that provides some functions to look who are your friends in your identi.ca account. ;; Author: Christian Giménez ;; Maintainer: ;; Created: dom sep 25 17:58:40 2011 (-0300) ;; Version: ;; Last-Updated: ;; By: ;; Update #: 0 ;; URL: ;; Keywords: ;; Compatibility: ;; ;; Features that might be required by this library: ;; ;; None ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; Use M-x identica first, if you are not connected, this library ;; will not work. ;; You can check who are your friends on Identi.ca using the function ;; M-x identica-show-friends ;; If you want to check who are following you, type: ;; M-x identica-show-followers ;; ;; I divided the code into sections. This sections are tabbed asside ;; and commented by an only one ";". Also are overlined and underlined ;; so, they are very visible. ;; ;; Convention: ;; All functions and variables in this modules has the prefix ;; "identica-friends" so you can identify easyly. ;; The main functions may not have this prefix so users don't get ;; confused. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change Log: ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 3, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: (require 'xml) (require 'identica-mode) ; ____________________ ; ; Variables ; ____________________ (defvar identica-friends-buffer nil "Friend's Buffer. Internal use of identica-friends.el." ) (defvar identica-friends-buffer-name "*identica-friends*" "Friends buffer's name. Changing this variable will effect after you recall identica-friends functions. Be aware of no function or actual buffers exists. Reboot all identica-friends functions." ) (defvar identica-friends-buffer-type nil "If the buffer contains a list of users, the this is setted into 'users. If the buffer contains a list of groups, this is setted into 'groups. Nil means, no buffer or just the programmer forgot to set it! :-S ." ) ; ---- ; Hooks Variables ; ---- (defcustom identica-friends-good-bye-hooks 'nil "These functions are called as soon as the `identica-friends-good-bye' functions finnish." :type '(hook) ) (defcustom identica-friends-mode-hooks 'nil "These functions are called as soon as the `identica-friends-mode' functions finnish." :type '(hook) ) (defcustom identica-friends-show-friends-hooks 'nil "These functions are called as soon as the `identica-show-friends' functions finnish." :type '(hook) ) (defcustom identica-friends-show-followers-hooks 'nil "These functions are called as soon as the `identica-show-followers' functions finnish." :type '(hook) ) (defcustom identica-friends-next-user-hooks 'nil "These functions are called as soon as the `identica-friends-next-user' functions finnish." :type '(hook) ) (defcustom identica-friends-prev-user-hooks 'nil "These functions are called as soon as the `identica-friends-prev-user' functions finnish." :type '(hook) ) ; ____________________ ; ; Faces and font-lock ; ____________________ (defface identica-friends-mode-id '( ; If there's dark background... (((class color) (background dark)) :foreground "yellow" ) ; If there's light background... (((class color) (background light)) :foreground "red" ) (t :background "white" :foreground "blue") ) "" ) (defface identica-friends-mode-bar '( ; If there's dark background... (((class color) (background dark)) :bold t ) ; If there's light background... (((class color) (background light)) :bold t ) (t :background "white" :foreground "blue" :bold t) ) "" ) (defvar identica-friends-mode-font-lock '( ;; font-lock-keywords ( ("^Id: .*$" . 'identica-friends-mode-id) ("^Nick: .*$" . 'identica-username-face) ("^--------------------$" . 'identica-friends-mode-bar) ) ;; Otros... ) ;; "Font lock for `identica-friends--mode'" ) ; ____________________ ; ; Keymaps ; ____________________ ;; Keymaps calls functions from the "Interactive API Commands" sections(see below). (defvar identica-friends-mode-map (let ((map (make-sparse-keymap))) (define-key map "q" 'identica-friends-good-bye) (define-key map "n" 'identica-friends-next-user) (define-key map "p" 'identica-friends-prev-user) (define-key map [down] 'identica-friends-next-user) (define-key map [up] 'identica-friends-prev-user) (define-key map [left] 'identica-friends-prev-user) (define-key map [right] 'identica-friends-next-user) (define-key map [return] 'identica-friends-goto-timeline-at-point) map) "Keymap for `identica-friends-mode'." ) ; ____________________ ; ; Major Mode ; ____________________ (define-derived-mode identica-friends-mode nil "Identica-friends-mode" "Major mode for identica-friends buffer. Use `identica-show-friends' to call this buffer." ;; font lock para ej-mode (set (make-local-variable 'font-lock-defaults) identica-friends-mode-font-lock) (set (make-local-variable 'buffer-read-only) t) (make-local-variable 'inhibit-read-only) (run-hooks 'identica-friends-mode-hooks) ) ; ________________________________________ ; ; Interactive API Commands ; ________________________________________ (defun identica-friends-good-bye () "Bury the *identica-friends* buffer" (interactive) (with-current-buffer identica-friends-buffer (bury-buffer) (run-hooks 'identica-friends-good-bye-hooks) ) ) (defun identica-friends-next-user () "Put the pointer in the next friend or follower in the identica-friend buffer." (interactive) (with-current-buffer identica-friends-buffer (goto-char (identica-friends-find-next-user-position)) ) (run-hooks 'identica-friends-next-user-hooks) ) (defun identica-friends-prev-user () "Put the pointer in the previous friend or follower in the identica-friend buffer." (interactive) (with-current-buffer identica-friends-buffer (goto-char (identica-friends-find-prev-user-position)) ) (run-hooks 'identica-friends-prev-user-hooks) ) (defun identica-friends-goto-timeline-at-point () "Check whenever we are in user-list or group-list. If we are listing user, call `identica-friends-goto-user-timeline-at-point', if not call `identica-friends-goto-group-timeline-at-point'." (interactive) (cond ((eq identica-friends-buffer-type 'users) (identica-friends-goto-user-timeline-at-point) ) ((eq identica-friends-buffer-type 'groups) (identica-friends-goto-group-timeline-at-point) ) ) ) (defun identica-friends-goto-user-timeline-at-point () "Search for the username and go to his timeline." (interactive) (let ((username (identica-friends-find-username)) ) (identica-user-timeline username) (switch-to-buffer identica-buffer) ) ) (defun identica-friends-goto-group-timeline-at-point () "Search for the group name and go to his timeline." (interactive) ;; Look that `identica-friends-find-username' can be used for getting anything that starts with the "Nick: " string, ;; so is usefull here as well! (let ((groupname (identica-friends-find-username)) ) (identica-group-timeline groupname) (switch-to-buffer identica-buffer) ) ) ; ; Main function: ; Followers Commands ; (defun identica-show-followers() (interactive) (setq identica-friends-buffer-type 'users) (identica-http-get (sn-account-server sn-current-account) (sn-account-auth-mode sn-current-account) "statuses" "followers" nil 'identica-friends-show-user-sentinel '("follower")) (run-hooks 'identica-friends-show-followers-hooks) ) ; ; Main function: ; Friends Commands ; (defun identica-show-friends () (interactive) ; (setq identica-method-class "statuses") ; (setq identica-method "friends") ; (identica-http-get identica-method-class identica-method identica-show-friend-sentinel) (setq identica-friends-buffer-type 'users) (identica-http-get (sn-account-server sn-current-account) ;; server (sn-account-auth-mode sn-current-account);; auth-mode "statuses" "friends" nil 'identica-friends-show-user-sentinel '("friend")) (run-hooks 'identica-friends-show-friends-hooks) ) (defun identica-show-groups () (interactive) ;; (setq identica-method-class "statuses") ;; (setq identica-method "friends") ;; (identica-http-get identica-method-class identica-method identica-show-friend-sentinel) (setq identica-friends-buffer-type 'groups) (identica-http-get (sn-account-server sn-current-account) ;; server (sn-account-auth-mode sn-current-account);; auth-mode "statusnet" "groups/list" nil 'identica-friends-show-user-sentinel '("group")) ;;(run-hooks 'identica-friends-show-groups-hooks) ) ; ____________________ ; ; Auxiliary Functions ; ____________________ (defun identica-friends-find-username () "Find the username in the nearby at current position. I suppose that the cursor is on the nickname and not anywhere." (save-excursion (if (search-forward-regexp "Nick: \\(.*\\)" nil t) (match-string-no-properties 1) nil ) ) ) (defun identica-friends-buffer () "Show a new buffer with all the friends. " (setq identica-friends-buffer (get-buffer-create identica-friends-buffer-name)) (switch-to-buffer identica-friends-buffer) (identica-friends-mode) ) (defun identica-friends-get-current-user () "Return the current user(friend or follower) that we are pointing now in the *identica-buffer*. This will be returned as a list wich components are in these order: (NICK NAME DESCRIPTION LOCATION)" (setq usr '()) (save-excursion ;; Position at the beginning of the user. (search-backward-regexp "^--------------------$" nil t) (goto-char (match-beginning 0)) (setq usr (cons (identica-friends-get-location) usr)) (setq usr (cons (identica-friends-get-desc) usr)) (setq usr (cons (identica-friends-get-name) usr)) (setq usr (cons (identica-friends-get-nick) usr)) ) usr ) (defun identica-friends-get-nick () "Get the *next* user(friend or follower) nick. If there are no user, return nil." (with-current-buffer identica-friends-buffer (save-excursion (search-forward-regexp "Nick: \\(.*\\)$" nil t) (match-string-no-properties 1) ) ) ) (defun identica-friends-get-name () "Get the *next* user(friend or follower) nick. If there are no user, return nil." (with-current-buffer identica-friends-buffer (save-excursion (search-forward-regexp "Name: \\(.*\\)$" nil t) (match-string-no-properties 1) ) ) ) (defun identica-friends-get-desc () "Get the current user(friend or follower) nick. If there are no user, return nil." (with-current-buffer identica-friends-buffer (save-excursion (search-forward-regexp "Description: \\(.*\\)$" nil t) (match-string-no-properties 1) ) ) ) (defun identica-friends-get-location () "Get the current user(friend or follower) nick. If there are no user, return nil." (with-current-buffer identica-friends-buffer (save-excursion (search-forward-regexp "Location: \\(.*\\)$" nil t) (match-string-no-properties 1) ) ) ) (defun identica-friends-show-user-sentinel (&optional status method-class method parameters type-of-user) "Sentinel executed after recieving all the information from identi.ca. This sentinel needs to know if the TYPE-OF-USER(or type of list) is one of these: - \"friend\" - \"follower\" - \"group\" First, its parse the XML file recieved by identi.ca. While parsing, it show the user data into a buffer. " ;; cnngimenez: This I used for debug HTTP (identica-friends-copiar-http-buffer) ;; Search for the begining of the xml... (goto-char (point-min)) (search-forward "