diff --git a/hotness/anitya.py b/hotness/anitya.py
index f5430fd..0d9a87d 100644
--- a/hotness/anitya.py
+++ b/hotness/anitya.py
@@ -1,14 +1,12 @@
import copy
import logging
-import os
-import pickle
import bs4
-import requests
ANITYA_URL = 'https://release-monitoring.org/'
from fedora.client import AuthError
+from fedora.client import OpenIdBaseClient
log = logging.getLogger('fedmsg')
@@ -80,145 +78,37 @@ def _parse_service_form(response):
return (parsed.form.attrs['action'], inputs)
-class Anitya(object):
-
- def __init__(self, url=ANITYA_URL, insecure=False, cookies=None,
- login_callback=None, login_attempts=3,
- sessionfile="~/.cache/anitya-session.pickle"):
-
- self.url = url
- self.session = requests.session()
- self.insecure = insecure
- self.username = None
- self.password = None
- self.login_callback = login_callback
- self.login_attempts = login_attempts
- self.sessionfile = os.path.expanduser(sessionfile)
-
- try:
- with open(self.sessionfile, "rb") as sessionfo:
- self.session.cookies = pickle.load(sessionfo)["cookies"]
- except (IOError, KeyError, TypeError):
- pass
-
- def __send_request(self, url, method, params=None, data=None):
- log.debug(
- 'Calling: %s with arg: %s and data: %s', url, params, data)
- req = self.session.request(
- method=method,
- url=url,
- params=params,
- data=data,
- verify=not self.insecure,
+class Anitya(OpenIdBaseClient):
+ def __init__(self, url=ANITYA_URL, insecure=False):
+ super(Anitya, self).__init__(
+ base_url=url,
+ login_url=url + "/login/fedora",
+ useragent="The New Hotness",
+ debug=False,
+ insecure=insecure,
+ openid_insecure=insecure,
+ username=None, # We supply this later
+ cache_session=True,
+ retries=7,
+ timeout=120,
+ retry_backoff_factor=0.3,
)
- self._save_cookies()
- return req
-
- def _save_cookies(self):
- try:
- with open(self.sessionfile, 'rb') as sessionfo:
- data = pickle.load(sessionfo)
- except:
- data = {}
- try:
- with open(self.sessionfile, 'wb', 0600) as sessionfo:
- sessionfo.seek(0)
- data["cookies"] = self.session.cookies
- pickle.dump(data, sessionfo)
- except:
- pass
@property
def is_logged_in(self):
- response = self.session.get(self.url)
+ response = self._session.get(self.base_url)
return "logout" in response.text
- def login(self, username=None, password=None, openid_insecure=False,
- response=None):
-
- log.info("Attempting to login to anitya")
-
- if not username:
- username = self.username
- if not password:
- password = self.password
- if self.login_callback and not password:
- username, password = self.login_callback(username=username,
- bad_password=False)
-
- if not username or not password:
- raise AnityaAuthException('Username or password missing')
-
- import re
- from urlparse import urlparse, parse_qs
-
- fedora_openid_api = r'https://id.fedoraproject.org/api/v1/'
- fedora_openid = r'^http(s)?:\/\/id\.(|stg.|dev.)?fedoraproject'\
- '\.org(/)?'
- motif = re.compile(fedora_openid)
-
- # Log into the service
- if not response:
- response = self.session.get(self.url + '/login/fedora')
-
- openid_url = ''
- if '
OpenID transaction in progress' \
- in response.text:
- # requests.session should hold onto this for us....
- openid_url, data = _parse_service_form(response)
- if not motif.match(openid_url):
- raise AnityaException(
- 'Un-expected openid provider asked: %s' % openid_url)
- elif 'logged in as' in response.text:
- # User already logged in via its cookie file by default:
- # ~/.cache/anitya-session.pickle
- return
- else:
- data = {}
- for resp in response.history:
- if motif.match(resp.url):
- parsed = parse_qs(urlparse(resp.url).query)
- for key, value in parsed.items():
- data[key] = value[0]
- break
- else:
- log.info(response.text)
- raise AnityaException(
- 'Unable to determine openid parameters from login: %r' %
- openid_url)
-
- # Contact openid provider
- data['username'] = username
- data['password'] = password
- # Let's precise to FedOAuth that we want to authenticate with FAS
- data['auth_module'] = 'fedoauth.auth.fas.Auth_FAS'
-
- response = self.__send_request(
- url=fedora_openid_api,
- method='POST',
- data=data)
- output = response.json()
-
- if not output['success']:
- raise AnityaException(output['message'])
-
- response = self.__send_request(
- url=output['response']['openid.return_to'],
- method='POST',
- data=output['response'])
-
- return output
-
def search_by_homepage(self, name, homepage):
- url = '{0}/api/projects/?homepage={1}'.format(self.url, homepage)
+ url = '{0}/api/projects/?homepage={1}'.format(self.base_url, homepage)
log.info("Looking for %r via %r" % (name, url))
- response = self.__send_request(url, method='GET')
+ response = self.send_request(url, verb='GET')
return response.json()
def get_project_by_package(self, name):
- url = '{0}/api/project/Fedora/{1}'.format(self.url, name)
+ url = '{0}/api/project/Fedora/{1}'.format(self.base_url, name)
log.info("Looking for %r via %r" % (name, url))
- response = self.__send_request(url, method='GET')
+ response = self.send_request(url, verb='GET')
if not response.status_code == 200:
log.warn('No existing anitya project found mapped to %r' % name)
return None
@@ -230,8 +120,8 @@ def update_url(self, project, homepage):
raise AnityaException('Could not add anitya project. '
'Not logged in.')
idx = project['id']
- url = self.url + '/project/%i/edit' % idx
- response = self.__send_request(url, method='GET')
+ url = self.base_url + '/project/%i/edit' % idx
+ response = self.send_request(url, verb='GET')
if not response.status_code == 200:
code = response.status_code
raise AnityaException("Couldn't get form to get "
@@ -241,7 +131,7 @@ def update_url(self, project, homepage):
data = copy.copy(project)
data['homepage'] = homepage
data['csrf_token'] = soup.find(id='csrf_token').attrs['value']
- response = self.__send_request(url, method='POST', data=data)
+ response = self.send_request(url, verb='POST', data=data)
if not response.status_code == 200:
del data['csrf_token']
@@ -262,9 +152,8 @@ def update_url(self, project, homepage):
def force_check(self, project):
""" Force anitya to check for a new upstream release. """
idx = project['id']
- url = '%s/api/version/get' % self.url
- resp = self.session.post(url, data=dict(id=idx))
- data = resp.json()
+ url = '%s/api/version/get' % self.base_url
+ data = self.send_request(url, verb='POST', data=dict(id=idx))
if 'error' in data:
log.warning('Anitya error: %r' % data['error'])
@@ -278,8 +167,8 @@ def map_new_package(self, name, project):
'Not logged in.')
idx = project['id']
- url = self.url + '/project/%i/map' % idx
- response = self.__send_request(url, method='GET')
+ url = self.base_url + '/project/%i/map' % idx
+ response = self.send_request(url, verb='GET')
if not response.status_code == 200:
code = response.status_code
raise AnityaException("Couldn't get form to get "
@@ -292,7 +181,7 @@ def map_new_package(self, name, project):
package_name=name,
csrf_token=csrf_token,
)
- response = self.__send_request(url, method='POST', data=data)
+ response = self.send_request(url, verb='POST', data=data)
if not response.status_code == 200:
# Hide this from stuff we republish to the bus
@@ -348,8 +237,8 @@ def add_new_project(self, name, homepage):
if data['backend'] == 'github' and 'github.com' in data['homepage']:
data['version_url'] = data['homepage']
- url = self.url + '/project/new'
- response = self.__send_request(url, method='GET')
+ url = self.base_url + '/project/new'
+ response = self.send_request(url, verb='GET')
if not response.status_code == 200:
code = response.status_code
@@ -359,7 +248,7 @@ def add_new_project(self, name, homepage):
soup = bs4.BeautifulSoup(response.text, "lxml")
data['csrf_token'] = soup.find(id='csrf_token').attrs['value']
- response = self.__send_request(url, method='POST', data=data)
+ response = self.send_request(url, verb='POST', data=data)
if not response.status_code == 200:
# Hide this from stuff we republish to the bus