# -*- encoding: utf-8 -*-
# PKGBUILDer v4.3.2
# An AUR helper (and library) in Python 3.
# Copyright © 2011-2023, Chris Warrick.
# See /LICENSE for licensing information.
"""
Call the AUR API.
:Copyright: © 2011-2023, Chris Warrick.
:License: BSD (see /LICENSE).
"""
import pkgbuilder
from pkgbuilder.exceptions import ConnectionError, HTTPError, NetworkError
import requests
import requests.exceptions
import json
__all__ = ('AUR',)
[docs]class AUR(object):
"""
Call the AUR API.
Valid request types for :meth:`request()` (and
:meth:`jsonrequest()`):
+---------+-----------------------------------+
+ name | purpose |
+=========+===================================+
| info | get info about `arg` |
+---------+-----------------------------------+
| search | search for `arg` in the AUR |
+---------+-----------------------------------+
| msearch | show packages maintained by `arg` |
+---------+-----------------------------------+
A more accurate list might be available at the AUR RPC website:
https://aur.archlinux.org/rpc.php
multiinfo is implemented in another function, :meth:`multiinfo()`.
.. note:: Most people don’t actually want this and will prefer to use
``pkgbuilder.utils.{info,search,msearch}()`` instead.
"""
base = 'https://aur.archlinux.org'
rpcver = 5
_rpc = '/rpc/?v='
emptystr = '{"version":%s,"type":"%s","resultcount":0,"results":[]}'
ua = 'PKGBUILDer/' + pkgbuilder.__version__
@property
def rpc(self):
"""Return the RPC URL."""
return self.base + self._rpc + str(self.rpcver)
[docs] def jsonreq(self, rtype, arg, search_by=None):
"""Make a request and return plain JSON data."""
if not arg:
# No need to bother.
return self.emptystr % (self.rpcver, rtype)
params = {'type': rtype, 'arg': arg}
if search_by is not None:
params['search_by'] = search_by
try:
req = requests.get(self.rpc, params=params,
headers={'User-Agent': self.ua})
req.raise_for_status()
except requests.exceptions.ConnectionError as e:
raise ConnectionError(e.args[0].args[0], e)
except requests.exceptions.HTTPError as e:
raise HTTPError(req, e)
except requests.exceptions.RequestException as e:
raise NetworkError(str(e), e)
return req.text
[docs] def jsonmultiinfo(self, args):
"""Make a multiinfo request and return plain JSON data."""
if not args:
# No need to bother.
return self.emptystr % (self.rpcver, 'multiinfo')
try:
req = requests.get(self.rpc,
params={'type': 'multiinfo', 'arg[]': args},
headers={'User-Agent': self.ua})
req.raise_for_status()
except requests.exceptions.ConnectionError as e:
raise ConnectionError(e.args[0].args[0], e)
except requests.exceptions.HTTPError as e:
raise HTTPError(req, e)
except requests.exceptions.RequestException as e:
raise NetworkError(str(e), e)
return req.text
[docs] def request(self, rtype, arg, search_by=None):
"""Make a request and return the AURDict."""
return json.loads(self.jsonreq(rtype, arg, search_by))
[docs] def search(self, search_by, arg):
"""Search the AUR and return the AURDict."""
return json.loads(self.jsonreq('search', arg, search_by))
[docs] def multiinfo(self, args):
"""Make a multiinfo request and return the AURDict."""
if not args:
# If there are 0 packages, use jsonmultiinfo’s “empty string”
# fallback and decode it as JSON.
return json.loads(self.jsonmultiinfo(args))
MAX_SIZE = 150
args = list(args)
size = len(args)
results = []
i = 0
while i < size:
query = args[i:i + MAX_SIZE]
i += MAX_SIZE
response = json.loads(self.jsonmultiinfo(query))
if response['type'] == 'error':
return response
results.extend(response['results'])
response['resultcount'] = len(results)
response['results'] = results
return response