diff options
author | Matěj Cepl <mcepl@cepl.eu> | 2018-06-20 17:50:15 +0200 |
---|---|---|
committer | Matěj Cepl <mcepl@cepl.eu> | 2018-06-20 17:50:15 +0200 |
commit | ce0d32c6b7aacc3e4f551b8cf4081ebc204cab11 (patch) | |
tree | 1dca678566c2e5ecdc8a9a8dff2f344667f9ba84 /dlpcvp.py | |
parent | c97618e1f707e34cf8d20827c9bb2b79f2f987fc (diff) | |
download | dlp_check_version_PyPI-ce0d32c6b7aacc3e4f551b8cf4081ebc204cab11.tar.gz |
Fix urllib.request exception handling.
Signed-off-by: Matěj Cepl <mcepl@cepl.eu>
Diffstat (limited to 'dlpcvp.py')
-rwxr-xr-x | dlpcvp.py | 106 |
1 files changed, 62 insertions, 44 deletions
@@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/python3.6 # Requires: python3-rpm import configparser @@ -6,9 +6,11 @@ import json import logging import os import os.path -import sqlite3 +# import sqlite3 +import sys import tempfile import urllib.request +from urllib.error import HTTPError from urllib.request import Request, urlopen from typing import Iterable, Tuple import xml.etree.ElementTree as ET @@ -36,7 +38,7 @@ handler = urllib.request.HTTPBasicAuthHandler(password_mgr) opener = urllib.request.build_opener(handler) -def get_version_from_pypi(name:str, etag: str = None) -> Tuple[str, str, str]: +def get_version_from_pypi(name: str, etag: str = None) -> Tuple[str, str, str]: """ For the given name of module return the latest version available on PyPI. """ @@ -47,82 +49,98 @@ def get_version_from_pypi(name:str, etag: str = None) -> Tuple[str, str, str]: if etag is not None: req.add_header('ETag', etag) - with urlopen(req) as resp: - if resp.getcode() == 200: + try: + with urlopen(req) as resp: data = json.load(resp) info_dict = data['info'] return info_dict['name'], info_dict['version'], resp.info()['ETag'] - else: - IOError(resp.info()) + except HTTPError: + log.exception(f'Cannot find {name} on PyPI') -def suse_packages(project:str, etag: str = None) -> Iterable[str]: +def suse_packages(proj:str) -> Iterable[str]: """ - Iterator returning names of all packages in the given project - """ - req = Request(url=OBS_base+f'/source/{project}') + Iterator returning names of all packages in the given proj - if etag is not None: - req.add_header('ETag', etag) + ETag management won't work here, because I don't like any way how to + return it in iterator. + """ + req = Request(url=OBS_base + f'/source/{proj}') - with opener.open(req) as resp: - if resp.getcode() == 200: + try: + with opener.open(req) as resp: raw_xml_data = ET.parse(resp) root = raw_xml_data.getroot() for elem in root.iter('entry'): yield elem.get('name') + except HTTPError: + log.exception(f'Cannot find packages for {proj}!') -def package_version(project:str, pkg:str, - etag_fn: str = None, etag_spcf: str = None) -> Tuple[str, ...]: +def package_version(proj:str, pkg_name:str, + etag_fn: str = None, etag_spcf: str = None) -> Tuple[str, str, str]: """ - Return the version of the given package in the given project. + Return the version of the given package in the given proj. Downloads SPEC file from OBS and parses it. """ - req_spc_name = Request(url=OBS_base+f'/source/{project}/{pkg}') + req_spc_name = Request(url=OBS_base + f'/source/{proj}/{pkg_name}') + spec_files = [] if etag_fn is not None: req_spc_name.add_header('ETag', etag_fn) - with opener.open(req_spc_name) as resp: - if resp.getcode() == 200: + try: + with opener.open(req_spc_name) as resp: + etag_fn = resp.info()['ETag'] raw_xml_data = ET.parse(resp) root = raw_xml_data.getroot() - spec_files = [] for elem in root.iter('entry'): name = elem.get('name') if name.endswith('.spec'): spec_files.append(name) + except HTTPError: + log.exception(f'Cannot accquire version of {pkg_name} in {proj}') + + if not spec_files: + IOError(f'Cannot find SPEC file for {pkg_name}') - if spec_files: - spc_fname = sorted(spec_files, key=len) - spc_fname = spc_fname[0] - else: - return None + spc_fname = sorted(spec_files, key=len)[0] - req_spec = Request(url=OBS_base+f'/source/{project}/{pkg}/{spc_fname}') + req_spec = Request(url=OBS_base + f'/source/{proj}/{pkg_name}/{spc_fname}') if etag_spcf is not None: req_spc_name.add_header('ETag', etag_spcf) - with opener.open(req_spec) as resp: - spec_file_str = resp.read() - spec_file_name = '' - with tempfile.NamedTemporaryFile(mode='w+b', delete=False) as spf: - spec_file_name = spf.name - spf.write(spec_file_str) - spf.flush() - os.fsync(spf.fileno()) - try: - spc = rpm.spec(spec_file_name) - except Exception as ex: - log.exception("Cannot parse {}".format(pkg)) - else: + try: + with opener.open(req_spec) as resp: + etag_spcf = resp.info()['ETag'] + spec_file_str = resp.read() + spec_file_name = '' + with tempfile.NamedTemporaryFile(mode='w+b', delete=False) as spf: + spec_file_name = spf.name + spf.write(spec_file_str) + spf.flush() + os.fsync(spf.fileno()) + + # rpm library generates awfull lot of nonsensical goo on + # stderr + old_stderr = sys.stderr + sys.stderr = os.devnull try: - return spc.packages[0].header['Version'].decode() - except IndexError: - pass + spc = rpm.spec(spec_file_name) + except Exception as ex: + log.exception("Cannot parse {}".format(pkg_name)) + else: + try: + return spc.packages[0].header['Version'].decode(), \ + etag_fn, etag_spcf + except IndexError: + pass + finally: + sys.stderr = old_stderr + except HTTPError: + log.exception(f'Cannot parse SPEC file {spc_fname} for {pkg_name}') if __name__=='__main__': |