| OLD | NEW |
| 1 # This file is part of the Adblock Plus web scripts, | 1 # This file is part of the Adblock Plus web scripts, |
| 2 # Copyright (C) 2006-2016 Eyeo GmbH | 2 # Copyright (C) 2006-2016 Eyeo GmbH |
| 3 # | 3 # |
| 4 # Adblock Plus is free software: you can redistribute it and/or modify | 4 # Adblock Plus is free software: you can redistribute it and/or modify |
| 5 # it under the terms of the GNU General Public License version 3 as | 5 # it under the terms of the GNU General Public License version 3 as |
| 6 # published by the Free Software Foundation. | 6 # published by the Free Software Foundation. |
| 7 # | 7 # |
| 8 # Adblock Plus is distributed in the hope that it will be useful, | 8 # Adblock Plus is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 import subprocess | 22 import subprocess |
| 23 import urlparse | 23 import urlparse |
| 24 import zipfile | 24 import zipfile |
| 25 import logging | 25 import logging |
| 26 | 26 |
| 27 | 27 |
| 28 class Source: | 28 class Source: |
| 29 def resolve_link(self, url, locale): | 29 def resolve_link(self, url, locale): |
| 30 parsed = urlparse.urlparse(url) | 30 parsed = urlparse.urlparse(url) |
| 31 page = parsed.path | 31 page = parsed.path |
| 32 if parsed.scheme != "" or page.startswith("/") or page.startswith("."): | 32 if parsed.scheme != '' or page.startswith('/') or page.startswith('.'): |
| 33 # Not a page link | 33 # Not a page link |
| 34 return None, None | 34 return None, None |
| 35 | 35 |
| 36 if page == "" and url != "": | 36 if page == '' and url != '': |
| 37 # Page-relative link | 37 # Page-relative link |
| 38 return None, None | 38 return None, None |
| 39 | 39 |
| 40 config = self.read_config() | 40 config = self.read_config() |
| 41 default_locale = config.get("general", "defaultlocale") | 41 default_locale = config.get('general', 'defaultlocale') |
| 42 default_page = config.get("general", "defaultpage") | 42 default_page = config.get('general', 'defaultpage') |
| 43 alternative_page = "/".join([page.rstrip("/"), default_page]).lstrip("/"
) | 43 alternative_page = '/'.join([page.rstrip('/'), default_page]).lstrip('/'
) |
| 44 | 44 |
| 45 if self.has_localizable_file(default_locale, page): | 45 if self.has_localizable_file(default_locale, page): |
| 46 if not self.has_localizable_file(locale, page): | 46 if not self.has_localizable_file(locale, page): |
| 47 locale = default_locale | 47 locale = default_locale |
| 48 elif self.has_page(page): | 48 elif self.has_page(page): |
| 49 if not self.has_locale(locale, page): | 49 if not self.has_locale(locale, page): |
| 50 locale = default_locale | 50 locale = default_locale |
| 51 elif self.has_page(alternative_page): | 51 elif self.has_page(alternative_page): |
| 52 if not self.has_locale(locale, alternative_page): | 52 if not self.has_locale(locale, alternative_page): |
| 53 locale = default_locale | 53 locale = default_locale |
| 54 else: | 54 else: |
| 55 logging.warning("Link to %s cannot be resolved", page) | 55 logging.warning('Link to %s cannot be resolved', page) |
| 56 | 56 |
| 57 parts = page.split("/") | 57 parts = page.split('/') |
| 58 if parts[-1] == default_page: | 58 if parts[-1] == default_page: |
| 59 page = "/".join(parts[:-1]) | 59 page = '/'.join(parts[:-1]) |
| 60 | 60 |
| 61 path = "/%s/%s" % (locale, page) | 61 path = '/%s/%s' % (locale, page) |
| 62 return locale, urlparse.urlunparse(parsed[0:2] + (path,) + parsed[3:]) | 62 return locale, urlparse.urlunparse(parsed[0:2] + (path,) + parsed[3:]) |
| 63 | 63 |
| 64 def read_config(self): | 64 def read_config(self): |
| 65 configdata = self.read_file("settings.ini")[0] | 65 configdata = self.read_file('settings.ini')[0] |
| 66 config = ConfigParser.SafeConfigParser() | 66 config = ConfigParser.SafeConfigParser() |
| 67 config.readfp(StringIO(configdata)) | 67 config.readfp(StringIO(configdata)) |
| 68 return config | 68 return config |
| 69 | 69 |
| 70 def exec_file(self, filename): | 70 def exec_file(self, filename): |
| 71 source, filename = self.read_file(filename) | 71 source, filename = self.read_file(filename) |
| 72 code = compile(source, filename, "exec") | 72 code = compile(source, filename, 'exec') |
| 73 namespace = {} | 73 namespace = {} |
| 74 exec code in namespace | 74 exec code in namespace |
| 75 return namespace | 75 return namespace |
| 76 | 76 |
| 77 # | 77 # |
| 78 # Page helpers | 78 # Page helpers |
| 79 # | 79 # |
| 80 | 80 |
| 81 @staticmethod | 81 @staticmethod |
| 82 def page_filename(page, format): | 82 def page_filename(page, format): |
| 83 return "pages/%s.%s" % (page, format) | 83 return 'pages/%s.%s' % (page, format) |
| 84 | 84 |
| 85 def list_pages(self): | 85 def list_pages(self): |
| 86 for filename in self.list_files("pages"): | 86 for filename in self.list_files('pages'): |
| 87 root, ext = os.path.splitext(filename) | 87 root, ext = os.path.splitext(filename) |
| 88 format = ext[1:].lower() | 88 format = ext[1:].lower() |
| 89 yield root, format | 89 yield root, format |
| 90 | 90 |
| 91 def has_page(self, page, format=None): | 91 def has_page(self, page, format=None): |
| 92 if format is None: | 92 if format is None: |
| 93 from cms.converters import converters | 93 from cms.converters import converters |
| 94 return any( | 94 return any( |
| 95 self.has_page(page, format) | 95 self.has_page(page, format) |
| 96 for format in converters.iterkeys() | 96 for format in converters.iterkeys() |
| 97 ) | 97 ) |
| 98 else: | 98 else: |
| 99 return self.has_file(self.page_filename(page, format)) | 99 return self.has_file(self.page_filename(page, format)) |
| 100 | 100 |
| 101 def read_page(self, page, format): | 101 def read_page(self, page, format): |
| 102 return self.read_file(self.page_filename(page, format)) | 102 return self.read_file(self.page_filename(page, format)) |
| 103 | 103 |
| 104 # | 104 # |
| 105 # Localizable files helpers | 105 # Localizable files helpers |
| 106 # | 106 # |
| 107 | 107 |
| 108 @staticmethod | 108 @staticmethod |
| 109 def localizable_file_filename(locale, filename): | 109 def localizable_file_filename(locale, filename): |
| 110 return "locales/%s/%s" % (locale, filename) | 110 return 'locales/%s/%s' % (locale, filename) |
| 111 | 111 |
| 112 def list_localizable_files(self): | 112 def list_localizable_files(self): |
| 113 default_locale = self.read_config().get("general", "defaultlocale") | 113 default_locale = self.read_config().get('general', 'defaultlocale') |
| 114 return filter( | 114 return filter( |
| 115 lambda f: os.path.splitext(f)[1].lower() != ".json", | 115 lambda f: os.path.splitext(f)[1].lower() != '.json', |
| 116 self.list_files("locales/%s" % default_locale) | 116 self.list_files('locales/%s' % default_locale) |
| 117 ) | 117 ) |
| 118 | 118 |
| 119 def has_localizable_file(self, locale, filename): | 119 def has_localizable_file(self, locale, filename): |
| 120 return self.has_file(self.localizable_file_filename(locale, filename)) | 120 return self.has_file(self.localizable_file_filename(locale, filename)) |
| 121 | 121 |
| 122 def read_localizable_file(self, locale, filename): | 122 def read_localizable_file(self, locale, filename): |
| 123 return self.read_file(self.localizable_file_filename(locale, filename),
binary=True)[0] | 123 return self.read_file(self.localizable_file_filename(locale, filename),
binary=True)[0] |
| 124 | 124 |
| 125 # | 125 # |
| 126 # Static file helpers | 126 # Static file helpers |
| 127 # | 127 # |
| 128 | 128 |
| 129 @staticmethod | 129 @staticmethod |
| 130 def static_filename(filename): | 130 def static_filename(filename): |
| 131 return "static/%s" % filename | 131 return 'static/%s' % filename |
| 132 | 132 |
| 133 def list_static(self): | 133 def list_static(self): |
| 134 return self.list_files("static") | 134 return self.list_files('static') |
| 135 | 135 |
| 136 def has_static(self, filename): | 136 def has_static(self, filename): |
| 137 return self.has_file(self.static_filename(filename)) | 137 return self.has_file(self.static_filename(filename)) |
| 138 | 138 |
| 139 def read_static(self, filename): | 139 def read_static(self, filename): |
| 140 return self.read_file(self.static_filename(filename), binary=True)[0] | 140 return self.read_file(self.static_filename(filename), binary=True)[0] |
| 141 | 141 |
| 142 # | 142 # |
| 143 # Locale helpers | 143 # Locale helpers |
| 144 # | 144 # |
| 145 | 145 |
| 146 @classmethod | 146 @classmethod |
| 147 def locale_filename(cls, locale, page): | 147 def locale_filename(cls, locale, page): |
| 148 return cls.localizable_file_filename(locale, page + ".json") | 148 return cls.localizable_file_filename(locale, page + '.json') |
| 149 | 149 |
| 150 def list_locales(self): | 150 def list_locales(self): |
| 151 result = set() | 151 result = set() |
| 152 for filename in self.list_files("locales"): | 152 for filename in self.list_files('locales'): |
| 153 if "/" in filename: | 153 if '/' in filename: |
| 154 locale, path = filename.split("/", 1) | 154 locale, path = filename.split('/', 1) |
| 155 result.add(locale) | 155 result.add(locale) |
| 156 return result | 156 return result |
| 157 | 157 |
| 158 def has_locale(self, locale, page): | 158 def has_locale(self, locale, page): |
| 159 config = self.read_config() | 159 config = self.read_config() |
| 160 try: | 160 try: |
| 161 page = config.get("locale_overrides", page) | 161 page = config.get('locale_overrides', page) |
| 162 except ConfigParser.Error: | 162 except ConfigParser.Error: |
| 163 pass | 163 pass |
| 164 return self.has_file(self.locale_filename(locale, page)) | 164 return self.has_file(self.locale_filename(locale, page)) |
| 165 | 165 |
| 166 def read_locale(self, locale, page): | 166 def read_locale(self, locale, page): |
| 167 default_locale = self.read_config().get("general", "defaultlocale") | 167 default_locale = self.read_config().get('general', 'defaultlocale') |
| 168 result = collections.OrderedDict() | 168 result = collections.OrderedDict() |
| 169 if locale != default_locale: | 169 if locale != default_locale: |
| 170 result.update(self.read_locale(default_locale, page)) | 170 result.update(self.read_locale(default_locale, page)) |
| 171 | 171 |
| 172 if self.has_locale(locale, page): | 172 if self.has_locale(locale, page): |
| 173 filedata = self.read_file(self.locale_filename(locale, page))[0] | 173 filedata = self.read_file(self.locale_filename(locale, page))[0] |
| 174 localedata = json.loads(filedata) | 174 localedata = json.loads(filedata) |
| 175 for key, value in localedata.iteritems(): | 175 for key, value in localedata.iteritems(): |
| 176 result[key] = value["message"] | 176 result[key] = value['message'] |
| 177 | 177 |
| 178 return result | 178 return result |
| 179 | 179 |
| 180 # | 180 # |
| 181 # Template helpers | 181 # Template helpers |
| 182 # | 182 # |
| 183 | 183 |
| 184 @staticmethod | 184 @staticmethod |
| 185 def template_filename(template): | 185 def template_filename(template): |
| 186 return "templates/%s.tmpl" % template | 186 return 'templates/%s.tmpl' % template |
| 187 | 187 |
| 188 def read_template(self, template): | 188 def read_template(self, template): |
| 189 return self.read_file(self.template_filename(template)) | 189 return self.read_file(self.template_filename(template)) |
| 190 | 190 |
| 191 # | 191 # |
| 192 # Include helpers | 192 # Include helpers |
| 193 # | 193 # |
| 194 | 194 |
| 195 @staticmethod | 195 @staticmethod |
| 196 def include_filename(include, format): | 196 def include_filename(include, format): |
| 197 return "includes/%s.%s" % (include, format) | 197 return 'includes/%s.%s' % (include, format) |
| 198 | 198 |
| 199 def has_include(self, include, format): | 199 def has_include(self, include, format): |
| 200 return self.has_file(self.include_filename(include, format)) | 200 return self.has_file(self.include_filename(include, format)) |
| 201 | 201 |
| 202 def read_include(self, include, format): | 202 def read_include(self, include, format): |
| 203 return self.read_file(self.include_filename(include, format)) | 203 return self.read_file(self.include_filename(include, format)) |
| 204 | 204 |
| 205 | 205 |
| 206 class MercurialSource(Source): | 206 class MercurialSource(Source): |
| 207 def __init__(self, repo): | 207 def __init__(self, repo): |
| 208 command = ["hg", "-R", repo, "archive", "-r", "default", | 208 command = ['hg', '-R', repo, 'archive', '-r', 'default', |
| 209 "-t", "uzip", "-p", ".", "-"] | 209 '-t', 'uzip', '-p', '.', '-'] |
| 210 data = subprocess.check_output(command) | 210 data = subprocess.check_output(command) |
| 211 self._archive = zipfile.ZipFile(StringIO(data), mode="r") | 211 self._archive = zipfile.ZipFile(StringIO(data), mode='r') |
| 212 | 212 |
| 213 command = ["hg", "-R", repo, "id", "-n", "-r", "default"] | 213 command = ['hg', '-R', repo, 'id', '-n', '-r', 'default'] |
| 214 self.version = subprocess.check_output(command).strip() | 214 self.version = subprocess.check_output(command).strip() |
| 215 | 215 |
| 216 self._name = os.path.basename(repo.rstrip(os.path.sep)) | 216 self._name = os.path.basename(repo.rstrip(os.path.sep)) |
| 217 | 217 |
| 218 def __enter__(self): | 218 def __enter__(self): |
| 219 return self | 219 return self |
| 220 | 220 |
| 221 def __exit__(self, type, value, traceback): | 221 def __exit__(self, type, value, traceback): |
| 222 self.close() | 222 self.close() |
| 223 return False | 223 return False |
| 224 | 224 |
| 225 def close(self): | 225 def close(self): |
| 226 self._archive.close() | 226 self._archive.close() |
| 227 | 227 |
| 228 def has_file(self, filename): | 228 def has_file(self, filename): |
| 229 try: | 229 try: |
| 230 self._archive.getinfo("./%s" % filename) | 230 self._archive.getinfo('./%s' % filename) |
| 231 except KeyError: | 231 except KeyError: |
| 232 return False | 232 return False |
| 233 return True | 233 return True |
| 234 | 234 |
| 235 def read_file(self, filename, binary=False): | 235 def read_file(self, filename, binary=False): |
| 236 data = self._archive.read("./%s" % filename) | 236 data = self._archive.read('./%s' % filename) |
| 237 if not binary: | 237 if not binary: |
| 238 data = data.decode("utf-8") | 238 data = data.decode('utf-8') |
| 239 return (data, "%s!%s" % (self._name, filename)) | 239 return (data, '%s!%s' % (self._name, filename)) |
| 240 | 240 |
| 241 def list_files(self, subdir): | 241 def list_files(self, subdir): |
| 242 prefix = "./%s/" % subdir | 242 prefix = './%s/' % subdir |
| 243 for filename in self._archive.namelist(): | 243 for filename in self._archive.namelist(): |
| 244 if filename.startswith(prefix): | 244 if filename.startswith(prefix): |
| 245 yield filename[len(prefix):] | 245 yield filename[len(prefix):] |
| 246 | 246 |
| 247 if os.name == "posix": | 247 if os.name == 'posix': |
| 248 def get_cache_dir(self): | 248 def get_cache_dir(self): |
| 249 return "/var/cache/" + self._name | 249 return '/var/cache/' + self._name |
| 250 | 250 |
| 251 | 251 |
| 252 class FileSource(Source): | 252 class FileSource(Source): |
| 253 def __init__(self, dir): | 253 def __init__(self, dir): |
| 254 self._dir = dir | 254 self._dir = dir |
| 255 | 255 |
| 256 def __enter__(self): | 256 def __enter__(self): |
| 257 return self | 257 return self |
| 258 | 258 |
| 259 def __exit__(self, type, value, traceback): | 259 def __exit__(self, type, value, traceback): |
| 260 return False | 260 return False |
| 261 | 261 |
| 262 def close(self): | 262 def close(self): |
| 263 pass | 263 pass |
| 264 | 264 |
| 265 def get_path(self, filename): | 265 def get_path(self, filename): |
| 266 return os.path.join(self._dir, *filename.split("/")) | 266 return os.path.join(self._dir, *filename.split('/')) |
| 267 | 267 |
| 268 def has_file(self, filename): | 268 def has_file(self, filename): |
| 269 return os.path.isfile(self.get_path(filename)) | 269 return os.path.isfile(self.get_path(filename)) |
| 270 | 270 |
| 271 def read_file(self, filename, binary=False): | 271 def read_file(self, filename, binary=False): |
| 272 path = self.get_path(filename) | 272 path = self.get_path(filename) |
| 273 | 273 |
| 274 if binary: | 274 if binary: |
| 275 file = open(path, "rb") | 275 file = open(path, 'rb') |
| 276 else: | 276 else: |
| 277 file = io.open(path, "r", encoding="utf-8") | 277 file = io.open(path, 'r', encoding='utf-8') |
| 278 | 278 |
| 279 with file: | 279 with file: |
| 280 return (file.read(), path) | 280 return (file.read(), path) |
| 281 | 281 |
| 282 def list_files(self, subdir): | 282 def list_files(self, subdir): |
| 283 result = [] | 283 result = [] |
| 284 | 284 |
| 285 def do_list(dir, relpath): | 285 def do_list(dir, relpath): |
| 286 try: | 286 try: |
| 287 files = os.listdir(dir) | 287 files = os.listdir(dir) |
| 288 except OSError: | 288 except OSError: |
| 289 return | 289 return |
| 290 | 290 |
| 291 for filename in files: | 291 for filename in files: |
| 292 path = os.path.join(dir, filename) | 292 path = os.path.join(dir, filename) |
| 293 if os.path.isfile(path): | 293 if os.path.isfile(path): |
| 294 result.append(relpath + filename) | 294 result.append(relpath + filename) |
| 295 elif os.path.isdir(path): | 295 elif os.path.isdir(path): |
| 296 do_list(path, relpath + filename + "/") | 296 do_list(path, relpath + filename + '/') |
| 297 do_list(self.get_path(subdir), "") | 297 do_list(self.get_path(subdir), '') |
| 298 return result | 298 return result |
| 299 | 299 |
| 300 def get_cache_dir(self): | 300 def get_cache_dir(self): |
| 301 return os.path.join(self._dir, "cache") | 301 return os.path.join(self._dir, 'cache') |
| OLD | NEW |