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
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-18 21:57 +0000
1import datetime
2import logging
3from typing import Any
5import click
6from click.core import Context
8from amazonorders.exception import AmazonOrdersError
9from amazonorders.orders import AmazonOrders
10from amazonorders.session import AmazonSession, IODefault
12__author__ = "Alex Laird"
13__copyright__ = "Copyright 2024, Alex Laird"
14__version__ = "1.0.3"
16logger = logging.getLogger("amazonorders")
19class IOClick(IODefault):
20 def echo(self,
21 msg,
22 fg=None,
23 **kwargs):
24 click.secho(msg, fg=fg)
26 def prompt(self,
27 msg,
28 type=None,
29 **kwargs):
30 return click.prompt(msg, type=type)
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.
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.
48 Documentation can be found at https://amazon-orders.readthedocs.io.
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()
55 ctx.ensure_object(dict)
56 for key, value in kwargs.items():
57 if value:
58 ctx.obj[key] = value
60 if kwargs["debug"]:
61 logger.setLevel(logging.DEBUG)
62 logger.addHandler(logging.StreamHandler())
64 username = kwargs.get("username")
65 password = kwargs.get("password")
67 amazon_session = AmazonSession(username,
68 password,
69 debug=kwargs["debug"],
70 io=IOClick())
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())
79 ctx.fail("Amazon --username and --password must be provided, since no previous session was found.")
81 ctx.obj["amazon_session"] = amazon_session
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"]
98 year = kwargs["year"]
99 start_index = kwargs["start_index"]
100 full_details = kwargs["full_details"]
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 ""))
109 click.echo("Info: This might take a minute ...\n")
111 try:
112 amazon_session.login()
114 amazon_orders = AmazonOrders(amazon_session,
115 debug=amazon_session.debug)
117 orders = amazon_orders.get_order_history(year=kwargs["year"],
118 start_index=kwargs["start_index"],
119 full_details=kwargs["full_details"])
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))
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"]
138 try:
139 amazon_session.login()
141 amazon_orders = AmazonOrders(amazon_session,
142 debug=amazon_session.debug)
144 o = amazon_orders.get_order(order_id)
146 click.echo("""-----------------------------------------------------------------------
147Order #{}
148-----------------------------------------------------------------------\n""".format(o.order_number))
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))
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")
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()
178 click.echo("Info: Successfully logged out of the Amazon session.\n")
181def _print_banner():
182 click.echo("""
183=======================================================================
184 ___ _____ _
185 / _ \ | _ | | |
186/ /_\ \_ __ ___ __ _ _______ _ __ | | | |_ __ __| | ___ _ __ ___
187| _ | '_ ` _ \ / _` |_ / _ \| '_ \ | | | | '__/ _` |/ _ \ '__/ __|
188| | | | | | | | | (_| |/ / (_) | | | | \ \_/ / | | (_| | __/ | \__ \\
189\_| |_/_| |_| |_|\__,_/___\___/|_| |_| \___/|_| \__,_|\___|_| |___/
190=======================================================================\n""")
193if __name__ == "__main__":
194 amazon_orders_cli(obj={})