Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: sitescripts/web/sources.py

Issue 17817001: Simple CMS as Anwiki replacement (Closed)
Left Patch Set: Created Oct. 23, 2013, 1:52 p.m.
Right Patch Set: Fixed MIME type Created Nov. 4, 2013, 4:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « sitescripts/web/converters.py ('k') | sitescripts/web/utils.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This file is part of the Adblock Plus web scripts, 3 # This file is part of the Adblock Plus web scripts,
4 # Copyright (C) 2006-2013 Eyeo GmbH 4 # Copyright (C) 2006-2013 Eyeo GmbH
5 # 5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify 6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as 7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation. 8 # published by the Free Software Foundation.
9 # 9 #
10 # Adblock Plus is distributed in the hope that it will be useful, 10 # Adblock Plus is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details. 13 # GNU General Public License for more details.
14 # 14 #
15 # You should have received a copy of the GNU General Public License 15 # You should have received a copy of the GNU General Public License
16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
17 17
18 import sys, os, subprocess, zipfile, json, urlparse 18 import sys, os, subprocess, zipfile, json, urlparse, codecs
19 from StringIO import StringIO 19 from StringIO import StringIO
20 from ConfigParser import SafeConfigParser 20 from ConfigParser import SafeConfigParser
21
22 default_locale = "en"
23 21
24 class Source: 22 class Source:
25 def resolve_link(self, url, locale): 23 def resolve_link(self, url, locale):
26 parsed = urlparse.urlparse(url) 24 parsed = urlparse.urlparse(url)
27 page = parsed.path 25 page = parsed.path
28 if parsed.scheme != "" or page.startswith("/") or page.startswith("."): 26 if parsed.scheme != "" or page.startswith("/") or page.startswith("."):
29 # Not a page link 27 # Not a page link
30 return None, None 28 return None, None
31 29
32 if self.has_localizable_file(default_locale, page): 30 config = self.read_config()
33 if not self.has_localizable_file(locale, page): 31 default_locale = config.get("general", "defaultlocale")
32 default_page = config.get("general", "defaultpage")
33
34 checked_page = page
35 if config.has_option("locale_overrides", page):
36 checked_page = config.get("locale_overrides", page)
37
38 if self.has_localizable_file(default_locale, checked_page):
39 if not self.has_localizable_file(locale, checked_page):
34 locale = default_locale 40 locale = default_locale
35 elif self.has_locale(default_locale, page): 41 elif self.has_locale(default_locale, checked_page):
36 if not self.has_locale(locale, page): 42 if not self.has_locale(locale, checked_page):
37 locale = default_locale 43 locale = default_locale
38 else: 44 else:
39 print >>sys.stderr, "Warning: Link to %s cannot be resolved" % page 45 print >>sys.stderr, "Warning: Link to %s cannot be resolved" % page
40 46
41 if page == "index": 47 if page == default_page:
42 page = "" 48 page = ""
43 49
44 path = "/%s/%s" % (locale, page) 50 path = "/%s/%s" % (locale, page)
45 return locale, urlparse.urlunparse(list(parsed[0:2]) + [path] + list(parsed[ 3:])) 51 return locale, urlparse.urlunparse(parsed[0:2] + (path,) + parsed[3:])
46 52
47 def read_config(self): 53 def read_config(self):
48 configdata = self.read_file("settings.ini").decode("utf-8") 54 configdata = self.read_file("settings.ini")
49 config = SafeConfigParser() 55 config = SafeConfigParser()
50 config.readfp(StringIO(configdata)) 56 config.readfp(StringIO(configdata))
51 return config 57 return config
52 58
53 # 59 #
54 # Page helpers 60 # Page helpers
55 # 61 #
56 62
57 @staticmethod 63 @staticmethod
58 def page_filename(page, format): 64 def page_filename(page, format):
(...skipping 13 matching lines...) Expand all
72 78
73 # 79 #
74 # Localizable files helpers 80 # Localizable files helpers
75 # 81 #
76 82
77 @staticmethod 83 @staticmethod
78 def localizable_file_filename(locale, filename): 84 def localizable_file_filename(locale, filename):
79 return "locales/%s/%s" % (locale, filename) 85 return "locales/%s/%s" % (locale, filename)
80 86
81 def list_localizable_files(self): 87 def list_localizable_files(self):
88 default_locale = self.read_config().get("general", "defaultlocale")
82 return filter( 89 return filter(
83 lambda f: os.path.splitext(f)[1] != ".json", 90 lambda f: os.path.splitext(f)[1] != ".json",
84 self.list_files("locales/%s" % default_locale) 91 self.list_files("locales/%s" % default_locale)
85 ) 92 )
86 93
87 def has_localizable_file(self, locale, filename): 94 def has_localizable_file(self, locale, filename):
88 return self.has_file(self.localizable_file_filename(locale, filename)) 95 return self.has_file(self.localizable_file_filename(locale, filename))
89 96
90 def read_localizable_file(self, locale, filename): 97 def read_localizable_file(self, locale, filename):
91 return self.read_file(self.localizable_file_filename(locale, filename)) 98 return self.read_file(self.localizable_file_filename(locale, filename), bina ry=True)
92 99
93 # 100 #
94 # Static file helpers 101 # Static file helpers
95 # 102 #
96 103
97 @staticmethod 104 @staticmethod
98 def static_filename(filename): 105 def static_filename(filename):
99 return "static/%s" % filename 106 return "static/%s" % filename
100 107
101 def list_static(self): 108 def list_static(self):
102 return self.list_files("static") 109 return self.list_files("static")
103 110
104 def has_static(self, filename): 111 def has_static(self, filename):
105 return self.has_file(self.static_filename(filename)) 112 return self.has_file(self.static_filename(filename))
106 113
107 def read_static(self, filename): 114 def read_static(self, filename):
108 return self.read_file(self.static_filename(filename)) 115 return self.read_file(self.static_filename(filename), binary=True)
109 116
110 # 117 #
111 # Locale helpers 118 # Locale helpers
112 # 119 #
113 120
114 @staticmethod 121 @classmethod
115 def locale_filename(locale, page): 122 def locale_filename(cls, locale, page):
116 return "locales/%s/%s.json" % (locale, page) 123 return cls.localizable_file_filename(locale, page + ".json")
117 124
118 def list_locales(self): 125 def list_locales(self):
119 result = set() 126 result = set()
120 for filename in self.list_files("locales"): 127 for filename in self.list_files("locales"):
121 if "/" in filename: 128 if "/" in filename:
122 locale, path = filename.split("/", 1) 129 locale, path = filename.split("/", 1)
123 result.add(locale) 130 result.add(locale)
124 return result 131 return result
125 132
126 def has_locale(self, locale, page): 133 def has_locale(self, locale, page):
134 config = self.read_config()
135 if config.has_option("locale_overrides", page):
136 page = config.get("locale_overrides", page)
127 return self.has_file(self.locale_filename(locale, page)) 137 return self.has_file(self.locale_filename(locale, page))
128 138
129 def read_locale(self, locale, page): 139 def read_locale(self, locale, page):
140 default_locale = self.read_config().get("general", "defaultlocale")
130 if locale == default_locale: 141 if locale == default_locale:
131 result = {} 142 result = {}
132 else: 143 else:
133 result = self.read_locale(default_locale, page) 144 result = self.read_locale(default_locale, page)
134 145
135 if self.has_locale(locale, page): 146 if self.has_locale(locale, page):
136 filedata = self.read_file(self.locale_filename(locale, page)) 147 filedata = self.read_file(self.locale_filename(locale, page))
137 localedata = json.loads(filedata.decode("utf-8")) 148 localedata = json.loads(filedata)
138 for key, value in localedata.iteritems(): 149 for key, value in localedata.iteritems():
139 result[key] = value["message"] 150 result[key] = value["message"]
140 151
141 return result 152 return result
142 153
143 # 154 #
144 # Template helpers 155 # Template helpers
145 # 156 #
146 157
147 @staticmethod 158 @staticmethod
148 def template_filename(template): 159 def template_filename(template):
149 return "templates/%s.tmpl" % template 160 return "templates/%s.tmpl" % template
150 161
151 def read_template(self, template): 162 def read_template(self, template):
152 return self.read_file(self.template_filename(template)) 163 return self.read_file(self.template_filename(template))
153 164
165 #
166 # Include helpers
167 #
168
169 @staticmethod
170 def include_filename(include, format):
171 return "includes/%s.%s" % (include, format)
172
173 def has_include(self, include, format):
174 return self.has_file(self.include_filename(include, format))
175
176 def read_include(self, include, format):
177 return self.read_file(self.include_filename(include, format))
178
154 class MercurialSource(Source): 179 class MercurialSource(Source):
155 def __init__(self, repo): 180 def __init__(self, repo):
156 command = ["hg", "-R", repo, "archive", "-t", "uzip", "-p", ".", "-"] 181 command = ["hg", "-R", repo, "archive", "-r", "default",
157 data, _ = subprocess.Popen(command, stdout=subprocess.PIPE).communicate() 182 "-t", "uzip", "-p", ".", "-"]
183 data = subprocess.check_output(command)
158 self._archive = zipfile.ZipFile(StringIO(data), mode="r") 184 self._archive = zipfile.ZipFile(StringIO(data), mode="r")
185
186 command = ["hg", "-R", repo, "id", "-n", "-r", "default"]
187 self.version = subprocess.check_output(command).strip()
159 188
160 def __enter__(self): 189 def __enter__(self):
161 return self 190 return self
162 191
163 def __exit__(self, type, value, traceback): 192 def __exit__(self, type, value, traceback):
164 self.close() 193 self.close()
165 return False 194 return False
166 195
167 def close(self): 196 def close(self):
168 self._archive.close() 197 self._archive.close()
169 198
170 def has_file(self, filename): 199 def has_file(self, filename):
171 try: 200 try:
172 self._archive.getinfo("./%s" % filename) 201 self._archive.getinfo("./%s" % filename)
173 except KeyError: 202 except KeyError:
174 return False 203 return False
175 return True 204 return True
176 205
177 def read_file(self, filename): 206 def read_file(self, filename, binary=False):
178 return self._archive.read("./%s" % filename) 207 result = self._archive.read("./%s" % filename)
208 if not binary:
209 result = result.decode("utf-8")
210 return result
179 211
180 def list_files(self, subdir): 212 def list_files(self, subdir):
181 prefix = "./" + subdir + "/" 213 prefix = "./%s/" % subdir
182 for filename in self._archive.namelist(): 214 for filename in self._archive.namelist():
183 if filename.startswith(prefix): 215 if filename.startswith(prefix):
184 yield filename[len(prefix):] 216 yield filename[len(prefix):]
185 217
186 class FileSource(Source): 218 class FileSource(Source):
187 def __init__(self, dir): 219 def __init__(self, dir):
188 self._dir = dir 220 self._dir = dir
189 221
190 def __enter__(self): 222 def __enter__(self):
191 return self 223 return self
192 224
193 def __exit__(self, type, value, traceback): 225 def __exit__(self, type, value, traceback):
194 return False 226 return False
195 227
196 def close(self): 228 def close(self):
197 pass 229 pass
198 230
199 def get_path(self, filename): 231 def get_path(self, filename):
200 return os.path.join(self._dir, *filename.split("/")) 232 return os.path.join(self._dir, *filename.split("/"))
201 233
202 def has_file(self, filename): 234 def has_file(self, filename):
203 return os.path.isfile(self.get_path(filename)) 235 return os.path.isfile(self.get_path(filename))
204 236
205 def read_file(self, filename): 237 def read_file(self, filename, binary=False):
206 with open(self.get_path(filename), "rb") as handle: 238 encoding = None if binary else "utf-8"
239 with codecs.open(self.get_path(filename), "rb", encoding=encoding) as handle :
207 return handle.read() 240 return handle.read()
208 241
209 def list_files(self, subdir): 242 def list_files(self, subdir):
210 result = [] 243 result = []
211 def do_list(dir, relpath): 244 def do_list(dir, relpath):
212 files = os.listdir(dir) 245 files = os.listdir(dir)
213 for filename in files: 246 for filename in files:
214 path = os.path.join(dir, filename) 247 path = os.path.join(dir, filename)
215 if os.path.isfile(path): 248 if os.path.isfile(path):
216 result.append(relpath + filename) 249 result.append(relpath + filename)
217 elif os.path.isdir(path): 250 elif os.path.isdir(path):
218 do_list(path, relpath + filename + "/") 251 do_list(path, relpath + filename + "/")
219 do_list(self.get_path(subdir), "") 252 do_list(self.get_path(subdir), "")
220 return result 253 return result
LEFTRIGHT

Powered by Google App Engine
This is Rietveld