making loading old settings more resilient
[nqaap] / src / FileStorage.py
1 from __future__ import with_statement   # enable with
2
3 import os
4 import simplejson
5 import logging
6
7
8 _moduleLogger = logging.getLogger(__name__)
9
10
11 # @todo Add bookmarks
12
13
14 class FileStorage(object):
15
16         def __init__(self, path="~/.SornPlayer/"):
17                 # Setup dir
18                 _moduleLogger.info("init filestorage")
19                 self.path = path
20                 self.books_path = os.path.join(self.path, "books.json")
21                 self.selected = None
22                 self._books = {}
23
24         def load(self):
25                 if not os.path.isdir(self.path):
26                         os.makedirs(self.path)
27
28                 try:
29                         with open(self.books_path, "r") as settingsFile:
30                                 settings = simplejson.load(settingsFile)
31                 except IOError, e:
32                         _moduleLogger.info("No settings")
33                         settings = {}
34                 except ValueError:
35                         _moduleLogger.info("Settings were corrupt")
36                         settings = {}
37
38                 if settings:
39                         self._books = settings["books"]
40                         self.selected = settings["selected"]
41                 else:
42                         _moduleLogger.info("Falling back to old settings format")
43                         self._load_old_settings()
44
45         def save(self):
46                 settings = {
47                         "selected": self.selected,
48                         "books": self._books,
49                 }
50                 with open(self.books_path, "w") as settingsFile:
51                         simplejson.dump(settings, settingsFile)
52
53         def get_selected(self):
54                 """returns the currently selected book"""
55                 return self.selected
56
57         def select_book(self, bookName):
58                 """ Sets the book as the currently playing, and adds it to the
59                 database if it is not already there"""
60                 book_file = os.path.join(self.books_path, bookName)
61                 if bookName not in self._books:
62                         self._books[bookName] = {
63                                 "chapter": 0,
64                                 "position": 0,
65                         }
66
67                 self.selected = bookName
68
69         def set_time(self, chapter, position):
70                 """ Sets the current time for the book that is currently selected"""
71                 bookInfo = self._books[self.selected]
72                 bookInfo["chapter"] = chapter
73                 bookInfo["position"] = position
74
75         def get_time(self):
76                 """Returns the current saved time for the current selected book"""
77                 bookInfo = self._books[self.selected]
78                 return bookInfo["chapter"], bookInfo["position"]
79
80         def _load_old_settings(self):
81                 conf = os.path.join(self.path, "current")
82
83                 try:
84                         with open(conf) as f:
85                                 self.selected = f.readline()
86
87                         books_path = os.path.join(self.path, "books/")
88                         for book in os.listdir(books_path):
89                                 book_file = os.path.join(books_path, book)
90                                 with open(book_file, 'r') as f:
91                                         try:
92                                                 chapter = int(f.readline())
93                                                 position = int(f.readline())
94                                         except ValueError:
95                                                 _moduleLogger.exception("Trouble loading old settings from %s" % book_file)
96                                                 chapter = 0
97                                                 position = 0
98                                 self._books[book] = {
99                                         "chapter": chapter,
100                                         "position": position,
101                                 }
102                 except IOError, e:
103                         if e.errno == 2:
104                                 pass
105                         else:
106                                 raise
107                 except OSError, e:
108                         if e.errno == 2:
109                                 pass
110                         else:
111                                 raise