| Index: packagerSafari.py | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/packagerSafari.py | 
| @@ -0,0 +1,153 @@ | 
| +# coding: utf-8 | 
| + | 
| +# This file is part of the Adblock Plus build tools, | 
| +# Copyright (C) 2006-2013 Eyeo GmbH | 
| +# | 
| +# Adblock Plus is free software: you can redistribute it and/or modify | 
| +# it under the terms of the GNU General Public License version 3 as | 
| +# published by the Free Software Foundation. | 
| +# | 
| +# Adblock Plus is distributed in the hope that it will be useful, | 
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| +# GNU General Public License for more details. | 
| +# | 
| +# You should have received a copy of the GNU General Public License | 
| +# along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| + | 
| +import re, json | 
| +from urlparse import urlparse | 
| +from collections import OrderedDict | 
| + | 
| +from packager import readMetadata, getDefaultFileName, getBuildVersion, getTemplate, Files | 
| +from buildtools.packagerChrome import convertJS, importGeckoLocales, getIgnoredFiles, getPackageFiles, ImageConverter | 
| + | 
| +def createPlist(params, files): | 
| +  template = getTemplate('Info.plist.tmpl') | 
| +  metadata = params['metadata'] | 
| +  catalog = json.loads(files['_locales/en_US/messages.json']) | 
| + | 
| +  def toxml(val, indent=0): | 
| +    if isinstance(val, bool): | 
| +      return '<true/>' if val else '<false/>' | 
| +    if isinstance(val, (int, long)): | 
| +      return '<real>%d</real>' % val | 
| +    if isinstance(val, basestring): | 
| +      return '<string>%s</string>' % val | 
| + | 
| +  def parse_section(section, levels=1): | 
| +    rv = OrderedDict() | 
| + | 
| +    if not metadata.has_section(section): | 
| +      return rv | 
| + | 
| +    for opt in metadata.options(section): | 
| +      bits = opt.split('_', levels) | 
| +      key = bits.pop(-1).replace('_', ' ').title() | 
| +      d = rv | 
| + | 
| +      for x in bits: | 
| +        try: | 
| +          d = d[x] | 
| +        except KeyError: | 
| +          d[x] = d = OrderedDict() | 
| + | 
| +      d[key] = metadata.get(section, opt) | 
| + | 
| +    return rv | 
| + | 
| +  allowedDomains = set() | 
| +  allowAllDomains = False | 
| +  allowSecurePages = False | 
| + | 
| +  for perm in re.split(r'\s+', metadata.get('general', 'permissions')): | 
| +    if perm == '<all_urls>': | 
| +      allowAllDomains = True | 
| +      allowSecurePages = True | 
| +      continue | 
| + | 
| +    url = urlparse(perm) | 
| + | 
| +    if url.scheme == 'https': | 
| +      allowSecurePages = True | 
| +    elif url.scheme != 'http': | 
| +      continue | 
| + | 
| +    if '*' in url.hostname: | 
| +      allowAllDomains = True | 
| +      continue | 
| + | 
| +    allowedDomains.add(url.hostname) | 
| + | 
| +  menus = parse_section('menus', 2) | 
| +  toolbarItems = parse_section('toolbar_items') | 
| + | 
| +  return template.render( | 
| +    author=metadata.get('general', 'author'), | 
| +    version=params['version'], | 
| +    name=catalog['name']['message'], | 
| +    description=catalog['description']['message'], | 
| +    website=metadata.get('general', 'website'), | 
| +    identifier=metadata.get('general', 'identifier'), | 
| +    allowedDomains=allowedDomains, | 
| +    allowAllDomains=allowAllDomains, | 
| +    allowSecurePages=allowSecurePages, | 
| +    contentScripts={ | 
| +      'start': metadata.get('contentScripts', 'document_start').split(), | 
| +      'end':   metadata.get('contentScripts', 'document_end'  ).split(), | 
| +    }, | 
| +    menus=parse_section('menus', 2), | 
| +    toolbarItems=parse_section('toolbar_items'), | 
| +    popovers=parse_section('popovers'), | 
| +    toxml=toxml | 
| +  ).encode('utf-8') | 
| + | 
| +def createBackgroundPage(params): | 
| +  template = getTemplate('background.html.tmpl') | 
| +  return template.render( | 
| +    backgroundScripts=re.split(r'\s+', params['metadata'].get( | 
| +      'general', 'backgroundScripts' | 
| +    )) | 
| +  ).encode('utf-8') | 
| + | 
| +def createInfoModule(params): | 
| +  template = getTemplate('safariInfo.js.tmpl') | 
| +  return template.render(params).encode('utf-8'); | 
| + | 
| +def createBuild(baseDir, type, outFile=None, buildNum=None, releaseBuild=False): | 
| +  metadata = readMetadata(baseDir, type) | 
| +  version = getBuildVersion(baseDir, metadata, releaseBuild, buildNum) | 
| + | 
| +  if outFile == None: | 
| +    outFile = getDefaultFileName(baseDir, metadata, version, 'zip') | 
| + | 
| +  params = { | 
| +    'type': type, | 
| +    'baseDir': baseDir, | 
| +    'releaseBuild': releaseBuild, | 
| +    'version': version, | 
| +    'devenv': False, | 
| +    'metadata': metadata, | 
| +  } | 
| + | 
| +  files = Files(getPackageFiles(params), getIgnoredFiles(params), | 
| +                process=lambda path, data: data) | 
| +  if metadata.has_section('mapping'): | 
| +    files.readMappedFiles(metadata.items('mapping')) | 
| +  files.read(baseDir) | 
| + | 
| +  if metadata.has_section('convert_js'): | 
| +    convertJS(params, files) | 
| + | 
| +  if metadata.has_section('convert_img'): | 
| +    ImageConverter().convert(params, files) | 
| + | 
| +  if metadata.has_section('import_locales'): | 
| +    importGeckoLocales(params, files) | 
| + | 
| +  files['lib/info.js'] = createInfoModule(params) | 
| +  files['background.html'] = createBackgroundPage(params) | 
| +  files['Info.plist'] = createPlist(params, files) | 
| + | 
| +  with open(outFile, 'wb') as f: | 
| +    f.write(files.zipToString()) | 
|  |