def main(): # store the original SIGINT handler global original_sigint original_sigint = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, exit_gracefully) parser = get_main_parser() args = parser.parse_args() # print(vars(args)) log = get_logger(__name__, args.verbosity) log.setLevel(args.verbosity.upper()) log.debug('logging is set to debug') if args.command == "login": login(phone_no=args.phone_no, pin=args.pin) elif args.command == "dl_docs": dl = DL(login(), args.output) asyncio.get_event_loop().run_until_complete(dl.dl_loop()) elif args.command == "set_price_alarms": # TODO pass elif args.command == "get_price_alarms": Alarms(login()).get() elif args.command == "details": Details(login(), args.isin).get() elif args.command == "portfolio": Portfolio(login()).get() else: parser.print_help()
def __init__(self, tr, output_path, filename_fmt, since_timestamp=0, history_file='pytr_history'): ''' tr: api object output_path: name of the directory where the downloaded files are saved filename_fmt: format string to customize the file names since_timestamp: downloaded files since this date (unix timestamp) ''' self.tr = tr self.output_path = Path(output_path) self.history_file = self.output_path / history_file self.filename_fmt = filename_fmt self.since_timestamp = since_timestamp self.session = FuturesSession() self.futures = [] self.docs_request = 0 self.done = 0 self.filepaths = [] self.doc_urls = [] self.doc_urls_history = [] self.tl = Timeline(self.tr) self.log = get_logger(__name__) self.load_history()
def __init__(self, phone_no=None, pin=None, keyfile=None, locale='de', save_cookies=False): self.log = get_logger(__name__) self._locale = locale self._save_cookies = save_cookies if not (phone_no and pin): try: with open(CREDENTIALS_FILE, 'r') as f: lines = f.readlines() self.phone_no = lines[0].strip() self.pin = lines[1].strip() except FileNotFoundError: raise ValueError(f'phone_no and pin must be specified explicitly or via {CREDENTIALS_FILE}') else: self.phone_no = phone_no self.pin = pin self.keyfile = keyfile if keyfile else KEY_FILE try: with open(self.keyfile, 'rb') as f: self.sk = SigningKey.from_pem(f.read(), hashfunc=hashlib.sha512) except FileNotFoundError: pass self._websession = requests.Session() self._websession.headers = self._default_headers_web if self._save_cookies: self._websession.cookies = MozillaCookieJar(COOKIES_FILE)
def main(): # store the original SIGINT handler global original_sigint original_sigint = signal.getsignal(signal.SIGINT) signal.signal(signal.SIGINT, exit_gracefully) parser = get_main_parser() args = parser.parse_args() # print(vars(args)) log = get_logger(__name__, args.verbosity) log.setLevel(args.verbosity.upper()) log.debug('logging is set to debug') weblogin = not args.applogin if args.command == 'login': login(phone_no=args.phone_no, pin=args.pin, web=weblogin) elif args.command == 'dl_docs': if args.last_days == 0: since_timestamp = 0 else: since_timestamp = (time.time() - (24 * 3600 * args.last_days)) * 1000 dl = DL( login(phone_no=args.phone_no, pin=args.pin, web=weblogin), args.output, args.format, since_timestamp=since_timestamp, ) asyncio.get_event_loop().run_until_complete(dl.dl_loop()) elif args.command == 'set_price_alarms': # TODO print('Not implemented yet') elif args.command == 'get_price_alarms': Alarms(login(phone_no=args.phone_no, pin=args.pin, web=weblogin)).get() elif args.command == 'details': Details(login(phone_no=args.phone_no, pin=args.pin, web=weblogin), args.isin).get() elif args.command == 'portfolio': Portfolio(login(phone_no=args.phone_no, pin=args.pin, web=weblogin)).get() elif args.command == 'export_transactions': export_transactions(args.input, args.output, args.lang) elif args.version: installed_version = version('pytr') print(installed_version) check_version(installed_version) else: parser.print_help()
def login(phone_no=None, pin=None): """ Check if credentials file exists else create it. If no parameters are set but are needed then ask for input Try to login. Ask for device reset if needed """ home = pathlib.Path.home() credentials_file = os.path.join(home, ".pytr", "credentials") log = get_logger(__name__) if os.path.isfile(credentials_file): log.info("Found credentials file") with open(credentials_file) as f: lines = f.readlines() phone_no = lines[0].strip() pin = lines[1].strip() log.info(f"Phone: {phone_no}, PIN: {pin}") else: log.info("Credentials file not found") os.makedirs(os.path.dirname(credentials_file), exist_ok=True) if phone_no is None: print("Please enter your TradeRepbulic phone number in the format +49123456678:") phone_no = input() if pin is None: print("Please enter your TradeRepbulic pin:") pin = input() with open(credentials_file, "w") as f: f.writelines([phone_no + "\n", pin + "\n"]) log.info(f"Saved credentials in {credentials_file}") # use ~/.pytr/credentials and ~/.pytr/keyfile.pem tr = TradeRepublicApi() try: tr.login() except (KeyError, AttributeError): # old keyfile or no keyfile print("Error logging in. Reset device? (y)") confirmation = input() if confirmation == "y": reset(tr) else: print("Cancelling reset") exit(1) log.info("Logged in") log.debug(get_settings(tr)) return tr
def login(phone_no=None, pin=None, web=True): ''' If web is true, use web login method as else simulate app login. Check if credentials file exists else create it. If no parameters are set but are needed then ask for input ''' log = get_logger(__name__) save_cookies = True if phone_no is None and CREDENTIALS_FILE.is_file(): log.info('Found credentials file') with open(CREDENTIALS_FILE) as f: lines = f.readlines() phone_no = lines[0].strip() pin = lines[1].strip() phone_no_masked = phone_no[:-8] + '********' pin_masked = len(pin) * '*' log.info(f'Phone: {phone_no_masked}, PIN: {pin_masked}') else: CREDENTIALS_FILE.parent.mkdir(parents=True, exist_ok=True) if phone_no is None: log.info('Credentials file not found') print( 'Please enter your TradeRepbulic phone number in the format +4912345678:' ) phone_no = input() else: log.info('Phone number provided as argument') if pin is None: print('Please enter your TradeRepbulic pin:') pin = input() print('Save credentials? Type "y" to save credentials:') save = input() if save == 'y': with open(CREDENTIALS_FILE, 'w') as f: f.writelines([phone_no + '\n', pin + '\n']) log.info(f'Saved credentials in {CREDENTIALS_FILE}') else: save_cookies = False log.info('Credentials not saved') tr = TradeRepublicApi(phone_no=phone_no, pin=pin, save_cookies=save_cookies) if web: # Use same login as app.traderepublic.com if tr.resume_websession(): log.info('Web session resumed') else: try: countdown = tr.inititate_weblogin() except ValueError as e: log.fatal(str(e)) exit(1) request_time = time.time() print( 'Enter the code you received to your mobile app as a notification.' ) print( f'Enter nothing if you want to receive the (same) code as SMS. (Countdown: {countdown})' ) code = input('Code: ') if code == '': countdown = countdown - (time.time() - request_time) for remaining in range(int(countdown)): print( f'Need to wait {int(countdown-remaining)} seconds before requesting SMS...', end='\r') time.sleep(1) print() tr.resend_weblogin() code = input('SMS requested. Enter the confirmation code:') tr.complete_weblogin(code) else: # Try to login. Ask for device reset if needed try: tr.login() except (KeyError, AttributeError): # old keyfile or no keyfile print('Error logging in. Reset device? (y)') confirmation = input() if confirmation == 'y': tr.initiate_device_reset() print( 'You should have received a SMS with a token. Please type it in:' ) token = input() tr.complete_device_reset(token) print('Reset done') else: print('Cancelling reset') exit(1) log.info('Logged in') # log.debug(get_settings(tr)) return tr