Skip to content

Instantly share code, notes, and snippets.

@reinout
Created August 29, 2016 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reinout/40902e8864e851e3c71394630b40d917 to your computer and use it in GitHub Desktop.
Save reinout/40902e8864e851e3c71394630b40d917 to your computer and use it in GitHub Desktop.
import glob
import os
import zipfile
from ConfigParser import ConfigParser # TODO python 3
START = '''<?xml version="1.0"?>
<plugins>
'''
END = '''
</plugins>
'''
TEMPLATE = '''
<pyqgis_plugin name="{name}" version="{version}">
<description>{description}</description>
<homepage>{homepage}</homepage>
<qgis_minimum_version>{qgis_minimum_version}</qgis_minimum_version>
<file_name>{filename}</file_name>
<author_name>{author}</author_name>
<download_url>https://plugins.lizard.net/{filename}</download_url>
</pyqgis_plugin>
'''
PLUGINS_XML = 'plugins.xml'
def extract_name_and_version(filename):
FAULTY = None, None
if not filename.endswith('.zip'):
return FAULTY
filename = filename[:-4]
parts = filename.split('.')
if len(parts) < 2:
return FAULTY
name = parts[0] # Name should not contain a dot, apparently.
version = '.'.join(parts[1:])
return name, version
class PluginZipFile(object):
"""Wrapper around a zip file that extracts metadata"""
def __init__(self, filename):
self.filename = filename
self.name, self.version = extract_name_and_version(filename)
def extract_metadata(self):
"""Return info from the metadata.txt inside the zip file"""
opened_zip_file = zipfile.ZipFile(self.filename, 'r')
expected = os.path.join(self.name, 'metadata.txt')
metadata = ConfigParser()
metadata.readfp(opened_zip_file.open(expected))
result = {}
result['name'] = metadata.get('general', 'name')
result['description'] = metadata.get('general', 'description')
result['homepage'] = metadata.get('general', 'homepage')
result['qgis_minimum_version'] = metadata.get('general', 'qgisMinimumVersion')
result['author'] = metadata.get('general', 'author').replace('&', '&amp;')
# ^^^ TODO: safer replacement wanted
return result
def as_xml(self):
"""Return info about zip file as xml"""
metadata = self.extract_metadata()
metadata['version'] = self.version
metadata['filename'] = self.filename
return TEMPLATE.format(**metadata)
def main(directory=None):
"""Directory is passed by a buildout recipe.
"""
print("Looking in %s" % directory)
current_directory = os.getcwd()
os.chdir(directory)
plugin_zip_files = [PluginZipFile(filename)
for filename in glob.glob('*.zip')]
# Filter out the correctly-named ones.
plugin_zip_files = [plugin_zip_file for plugin_zip_file in plugin_zip_files
if plugin_zip_file.version]
output = ''
output += START
for plugin_zip_file in plugin_zip_files:
try:
output += plugin_zip_file.as_xml()
except Exception as e:
print("Something went wrong with %s" % plugin_zip_file.filename)
print(e)
output += END
open(PLUGINS_XML, 'w').write(output)
print("Wrote %s" % os.path.join(directory, PLUGINS_XML))
os.chdir(current_directory)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment