Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed May 3, 2021
0 parents commit 0e60875
Show file tree
Hide file tree
Showing 12 changed files with 591 additions and 0 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Run tests and release

on:
push:
tags: "*"
branches:
- master
pull_request:
branches:
- master

env:
PROJECT_FOLDER: "qgis_plugin_repo"
PYTHON_VERSION: 3.8

jobs:
# tests:
# name: "Tests"
# runs-on: ubuntu-latest
#
# steps:
# - name: Get source code
# uses: actions/checkout@v2
#
# - name: Set up Python
# uses: actions/setup-python@v1
# with:
# python-version: ${{ env.PYTHON_VERSION }}
#
# - name: Install Python requirements
# run: python -m pip install -U pip setuptools wheel
#
# - name: Run tests
# working-directory: tests
# run: python -m unittest

release:
name: "Release on tag 🚀"
runs-on: ubuntu-latest
needs: [tests]

if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')

steps:
- name: Get source code
uses: actions/checkout@v2

- name: Setup
run: |
VERSION=${GITHUB_REF:-0.0.0}
VERSION=${VERSION##*/}
sed "s/__VERSION__/${VERSION}/" setup.py > setup.py
- name: Deploy to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#IDE
.idea/

# Python
__pycache__/
*.egg-info
.venv
venv
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# QGIS-Plugin-Repo-Merge

Merge some QGIS plugin repository together

```bash
qgis-plugin-repo-merge all_plugins.xml https://path/to/plugins_to_add.xml
```
3 changes: 3 additions & 0 deletions qgis_plugin_repo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__copyright__ = 'Copyright 2021, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'
71 changes: 71 additions & 0 deletions qgis_plugin_repo/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3

import argparse

from qgis_plugin_repo.merger import Merger

__copyright__ = 'Copyright 2021, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'


def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
"-v", "--version", help="Print the version and exit", action="store_true"
)

subparsers = parser.add_subparsers(
title="commands", description="qgis-plugin-repo-merge command", dest="command"
)

read = subparsers.add_parser("read", help="Read plugins available in a repository")
read.add_argument("xml_file", help="The XML file to parse")

merge = subparsers.add_parser("merge", help="Merge two repository file")
merge.add_argument("input_xml", help="The XML to append")
merge.add_argument("output_xml", help="The XML to edit")

args = parser.parse_args()

# print the version and exit
if args.version:
import pkg_resources

print(
"qgis-plugin-manager version: {}".format(
pkg_resources.get_distribution("qgis-plugin-manager").version
)
)
parser.exit()

# if no command is passed, print the help and exit
if not args.command:
parser.print_help()
parser.exit()

exit_val = 0

if args.command == "read":
merger = Merger(None, args.xml_file)
merger.xml_input_parser()
print(f"List of plugins in {args.xml_file}")
for plugin in merger.plugins(merger.input_parser):
if plugin.experimental:
print(f"{plugin.name} {plugin.version} experimental")
else:
print(f"{plugin.name} {plugin.version}")

elif args.command == "merge":
merger = Merger(args.output_xml, args.input_xml)
merger.xml_input_parser()
merger.xml_output_parser()
merger.merge()

return exit_val


if __name__ == "__main__":
exit(main())
146 changes: 146 additions & 0 deletions qgis_plugin_repo/merger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
from collections import namedtuple
from pathlib import Path
from typing import Union
from urllib.parse import urlparse
import requests
import xml.etree.ElementTree as ET


__copyright__ = 'Copyright 2021, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'


class FileDoesNotExist(Exception):
pass


Plugin = namedtuple('Plugin', ['name', 'experimental', 'version'])


class Merger:

@classmethod
def xml_template(cls):
return (
"<?xml version = '1.0' encoding = 'UTF-8'?>\n"
"<plugins>\n"
"</plugins>\n"
)

def __init__(self, destination: Union[Path, None], input_uri: Union[Path, str, None]):
self.destination = destination
self.input_uri = input_uri
self.input_parser = None
self.output_tree = None
self.output_parser = None

def exists(self) -> bool:
return self.destination.exists()

def init(self) -> None:
print(f"Creating source {self.destination.absolute()}")
with open(self.destination, 'w', encoding='utf8') as f:
f.write(self.xml_template())

def xml_input_parser(self) -> ET.Element:
if self.input_is_url():
self.input_parser = ET.fromstring(requests.get(self.input_uri).content)
return self.input_parser

else:
tree = ET.parse(self.input_uri.absolute())
self.input_parser = tree.getroot()
return self.input_parser

def xml_output_parser(self) -> ET.Element:
if isinstance(self.destination, str):
self.destination = Path(self.destination)

if not self.exists():
self.init()

self.output_tree = ET.parse(self.destination.absolute())
self.output_parser = self.output_tree.getroot()
return self.output_parser

def input_is_url(self) -> bool:
if isinstance(self.input_uri, Path):
return False

# noinspection PyBroadException
try:
urlparse(self.input_uri)
return True
except Exception:
return False

@staticmethod
def plugins(parser) -> list:
""" Return the plugins in the XML file. """
plugins_list = []
for plugin in parser:
experimental = False
for element in plugin:
element: ET.Element
if element.tag == "experimental":
experimental = True if element.text == 'True' else False
break

plugins_list.append(Plugin(
plugin.attrib['name'],
experimental,
plugin.attrib['version']))

return plugins_list

@staticmethod
def plugin_element(parser, name: str, experimental: bool) -> ET.Element:
for plugin in parser:
if plugin.attrib['name'] != name:
continue

for element in plugin:
element: ET.Element
if element.tag == "experimental":
flag = True if element.text == 'True' else False
if flag != experimental:
continue

return plugin

@staticmethod
def diff_plugins(plugins_input, plugins_output):
new = []
for plugin in plugins_input:
if plugin not in plugins_output:
new.append(plugin)

return new

def merge(self):
if not self.exists():
raise FileDoesNotExist

output_plugins = self.plugins(self.output_parser)
input_plugins = self.plugins(self.input_parser)

diff = self.diff_plugins(input_plugins, output_plugins)

print(f"Updating source {self.destination.absolute()}")
print(f"with {self.input_uri}")

if len(diff) == 0:
print("No update is necessary")

for plugin in diff:
# Remove old version
element = self.plugin_element(self.output_parser, plugin.name, plugin.experimental)
if element:
print(f"Removing previous {plugin.name} {plugin.experimental} {element.attrib['version']}")
self.output_parser.remove(element)

print(f"Adding new version {plugin.name} {plugin.experimental} {plugin.version}")
self.output_parser.append(self.plugin_element(self.input_parser, plugin.name, plugin.experimental))

self.output_tree.write(self.destination.absolute())
19 changes: 19 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[flake8]
max-line-length = 110
max-complexity = 16

exclude =
.git,
venv,
.venv,
__pycache__,

[isort]
multi_line_output = 3
include_trailing_comma = True
use_parentheses = True
ensure_newline_before_comments = True
lines_between_types = 1
skip =
.venv/,
venv/,
47 changes: 47 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os
import sys

from setuptools import setup

__copyright__ = 'Copyright 2021, 3Liz'
__license__ = 'GPL version 3'
__email__ = 'info@3liz.org'

python_min_version = (3, 7)

if os.getenv('CI') == 'true':
VERSION = "__VERSION__"
else:
VERSION = "0.0.0"

if sys.version_info < python_min_version:
sys.exit(
"qgis-plugin-repo requires at least Python version {vmaj}.{vmin}.\n"
"You are currently running this installation with\n\n{curver}".format(
vmaj=python_min_version[0], vmin=python_min_version[1], curver=sys.version
)
)

setup(
name="qgis-plugin-repo",
packages=["qgis_plugin_repo"],
entry_points={"console_scripts": ["qgis-plugin-repo = qgis_plugin_repo.cli:main"]},
version=VERSION,
description="Manipulate a QGIS Plugin repository.",
author="Etienne Trimaille",
author_email="etrimaille@3liz.com",
# url="https://github.com/opengisch/qgis-plugin-ci",
# download_url="https://github.com/opengisch/qgis-plugin-ci/archive/{}.tar.gz".format(VERSION),
keywords=["QGIS"],
classifiers=[
"Topic :: Scientific/Engineering :: GIS",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Intended Audience :: System Administrators",
"Intended Audience :: Information Technology",
],
install_requires=["requests"],
extra_require=dict(tests=['pytest']),
python_requires=">={vmaj}.{vmin}".format(
vmaj=python_min_version[0], vmin=python_min_version[1]
),
)
21 changes: 21 additions & 0 deletions tests/fixtures/pgmetadata_experimental.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version = '1.0' encoding = 'UTF-8'?>
<plugins>
<pyqgis_plugin name="PgMetadata" version="0.7.0">
<description><![CDATA[Metadata manager stored in PostgreSQL]]></description>
<version>0.7.0</version>
<qgis_minimum_version>3.10</qgis_minimum_version>
<homepage>https://docs.3liz.org/qgis-pgmetadata-plugin/</homepage>
<file_name>pg_metadata.0.7.0.zip</file_name>
<icon>resources/icons/icon.png</icon>
<author_name>3Liz</author_name>
<download_url>https://github.com/3liz/qgis-pgmetadata-plugin/releases/download/0.7.0/pg_metadata.0.7.0.zip</download_url>
<uploaded_by>3Liz</uploaded_by>
<create_date>2021-02-19</create_date>
<update_date>2021-02-19</update_date>
<experimental>True</experimental>
<deprecated>False</deprecated>
<tracker>https://github.com/3liz/qgis-pgmetadata-plugin/issues</tracker>
<repository>https://github.com/3liz/qgis-pgmetadata-plugin</repository>
<tags>metadata,postgresql,qgis,metadonnees</tags>
</pyqgis_plugin>
</plugins>
Loading

0 comments on commit 0e60875

Please sign in to comment.