mirror of
https://github.com/lilydjwg/nvchecker.git
synced 2025-03-10 06:14:02 +00:00
feat : add token option for regex and httpheader. add htmlparser with xpath source
This commit is contained in:
parent
9d2d47ed15
commit
588d824077
4 changed files with 176 additions and 46 deletions
|
@ -233,6 +233,17 @@ regex
|
||||||
|
|
||||||
When multiple version strings are found, the maximum of those is chosen.
|
When multiple version strings are found, the maximum of those is chosen.
|
||||||
|
|
||||||
|
token
|
||||||
|
(*Optional*) A personal authorization token used to call the url. The token type depends the authorization required.
|
||||||
|
|
||||||
|
- For Bearer token set : ``Bearer Your_bearer_token``
|
||||||
|
- For Basic token set : ``Basic Your_base64_encoded_token``
|
||||||
|
|
||||||
|
To set an authorization token, you can set:
|
||||||
|
|
||||||
|
- a key named ``regex_<app_name>`` in the keyfile
|
||||||
|
- the token option
|
||||||
|
|
||||||
This source supports :ref:`list options`.
|
This source supports :ref:`list options`.
|
||||||
|
|
||||||
Search in an HTTP header
|
Search in an HTTP header
|
||||||
|
@ -262,6 +273,41 @@ method
|
||||||
follow_redirects
|
follow_redirects
|
||||||
(*Optional*) Whether to follow 3xx HTTP redirects. Default is ``false``. If you are looking at a ``Location`` header, you shouldn't change this.
|
(*Optional*) Whether to follow 3xx HTTP redirects. Default is ``false``. If you are looking at a ``Location`` header, you shouldn't change this.
|
||||||
|
|
||||||
|
token
|
||||||
|
(*Optional*) A personal authorization token used to call the url. The token type depends the authorization required.
|
||||||
|
|
||||||
|
- For Bearer token set : ``Bearer Your_bearer_token``
|
||||||
|
- For Basic token set : ``Basic Your_base64_encoded_token``
|
||||||
|
|
||||||
|
To set an authorization token, you can set:
|
||||||
|
|
||||||
|
- a key named ``httpheader_<app_name>`` in the keyfile
|
||||||
|
- the token option
|
||||||
|
|
||||||
|
Search with an HTML Parser
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
::
|
||||||
|
|
||||||
|
source = "htmlparser"
|
||||||
|
|
||||||
|
Send an HTTP request and search through the body a specific xpath.
|
||||||
|
|
||||||
|
url
|
||||||
|
The URL of the HTTP request.
|
||||||
|
|
||||||
|
xpath
|
||||||
|
A xpath expression used to find the version string
|
||||||
|
|
||||||
|
token
|
||||||
|
(*Optional*) A personal authorization token used to call the url. The token type depends the authorization required.
|
||||||
|
|
||||||
|
- For Bearer token set : ``Bearer Your_bearer_token``
|
||||||
|
- For Basic token set : ``Basic Your_base64_encoded_token``
|
||||||
|
|
||||||
|
To set an authorization token, you can set:
|
||||||
|
|
||||||
|
- a key named ``htmlparser_<app_name>`` in the keyfile
|
||||||
|
- the token option
|
||||||
|
|
||||||
Find with a Command
|
Find with a Command
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
48
nvchecker_source/htmlparser.py
Normal file
48
nvchecker_source/htmlparser.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# MIT licensed
|
||||||
|
# Copyright (c) 2013-2020 lilydjwg <lilydjwg@gmail.com>, et al.
|
||||||
|
|
||||||
|
from lxml import html, etree
|
||||||
|
|
||||||
|
from nvchecker.api import (
|
||||||
|
VersionResult, Entry, KeyManager,
|
||||||
|
TemporaryError, session
|
||||||
|
)
|
||||||
|
|
||||||
|
async def get_version(name, conf, **kwargs):
|
||||||
|
try:
|
||||||
|
return await get_version_real(name, conf, **kwargs)
|
||||||
|
except TemporaryError as e:
|
||||||
|
check_ratelimit(e, name)
|
||||||
|
|
||||||
|
async def get_version_real(
|
||||||
|
name: str, conf: Entry, *, keymanager: KeyManager,
|
||||||
|
**kwargs,
|
||||||
|
) -> VersionResult:
|
||||||
|
|
||||||
|
encoding = conf.get('encoding', 'latin1')
|
||||||
|
|
||||||
|
# Load token from config
|
||||||
|
token = conf.get('token')
|
||||||
|
# Load token from keyman
|
||||||
|
if token is None:
|
||||||
|
key_name = 'htmlparser_' + name
|
||||||
|
token = keymanager.get_key(key_name)
|
||||||
|
|
||||||
|
# Set private token if token exists.
|
||||||
|
headers = {}
|
||||||
|
if token:
|
||||||
|
headers["Authorization"] = token
|
||||||
|
|
||||||
|
data = await session.get(conf.get('url'), headers = headers)
|
||||||
|
body = html.fromstring(data.body.decode(encoding))
|
||||||
|
try:
|
||||||
|
checkxpath = body.xpath(conf.get('xpath'))
|
||||||
|
except etree.XPathEvalError as e:
|
||||||
|
raise GetVersionError('bad xpath', exc_info=e)
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = body.xpath(conf.get('xpath'))
|
||||||
|
except ValueError:
|
||||||
|
if not conf.get('missing_ok', False):
|
||||||
|
raise GetVersionError('version string not found.')
|
||||||
|
return version
|
|
@ -3,37 +3,53 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sre_constants
|
import sre_constants
|
||||||
|
from nvchecker.api import (
|
||||||
|
VersionResult, Entry, KeyManager,
|
||||||
|
TemporaryError,session, GetVersionError
|
||||||
|
)
|
||||||
|
|
||||||
from nvchecker.api import session, GetVersionError
|
async def get_version(name, conf, **kwargs):
|
||||||
|
return await get_version_real(name, conf, **kwargs)
|
||||||
|
|
||||||
async def get_version(name, conf, *, cache, **kwargs):
|
async def get_version_real(
|
||||||
key = tuple(sorted(conf.items()))
|
name: str, conf: Entry, *, keymanager: KeyManager,
|
||||||
return await cache.get(key, get_version_impl)
|
**kwargs,
|
||||||
|
) -> VersionResult:
|
||||||
|
|
||||||
async def get_version_impl(info):
|
url = conf.get('url')
|
||||||
conf = dict(info)
|
header = conf.get('header', 'Location')
|
||||||
url = conf['url']
|
follow_redirects = conf.get('follow_redirects', False)
|
||||||
header = conf.get('header', 'Location')
|
method = conf.get('method', 'HEAD')
|
||||||
follow_redirects = conf.get('follow_redirects', False)
|
|
||||||
method = conf.get('method', 'HEAD')
|
|
||||||
|
|
||||||
try:
|
# Load token from config
|
||||||
regex = re.compile(conf['regex'])
|
token = conf.get('token')
|
||||||
except sre_constants.error as e:
|
# Load token from keyman
|
||||||
raise GetVersionError('bad regex', exc_info=e)
|
if token is None:
|
||||||
|
key_name = 'httpheader_' + name
|
||||||
|
token = keymanager.get_key(key_name)
|
||||||
|
|
||||||
res = await session.request(
|
# Set private token if token exists.
|
||||||
url,
|
headers = {}
|
||||||
method = method,
|
if token:
|
||||||
follow_redirects = follow_redirects,
|
headers["Authorization"] = token
|
||||||
)
|
|
||||||
|
|
||||||
header_value = res.headers.get(header)
|
try:
|
||||||
if not header_value:
|
regex = re.compile(conf['regex'])
|
||||||
raise GetVersionError('header %s not found or is empty' % header)
|
except sre_constants.error as e:
|
||||||
|
raise GetVersionError('bad regex', exc_info=e)
|
||||||
|
|
||||||
try:
|
res = await session.request(
|
||||||
version = regex.findall(header_value)
|
url,
|
||||||
except ValueError:
|
method=method,
|
||||||
raise GetVersionError('version string not found.')
|
headers=headers,
|
||||||
return version
|
follow_redirects=follow_redirects,
|
||||||
|
)
|
||||||
|
|
||||||
|
header_value = res.headers.get(header)
|
||||||
|
if not header_value:
|
||||||
|
raise GetVersionError('header %s not found or is empty' % header)
|
||||||
|
try:
|
||||||
|
version = regex.findall(header_value)
|
||||||
|
except ValueError:
|
||||||
|
raise GetVersionError('version string not found.')
|
||||||
|
return version
|
||||||
|
|
|
@ -3,28 +3,48 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sre_constants
|
import sre_constants
|
||||||
|
from nvchecker.api import (
|
||||||
|
VersionResult, Entry, KeyManager,
|
||||||
|
TemporaryError, session, GetVersionError
|
||||||
|
)
|
||||||
|
|
||||||
from nvchecker.api import session, GetVersionError
|
|
||||||
|
|
||||||
async def get_version(name, conf, *, cache, **kwargs):
|
async def get_version(name, conf, **kwargs):
|
||||||
key = tuple(sorted(conf.items()))
|
try:
|
||||||
return await cache.get(key, get_version_impl)
|
return await get_version_real(name, conf, **kwargs)
|
||||||
|
except TemporaryError as e:
|
||||||
|
check_ratelimit(e, name)
|
||||||
|
|
||||||
async def get_version_impl(info):
|
|
||||||
conf = dict(info)
|
|
||||||
|
|
||||||
try:
|
async def get_version_real(
|
||||||
regex = re.compile(conf['regex'])
|
name: str, conf: Entry, *, keymanager: KeyManager,
|
||||||
except sre_constants.error as e:
|
**kwargs,
|
||||||
raise GetVersionError('bad regex', exc_info=e)
|
) -> VersionResult:
|
||||||
|
|
||||||
encoding = conf.get('encoding', 'latin1')
|
# Load token from config
|
||||||
|
token = conf.get('token')
|
||||||
|
# Load token from keyman
|
||||||
|
if token is None:
|
||||||
|
key_name = 'regex_' + name
|
||||||
|
token = keymanager.get_key(key_name)
|
||||||
|
|
||||||
res = await session.get(conf['url'])
|
# Set private token if token exists.
|
||||||
body = res.body.decode(encoding)
|
headers = {}
|
||||||
try:
|
if token:
|
||||||
version = regex.findall(body)
|
headers["Authorization"] = token
|
||||||
except ValueError:
|
|
||||||
if not conf.get('missing_ok', False):
|
try:
|
||||||
raise GetVersionError('version string not found.')
|
regex = re.compile(conf['regex'])
|
||||||
return version
|
except sre_constants.error as e:
|
||||||
|
raise GetVersionError('bad regex', exc_info=e)
|
||||||
|
|
||||||
|
encoding = conf.get('encoding', 'latin1')
|
||||||
|
|
||||||
|
res = await session.get(conf.get('url'), headers=headers)
|
||||||
|
body = res.body.decode(encoding)
|
||||||
|
try:
|
||||||
|
version = regex.findall(body)
|
||||||
|
except ValueError:
|
||||||
|
if not conf.get('missing_ok', False):
|
||||||
|
raise GetVersionError('version string not found.')
|
||||||
|
return version
|
Loading…
Add table
Reference in a new issue