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