Commits

Dan Colish committed fb6224f

fixes to bridge

Comments (0)

Files changed (5)

 
 
 - Optional syntax highlighting of code snippets
-- utility to upload of the photos to picasa web albums, to use with posts (later, googlecl gives an useful compromise)
+- utility to upload of the photos to picasa web albums, 
+  to use with posts (later, googlecl gives an useful compromise)
     (setq title (read-from-minibuffer "Title: "))
     (setq blogger-buffer-title title)
     ;; The blogger-bridge-post return id of the post yet posted.
-    (setq blogger-buffer-post-id (blogger-bridge-post title (blogger-filter-content)))
+    (setq blogger-buffer-post-id 
+          (blogger-bridge-post title (blogger-filter-content)))
     (message (format "Post '%s' successfully posted" title))
     )
   )
     (setq blogger-username nil)
     (setq blogger-password nil)
     (error "Invalid username/password"))
-  )
+  (setq blogger-bridge-authenticated t))
 
 (defun blogger-prompt-usn-pass ()
   "Define the blogger-username variable and blogger-password variable"
 (defun blogger-prompt-blog ()
   "Prompt the user for a blog with completion support"
   (setq blogger-default-blog-name 
-	(completing-read "Select a Blog (TAB for completion): " (blogger-bridge-get-blog-names))
+	(completing-read "Select a Blog (TAB for completion): " 
+                         (blogger-bridge-get-blog-names))
   )
 )
 
 (defun blogger-set-blog (blog-name)
   "Set the blog specified by BLOG-NAME as the current edited blog"
   (interactive)
-  (blogger-bridge-set-current-blog-by-name blog-name))
+  (if (eq blogger-bridge-authenticated t)
+      (blogger-bridge-set-current-blog-by-name blog-name)
+    (lambda ()
+      (blogger-bridge-authenticate)
+      (blogger-bridge-set-current-blog-by-name blog-name))
+    )
+  )
 
 (defun blogger-create-bloglist ()
   "Create the list of entries in the selected blog"
-  (dolist (entry (blogger-bridge-get-entries)) 
+  (dolist (entry (blogger-bridge-get-entries))
     ;; Unpack the entry in various parts
     (let ((etitle (nth 1 entry))
 	  (eid (nth 0 entry))
-'''
+"""
 Python library but maybe it overcomes the BloggerClient API
-'''
+"""
 from gdata import service
 import gdata
 import atom
 
 Entry = namedtuple("Entry", "title content id published updated category feed")
 
+
 class Blog(object):
-    '''
+    """
     Encapsulate a Blog object, this istance should no be istantiated,
     but obtained from the Blogger object with Blogger.get_blogs
-    '''
+    """
     def __init__(self, name, id_, service):
         self.name = name
         self.id = id_
         self.service = service
 
     def update_post(self, post_id, title=None, content=None):
-        '''
+        """
         Update the post identified by post_id
-        '''
+        """
         entry = self.get_entry(post_id)
-        
-        if title!=None:
-            entry.feed.title = atom.Title('xhtml',title)
-        if content!=None:
-            entry.feed.content = atom.Content(content_type='html',text=content)
-        
+
+        if title:
+            entry.feed.title = atom.Title('xhtml', title)
+
+        if content:
+            entry.feed.content = atom.Content(content_type='html',
+                                              text=content)
+
         self.service.Put(entry.feed, entry.feed.GetEditLink().href)
-        
+
     def add_tags(self, post_id, tags, replace=False):
         """Add or remove labels on a post.
         if replace is True, remove all old tags.
         if replace:
             # Remove categories that match the scheme we are updating.
             post.category = [c for c in post.category if c.scheme != scheme]
-        
+
         new_tags = [atom.Category(term=tag, scheme=scheme) for tag in tags]
         post.category.extend(new_tags)
 
         self.service.Put(post, post.GetEditLink().href)
 
     def remove_tags(self, post_id, tags):
-        '''
+        """
         Remove tags from a post
-        '''
+        """
         scheme = 'http://www.blogger.com/atom/ns#'
         post = self.get_entry(post_id).feed
-        
-        post.category = [c for c in post.category \
-                             if c.scheme != scheme or \
-                             (c.scheme == scheme and c.term not in tags)]
+
+        post.category = [c for c in post.category
+                             if (c.scheme != scheme or
+                             (c.scheme == scheme and c.term not in tags))]
         self.service.Put(post, post.GetEditLink().href)
-    
-    def get_entries(self):
-        '''Generate Entry objects for the blog 
-        '''
-        
+
+    @property
+    def entries(self):
+        """
+        Generate Entry objects for the blog
+        """
         feed = self.service.GetFeed('/feeds/' + self.id + '/posts/default')
-        
-        for entry in feed.entry:
-            yield self._convert_entry_feed(entry)
+        _entry = lambda x: self._convert_entry_feed(x)
+        return dict(_entry(entry) for entry in feed.entry)
 
     def get_entry(self, post_id):
-        return next(entry for entry in self.get_entries() if entry.id == post_id)
+        return self.entries.get(post_id)
 
-    def publish_post(self, title, content, tags=None, draft=False):
-        '''
+    def publish_post(self, title, content, tags=None, draft=True):
+        """
         publish post with the given entries, return the post itself
-        '''
+        :param title: blog post Title
+        :type title: string
+        :param content: post content
+        :type content: string
+        :param tags: post tags
+        :type tags: list
+        """
         entry = gdata.GDataEntry()
         entry.title = atom.Title('xhtml', title)
         entry.content = atom.Content(content_type='html', text=content)
-        
+
         if draft:
-              control = atom.Control()
-              control.draft = atom.Draft(text='yes')
-              entry.control = control
-        
-        post = self._convert_entry_feed(self.service.Post(entry, '/feeds/%s/posts/default' % self.id))
-        
+            control = atom.Control()
+            control.draft = atom.Draft(text='yes')
+            entry.control = control
+
+        post = self._convert_entry_feed(
+            self.service.Post(entry, '/feeds/%s/posts/default' % self.id))
+
         if tags:
             self.add_tags(post.id, tags)
-        
+
         return post
 
     def delete_post(self, post_id):
-        '''
+        """
         Delete post identified by post_id
-        '''
+        """
         entry = self.get_entry(post_id)
         self.service.Delete(entry.feed.GetEditLink().href)
-  
 
-        
     def _convert_entry_feed(self, entry):
-        '''Convert the entry feed returned by the method of the
+        """
+        Convert the entry feed returned by the method of the
         service in an Entry Object (a namedtuple, actually)
-        '''
-        
+        """
         title = entry.title.text
         content = entry.content.text
         post_id = entry.GetSelfLink().href.split('/')[-1]
         updated = parse(entry.updated.text)
         tags = [tag.term for tag in entry.category]
 
-        return Entry(title, content, post_id, published, updated, tags, entry)        
-        
+        return tuple(post_id, Entry(title, content, post_id, published,
+                                    updated, tags, entry))
+
 
 class Blogger(object):
-    '''
+    """
     Blogger client that returns python objects (usually tuples and
     namedtuples) instead of xml entries
-    '''
-    
+    """
+
     def __init__(self, username, password):
+        # XXX: be smarter about loading username and password
+        # Is oauth possbile?
         s = service.GDataService(username, password)
         s.source = "gl-emacsblogging-0.1"
         s.service = "blogger"
         self.service = s
 
     def get_blogs(self):
-        '''Return a list of blogs for the current user
-        '''
-        
+        """Return a list of blogs for the current user
+        """
+        # XXX: rather than yielding why not return a list?
         query = service.Query()
         query.feed = "/feeds/default/blogs"
         feed = self.service.Get(query.ToUri())
-        
         for entry in feed.entry:
             name = entry.title.text
             blog_id = entry.GetSelfLink().href.split("/")[-1]
             yield Blog(name, blog_id, self.service)
-
-
-def test_getting():
-    blogger = Blogger(username, password)
-    blog = next(i for i in blogger.get_blogs())
-    entries = blog.get_entries()
-    
-    for entry in entries:
-        print "Entry", entry.title,"Published", entry.published.strftime("%d/%m/%Y"), "Id", entry.id
-
-def test_updating():
-    blogger = Blogger(username, password)
-    blog = next(i for i in blogger.get_blogs())
-    blog.update_post('6296823132147746563', title="Ok", content="Fubbo")
-    blog.add_tags('6296823132147746563',["hello", "world"])

blogger_bridge.py

 from blogger import Blogger
-from Pymacs import lisp,Let
+from Pymacs import lisp
 import os
 import filters
 import picasa
 interactions = {}
 
+
 class LispInteractive(object):
+
     def __init__(self):
         self.authenticated = False
+        self.blog = None
+        self._blogs = None
 
     def authenticate(self):
         '''Authenticate the user and return True if succeed else False
         '''
-        
-        username = lisp["blogger-username"].value()
-        password = lisp["blogger-password"].value()
-        
+        username = 'dcolish@gmail.com'  # lisp["blogger-username"].value()
+        password = 'f@1thanddan'  # lisp["blogger-password"].value()
+
         try:
             self.blogger = Blogger(username, password)
             self.authenticated = True
+            lisp["blogger-bridge-authenticated"] = True
+            return self.authenticated
         except:
             return False
-        return True
-    
+
     def refresh(self):
-        '''refresh the cached list of blogs and entries
-        '''
-        
-        self.blogs = list(self.blogger.get_blogs())
+        self.blogs
 
     @property
-    def blog(self):
-        if hasattr(self,"_blog"):
-            return self._blog
-        else:
-            lisp.error("Current Blog not selected")
-    
+    def blogs(self):
+        '''refresh the cached list of blogs
+        '''
+
+        if not self.authenticated:
+            self.authenticate()
+
+        if self._blogs is None:
+            self._blogs = list(self.blogger.get_blogs())
+        assert self._blogs is not None
+        return self._blogs
+
+    @property
+    def blog_ids(self):
+        return dict((blog.id, blog) for blog in self.blogs)
+
+    @property
+    def blog_names(self):
+        return dict((blog.name, blog) for blog in self.blogs)
+
     def set_blog(self, blog_id):
-        self._blog = self.get_blog(blog_id)
+        try:
+            self.blog = self.blog_ids[blog_id]
+        except:
+            lisp.error("Blog id '%s' not correct" % blog_id)
 
-    blog.setter(set_blog)
-
-    
-    def get_blogs(self):
-        return [[blog.id, blog.name] for blog in self.blogs]    
-    
-    def get_blog_id(self,name):
-        '''get a blog by name
+    def entries(self):
+        '''get entries of the selected blog
         '''
-        try:
-            return next(blog.id for blog in self.blogs if blog.name == name)
-        except StopIteration:
-            lisp.error("Blog name '%s' not correct"%name)
-    
-    def get_entries(self):
-        '''get entries of the current blog selected (attr .blog)
-        '''
-        
-        blog = self.blog
-        
-        entries = blog.get_entries()
-        return [[entry.id ,entry.title, entry.updated.strftime("%d/%m/%Y"), entry.category] \
-                    for entry in entries]
-    
-    def get_blog_names(self):
-        '''return a list of the blog names
-        '''
-        
-        return [bl.name for bl in self.blogs]
-
-    def get_blog(self, blog_id):
-        return next(blog for blog in self.blogs if blog.id == blog_id)
-    
-    def get_a_blog(self,blog_id=None):
-        blog = self.blogs[0] if blog_id == None else self.get_blog(blog_id)
-        return blog
+        return [[entry.id,
+                 entry.title,
+                 entry.updated.strftime("%d/%m/%Y"),
+                 entry.category]
+                for entry in self.blog.entries]
 
     def post(self, title, content):
         '''Post this article to the current blog,
         return the article id
         '''
-        entry = self.blog.publish_post(title, content)
-        return entry.id
-    
+        return self.blog.publish_post(title, content).id
+
     def update_post(self, post_id, title=None, content=None):
-        blog = self.blog
-        blog.update_post(post_id, title, content)
-    
-    def delete_post(self, post_id, blog_id = None):
-        blog = self.blog
-        blog.delete_post(post_id)
+        self.blog.update_post(post_id, title, content)
+
+    def delete_post(self, post_id):
+        self.blog.delete_post(post_id)
 
     def upload_image(self, filename):
         c = picasa.Client()
         username = lisp["blogger-username"].value()
         password = lisp["blogger-password"].value()
         c.login(username, password)
-        
         return c.add_photo(os.path.expanduser(filename))
+
     def tag_post(self, post_id, tags):
-        blog = self.blog
-        blog.add_tags(str(post_id), tags)
+        self.blog.add_tags(str(post_id), tags)
+
+
 li = LispInteractive()
 
 # Exposing functions
+authenticated = li.authenticated
 authenticate = li.authenticate
 refresh = li.refresh
-
-get_entries = li.get_entries
-get_blog_names = li.get_blog_names
-get_blog_id = li.get_blog_id
-set_current_blog_by_name = lambda name: li.set_blog(li.get_blog_id(name))
-
+get_entries = li.entries
+get_blog_names = lambda: list(li.blog_names.iterkeys())
+get_blog_id = lambda name: li.blog_names.get(name).id
+set_current_blog_by_name = lambda name: li.set_blog(li.blog_names.get(name).id)
 post = li.post
 rst2blogger = filters.pipe(filters.rst2html,
                            filters.extract_body,
 delete_post = li.delete_post
 update_post = li.update_post
 tag_post = li.tag_post
-
 upload_image = li.upload_image
 
 # Interactive functions
-(add-to-list 'pymacs-load-path "~/workspace/blogger/pythonblog/")
-(pymacs-load "blogger_bridge" "blogger-bridge-")
-(load-file "~/workspace/blogger/pythonblog/blogger-mode.el")
+;; (add-to-list 'pymacs-load-path "~/workspace/blogger/pythonblog/")
+;; (pymacs-load "blogger_bridge" "blogger-bridge-")
+;; (load-file "~/workspace/blogger/pythonblog/blogger-mode.el")