Skip to content

Commit

Permalink
Rewrite to be beautiful
Browse files Browse the repository at this point in the history
  • Loading branch information
jaymoulin committed Dec 28, 2018
1 parent aac0f3f commit 1d45e70
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 128 deletions.
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ First, I register my webhook :

.. code::
github-release-notifier --action subscribe --webhook https://acme.com/updated --package jaymoulin/google-music-manager
github-release-notifier --action subscribe --webhook https://example.com/updated --package jaymoulin/google-music-manager
an UUID is printed. this UUID will be required to unsubscribe the webhook.

When `jaymoulin/google-music-manager` releases a new version, `https://acme.com/updated` will be called with HTTP verb `POST` and body, a JSON like this :
When `jaymoulin/google-music-manager` releases a new version, `https://example.com/updated` will be called with HTTP verb `POST` and body, a JSON like this :

.. code::
Expand Down Expand Up @@ -112,7 +112,7 @@ Then register your webhook :

.. code::
docker exec GRN -a subscribe -p jaymoulin/google-music-manager -w https://acme.com/updated
docker exec GRN -a subscribe -p jaymoulin/google-music-manager -w https://example.com/updated
Submitting bugs and feature requests
Expand Down
6 changes: 3 additions & 3 deletions github_release_notifier/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
This program will allow you to be notified of Github new releases
"""
from .parser import *
from .webhook import *
from .notifier import *

__all__ = ['parser', 'webhook', 'notifier']
__version__ = '0.2.3'
32 changes: 23 additions & 9 deletions github_release_notifier/cli.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding: utf-8

import argparse
import github_release_notifier


def main():
parser = argparse.ArgumentParser()
parser.add_argument("--action", '-a',
default='cron',
choices=['cron', 'subscribe', 'unsubscribe'],
help="Action to do (default: cron)")
parser.add_argument("--package", '-p',
help="Github package name / url (required for subscribe/unsubscribe) - prints uuid on subscription")
parser.add_argument("--webhook", '-w', help="URL to your webhook (required for subscribe/unsubscribe)")
parser.add_argument("--uuid", '-u', help="UUID of your webhook (required for unsubscribe)")
parser.add_argument(
"--action",
'-a',
default='cron',
choices=['cron', 'subscribe', 'unsubscribe'],
help="Action to do (default: cron)"
)
parser.add_argument(
"--package",
'-p',
help="Github package name / url (required for subscribe/unsubscribe) - prints uuid on subscription"
)
parser.add_argument(
"--webhook",
'-w',
help="URL to your webhook (required for subscribe/unsubscribe)"
)
parser.add_argument(
"--uuid",
'-u',
help="UUID of your webhook (required for unsubscribe)"
)
args = parser.parse_args()
if args.action == 'cron':
print(github_release_notifier.notifier.run())
Expand Down
51 changes: 23 additions & 28 deletions github_release_notifier/notifier.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, json, os, requests, logging, re, threading
# coding: utf-8

import sys
import json
import os
import requests
import logging
import re
import threading
from .webhook import get, get_list
from .parser import parse
from pathlib import Path

__DEFAULT_FILE__ = '/root/.github_release_notifier/versions'


def version_compare(version1, version2):
def version_compare(version1: str, version2: str) -> int:
def normalize(v):
return [int(x) for x in re.sub(r'([^\.0-9]+)', '', v).split(".")]
return [int(x) for x in re.sub(r'([^.0-9]+)', '', v).split(".")]

return (normalize(version1) > normalize(version2)) - (normalize(version1) < normalize(version2))

def _call_webhook(webhook, entry, logger):

def _call_webhook(webhook: str, entry: str, logger: logging.Logger) -> None:
logger.info("Hook call : %s / %s" % (webhook, json.dumps(entry)))
try:
requests.post(webhook, json=entry)
except:
except requests.exceptions.RequestException:
logger.error("Error occured : %s" % (sys.exc_info()[0]))

def run(file=__DEFAULT_FILE__):

def run(file: str = __DEFAULT_FILE__) -> dict:
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
updated = {}
Expand All @@ -38,14 +45,13 @@ def run(file=__DEFAULT_FILE__):
return updated


def _get_database(file=__DEFAULT_FILE__):
database = {}
if Path(file).is_file():
database = json.loads(open(file, "r").read())
return database
def _get_database(file: str = __DEFAULT_FILE__) -> dict:
if not Path(file).is_file():
raise ValueError('Unexpected database file provided')
return json.loads(open(file, "r").read())


def _set_database(database, filepath=__DEFAULT_FILE__):
def _set_database(database: dict, filepath: str = __DEFAULT_FILE__) -> None:
dirname = os.path.dirname(filepath)
if not os.path.exists(dirname):
os.makedirs(dirname)
Expand All @@ -54,17 +60,6 @@ def _set_database(database, filepath=__DEFAULT_FILE__):
file.close()


def get_version(package, file=__DEFAULT_FILE__):
def get_version(package: str, file: str = __DEFAULT_FILE__) -> str:
database = _get_database(file)
try:
return database[package]
except KeyError:
return '0.0.0'


def main():
print(run())


if __name__ == "__main__":
main()
return database.get(package, '0.0.0')
43 changes: 23 additions & 20 deletions github_release_notifier/parser.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding: utf-8

import sys, feedparser, re, requests
import feedparser
import re
import requests
from typing import List

__all__ = ['parse', 'get_package']


def parse(package):
def parse(package: str) -> List[dict]:
package_name = get_package(package)
url = 'https://github.com/%s/releases.atom' % package_name
feed = feedparser.parse(url)
entries = []
for item in feed['entries']:
entries.append({
"author": item['authors'][0]['name'] if 'authors' in item and item['authors'] and item['authors'][0] and item['authors'][0]['name'] else None,
current_dict = {
'author': None,
"content": None,
"media": None,
"date": item['updated_parsed'],
"title": item['title_detail']['value'],
"content": item['content'][0]['value'] if 'content' in item and item['content'] and item['content'][0] and item['content'][0]['value'] else None,
"version": re.search('(?<=Repository/)[0-9]+/(.+)', item['id']).group(1),
"media": item['media_thumbnail'][0]['url'] if 'media_thumbnail' in item and item['media_thumbnail'] and item['media_thumbnail'][0] and item['media_thumbnail'][0]['url'] else None,
"package_name": package_name,
})
}
if 'authors' in item and item['authors'].get(0) is not None and 'name' in item['authors'][0]:
current_dict['author'] = item['authors'][0]['name']
if 'content' in item and item['content'].get(0) is not None and 'value' in item['content'][0]:
current_dict['content'] = item['content'][0]['value']
if (
'media_thumbnail' in item and
item['media_thumbnail'].get(0) is not None
and 'url' in item['media_thumbnail'][0]
):
current_dict['media'] = item['media_thumbnail'][0]['url']
entries.append(current_dict)
return entries


def get_package(entry):
def get_package(entry: str) -> str:
if 'github' in entry:
entry = re.search('(?<=github.com/)[^/]+/[^/]+', entry).group(0)
request = requests.get('https://github.com/%s/tags.atom' % entry)
if request.status_code != 200:
raise NameError('%s is not a valid github url/package' % entry)
return entry


def main():
print(parse(sys.argv[1]))


if __name__ == "__main__":
main()
44 changes: 16 additions & 28 deletions github_release_notifier/webhook.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding: utf-8

import sys, json, os
from github_release_notifier.parser import get_package
import json
import os
from .parser import get_package
from pathlib import Path
from hashlib import sha224
from typing import KeysView

__all__ = ['subscribe', 'unsubscribe', 'get', 'get_list']
__SALT__ = 'saltedUnique'
__DEFAULT_FILE__ = '/root/.github_release_notifier/hooks'


def _get_database(file=__DEFAULT_FILE__):
def _get_database(file: str = __DEFAULT_FILE__) -> dict:
database = {}
if Path(file).is_file():
database = json.loads(open(file, "r").read())
return database


def _set_database(database, filepath=__DEFAULT_FILE__):
def _set_database(database: dict, filepath: str = __DEFAULT_FILE__) -> None:
dirname = os.path.dirname(filepath)
if not os.path.exists(dirname):
os.makedirs(dirname)
Expand All @@ -27,51 +27,39 @@ def _set_database(database, filepath=__DEFAULT_FILE__):
file.close()


def subscribe(package, callback, file=__DEFAULT_FILE__, salt=__SALT__):
def subscribe(package: str, callback: str, file: str = __DEFAULT_FILE__, salt: str = __SALT__) -> str:
package = get_package(package)
database = _get_database(file)
try:
database[package] = list(filter((callback).__ne__, database[package]))
database[package].append(callback)
database[package] = list(filter(callback.__ne__, database[package]))
except KeyError:
database[package] = []
database[package].append(callback)
database[package].append(callback)
_set_database(database, file)
return get_uuid(package, callback, salt)


def get_uuid(package, callback, salt=__SALT__):
def get_uuid(package: str, callback: str, salt: str = __SALT__) -> str:
package = get_package(package)
return sha224(callback.encode('utf-8') + package.encode('utf-8') + salt.encode('utf-8')).hexdigest()


def unsubscribe(uuid, package, callback, file=__DEFAULT_FILE__, salt=__SALT__):
def unsubscribe(uuid: str, package: str, callback, file: str = __DEFAULT_FILE__, salt: str = __SALT__) -> None:
package = get_package(package)
database = _get_database(file)
if uuid == get_uuid(package, callback, salt):
database[package] = list(filter((callback).__ne__, database[package]))
database[package] = list(filter(callback.__ne__, database[package]))
else:
raise NameError('Wrong uuid for your package')
_set_database(database, file)


def get(package, file=__DEFAULT_FILE__):
def get(package: str, file: str = __DEFAULT_FILE__) -> dict:
package = get_package(package)
database = _get_database(file)
try:
return database[package]
except KeyError:
return []
return database.get(package, {})


def get_list(file=__DEFAULT_FILE__):
def get_list(file: str = __DEFAULT_FILE__) -> KeysView:
database = _get_database(file)
return database.keys()


def main():
print(subscribe(sys.argv[1], sys.argv[2]))


if __name__ == "__main__":
main()
33 changes: 33 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[metadata]
name = github_release_notifier
version = attr: github_release_notifier.__version__
description = Get notified when a specific package got a new release on Github
long_description = file: README.rst
author = Jay MOULIN
author_email = [email protected]
url = https://github.com/femtopixel/github-release-notifier/
license = MIT
classifiers =
Development Status :: 5 - Production/Stable
Programming Language :: Python
License :: OSI Approved :: MIT License
Natural Language :: English
Operating System :: OS Independent
Programming Language :: Python :: 3
Topic :: Communications
Topic :: Internet
Topic :: Software Development :: Pre-processors
Intended Audience :: Developers
Topic :: Software Development :: Build Tools

[options]
include_package_data = True
packages = find:
install_requires =
feedparser
requests
python_requires = >=3

[options.entry_points]
console_scripts =
github-release-notifier = github_release_notifier.cli:main
40 changes: 3 additions & 37 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# coding: utf-8

from setuptools import setup, find_packages
from setuptools import setup

__version__ = '0.2.2'

setup(
name='github_release_notifier',
python_requires=">=3",
version=__version__,
packages=find_packages(),
author="Jay MOULIN",
author_email="[email protected]",
description="Github Notifier",
long_description=open('README.rst').read(),
install_requires=["feedparser", "requests"],
include_package_data=True,
url='http://github.com/femtopixel/github-release-notifier/',
classifiers=[
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Topic :: Communications",
"Topic :: Internet",
"Topic :: Software Development :: Pre-processors",
"Intended Audience :: Developers",
"Topic :: Software Development :: Build Tools",
],
entry_points={
'console_scripts': [
'github-release-notifier = github_release_notifier.cli:main',
],
},
license="MIT",
)
setup()

0 comments on commit 1d45e70

Please sign in to comment.