gpkgstatus.gpkgstatus API documentation

# gpkgstatus.gpkgstatus

The gpkgstatus module searches package and prints its update info.

The gpkgstatus module that searches the package from selected url or cached file and prints the update info to terminal.

View Source

      1"""The gpkgstatus module searches package and prints its update info.
      2
      3The gpkgstatus module that searches the package from selected url or
      4cached file and prints the update info to terminal.
      5
      6"""
      7import argparse
      8import logging
      9from random import randint
     10import sys
     11
     12from typing import Optional
     13
     14from termcolor import colored
     15
     16from gpkgstatus.utils.config import Config
     17from gpkgstatus.utils.json_file_reader import FileNotFoundException, JSONFileReader
     18from gpkgstatus.utils.url_reader import URLReader
     19from gpkgstatus import __version__
     20
     21
     22def select_url(name: Optional[str], version: str):
     23    """Selects url based on name based on corresponding release \
     24        version if specified or else globally.
     25
     26    Selects url based on first character of version from a dictionary of
     27    urls. If url is not present in urls, then program halts with exit
     28    status 1 and immediately states that given version/Linux distribution
     29    release is invalid.
     30
     31    Args:
     32        name (Optional[str]): Name of the package. Defaults to None if none \
     33            is given in command-line arguments.
     34        version (str): If version is given, then package will be searched \
     35            in specific release; or else the package will be searched globally. \
     36                Defaults to None.
     37
     38    Returns:
     39        str : Complete URL containing parameters based on given arguments that searches \
     40            a package with given name in corresponding release version if specified.
     41    """
     42    first_letter = version[0]
     43    urls = {
     44        "f": "https://bodhi.fedoraproject.org/updates/?",
     45    }
     46
     47    if first_letter in urls:
     48        url = urls[first_letter]
     49        logging.info("Given version is in list")
     50    else:
     51        print(colored("Error: Invalid Distribution Release. Format: f{version}", "red"))
     52        logging.debug("Invalid Version: %s", version)
     53
     54        sys.exit(1)
     55
     56    if name:
     57        url += f"&search={name}"
     58
     59    if len(version) > 1:
     60        url += f"&releases={version}"
     61
     62    logging.info("URL Selected: %s", url)
     63
     64    return url
     65
     66
     67def print_update_info(update: dict, status_color: str = None, more_info=False):
     68    """Prints colored update info to terminal.
     69
     70    The color is selected based on current status of package
     71    from a colors dictionary with keys as status and colors
     72    as values. If status is not present in colors, then
     73    default color is blue.
     74
     75    If terminal does not support ASCII colors, then normal text
     76    is printed.
     77
     78    Args:
     79        update (dict): Dictionary of Updates containing metadata.
     80        status_color (str): ASCII Color if explicitly given.
     81    """
     82    colors = {"stable": "green", "testing": "yellow", "pending": "red"}
     83
     84    if update["status"].lower() in colors:
     85        status_color = colors[update["status"]]
     86    else:
     87        status_color = "blue"
     88
     89    print(colored(f"Update ID: {update['updateid']}", status_color))
     90    print(colored(f"Package Name: {update['title']}", status_color))
     91    print(colored(f"Status: {update['status']}", status_color))
     92    if more_info:
     93        print(colored(f"Alias: {update['alias']}", status_color))
     94        print(colored(f"Date Submitted: {update['date_submitted']}", status_color))
     95        print(colored(f"Severity: {update['severity']}", status_color))
     96        print(colored(f"Version Hash: {update['version_hash']}", status_color))
     97        print(colored(f"URL: {update['url']}", status_color))
     98        print(colored(f"Notes: {update['notes']}", status_color))
     99
    100    print("------------------------------")
    101
    102
    103def search_pkg(args: dict):
    104    """Search Package from cached file or given JSON url.
    105
    106    If --force argument is specified, url will be used for searching
    107    irrespective of whether cached expired or not. After requesting the
    108    url, the program stores the JSON response in a file named as
    109    "name_release.json"; that has searched packages of corresponding release.
    110    In case if --name argument is not specified, the file will be named
    111    as "None_release.json".
    112
    113    If --noconfig argument is specified, config will be ignored and values of
    114    cache_time and verbose will be set to default values.
    115
    116    Args:
    117        args (dict): Command-Line arguments in the form of dictionary.
    118    """
    119    logger = logging.getLogger()
    120    logger.addHandler(logging.StreamHandler(sys.stdout))
    121
    122    if not args["noconfig"]:
    123        config = Config()
    124        config.main()
    125
    126        if config.verbose or args["verbose"]:
    127            logger.setLevel(logging.INFO)
    128
    129        cache_time = config.cache_time
    130    else:
    131        cache_time = randint(52, 65) * 60
    132        if args["verbose"]:
    133            logger.setLevel(logging.INFO)
    134
    135        logging.info("Forced to ignore config file")
    136
    137    logging.info(args)
    138    logging.info("Cache Time: %d min", cache_time // 60)
    139
    140    release = args["release"][0]
    141    name = args["name"][0] if args["name"] else None
    142    more_info = args["moreinfo"]
    143
    144    try:
    145        limit = int(args["limit"][0])
    146    except ValueError:
    147        print(colored("You must enter an integer value.", "red"))
    148        sys.exit(1)
    149
    150    cache_file = f"{name}_{release}.json"
    151    url = select_url(name, release.lower())
    152
    153    try:
    154        file_reader = JSONFileReader(cache_file, "updates")
    155
    156        if args["force"]:
    157            logging.info("Forced to update the cache")
    158
    159        if args["force"] or (file_reader.relative_time() > cache_time):
    160            logging.info("File cache is outdated")
    161
    162            print(colored("Getting list of updates...", "green"))
    163            url_reader = URLReader(url)
    164            url_reader.save_as_file(cache_file)
    165
    166    except FileNotFoundException:
    167        print(colored("Getting list of updates...", "green"))
    168
    169        url_reader = URLReader(url)
    170        url_reader.save_as_file(cache_file)
    171        file_reader = JSONFileReader(cache_file, "updates")
    172
    173    finally:
    174        updates = file_reader.read(limit)
    175
    176        if not updates:
    177            print(colored("No Updates Found. Check your arguments.", "red"))
    178            sys.exit(0)
    179
    180        print("------------------------------")
    181        for update in updates:
    182            print_update_info(update, more_info=more_info)
    183
    184
    185def cli():
    186    """Command Line Interface of Program.
    187
    188    The CLI takes arguments from terminal ,parses it using ArgumentParser,
    189    converts arguments into form of dictionary, and calls the search_pkg
    190    function.
    191    """
    192    parser = argparse.ArgumentParser(
    193        prog="gpkgstatus",
    194        description="Get Current Package Status from Fedora Updates System",
    195    )
    196
    197    parser.add_argument(
    198        "-f",
    199        "--force",
    200        help="Sync cached info with Fedora Updates System",
    201        action="store_true",
    202    )
    203
    204    # limit = 5 (default)
    205    parser.add_argument(
    206        "-l",
    207        "--limit",
    208        help="Maximum limit on number of packages shown for package search",
    209        default="5",
    210        nargs=1,
    211    )
    212    parser.add_argument(
    213        "--moreinfo",
    214        help="Verbose (More Info) in Update Info",
    215        action="store_true",
    216    )
    217    parser.add_argument(
    218        "-n",
    219        "--name",
    220        help="Name of the package",
    221        nargs=1,
    222    )
    223    parser.add_argument(
    224        "--noconfig",
    225        help="Do not check for config file",
    226        action="store_true",
    227    )
    228    parser.add_argument(
    229        "-r",
    230        "--release",
    231        help="Checks package status for corresponding Fedora release",
    232        default="f",
    233        nargs=1,
    234    )
    235    parser.add_argument(
    236        "-v",
    237        "--verbose",
    238        help="Enable verbose output",
    239        action="store_true",
    240    )
    241    parser.add_argument(
    242        "--version",
    243        help="gpkgstatus version",
    244        action="version",
    245        version=__version__,
    246    )
    247    args = parser.parse_args()
    248
    249    search_pkg(vars(args))

def select_url(name: Optional[str], version: str): View Source

    23def select_url(name: Optional[str], version: str):
    24    """Selects url based on name based on corresponding release \
    25        version if specified or else globally.
    26
    27    Selects url based on first character of version from a dictionary of
    28    urls. If url is not present in urls, then program halts with exit
    29    status 1 and immediately states that given version/Linux distribution
    30    release is invalid.
    31
    32    Args:
    33        name (Optional[str]): Name of the package. Defaults to None if none \
    34            is given in command-line arguments.
    35        version (str): If version is given, then package will be searched \
    36            in specific release; or else the package will be searched globally. \
    37                Defaults to None.
    38
    39    Returns:
    40        str : Complete URL containing parameters based on given arguments that searches \
    41            a package with given name in corresponding release version if specified.
    42    """
    43    first_letter = version[0]
    44    urls = {
    45        "f": "https://bodhi.fedoraproject.org/updates/?",
    46    }
    47
    48    if first_letter in urls:
    49        url = urls[first_letter]
    50        logging.info("Given version is in list")
    51    else:
    52        print(colored("Error: Invalid Distribution Release. Format: f{version}", "red"))
    53        logging.debug("Invalid Version: %s", version)
    54
    55        sys.exit(1)
    56
    57    if name:
    58        url += f"&search={name}"
    59
    60    if len(version) > 1:
    61        url += f"&releases={version}"
    62
    63    logging.info("URL Selected: %s", url)
    64
    65    return url

Selects url based on name based on corresponding release version if specified or else globally.

Selects url based on first character of version from a dictionary of urls. If url is not present in urls, then program halts with exit status 1 and immediately states that given version/Linux distribution release is invalid.

###### Arguments:

- name (Optional[str]): Name of the package. Defaults to None if none is given in command-line arguments.
- version (str): If version is given, then package will be searched in specific release; or else the package will be searched globally. Defaults to None.

###### Returns:

> str : Complete URL containing parameters based on given arguments that searches a package with given name in corresponding release version if specified.

def print_update_info(update: dict, status_color: str = None, more_info=False): View Source

     68def print_update_info(update: dict, status_color: str = None, more_info=False):
     69    """Prints colored update info to terminal.
     70
     71    The color is selected based on current status of package
     72    from a colors dictionary with keys as status and colors
     73    as values. If status is not present in colors, then
     74    default color is blue.
     75
     76    If terminal does not support ASCII colors, then normal text
     77    is printed.
     78
     79    Args:
     80        update (dict): Dictionary of Updates containing metadata.
     81        status_color (str): ASCII Color if explicitly given.
     82    """
     83    colors = {"stable": "green", "testing": "yellow", "pending": "red"}
     84
     85    if update["status"].lower() in colors:
     86        status_color = colors[update["status"]]
     87    else:
     88        status_color = "blue"
     89
     90    print(colored(f"Update ID: {update['updateid']}", status_color))
     91    print(colored(f"Package Name: {update['title']}", status_color))
     92    print(colored(f"Status: {update['status']}", status_color))
     93    if more_info:
     94        print(colored(f"Alias: {update['alias']}", status_color))
     95        print(colored(f"Date Submitted: {update['date_submitted']}", status_color))
     96        print(colored(f"Severity: {update['severity']}", status_color))
     97        print(colored(f"Version Hash: {update['version_hash']}", status_color))
     98        print(colored(f"URL: {update['url']}", status_color))
     99        print(colored(f"Notes: {update['notes']}", status_color))
    100
    101    print("------------------------------")

Prints colored update info to terminal.

The color is selected based on current status of package from a colors dictionary with keys as status and colors as values. If status is not present in colors, then default color is blue.

If terminal does not support ASCII colors, then normal text is printed.

###### Arguments:

- update (dict): Dictionary of Updates containing metadata.
- status_color (str): ASCII Color if explicitly given.

def search_pkg(args: dict): View Source

    104def search_pkg(args: dict):
    105    """Search Package from cached file or given JSON url.
    106
    107    If --force argument is specified, url will be used for searching
    108    irrespective of whether cached expired or not. After requesting the
    109    url, the program stores the JSON response in a file named as
    110    "name_release.json"; that has searched packages of corresponding release.
    111    In case if --name argument is not specified, the file will be named
    112    as "None_release.json".
    113
    114    If --noconfig argument is specified, config will be ignored and values of
    115    cache_time and verbose will be set to default values.
    116
    117    Args:
    118        args (dict): Command-Line arguments in the form of dictionary.
    119    """
    120    logger = logging.getLogger()
    121    logger.addHandler(logging.StreamHandler(sys.stdout))
    122
    123    if not args["noconfig"]:
    124        config = Config()
    125        config.main()
    126
    127        if config.verbose or args["verbose"]:
    128            logger.setLevel(logging.INFO)
    129
    130        cache_time = config.cache_time
    131    else:
    132        cache_time = randint(52, 65) * 60
    133        if args["verbose"]:
    134            logger.setLevel(logging.INFO)
    135
    136        logging.info("Forced to ignore config file")
    137
    138    logging.info(args)
    139    logging.info("Cache Time: %d min", cache_time // 60)
    140
    141    release = args["release"][0]
    142    name = args["name"][0] if args["name"] else None
    143    more_info = args["moreinfo"]
    144
    145    try:
    146        limit = int(args["limit"][0])
    147    except ValueError:
    148        print(colored("You must enter an integer value.", "red"))
    149        sys.exit(1)
    150
    151    cache_file = f"{name}_{release}.json"
    152    url = select_url(name, release.lower())
    153
    154    try:
    155        file_reader = JSONFileReader(cache_file, "updates")
    156
    157        if args["force"]:
    158            logging.info("Forced to update the cache")
    159
    160        if args["force"] or (file_reader.relative_time() > cache_time):
    161            logging.info("File cache is outdated")
    162
    163            print(colored("Getting list of updates...", "green"))
    164            url_reader = URLReader(url)
    165            url_reader.save_as_file(cache_file)
    166
    167    except FileNotFoundException:
    168        print(colored("Getting list of updates...", "green"))
    169
    170        url_reader = URLReader(url)
    171        url_reader.save_as_file(cache_file)
    172        file_reader = JSONFileReader(cache_file, "updates")
    173
    174    finally:
    175        updates = file_reader.read(limit)
    176
    177        if not updates:
    178            print(colored("No Updates Found. Check your arguments.", "red"))
    179            sys.exit(0)
    180
    181        print("------------------------------")
    182        for update in updates:
    183            print_update_info(update, more_info=more_info)

Search Package from cached file or given JSON url.

If --force argument is specified, url will be used for searching irrespective of whether cached expired or not. After requesting the url, the program stores the JSON response in a file named as "name_release.json"; that has searched packages of corresponding release. In case if --name argument is not specified, the file will be named as "None_release.json".

If --noconfig argument is specified, config will be ignored and values of cache_time and verbose will be set to default values.

###### Arguments:

- args (dict): Command-Line arguments in the form of dictionary.

def cli(): View Source

    186def cli():
    187    """Command Line Interface of Program.
    188
    189    The CLI takes arguments from terminal ,parses it using ArgumentParser,
    190    converts arguments into form of dictionary, and calls the search_pkg
    191    function.
    192    """
    193    parser = argparse.ArgumentParser(
    194        prog="gpkgstatus",
    195        description="Get Current Package Status from Fedora Updates System",
    196    )
    197
    198    parser.add_argument(
    199        "-f",
    200        "--force",
    201        help="Sync cached info with Fedora Updates System",
    202        action="store_true",
    203    )
    204
    205    # limit = 5 (default)
    206    parser.add_argument(
    207        "-l",
    208        "--limit",
    209        help="Maximum limit on number of packages shown for package search",
    210        default="5",
    211        nargs=1,
    212    )
    213    parser.add_argument(
    214        "--moreinfo",
    215        help="Verbose (More Info) in Update Info",
    216        action="store_true",
    217    )
    218    parser.add_argument(
    219        "-n",
    220        "--name",
    221        help="Name of the package",
    222        nargs=1,
    223    )
    224    parser.add_argument(
    225        "--noconfig",
    226        help="Do not check for config file",
    227        action="store_true",
    228    )
    229    parser.add_argument(
    230        "-r",
    231        "--release",
    232        help="Checks package status for corresponding Fedora release",
    233        default="f",
    234        nargs=1,
    235    )
    236    parser.add_argument(
    237        "-v",
    238        "--verbose",
    239        help="Enable verbose output",
    240        action="store_true",
    241    )
    242    parser.add_argument(
    243        "--version",
    244        help="gpkgstatus version",
    245        action="version",
    246        version=__version__,
    247    )
    248    args = parser.parse_args()
    249
    250    search_pkg(vars(args))

Command Line Interface of Program.

The CLI takes arguments from terminal ,parses it using ArgumentParser, converts arguments into form of dictionary, and calls the search_pkg function.