|
1 import os, os.path |
|
2 |
|
3 import PIL.Image |
|
4 |
|
5 import settings, utils |
|
6 from log import index, render |
|
7 from template import image as image_tpl |
|
8 |
|
9 class Image (object) : |
|
10 def __init__ (self, dir, name) : |
|
11 # the image filename, e.g. DSC3948.JPG |
|
12 self.name = name |
|
13 |
|
14 # the Folder object that we are in |
|
15 self.dir = dir |
|
16 |
|
17 # the relative path from the root to us |
|
18 self.path = dir.pathFor(name) |
|
19 |
|
20 # the basename+ext, e.g. DSCR3948, .JPG |
|
21 self.base_name, self.ext = os.path.splitext(name) |
|
22 |
|
23 # our user-friendly title |
|
24 self.title = name |
|
25 |
|
26 # our long-winded description |
|
27 self.descr = '' |
|
28 |
|
29 # the image before and after us, both may be None |
|
30 self.prev = self.next = None |
|
31 |
|
32 # the image-relative names for the html page, thumb and preview images |
|
33 self.html_name = self.name + ".html" |
|
34 self.thumb_name = utils.url_join(settings.THUMB_DIR, self.name) |
|
35 self.preview_name = utils.url_join(settings.PREVIEW_DIR, self.name) |
|
36 |
|
37 # the root-relative paths to the html page, thumb and preview images |
|
38 self.html_path = self.dir.pathFor(self.html_name) |
|
39 self.thumb_path = self.dir.pathFor(settings.THUMB_DIR, self.name) |
|
40 self.preview_path = self.dir.pathFor(settings.PREVIEW_DIR, self.name) |
|
41 |
|
42 # |
|
43 # Figured out after prepare |
|
44 # |
|
45 |
|
46 # (w, h) tuple |
|
47 self.img_size = None |
|
48 |
|
49 # the ShortURL code for this image |
|
50 self.shorturl_code = None |
|
51 |
|
52 # what to use in the rendered templates, intended to be overridden by subclasses |
|
53 self.series_act = "add" |
|
54 self.series_verb = "Add to" |
|
55 |
|
56 def getObjInfo (self) : |
|
57 """ |
|
58 Metadata for shorturl2.db |
|
59 """ |
|
60 return 'img', self.dir.path, self.name |
|
61 |
|
62 def breadcrumb (self) : |
|
63 """ |
|
64 Returns a [(fname, title)] list of this image's parents |
|
65 """ |
|
66 |
|
67 return self.dir.breadcrumb() + [(self.html_name, self.title)] |
|
68 |
|
69 def render (self) : |
|
70 """ |
|
71 Write out the .html file |
|
72 """ |
|
73 |
|
74 # stat the image file to get the filesize and mtime |
|
75 st = os.stat(self.path) |
|
76 |
|
77 self.filesize = st.st_size |
|
78 self.timestamp = st.st_mtime |
|
79 |
|
80 # open the image in PIL to get image attributes + generate thumbnails |
|
81 img = PIL.Image.open(self.path) |
|
82 |
|
83 self.img_size = img.size |
|
84 |
|
85 for out_path, geom in ((self.thumb_path, settings.THUMB_GEOM), (self.preview_path, settings.PREVIEW_GEOM)) : |
|
86 # if it doesn't exist, or it's older than the image itself, generate |
|
87 if not (os.path.exists(out_path) and os.stat(out_path).st_mtime > self.timestamp) : |
|
88 render.info("Create thumbnailed image at %s with geom %s", out_path, geom) |
|
89 |
|
90 # XXX: is this the most efficient way to do this? It seems slow |
|
91 out_img = img.copy() |
|
92 out_img.thumbnail(geom, resample=True) |
|
93 out_img.save(out_path) |
|
94 |
|
95 # look for the metadata file |
|
96 title_path = self.dir.pathFor(self.base_name + '.txt') |
|
97 |
|
98 self.title, self.descr = utils.readTitleDescr(title_path) |
|
99 |
|
100 if not self.title : |
|
101 self.title = self.name |
|
102 |
|
103 render.info("Rendering image %s", self.path) |
|
104 |
|
105 image_tpl.render_to(self.html_path, |
|
106 stylesheet_url = self.dir.inRoot('style.css'), |
|
107 title = self.title, |
|
108 breadcrumb = self.breadcrumb(), |
|
109 |
|
110 prev = self.prev, |
|
111 next = self.next, |
|
112 img = self, |
|
113 |
|
114 description = self.descr, |
|
115 |
|
116 filename = self.name, |
|
117 img_size = self.img_size, |
|
118 file_size = self.filesize, |
|
119 timestamp = self.timestamp, |
|
120 |
|
121 shorturl = self.dir.inRoot('s', self.shorturl_code), |
|
122 shorturl_code = self.shorturl_code, |
|
123 |
|
124 series_url = self.dir.inRoot('series/%s/%s' % (self.series_act, self.shorturl_code)), |
|
125 series_verb = self.series_verb, |
|
126 ) |
|
127 |
|
128 def __str__ (self) : |
|
129 return "Image `%s' in `%s'" % (self.name, self.dir.path) |