commit 04e8cb116f1b8af78d3dacb85960b1f81262eb21
Author: dsorber <david.sorber@gmail.com>
Date:   Sat Apr 4 11:54:02 2015 -0400

    w00t! I finally got the update operation working! It turns out that the wsgi.input object is a little tricky to deal with until you learn how to do so correctly. I still need to add displaying and modifying tags... and a bunch of other stuff.

diff --git a/software/bookmark_library/bmklib/web/base_controller.py b/software/bookmark_library/bmklib/web/base_controller.py
index 3d50e29..e591c0e 100644
--- a/software/bookmark_library/bmklib/web/base_controller.py
+++ b/software/bookmark_library/bmklib/web/base_controller.py
@@ -3,7 +3,7 @@ import os
 from genshi.template import TemplateLoader
 
 BASE_PATH = '/home/dsorber/Documents/phalanx-repo/software/bookmark_library/'
-DB_PATH = os.path.join(BASE_PATH, 'bookmarks.db')
+DB_PATH = os.path.join('/var/www', 'bookmarks.db')
 TEMPLATE_PATH = os.path.join(BASE_PATH, 'bmklib', 'web', 'templates')
 
 # Someday this should go into some sort of configuration
@@ -79,6 +79,22 @@ class BaseTextController(object):
         
         
 class TestController(BaseTextController):
-    
+        
     def build_content(self):
         self.body = 'hello there handsome'
+
+class BaseRedirectController(object):
+    
+    def __init__(self, environ):
+        
+        self.environ = environ
+        self.redirect_url = ''
+        
+    def process_request(self):
+        """ Override this method with the appropriate stuff to process the 
+        request.
+        
+        Don't forget to populate the "redirect_url" parameter.
+        """
+        pass
+        
diff --git a/software/bookmark_library/bmklib/web/bmklib.wsgi b/software/bookmark_library/bmklib/web/bmklib.wsgi
index e5c0236..6da212b 100644
--- a/software/bookmark_library/bmklib/web/bmklib.wsgi
+++ b/software/bookmark_library/bmklib/web/bmklib.wsgi
@@ -32,7 +32,7 @@ def application(environ, start_response):
     elif re.search('^/update_bookmark$', path) or re.search('^/update_bookmark/$', path):
         # Update bookmark
         controller = UpdateBookmarkController(environ)
-        response_headers, response_body = controller.generate_response()
+        response_headers, response_body = controller.generate_response()        
         
     else:
         # User supplied an invalid URL
diff --git a/software/bookmark_library/bmklib/web/controllers/all_bookmarks.py b/software/bookmark_library/bmklib/web/controllers/all_bookmarks.py
index 5953ec3..719f8d3 100644
--- a/software/bookmark_library/bmklib/web/controllers/all_bookmarks.py
+++ b/software/bookmark_library/bmklib/web/controllers/all_bookmarks.py
@@ -58,6 +58,11 @@ class AllBookmarksPageController(BaseHTMLController):
         self.content['bookmarks'] = bookmarks
         self.content['path_parts'] = len(path_parts)
         
+        # Calculate the URL "offset" for the update bookmark link
+        update_link = ['..']  * (len(path_parts) - 1)
+        update_link.extend(['bookmark'])
+        self.content['update_link'] = os.path.join(*update_link)
+        
         # Set previous link to control pagination in the template
         if page_idx == 1:
             self.content['previous'] = None
diff --git a/software/bookmark_library/bmklib/web/controllers/update_bookmark.py b/software/bookmark_library/bmklib/web/controllers/update_bookmark.py
index 38ae371..998ae2f 100644
--- a/software/bookmark_library/bmklib/web/controllers/update_bookmark.py
+++ b/software/bookmark_library/bmklib/web/controllers/update_bookmark.py
@@ -1,10 +1,10 @@
-import math
+from cgi import parse_qs, escape
 import os.path
 
 import sqlite3
 
 from bmklib.lib.bookmark import Bookmark, BookmarkNotFoundError
-from bmklib.web.base_controller import BaseHTMLController, DB_PATH, MAX_PER_PAGE
+from bmklib.web.base_controller import BaseHTMLController, DB_PATH
 
 class UpdateBookmarkController(BaseHTMLController):
     
@@ -13,36 +13,57 @@ class UpdateBookmarkController(BaseHTMLController):
     
     def build_content(self):
         
-        f = open('/home/dsorber/Desktop/poop', 'w')
-        f.write(environ['wsgi.input'])
-        f.close()
-        return
+        # Read the "content length" then read the wsgi.input stream
+        size = int(self.environ.get('CONTENT_LENGTH', 0))
+        post_raw = self.environ['wsgi.input'].read(size).decode('utf-8')
         
-        # Split the path so we can parse it below
-        path = self.environ['PATH_INFO'][1:]
-        path_parts = path.split('/')
+        # Make sure we got some post content
+        if not post_raw:
+            self.content['invalid'] = True
+            self.content['error'] = 'Invalid post request'
+            return
         
-        conn = sqlite3.connect(DB_PATH)        
-        db = conn.cursor()
+        # Parse the raw post string into a dictionary
+        post_vars = parse_qs(post_raw)
+        if 'id' not in post_vars:
+            self.content['invalid'] = True
+            self.content['error'] = 'Invalid post request (no ID specified)'
+            return
+            
+        with open('/tmp/poopchute', 'w') as f:
+            f.write(str(post_vars))
+                
+        # Split the path so we can parse it below
+        #~ path = self.environ['PATH_INFO'][1:]
+        #~ path_parts = path.split('/')
         
         # Do some basic validation
         try:
-            bmk_id = int(path_parts[1])
+            bmk_id = int(escape(post_vars['id'][0]))
         except (ValueError, IndexError):
             bmk_id = None
-        
-        if bmk_id is None or len(path_parts) != 2:
             self.content['invalid'] = True
-            self.content['error'] = 'Invalid bookmark path'
-        else:
-            self.content['invalid'] = False
+            self.content['error'] = 'Invalid post request'
+            return
+            
+        # Retrieve the specified Bookmark object and update its values
+        try:
+            conn = sqlite3.connect(DB_PATH)        
+            db = conn.cursor()
+            
+            bookmark = Bookmark(conn, id=bmk_id)
+            bookmark.url = escape(post_vars['url'][0])
+            bookmark.title = escape(post_vars['title'][0])
+            if 'description' in post_vars:
+                bookmark.description = escape(post_vars['description'][0])
+            if 'deleted' in post_vars:
+                bookmark.deleted = bool(escape(post_vars['deleted'][0]))
+            bookmark.save()     
             
-            # Build Bookmark object
-            try:
-                bookmark = Bookmark(conn, id=bmk_id)
-                self.content['bookmark'] = bookmark
-            except BookmarkNotFoundError:
-                self.content['invalid'] = True
-                self.content['error'] = '{:d} is not a valid bookmark ID'.format(bmk_id)
-                return
+            self.content['invalid'] = False
+            self.content['bookmark'] = bookmark
+        except BookmarkNotFoundError:
+            self.content['invalid'] = True
+            self.content['error'] = '{:d} is not a valid bookmark ID'.format(bmk_id)
+        return
 
diff --git a/software/bookmark_library/bmklib/web/templates/all_bookmarks.html b/software/bookmark_library/bmklib/web/templates/all_bookmarks.html
index 458add4..2fd398e 100644
--- a/software/bookmark_library/bmklib/web/templates/all_bookmarks.html
+++ b/software/bookmark_library/bmklib/web/templates/all_bookmarks.html
@@ -10,7 +10,7 @@
 <p>${page_idx} of ${max_page_idx}</p>
 <table>
     <tr py:for="idx, bookmark in enumerate(bookmarks)" class="${idx % 2 == 1 and 'odd' or 'even'}">
-        <td>${idx + ((page_idx - 1) * len(bookmarks)) + 1} <a class="detail_link" href="../bookmark/${bookmark.id}">+</a></td>
+        <td>${idx + ((page_idx - 1) * len(bookmarks)) + 1} <a class="detail_link" href="${update_link}/${bookmark.id}">+</a></td>
         <td><a href="${bookmark.url}">${bookmark.title and bookmark.title or 'no title'}</a></td>
         <td><py:for each="tag in bookmark.category_tags"><span class="tag">${tag.value}</span></py:for></td>
         <td><py:for each="tag in bookmark.description_tags"><span class="tag">${tag.value}</span></py:for></td>
diff --git a/software/bookmark_library/bmklib/web/templates/bookmark.html b/software/bookmark_library/bmklib/web/templates/bookmark.html
index 0dc4bc7..c05925b 100644
--- a/software/bookmark_library/bmklib/web/templates/bookmark.html
+++ b/software/bookmark_library/bmklib/web/templates/bookmark.html
@@ -9,6 +9,7 @@
 
 <body>
 <h1>Bookmarks</h1>
+<a href="/bmk/bookmarks">All bookmarks</a>
 
 <py:choose test="invalid">
   <py:when test="True">
@@ -41,7 +42,7 @@
                 <span class="form_label">Date added:</span>
                 <p>${bookmark.date_added.month}/${bookmark.date_added.day}/${bookmark.date_added.year}</p>
             </div>
-            <input class="button" type="submit" />
+            <input class="button" type="submit" value="Update" />
         </div>
     </form>
   </py:when>
