Coverage for amazonorders/cli.py: 76.92%

91 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-18 21:57 +0000

1import datetime 

2import logging 

3from typing import Any 

4 

5import click 

6from click.core import Context 

7 

8from amazonorders.exception import AmazonOrdersError 

9from amazonorders.orders import AmazonOrders 

10from amazonorders.session import AmazonSession, IODefault 

11 

12__author__ = "Alex Laird" 

13__copyright__ = "Copyright 2024, Alex Laird" 

14__version__ = "1.0.3" 

15 

16logger = logging.getLogger("amazonorders") 

17 

18 

19class IOClick(IODefault): 

20 def echo(self, 

21 msg, 

22 fg=None, 

23 **kwargs): 

24 click.secho(msg, fg=fg) 

25 

26 def prompt(self, 

27 msg, 

28 type=None, 

29 **kwargs): 

30 return click.prompt(msg, type=type) 

31 

32 

33@click.group() 

34@click.option('--username', help="An Amazon username.") 

35@click.option('--password', help="An Amazon password.") 

36@click.option('--debug', is_flag=True, default=False, help="Enable debugging and send output to command line.") 

37@click.pass_context 

38def amazon_orders_cli(ctx, 

39 **kwargs: Any): 

40 """ 

41 amazon-orders is an unofficial library that provides a command line interface alongside a programmatic API that 

42 can be used to interact with Amazon.com's consumer-facing website. 

43 

44 This works by parsing website data from Amazon.com. A nightly build validates functionality to ensure its 

45 stability, but as Amazon provides no official API to use, this package may break at any time. This 

46 package only supports the English version of the website. 

47 

48 Documentation can be found at https://amazon-orders.readthedocs.io. 

49 

50 Session data is persisted between requests and interactions with the CLI, minimizing the need to reauthenticate 

51 after a successful login attempt. 

52 """ 

53 _print_banner() 

54 

55 ctx.ensure_object(dict) 

56 for key, value in kwargs.items(): 

57 if value: 

58 ctx.obj[key] = value 

59 

60 if kwargs["debug"]: 

61 logger.setLevel(logging.DEBUG) 

62 logger.addHandler(logging.StreamHandler()) 

63 

64 username = kwargs.get("username") 

65 password = kwargs.get("password") 

66 

67 amazon_session = AmazonSession(username, 

68 password, 

69 debug=kwargs["debug"], 

70 io=IOClick()) 

71 

72 if amazon_session.auth_cookies_stored(): 

73 if username or password: 

74 click.echo("Info: You've provided --username and --password, but because a previous session still exists," 

75 "that is being ignored. If you would like to reauthenticate, call the `logout` command first.\n") 

76 elif not username and not password: 

77 click.echo(ctx.get_help()) 

78 

79 ctx.fail("Amazon --username and --password must be provided, since no previous session was found.") 

80 

81 ctx.obj["amazon_session"] = amazon_session 

82 

83 

84@amazon_orders_cli.command() 

85@click.pass_context 

86@click.option('--year', default=datetime.date.today().year, 

87 help="The year for which to get order history, defaults to the current year.") 

88@click.option('--start-index', help="Retrieve the single page of history at the given index.") 

89@click.option('--full-details', is_flag=True, default=False, 

90 help="Retrieve the full details for each order in the history.") 

91def history(ctx: Context, 

92 **kwargs: Any): 

93 """ 

94 Retrieve Amazon order history for a given year. 

95 """ 

96 amazon_session = ctx.obj["amazon_session"] 

97 

98 year = kwargs["year"] 

99 start_index = kwargs["start_index"] 

100 full_details = kwargs["full_details"] 

101 

102 click.echo("""----------------------------------------------------------------------- 

103Order History for {}{}{} 

104-----------------------------------------------------------------------\n""".format(year, 

105 ", startIndex={}, one page".format( 

106 start_index) if start_index else ", all pages", 

107 ", with full details" if full_details else "")) 

108 

109 click.echo("Info: This might take a minute ...\n") 

110 

111 try: 

112 amazon_session.login() 

113 

114 amazon_orders = AmazonOrders(amazon_session, 

115 debug=amazon_session.debug) 

116 

117 orders = amazon_orders.get_order_history(year=kwargs["year"], 

118 start_index=kwargs["start_index"], 

119 full_details=kwargs["full_details"]) 

120 

121 for o in orders: 

122 click.echo("{}\n".format(o)) 

123 except AmazonOrdersError as e: 

124 logger.debug("An error occurred.", exc_info=True) 

125 ctx.fail(str(e)) 

126 

127 

128@amazon_orders_cli.command() 

129@click.pass_context 

130@click.argument("order_id") 

131def order(ctx: Context, 

132 order_id: str): 

133 """ 

134 Retrieve the full details for the given Amazon order ID. 

135 """ 

136 amazon_session = ctx.obj["amazon_session"] 

137 

138 try: 

139 amazon_session.login() 

140 

141 amazon_orders = AmazonOrders(amazon_session, 

142 debug=amazon_session.debug) 

143 

144 o = amazon_orders.get_order(order_id) 

145 

146 click.echo("""----------------------------------------------------------------------- 

147Order #{} 

148-----------------------------------------------------------------------\n""".format(o.order_number)) 

149 

150 click.echo("{}\n".format(o)) 

151 except AmazonOrdersError as e: 

152 logger.debug("An error occurred.", exc_info=True) 

153 ctx.fail(str(e)) 

154 

155 

156@amazon_orders_cli.command(short_help="Check if persisted session exists.") 

157@click.pass_context 

158def check_session(ctx: Context): 

159 """ 

160 Check if a persisted session exists, meaning commands can be called without needing to provide credentials. 

161 """ 

162 amazon_session = ctx.obj["amazon_session"] 

163 if amazon_session.auth_cookies_stored(): 

164 click.echo("Info: A persisted session exists.\n") 

165 else: 

166 click.echo("Info: No persisted session exists.\n") 

167 

168 

169@amazon_orders_cli.command() 

170@click.pass_context 

171def logout(ctx: Context): 

172 """ 

173 Logout of existing Amazon sessions and clear cookies. 

174 """ 

175 amazon_session = ctx.obj["amazon_session"] 

176 amazon_session.logout() 

177 

178 click.echo("Info: Successfully logged out of the Amazon session.\n") 

179 

180 

181def _print_banner(): 

182 click.echo(""" 

183======================================================================= 

184 ___ _____ _  

185 / _ \ | _ | | |  

186/ /_\ \_ __ ___ __ _ _______ _ __ | | | |_ __ __| | ___ _ __ ___  

187| _ | '_ ` _ \ / _` |_ / _ \| '_ \ | | | | '__/ _` |/ _ \ '__/ __| 

188| | | | | | | | | (_| |/ / (_) | | | | \ \_/ / | | (_| | __/ | \__ \\ 

189\_| |_/_| |_| |_|\__,_/___\___/|_| |_| \___/|_| \__,_|\___|_| |___/  

190=======================================================================\n""") 

191 

192 

193if __name__ == "__main__": 

194 amazon_orders_cli(obj={})