def upload_transactions(budget_id, transactions): if config["dry"]: log.info("Dry run, skipping upload to YNAB...") return 0, 0, 0 method = "v1/budgets/" + budget_id + "/transactions" reversed_transactions = list(reversed(transactions)) created = duplicates = patched = 0 new_list = [t for t in reversed_transactions if t.get("new")] for new_batch in chunker(new_list, 100): log.info("Creating transactions up to {}...".format( new_batch[-1]["date"])) new_result = post(method, {"transactions": new_batch}) created += len(new_result["transaction_ids"]) duplicates += len(new_result["duplicate_import_ids"]) patch_list = [ t for t in reversed_transactions if not t.get("new") and t.get("dirty") ] for patch_batch in chunker(patch_list, 100): log.debug("Patching transactions up to {}...".format( patch_batch[-1]["date"])) patch_result = patch(method, {"transactions": patch_batch}) patched += len(patch_result["transaction_ids"]) return created, duplicates, patched
def fetch_parameter(self, name): """Gets a Parameter from Parameter Store (Returns the Value) """ if not self.client: self.load() log.debug('Fetching Parameter %s', name) response = self.client.get_parameter( Name=name, WithDecryption=True) return response['Parameter']['Value']
def log_reply(reply): log.debug("Status: {0}".format(reply.status_code)) for k, v in reply.headers.items(): log.debug(" {0}: {1}".format(k, v)) log.debug("----------") if reply.headers["Content-Type"].startswith("application/json"): log.debug(json.dumps(reply.json(), indent=2)) else: log.debut(reply.text) log.debug("******************************")
def put_parameter(self, name, value): """Puts a Parameter into Parameter Store """ if not self.client: self.load() current_value = self.fetch_parameter(name) if current_value == value: log.debug('No need to update parameter %', name) return log.debug('Putting SSM Parameter %s', name) self.client.put_parameter(Name=name, Value=value, Overwrite=True)
def read_ssm_config(self): log.info('Reading config from SSM'.format(self.ssm_path)) try: resp = parameter_store.fetch_parameter(self.ssm_path) self.config = json.loads(resp) log.debug('Fetched configuration') except Exception as e: log.critical( "Error loading configuration from SSM Parameter: {}: {}". format(self.ssm_path, e)) sys.exit(1)
def merge(transactions): # Search for payment, reversal, payment triple log.debug("Merging ZeroFX duplicates...") for reversal in [t for t in transactions if "payment" in t]: if reversal["payment"]["sub_type"] == "REVERSAL": original = find_original(transactions, reversal) if not original: continue corrected = find_corrected(transactions, reversal) if not corrected: continue merge_triple(original, reversal, corrected)
def get_transactions(budget_id, account_id, start_date): transactions = get_raw_transactions(budget_id, account_id, start_date) same_day = [] for t in transactions: if same_day and same_day[0]["date"] != t["date"]: same_day.clear() same_day.append(t) occurrence = len([s for s in same_day if s["amount"] == t["amount"]]) if not t.get("import_id"): import_id = "YNAB:{}:{}:{}".format(t["amount"], t["date"], occurrence) log.debug("Simulated import_id {}".format(import_id)) t["import_id"] = import_id return transactions
def merge_triple(original, reversal, corrected): original_cat = original.get("category_id") if original_cat: if not reversal.get("category_id"): log.debug("Categorizing zerofx reversal...") reversal["category_id"] = original_cat reversal["dirty"] = True if not corrected.get("category_id"): log.debug("Categorizing zerofx corrected...") corrected["category_id"] = original_cat corrected["dirty"] = True if original.get("approved"): if not reversal.get("approved"): log.debug("Approving zerofx reversal...") reversal["approved"] = True reversal["dirty"] = True if not corrected.get("approved"): log.debug("Approving zerofx corrected...") corrected["approved"] = True corrected["dirty"] = True
def log_request(action, method, headers, data): log.debug("******************************") log.debug("{0} {1}".format(action, method)) for k, v in headers.items(): log.debug(" {0}: {1}".format(k, v)) if data: log.debug("-----") log.debug(json.dumps(data, indent=2)) log.debug("-----")