Noticed I introduced some tabs thanks to my makefile magic
[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.cover = 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