mirror of
https://github.com/lilydjwg/nvchecker
synced 2025-01-29 17:42:47 +00:00
refactor get_version.py
This commit is contained in:
parent
a2ed894c2d
commit
dbc35aa901
@ -1,167 +1,18 @@
|
||||
import re
|
||||
import sre_constants
|
||||
import logging
|
||||
from functools import partial
|
||||
import queue
|
||||
import json
|
||||
import urllib.parse
|
||||
import time
|
||||
|
||||
from pkg_resources import parse_version
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
import tornado.process
|
||||
from tornado.ioloop import IOLoop
|
||||
from importlib import import_module
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
handler_precedence = ('github', 'aur', 'pypi', 'pacman',
|
||||
'cmd', 'gcode_hg', 'regex')
|
||||
|
||||
try:
|
||||
import pycurl
|
||||
AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
|
||||
except ImportError:
|
||||
pycurl = None
|
||||
handler_precedence = (
|
||||
'github', 'aur', 'pypi', 'pacman',
|
||||
'cmd', 'gcode_hg', 'regex',
|
||||
)
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
g = globals()
|
||||
for key in handler_precedence:
|
||||
if key in conf:
|
||||
funcname = 'get_version_by_' + key
|
||||
g[funcname](name, conf, callback)
|
||||
func = import_module('.source.' + key, __package__).get_version
|
||||
func(name, conf, callback)
|
||||
break
|
||||
else:
|
||||
logger.error('%s: no idea to get version info.', name)
|
||||
callback(name, None)
|
||||
|
||||
def get_version_by_regex(name, conf, callback):
|
||||
try:
|
||||
r = re.compile(conf['regex'])
|
||||
except sre_constants.error:
|
||||
logger.warn('%s: bad regex, skipped.', name, exc_info=True)
|
||||
callback(name, None)
|
||||
return
|
||||
|
||||
encoding = conf.get('encoding', 'latin1')
|
||||
httpclient = AsyncHTTPClient()
|
||||
|
||||
kwargs = {}
|
||||
if conf.get('proxy'):
|
||||
if pycurl:
|
||||
host, port = urllib.parse.splitport(conf['proxy'])
|
||||
kwargs['proxy_host'] = host
|
||||
kwargs['proxy_port'] = int(port)
|
||||
else:
|
||||
logger.warn('%s: proxy set but not used because pycurl is unavailable.', name)
|
||||
|
||||
httpclient.fetch(conf['url'], partial(
|
||||
_get_version_by_regex, name, r, encoding, callback
|
||||
), **kwargs)
|
||||
|
||||
def _get_version_by_regex(name, regex, encoding, callback, res):
|
||||
body = res.body.decode(encoding)
|
||||
try:
|
||||
version = max(regex.findall(body), key=parse_version)
|
||||
except ValueError:
|
||||
logger.error('%s: version string not found.', name)
|
||||
callback(name, None)
|
||||
else:
|
||||
callback(name, version)
|
||||
|
||||
AUR_URL = 'https://aur.archlinux.org/rpc.php?type=info&arg='
|
||||
|
||||
def get_version_by_aur(name, conf, callback):
|
||||
aurname = conf.get('aur') or name
|
||||
url = AUR_URL + aurname
|
||||
AsyncHTTPClient().fetch(url, partial(_aur_done, name, callback))
|
||||
|
||||
def _aur_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data['results']['Version']
|
||||
callback(name, version)
|
||||
|
||||
GITHUB_URL = 'https://api.github.com/repos/%s/commits'
|
||||
|
||||
def get_version_by_github(name, conf, callback):
|
||||
repo = conf.get('github')
|
||||
url = GITHUB_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_github_done, name, callback))
|
||||
|
||||
def _github_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data[0]['commit']['committer']['date'].split('T', 1)[0].replace('-', '')
|
||||
callback(name, version)
|
||||
|
||||
cmd_q = queue.Queue()
|
||||
cmd_q.running = False
|
||||
|
||||
def get_version_by_cmd(name, conf, callback):
|
||||
cmd = conf['cmd']
|
||||
cmd_q.put((name, cmd, callback))
|
||||
if not cmd_q.running:
|
||||
_run_command()
|
||||
|
||||
def _run_command():
|
||||
cmd_q.running = True
|
||||
try:
|
||||
name, cmd, callback = cmd_q.get_nowait()
|
||||
except queue.Empty:
|
||||
cmd_q.running = False
|
||||
return
|
||||
|
||||
p = tornado.process.Subprocess(cmd, shell=True, io_loop=IOLoop.instance(),
|
||||
stdout=tornado.process.Subprocess.STREAM)
|
||||
p.set_exit_callback(partial(_command_done, name, callback, p))
|
||||
|
||||
def _command_done(name, callback, process, status):
|
||||
if status != 0:
|
||||
logger.error('%s: command exited with %d.', name, status)
|
||||
callback(name, None)
|
||||
else:
|
||||
process.stdout.read_until_close(partial(_got_version_from_cmd, callback, name))
|
||||
_run_command()
|
||||
|
||||
def _got_version_from_cmd(callback, name, output):
|
||||
output = output.strip().decode('latin1')
|
||||
callback(name, output)
|
||||
|
||||
PYPI_URL = 'https://pypi.python.org/pypi/%s/json'
|
||||
|
||||
def get_version_by_pypi(name, conf, callback):
|
||||
repo = conf.get('pypi') or name
|
||||
url = PYPI_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_pypi_done, name, callback))
|
||||
|
||||
def _pypi_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data['info']['version']
|
||||
callback(name, version)
|
||||
|
||||
GCODE_URL = 'https://code.google.com/p/%s/source/list'
|
||||
GCODE_HG_RE = re.compile(
|
||||
r'<a onclick="cancelBubble=true" href="detail\?r=[0-9a-f]+">([^<]+)</a>')
|
||||
|
||||
def get_version_by_gcode_hg(name, conf, callback):
|
||||
repo = conf.get('gcode_hg') or name
|
||||
url = GCODE_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_gcodehg_done, name, callback))
|
||||
|
||||
def _gcodehg_done(name, callback, res):
|
||||
data = res.body.decode('utf-8')
|
||||
m = GCODE_HG_RE.search(data)
|
||||
if m:
|
||||
t = time.strptime('Aug 15, 2013', '%b %d, %Y')
|
||||
version = time.strftime('%Y%m%d', t)
|
||||
else:
|
||||
logger.error('%s: version not found.', name)
|
||||
version = None
|
||||
callback(name, version)
|
||||
|
||||
|
||||
def get_version_by_pacman(name, conf, callback):
|
||||
referree = conf['pacman']
|
||||
cmd = "LANG=C pacman -Si %s | grep -F Version | awk '{print $3}'" % referree
|
||||
conf['cmd'] = cmd
|
||||
get_version_by_cmd(name, conf, callback)
|
||||
|
@ -1,11 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import configparser
|
||||
import logging
|
||||
import argparse
|
||||
from functools import partial
|
||||
|
||||
from pkg_resources import parse_version
|
||||
from tornado.ioloop import IOLoop
|
||||
@ -20,6 +17,7 @@ notifications = []
|
||||
g_counter = 0
|
||||
g_oldver = {}
|
||||
g_curver = {}
|
||||
args = None
|
||||
|
||||
def task_inc():
|
||||
global g_counter
|
||||
|
1
nvchecker/source/__init__.py
Normal file
1
nvchecker/source/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .base import *
|
16
nvchecker/source/aur.py
Normal file
16
nvchecker/source/aur.py
Normal file
@ -0,0 +1,16 @@
|
||||
from functools import partial
|
||||
import json
|
||||
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
|
||||
AUR_URL = 'https://aur.archlinux.org/rpc.php?type=info&arg='
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
aurname = conf.get('aur') or name
|
||||
url = AUR_URL + aurname
|
||||
AsyncHTTPClient().fetch(url, partial(_aur_done, name, callback))
|
||||
|
||||
def _aur_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data['results']['Version']
|
||||
callback(name, version)
|
7
nvchecker/source/base.py
Normal file
7
nvchecker/source/base.py
Normal file
@ -0,0 +1,7 @@
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
try:
|
||||
import pycurl
|
||||
AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
|
||||
except ImportError:
|
||||
pycurl = None
|
||||
|
41
nvchecker/source/cmd.py
Normal file
41
nvchecker/source/cmd.py
Normal file
@ -0,0 +1,41 @@
|
||||
import queue
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
import tornado.process
|
||||
from tornado.ioloop import IOLoop
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
cmd_q = queue.Queue()
|
||||
cmd_q.running = False
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
cmd = conf['cmd']
|
||||
cmd_q.put((name, cmd, callback))
|
||||
if not cmd_q.running:
|
||||
_run_command()
|
||||
|
||||
def _run_command():
|
||||
cmd_q.running = True
|
||||
try:
|
||||
name, cmd, callback = cmd_q.get_nowait()
|
||||
except queue.Empty:
|
||||
cmd_q.running = False
|
||||
return
|
||||
|
||||
p = tornado.process.Subprocess(cmd, shell=True, io_loop=IOLoop.instance(),
|
||||
stdout=tornado.process.Subprocess.STREAM)
|
||||
p.set_exit_callback(partial(_command_done, name, callback, p))
|
||||
|
||||
def _command_done(name, callback, process, status):
|
||||
if status != 0:
|
||||
logger.error('%s: command exited with %d.', name, status)
|
||||
callback(name, None)
|
||||
else:
|
||||
process.stdout.read_until_close(partial(_got_version_from_cmd, callback, name))
|
||||
_run_command()
|
||||
|
||||
def _got_version_from_cmd(callback, name, output):
|
||||
output = output.strip().decode('latin1')
|
||||
callback(name, output)
|
||||
|
29
nvchecker/source/gcode_hg.py
Normal file
29
nvchecker/source/gcode_hg.py
Normal file
@ -0,0 +1,29 @@
|
||||
import re
|
||||
import time
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GCODE_URL = 'https://code.google.com/p/%s/source/list'
|
||||
GCODE_HG_RE = re.compile(
|
||||
r'<a onclick="cancelBubble=true" href="detail\?r=[0-9a-f]+">([^<]+)</a>')
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
repo = conf.get('gcode_hg') or name
|
||||
url = GCODE_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_gcodehg_done, name, callback))
|
||||
|
||||
def _gcodehg_done(name, callback, res):
|
||||
data = res.body.decode('utf-8')
|
||||
m = GCODE_HG_RE.search(data)
|
||||
if m:
|
||||
t = time.strptime('Aug 15, 2013', '%b %d, %Y')
|
||||
version = time.strftime('%Y%m%d', t)
|
||||
else:
|
||||
logger.error('%s: version not found.', name)
|
||||
version = None
|
||||
callback(name, version)
|
17
nvchecker/source/github.py
Normal file
17
nvchecker/source/github.py
Normal file
@ -0,0 +1,17 @@
|
||||
import json
|
||||
from functools import partial
|
||||
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
|
||||
GITHUB_URL = 'https://api.github.com/repos/%s/commits'
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
repo = conf.get('github')
|
||||
url = GITHUB_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_github_done, name, callback))
|
||||
|
||||
def _github_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data[0]['commit']['committer']['date'].split('T', 1)[0].replace('-', '')
|
||||
callback(name, version)
|
7
nvchecker/source/pacman.py
Normal file
7
nvchecker/source/pacman.py
Normal file
@ -0,0 +1,7 @@
|
||||
from . import cmd
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
referree = conf['pacman']
|
||||
c = "LANG=C pacman -Si %s | grep -F Version | awk '{print $3}'" % referree
|
||||
conf['cmd'] = c
|
||||
cmd.get_version(name, conf, callback)
|
17
nvchecker/source/pypi.py
Normal file
17
nvchecker/source/pypi.py
Normal file
@ -0,0 +1,17 @@
|
||||
import json
|
||||
from functools import partial
|
||||
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
|
||||
PYPI_URL = 'https://pypi.python.org/pypi/%s/json'
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
repo = conf.get('pypi') or name
|
||||
url = PYPI_URL % repo
|
||||
AsyncHTTPClient().fetch(url, user_agent='lilydjwg/nvchecker',
|
||||
callback=partial(_pypi_done, name, callback))
|
||||
|
||||
def _pypi_done(name, callback, res):
|
||||
data = json.loads(res.body.decode('utf-8'))
|
||||
version = data['info']['version']
|
||||
callback(name, version)
|
46
nvchecker/source/regex.py
Normal file
46
nvchecker/source/regex.py
Normal file
@ -0,0 +1,46 @@
|
||||
import re
|
||||
import sre_constants
|
||||
import logging
|
||||
import urllib.parse
|
||||
from functools import partial
|
||||
|
||||
from pkg_resources import parse_version
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
|
||||
from .base import pycurl
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def get_version(name, conf, callback):
|
||||
try:
|
||||
r = re.compile(conf['regex'])
|
||||
except sre_constants.error:
|
||||
logger.warn('%s: bad regex, skipped.', name, exc_info=True)
|
||||
callback(name, None)
|
||||
return
|
||||
|
||||
encoding = conf.get('encoding', 'latin1')
|
||||
httpclient = AsyncHTTPClient()
|
||||
|
||||
kwargs = {}
|
||||
if conf.get('proxy'):
|
||||
if pycurl:
|
||||
host, port = urllib.parse.splitport(conf['proxy'])
|
||||
kwargs['proxy_host'] = host
|
||||
kwargs['proxy_port'] = int(port)
|
||||
else:
|
||||
logger.warn('%s: proxy set but not used because pycurl is unavailable.', name)
|
||||
|
||||
httpclient.fetch(conf['url'], partial(
|
||||
_got_version, name, r, encoding, callback
|
||||
), **kwargs)
|
||||
|
||||
def _got_version(name, regex, encoding, callback, res):
|
||||
body = res.body.decode(encoding)
|
||||
try:
|
||||
version = max(regex.findall(body), key=parse_version)
|
||||
except ValueError:
|
||||
logger.error('%s: version string not found.', name)
|
||||
callback(name, None)
|
||||
else:
|
||||
callback(name, version)
|
Loading…
Reference in New Issue
Block a user