Changing whitespace and fixing a bug with reconfiguring
[nqaap] / src / opt / Nqa-Audiobook-player / Audiobook.py
1 from __future__ import with_statement
2
3 import os
4
5 import logging
6
7
8 _moduleLogger = logging.getLogger(__name__)
9
10
11 class Audiobook(object):
12
13         def __init__(self, path, current_chapter = 0):
14                 self.title = ""
15                 self._coverPath = ""
16                 self._chapterPaths = []
17                 self.current_chapter = current_chapter
18
19                 if is_playlist_book(path):
20                         self._scan_index(path)
21                 elif is_dir_book(path):
22                         self._scan_dir(path)
23                 elif is_single_chapter(path):
24                         self._scan_chapter(path)
25                 else:
26                         _moduleLogger.info("Audiobook not found in path: " + path)
27                         raise IOError("Audiobook directory not found")
28
29                 if len(self._chapterPaths) <= self.current_chapter:
30                         _moduleLogger.warning(
31                                 "Audiobook chapter out of range (%s/%s)" % (
32                                         self.current_chapter, len(self._chapterPaths)
33                                 )
34                         )
35                         self.current_chapter = 0
36
37         @property
38         def chapters(self):
39                 return self._chapterPaths
40
41         def get_current_chapter(self):
42                 return self._chapterPaths[self.current_chapter]
43
44         def set_chapter(self, chapter):
45                 if chapter in self.chapters:
46                         self.current_chapter = self.chapters.index(chapter)
47                 else:
48                         raise Exception("Unknown chapter set")
49
50         def get_previous_chapter(self):
51                 """
52                 @returns the file name for the next chapter, without path
53                 """
54                 if 0 == self.current_chapter:
55                         return False
56                 else:
57                         self.current_chapter -= 1
58                         return self._chapterPaths[self.current_chapter]
59
60         def get_next_chapter(self):
61                 """
62                 @returns the file name for the next chapter, without path
63                 """
64                 if len(self._chapterPaths) == self.current_chapter:
65                         return False
66                 else:
67                         self.current_chapter += 1
68                         return self._chapterPaths[self.current_chapter]
69
70         def get_cover_img(self):
71                 if self._coverPath:
72                         return self._coverPath
73                 else:
74                         return "%s/NoCover.png" % os.path.dirname(__file__)
75
76         def _scan_dir(self, root):
77                 self.title = os.path.split(root)[-1]
78                 dirContent = (
79                         os.path.join(root, f)
80                         for f in os.listdir(root)
81                         if not f.startswith(".")
82                 )
83
84                 files = [
85                         path
86                         for path in dirContent
87                         if os.path.isfile(os.path.join(root, path))
88                 ]
89
90                 images = [
91                         path
92                         for path in files
93                         if path.rsplit(".", 1)[-1] in ["png", "gif", "jpg", "jpeg"]
94                 ]
95                 if 0 < len(images):
96                         self._coverPath = images[0]
97
98                 self._chapterPaths = [
99                         path
100                         for path in files
101                         if is_single_chapter(path)
102                 ]
103                 self._chapterPaths.sort()
104
105         def _scan_chapter(self, file):
106                 self._chapterPaths = [file]
107
108         def _scan_playlist(self, file):
109                 root = os.path.dirname(file)
110                 self.title = os.path.basename(file).rsplit(".")[0]
111
112                 with open(file, 'r') as f:
113                         for line in f:
114                                 if line.startswith("#"):
115                                         continue
116                                 path = line
117                                 if not os.path.isabs(path):
118                                         path = os.path.normpath(os.path.join(root, path))
119                                 self._chapterPaths.append(path)
120                 # Not sorting, assuming the file is in the desired order
121
122         def _scan_index(self, file):
123                 import unicodedata
124
125                 # Reading file
126                 looking_for_title = False
127                 looking_for_cover = False
128                 looking_for_chapters = False
129
130                 with open(file, 'r') as f:
131                         for line in f:
132                                 # title
133                                 ascii = unicodedata.normalize('NFKD', unicode(line, "latin-1")).encode('ascii', 'ignore')
134                                 print line[:-1], "PIC\n" in line, line in "#PIC"
135                                 if "#BOOK" in line:
136                                         looking_for_title = True
137                                         continue
138                                 if looking_for_title:
139                                         self.title = line[:-1]
140                                         looking_for_title = False
141                                 if "#PIC" in line:
142                                         looking_for_cover = True
143                                         continue
144                                 if looking_for_cover:
145                                         self.cover = line[:-1]
146                                         looking_for_cover = False
147                                 if "#TRACKS" in line:
148                                         looking_for_chapters = True
149                                         continue
150                                 if looking_for_chapters:
151                                         if "#CHAPTERS" in line:
152                                                 break              # no further information needed
153                                         self.chapters.append(line.split(':')[0])
154
155
156 def is_dir_book(path):
157         return os.path.isdir(path)
158
159
160 def is_playlist_book(path):
161         return path.rsplit(".", 1)[-1] in ["m3u"]
162
163
164 def is_single_chapter(path):
165         return path.rsplit(".", 1)[-1] in ["awb", "mp3", "spx", "ogg", "ac3", "wav"]
166
167
168 def is_book(path):
169         if is_dir_book(path):
170                 return True
171         elif is_playlist_book(path):
172                 return True
173         elif is_single_chapter(path):
174                 return True
175         else:
176                 return False