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.
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))
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.
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.
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.
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.