1 import os, os.path |
|
2 |
|
3 import settings |
|
4 |
|
5 """ |
1 """ |
6 Miscellaneous utilities |
2 Miscellaneous utilities |
7 """ |
3 """ |
8 |
4 |
9 def isImage (fname) : |
5 import functools |
|
6 |
|
7 class LazyProperty (property) : |
10 """ |
8 """ |
11 Is the given filename likely to be an image file? |
9 Lazy-loaded properties |
12 """ |
10 """ |
13 |
11 |
14 fname = fname.lower() |
12 def __init__ (self, func) : |
15 base, ext = os.path.splitext(fname) |
13 """ |
16 ext = ext.lstrip('.') |
14 Initialize with no value |
|
15 """ |
17 |
16 |
18 return ext in settings.IMAGE_EXTS |
17 super(LazyProperty, self).__init__(func) |
19 |
18 |
20 def readFile (path) : |
19 self.value = None |
21 fo = open(path, 'r') |
|
22 data = fo.read() |
|
23 fo.close() |
|
24 |
20 |
25 return data |
21 def run (self) : |
|
22 """ |
|
23 Run the background func and return the to-be-cached value |
|
24 """ |
26 |
25 |
27 def fuzzyDecode (bytes) : |
26 return super(LazyProperty, self).__call__() |
28 try : |
|
29 return bytes.decode('utf8') |
|
30 except UnicodeDecodeError : |
|
31 return bytes.decode('latin1', 'replace') |
|
32 |
27 |
33 def readTitleDescr (path) : |
28 def __call__ (self) : |
|
29 """ |
|
30 Return the cached value if it exists, otherwise, call the func |
|
31 """ |
|
32 |
|
33 if not self.value : |
|
34 # generate it |
|
35 self.value = self.run() |
|
36 |
|
37 return self.value |
|
38 |
|
39 class LazyIteratorProperty (LazyProperty) : |
34 """ |
40 """ |
35 Read a title.txt or <imgname>.txt file |
41 A lazy-loaded property that automatically converts an iterator/genexp into a list. |
36 """ |
42 """ |
37 |
43 |
38 if os.path.exists(path) : |
44 def run (self) : |
39 content = readFile(path) |
45 """ |
|
46 Wrap LazyProperty.run to return a list |
|
47 """ |
40 |
48 |
41 if '---' in content : |
49 return list(super(LazyIteratorProperty, self).run()) |
42 title, descr = content.split('---', 1) |
|
43 else : |
|
44 title, descr = content, '' |
|
45 |
|
46 title, descr = fuzzyDecode(title), fuzzyDecode(descr) |
|
47 |
50 |
48 return title.strip(), descr.strip() |
51 lazy_load = LazyProperty |
|
52 lazy_load_iter = LazyIteratorProperty |
49 |
53 |
50 return u"", u"" |
|
51 |
|
52 def url (*parts, **kwargs) : |
|
53 abs = kwargs.pop('abs', False) |
|
54 up = kwargs.pop('up', 0) |
|
55 trailing = kwargs.pop('trailing', False) |
|
56 |
|
57 return '/'.join(([""]*int(abs)) + ([".."]*up) + list(parts) + ([""]*int(trailing))) |
|
58 |
|
59 url_join = url |
|
60 |
|
61 def path_join (*parts) : |
|
62 return os.path.join(*[part for part in parts if part is not None]) |
|
63 |
|
64 def strip_path (path) : |
|
65 return path.lstrip('.').lstrip('/') |
|
66 |
|
67 def mtime (path) : |
|
68 try : |
|
69 return os.stat(path).st_mtime |
|
70 except OSError : |
|
71 # no such file or directory |
|
72 return None |
|
73 |
|