commit 137b22ce3600df61936ac1aa01ef2dae900eff42
Author: dsorber <david.sorber@gmail.com>
Date:   Sat Jul 19 11:45:09 2014 -0400

    Added a few things including a "date_added" column. Also adding a blank database so I don't have to recreate it. I'm proabably going to work on an import script next, then the web GUI. I really should write some unit tests at some point.

diff --git a/software/bookmark_library/lib/bookmark.py b/software/bookmark_library/lib/bookmark.py
index 5ab6c00..b6dcb03 100644
--- a/software/bookmark_library/lib/bookmark.py
+++ b/software/bookmark_library/lib/bookmark.py
@@ -1,6 +1,8 @@
+import datetime
 import re
 from urllib.request import urlopen
 
+import dateutil.parser
 import sqlite3
 
 from tag import Tag
@@ -9,7 +11,7 @@ from tag import Tag
 DB_PATH = 'bookmarks.db'
 
 SQL_SELECT_BOOKMARK = "SELECT * FROM bookmarks WHERE id=?"
-SQL_INSERT_BOOKMARK = "INSERT INTO bookmarks VALUES (?,?,?,?,?,?,?,?)"
+SQL_INSERT_BOOKMARK = "INSERT INTO bookmarks VALUES (?,?,?,?,?,?,?,?,?)"
 SQL_UPDATE_BOOKMARK = "UPDATE bookmarks SET {:s} WHERE id=?"
 SQL_SELECT_CAT_TAGS = "SELECT tag_id FROM category_tags WHERE bookmark_id=?"
 SQL_SELECT_DESC_TAGS = "SELECT tag_id FROM description_tags WHERE bookmark_id=?"
@@ -40,6 +42,13 @@ class DBConnectionError(Exception):
         return repr(self.value)
         
 
+def _format_date(date):
+    if date is not None:
+        return date.isoformat()
+    else:
+        return date
+
+
 class Bookmark(object):
     
     def __init__(self, db_conn, id=None, url=None):
@@ -58,8 +67,9 @@ class Bookmark(object):
         self.title = ''
         self.description = ''
         self.times_visited = 0
-        self.last_visited = 0
-        self.last_reachable = 0
+        self.last_visited = None
+        self.last_reachable = None
+        self.date_added = None
         self.deleted = False
         self.category_tags = set()
         self.description_tags = set()
@@ -79,9 +89,12 @@ class Bookmark(object):
             self.title = row[2]
             self.description = row[3]
             self.times_visited = int(row[4])
-            self.last_visited = row[5]
-            self.last_reachable = row[6]
-            if int(row[7]) == 0:
+            if row[5]:
+                self.last_visited = dateutil.parser.parse(row[5])
+            if row[6]:
+                self.last_reachable = dateutil.parser.parse(row[6])
+            self.date_added = dateutil.parser.parse(row[7])
+            if int(row[8]) == 0:
                 self.deleted = False
             else:
                 self.deleted = True
@@ -94,7 +107,7 @@ class Bookmark(object):
             for row in db.execute(SQL_SELECT_DESC_TAGS, (self.id,)):
                 self.description_tags.add(Tag(int(row[0])))
             
-        # Store hash of set for dirty comparison
+        # Store hash of tag sets for dirty comparison
         self._cat_tags_hash = hash(frozenset(self.category_tags))
         self._desc_tags_hash = hash(frozenset(self.description_tags))
         
@@ -129,6 +142,10 @@ class Bookmark(object):
         """ Customize setting data attributes so we can tell which ones
         are dirty.
         """
+        # The date_added attribute is immutable once it has been set
+        if hasattr(self, 'date_added') and name == 'date_added':
+            if getattr(self, name) is not None:
+                return
         
         # Check if the attr is a data attribute then check if the value has 
         # changed. If so, mark the attribute as dirty
@@ -142,9 +159,13 @@ class Bookmark(object):
         
     def _db_insert(self):
         """ Insert a new bookmark record into the database. """
+        self.date_added = datetime.datetime.now()
+        
         db = self._db_conn.cursor()
         values = (None, self.url, self.title, self.description, 
-                  self.times_visited, self.last_visited, self.last_reachable,
+                  self.times_visited, _format_date(self.last_visited), 
+                  _format_date(self.last_reachable), 
+                  _format_date(self.date_added),
                   self.deleted and '1' or '0')
         db.execute(SQL_INSERT_BOOKMARK, values)
         
@@ -176,7 +197,11 @@ class Bookmark(object):
         for key in self._dirty.keys():
             if self._dirty[key] == True:
                 sets.append('{:s}=?'.format(key))
-                values.append(getattr(self, key))
+                if key in ['last_reachable', 'last_visited']:
+                    # Datetime objects need to be formated before update
+                    values.append(_format_date(getattr(self, key)))
+                else:
+                    values.append(getattr(self, key))
         
         if values and sets:
             # Add the record id as the last value
@@ -186,7 +211,6 @@ class Bookmark(object):
             sql = SQL_UPDATE_BOOKMARK.format(','.join(sets))
             db = self._db_conn.cursor()
             db.execute(sql, values)
-            self._db_conn.commit()
             
             # Reset dirty flags
             for key in self._dirty.keys():
@@ -208,6 +232,8 @@ class Bookmark(object):
         if self.description_tags_dirty:
             update_tag_lists(SQL_DELETE_DESC_TAGS, SQL_INSERT_DESC_TAGS,
                              self.description_tags)
+                             
+        self._db_conn.commit()
     
     @property
     def category_tags_dirty(self):
@@ -251,7 +277,11 @@ class Bookmark(object):
         if self.url:
             response = urlopen(self.url)
             if response.getcode() == HTTP_OKAY:
+                self.last_reachable = datetime.datetime.now()
                 return True
         return False
         
-            
+    def visit(self):
+        """ Increment the visit count and update the last visited datestamp """
+        self.times_visited += 1
+        self.last_visited = datetime.datetime.now() 
diff --git a/software/bookmark_library/lib/bookmarks.db b/software/bookmark_library/lib/bookmarks.db
index 71cb32f..77b9429 100644
Binary files a/software/bookmark_library/lib/bookmarks.db and b/software/bookmark_library/lib/bookmarks.db differ
diff --git a/software/bookmark_library/lib/tag.py b/software/bookmark_library/lib/tag.py
index a6f4250..d600fb6 100644
--- a/software/bookmark_library/lib/tag.py
+++ b/software/bookmark_library/lib/tag.py
@@ -41,9 +41,6 @@ class Tag(object):
     def __str__(self, value):
         return repr(self.value)
         
-    def _get_id_from_value(self):
-        
-        
     def save(self):
         # Only insert a new tag if it does not already exist in the database
         if self.id is None:
