mirror of
https://abf.rosa.ru/djam/abf-console-client-src.git
synced 2025-02-25 10:52:51 +00:00
192 lines
No EOL
7.2 KiB
Python
192 lines
No EOL
7.2 KiB
Python
import urllib2, urllib
|
|
import re
|
|
import json
|
|
import os
|
|
import base64
|
|
import pdb
|
|
|
|
|
|
from abf.api.exceptions import *
|
|
|
|
|
|
from beaker.cache import Cache
|
|
from beaker.util import parse_cache_config_options
|
|
cache_data = Cache('abf_etag_data', expire = 86400, type='file', data_dir='/tmp/abf_cache/etag_data', lock_dir='/tmp/abf_cache/etag_data')
|
|
cache_etags = Cache('abf_etags', expire = 86400, type='file', data_dir='/tmp/abf_cache/etags', lock_dir='/tmp/abf_cache/etags')
|
|
|
|
|
|
class AbfJson(object):
|
|
def __init__(self,abf_url, login, password, log):
|
|
self.login = login
|
|
self.password = password
|
|
self.abf_url = re.compile('/+$').sub('',abf_url)
|
|
|
|
#does not work sometimes
|
|
'''self.password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
|
self.password_manager.add_password(None, abf_url, login, password)
|
|
self.auth = urllib2.HTTPBasicAuthHandler(self.password_manager)
|
|
self.opener = urllib2.build_opener(self.auth)
|
|
urllib2.install_opener(self.opener)
|
|
'''
|
|
|
|
# but it works!
|
|
self.base64_auth_string = base64.standard_b64encode('%s:%s' % (login, password)).replace('\n', '')
|
|
self.log = log
|
|
|
|
errors = {
|
|
"Invalid email or password.": AuthError,
|
|
"403 Forbidden | Rate Limit Exceeded": RateLimitError,
|
|
"Page not found": PageNotFoundError,
|
|
"Error 404. Resource not found!": PageNotFoundError,
|
|
"Something went wrong. We've been notified about this issue and we'll take a look at it shortly.": InternalServerError,
|
|
"We update the site, it will take some time. We are really trying to do it fast. We apologize for any inconvenience..": ServerWorksError,
|
|
"Requires authentication": AuthError,
|
|
"Forbidden. Sorry, you don't have enough rights for this action!": ForbiddenError,
|
|
"Access violation to this page!": ForbiddenError,
|
|
"Bad Request": BadRequestError,}
|
|
good_messages = ['Errors during build publishing!', 'Build is queued for publishing']
|
|
|
|
# in case of this error, get_url_contents will print the error message and exit
|
|
fatal_errors = [AuthError, RateLimitError, InternalServerError, ServerWorksError]
|
|
|
|
def get_url_contents(self, url, GET=None, POST=None):
|
|
url = self.abf_url + url
|
|
if GET:
|
|
get_string = urllib.urlencode(GET)
|
|
if '?' in url:
|
|
url = url + '&' + get_string
|
|
else:
|
|
url = url + '?' + get_string
|
|
self.log.debug('Fetching url %s' % url)
|
|
|
|
etag = None
|
|
if POST:
|
|
post_json = json.dumps(POST).encode('utf-8')
|
|
request = urllib2.Request(url, post_json, {'Content-Type': 'application/json'})
|
|
else:
|
|
request = urllib2.Request(url)
|
|
|
|
if cache_etags.has_key(url) :
|
|
etag = cache_etags.get(url)
|
|
self.log.debug("It was cached! ETag: " + etag)
|
|
request.add_header("If-None-Match", etag)
|
|
|
|
|
|
request.add_header("Authorization", "Basic %s" % self.base64_auth_string)
|
|
etag_new = None
|
|
try:
|
|
result = urllib2.urlopen(request)
|
|
res = result.read()
|
|
etag_new = result.headers.getheaders('ETag')[0]
|
|
except urllib2.HTTPError, ex:
|
|
if ex.code == 304: # data was not modified
|
|
res = cache_data.get(etag)
|
|
self.log.debug('Getting cached result (cache was validated)')
|
|
else:
|
|
self.log.debug('Return code: ' + str(ex.code))
|
|
|
|
if ex.code == 401: # auth failed
|
|
self.log.error("Authorization failed. Incorrect username or password")
|
|
exit()
|
|
|
|
#remove cached data if exists
|
|
if etag:
|
|
try:
|
|
cache_etags.remove(url)
|
|
cache_data.remove(etag)
|
|
except:
|
|
pass
|
|
res = ex.fp.read()
|
|
|
|
if etag_new:
|
|
self.log.debug("Caching the new value for %s. ETag is %s" % (url, etag_new))
|
|
cache_etags.put(url, etag_new)
|
|
cache_data.put(etag_new, res)
|
|
|
|
try:
|
|
res = json.loads(res)
|
|
except ValueError, ex:
|
|
self.log.error("Internal server error: it have returned non-json data. ")
|
|
exit(1)
|
|
|
|
if 'message' in res and res['message'] not in AbfJson.good_messages:
|
|
m = res['message']
|
|
if m in AbfJson.errors:
|
|
self.log.debug(m)
|
|
exception = AbfJson.errors[m]
|
|
else:
|
|
self.log.error("Unknown server error: " + m)
|
|
exception = AbfApiException
|
|
if exception == BadRequestError:
|
|
log.error('Sorry, but something went wrong and request I\'ve sent to ABF is bad. Please, '
|
|
'notify developers, send them a set of command-line arguments and the request data:\n%s\n%s' % (URL, post_json or "No POST DATA") )
|
|
exit(1)
|
|
|
|
if exception in AbfJson.fatal_errors:
|
|
exit(2)
|
|
raise exception(m)
|
|
|
|
#print 'RAW OUTPUT', res
|
|
return res
|
|
|
|
def get_architectures(self):
|
|
URL = "/api/v1/arches.json"
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_platforms(self, typ=None):
|
|
URL = "/api/v1/platforms.json"
|
|
GET = {}
|
|
if typ:
|
|
GET['type'] = typ
|
|
return self.get_url_contents(URL, GET)
|
|
|
|
def get_platform_by_id(self, pl_id):
|
|
pl_id = int(pl_id)
|
|
URL = "/api/v1/platforms/%d.json" % pl_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_build_platforms(self):
|
|
URL = "/api/v1/platforms/platforms_for_build.json"
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_repository_by_id(self, rep_id):
|
|
rep_id = int(rep_id)
|
|
URL = "/api/v1/repositories/%d.json" % rep_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_buildlist_by_id(self, bl_id):
|
|
bl_id = int(bl_id)
|
|
URL = "/api/v1/build_lists/%d.json" % bl_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_project_by_id(self, p_id):
|
|
p_id = int(p_id)
|
|
URL = "/api/v1/projects/%d.json" % p_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_project_id_by_name(self, key):
|
|
proj_owner, proj_name = key
|
|
URL = "/api/v1/projects/get_id.json"
|
|
GET = {'name': proj_name, 'owner':proj_owner}
|
|
return self.get_url_contents(URL, GET)
|
|
|
|
def new_build_task(self, data):
|
|
URL = "/api/v1/build_lists.json"
|
|
return self.get_url_contents(URL, GET=None, POST=data)
|
|
|
|
def publish(self, task_id):
|
|
task_id = int(task_id)
|
|
URL = "/api/v1/build_lists/%d/publish.json" % task_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_git_refs_list(self, proj_id):
|
|
proj_id = int(proj_id)
|
|
URL = "/api/v1/projects/%d/refs_list.json" % proj_id
|
|
return self.get_url_contents(URL)
|
|
|
|
def get_user_by_id(self, user_id):
|
|
user_id = int(user_id)
|
|
URL = "/api/v1/users/%d.json" % user_id
|
|
return self.get_url_contents(URL)
|
|
|
|
|