Switching from file-based book settings to json based, making it much easier to add...
authorepage <eopage@byu.net>
Mon, 5 Jul 2010 15:48:23 +0000 (15:48 +0000)
committerepage <eopage@byu.net>
Mon, 5 Jul 2010 15:48:23 +0000 (15:48 +0000)
git-svn-id: file:///svnroot/nqaap/trunk@43 00ff6f12-f5ab-46b1-af0e-967c86d3154f

src/opt/Nqa-Audiobook-player/FileStorage.py
src/opt/Nqa-Audiobook-player/Gui.py
src/opt/Nqa-Audiobook-player/Player.py

index 44cfc36..e47d2b2 100644 (file)
@@ -1,32 +1,51 @@
 from __future__ import with_statement   # enable with
 
 import os
-
+import simplejson
 import logging
 
 
-log = logging.getLogger(__name__)
+_moduleLogger = logging.getLogger(__name__)
 
 
 class FileStorage(object):
 
     def __init__(self, path="~/.SornPlayer/"):
         # Setup dir
-        log.info("init filestorage")
+        _moduleLogger.info("init filestorage")
         self.path = path
-        self.books_path = os.path.join(self.path, "books/")
-        if not os.path.isdir(self.books_path):
-            os.makedirs(self.books_path)
-
-        # Read config file
-        self.conf = os.path.join(self.path, "current")
+        self.books_path = os.path.join(self.path, "books.json")
         self.selected = None
+        self._books = {}
 
-        if os.path.isfile(self.conf):
-            with open(self.conf) as f:
-                self.selected = f.readline()
+    def load(self):
+        if not os.path.isdir(self.path):
+            os.makedirs(self.path)
 
-        # Read current book file
+        try:
+            with open(self.books_path, "r") as settingsFile:
+                settings = simplejson.load(settingsFile)
+        except IOError, e:
+            _moduleLogger.info("No settings")
+            settings = {}
+        except ValueError:
+            _moduleLogger.info("Settings were corrupt")
+            settings = {}
+
+        if settings:
+            self._books = settings["books"]
+            self.selected = settings["selected"]
+        else:
+            _moduleLogger.info("Falling back to old settings format")
+            self._load_old_settings()
+
+    def save(self):
+        settings = {
+            "selected": self.selected,
+            "books": self._books,
+        }
+        with open(self.books_path, "w") as settingsFile:
+            simplejson.dump(settings, settingsFile)
 
     def get_selected(self):
         """returns the currently selected book"""
@@ -36,33 +55,49 @@ class FileStorage(object):
         """ Sets the book as the currently playing, and adds it to the
         database if it is not already there"""
         book_file = os.path.join(self.books_path, bookName)
-        if not os.path.isfile(book_file):
-            with open(book_file, 'w') as f:
-                f.write("0\n") #Current chapter
-                f.write("0\n") #Current position
+        if bookName not in self._books:
+            self._books[bookName] = {
+                "chapter": 0,
+                "position": 0,
+            }
 
         self.selected = bookName
-        with open(self.conf, 'w') as f:
-            f.write(self.selected) #
 
     def set_time(self, chapter, position):
         """ Sets the current time for the book that is currently selected"""
-        try:
-            book_file = os.path.join(self.books_path, self.selected)
-            log.debug("writing time (%s, %s) to: %s"%( chapter, position, book_file ))
-            with open(book_file, 'w') as f:
-                f.write(str(int(chapter)) + "\n") #Current chapter
-                f.write(str(int(position)) + "\n") #Current position
-        except:
-            log.error("Unable to save to file: %s" % book_file)
+        bookInfo = self._books[self.selected]
+        bookInfo["chapter"] = chapter
+        bookInfo["position"] = position
 
     def get_time(self):
         """Returns the current saved time for the current selected book"""
-        chapter, position = 0 , 0
-        book_file = os.path.join(self.books_path, self.selected)
-        log.debug("getting time from: " + book_file)
-        with open(book_file, 'r') as f:
-            chapter = int(f.readline())
-            position = int(f.readline())
-
-        return chapter, position
+        bookInfo = self._books[self.selected]
+        return bookInfo["chapter"], bookInfo["position"]
+
+    def _load_old_settings(self):
+        conf = os.path.join(self.path, "current")
+
+        try:
+            with open(conf) as f:
+                self.selected = f.readline()
+
+            books_path = os.path.join(self.path, "books/")
+            for book in os.listdir(books_path):
+                book_file = os.path.join(books_path, book)
+                with open(book_file, 'r') as f:
+                    chapter = int(f.readline())
+                    position = int(f.readline())
+                self._books[book] = {
+                    "chapter": chapter,
+                    "position": position,
+                }
+        except IOError, e:
+            if e.errno == 2:
+                pass
+            else:
+                raise
+        except OSError, e:
+            if e.errno == 2:
+                pass
+            else:
+                raise
index 7a5b691..c3adb31 100644 (file)
@@ -42,11 +42,7 @@ class Gui(object):
 
         self.controller = None
         self.sleep_timer = None
-        self.auto_chapter_selected = False # true if we are in the
-                                           # midle of an automatic
-                                           # chapter change
 
-        self.ignore_next_chapter_change = False
         # set up gui
         self.setup()
         self._callMonitor.connect("call_start", self.__on_call_started)
@@ -232,6 +228,7 @@ class Gui(object):
         self._save_settings(config)
         with open(constants._user_settings_, "wb") as configFile:
             config.write(configFile)
+        self.controller.save()
 
     def _save_settings(self, config):
         config.add_section(constants.__pretty_app_name__)
@@ -273,7 +270,7 @@ class Gui(object):
         else:
             self.win.unfullscreen()
 
-        self.controller.load_books_path(booksPath)
+        self.controller.load(booksPath)
 
     @staticmethod
     def __format_name(path):
@@ -295,6 +292,7 @@ class Gui(object):
         self._bookSelectionIndex = index
         bookName = self._bookSelection[index]
         self.controller.set_book(bookName)
+        self.set_button_text("Play", "Start playing the audiobook") # reset button
 
     @gtk_toolbox.log_exception(_moduleLogger)
     def _on_select_chapter(self, *args):
@@ -309,6 +307,7 @@ class Gui(object):
         self._chapterSelectionIndex = index
         chapterName = self._chapterSelection[index]
         self.controller.set_chapter(chapterName)
+        self.set_button_text("Play", "Start playing the audiobook") # reset button
 
     @gtk_toolbox.log_exception(_moduleLogger)
     def _on_select_sleep(self, *args):
@@ -377,7 +376,7 @@ class Gui(object):
                 orientation = gtk.ORIENTATION_HORIZONTAL
             self.set_orientation(orientation)
         if self.__settingsManager.get_audiobook_path() != self.controller.get_books_path():
-            self.controller.load_books_path(self.__settingsManager.get_audiobook_path())
+            self.controller.reload(self.__settingsManager.get_audiobook_path())
 
         return True
 
@@ -534,24 +533,9 @@ class Gui(object):
     def change_chapter(self, chapterName):
         if chapterName is None:
             _moduleLogger.debug("chapter selection canceled.")
-            #import pdb; pdb.set_trace()     # start debugger
-            self.ignore_next_chapter_change = True
             return True                   # this should end the function and indicate it has been handled
 
-        if self.ignore_next_chapter_change:
-            self.ignore_next_chapter_change = False
-            _moduleLogger.debug("followup chapter selection canceled.")
-            #import pdb; pdb.set_trace()     # start debugger
-            return True                   # this should end the function and indicate it has been handled
-
-        if self.auto_chapter_selected:
-            _moduleLogger.debug("chapter changed (by controller) to: %s" % chapterName)
-            self.auto_chapter_selected = False
-            # do nothing
-        else:
-            _moduleLogger.debug("chapter selection sendt to controller: %s" % chapterName)
-            self.controller.set_chapter(chapterName) # signal controller
-            self.set_button_text("Play", "Start playing the audiobook") # reset button
+        _moduleLogger.debug("chapter changed (by controller) to: %s" % chapterName)
 
     def set_button_text(self, title, text):
         if hildonize.IS_FREMANTLE_SUPPORTED:
@@ -589,7 +573,7 @@ class Gui(object):
         if hildonize.IS_FREMANTLE_SUPPORTED:
             self.chapter_button.set_text("Chapter", str(chapterIndex))
         else:
-            self._chapterMenuItem.get_child().set_text("Chapter: %s" % (chapterIndex, ))
+            self._chapterMenuItem.get_child().set_text("Chapter: %s" % (chapterIndex+1, ))
 
     def set_chapters(self, chapters):
         _moduleLogger.debug("setting chapters" )
index 7b7098e..8535a43 100644 (file)
@@ -30,12 +30,16 @@ class Player(object):
     def get_books_path(self):
         return self._bookDir
 
-    def load_books_path(self, booksPath):
-        _moduleLogger.info("Loading books %s" % booksPath)
+    def reload(self, booksPath):
         if self.audiobook is not None:
             position = self.player.elapsed()
             self.storage.set_time(self.audiobook.current_chapter, position)
+        self.save()
+        self.load(booksPath)
 
+    def load(self, booksPath):
+        _moduleLogger.info("Loading books from %s" % booksPath)
+        self.storage.load()
         self._bookDir = booksPath
 
         self._bookPaths = dict(
@@ -62,6 +66,11 @@ class Player(object):
             except Exception:
                 _moduleLogger.exception("Can you say 'confusion'?")
 
+    def save(self):
+        position = self.player.elapsed()
+        self.storage.set_time(self.audiobook.current_chapter, position)
+        self.storage.save()
+
     @staticmethod
     def __format_name(path):
         if os.path.isfile(path):