def get_links_to_sight_index(): """ Return a dictionary with the links where the sight indexes can be found """ filename = 'cities.yaml' cities_data = load_from(filename) loaded_urls = flatten([city.values() for city in cities_data.values()]) save = False index_urls = flat_to_url(__conf__.get('pages'), __conf__.get('website')) for url in index_urls: if url in loaded_urls: continue # print(url) country, city = lpparser.get_country_city(url) if country: country_level = cities_data.setdefault(country, OrderedDict()) country_level[city] = url save = True if save: save_to(cities_data, filename) return cities_data
def delete_accounts(self, accounts, reassign_to=None): """Removes ``accounts`` from the document. If the account has entries assigned to it, these entries will be reassigned to the ``reassign_to`` account. :param accounts: List of :class:`.Account` to be removed. :param accounts: :class:`.Account` to use for reassignment. """ # Recording the "Remove account" action into the Undoer is quite something... action = Action(tr('Remove account')) accounts = set(accounts) action.deleted_accounts |= accounts all_entries = flatten(self.accounts.entries_for_account(a) for a in accounts) if reassign_to is None: transactions = {e.transaction for e in all_entries if not e.transaction.is_spawn} transactions = {t for t in transactions if not t.affected_accounts() - accounts} action.deleted_transactions |= transactions action.change_entries(all_entries, self.schedules) affected_schedules = [s for s in self.schedules if accounts & s.affected_accounts()] for schedule in affected_schedules: action.change_schedule(schedule) self._undoer.record(action) for account in accounts: self.transactions.reassign_account(account, reassign_to) for schedule in affected_schedules: schedule.reassign_account(account, reassign_to) self.accounts.remove(account) self._cook()
def select(self, column_name: str, operator: str, value: str, column_names: List[str] = None) -> List[DavisBaseType]: index = self.columns_metadata.index(column_name) value = self.columns_metadata.value(column_name, value) if not column_names or column_names[0] == "*": args = SelectArgs([i for i in range(len(self.columns_metadata.columns))], Condition(index, operator, value)) else: args = SelectArgs([self.columns_metadata.index(n) for n in column_names], Condition(index, operator, value)) return flatten([page.select(args) for page in self.pages])
def delete_accounts(self, accounts, reassign_to=None): """Removes ``accounts`` from the document. If the account has entries assigned to it, these entries will be reassigned to the ``reassign_to`` account. :param accounts: List of :class:`.Account` to be removed. :param accounts: :class:`.Account` to use for reassignment. """ # Recording the "Remove account" action into the Undoer is quite something... action = Action(tr('Remove account')) accounts = set(accounts) action.deleted_accounts |= accounts all_entries = flatten( self.accounts.entries_for_account(a) for a in accounts) if reassign_to is None: transactions = { e.transaction for e in all_entries if not e.transaction.is_spawn } transactions = { t for t in transactions if not t.affected_accounts() - accounts } action.deleted_transactions |= transactions action.change_entries(all_entries, self.schedules) affected_schedules = [ s for s in self.schedules if accounts & s.affected_accounts() ] for schedule in affected_schedules: action.change_schedule(schedule) for account in accounts: affected_budgets = [ b for b in self.budgets if b.account == account or b.target == account ] if account.is_income_statement_account() and reassign_to is None: action.deleted_budgets |= set(affected_budgets) else: for budget in affected_budgets: action.change_budget(budget) self._undoer.record(action) for account in accounts: self.transactions.reassign_account(account, reassign_to) for schedule in affected_schedules: schedule.reassign_account(account, reassign_to) for budget in affected_budgets: if budget.account == account: if reassign_to is None: self.budgets.remove(budget) else: budget.account = reassign_to elif budget.target == account: budget.target = reassign_to self.accounts.remove(account) self._cook()
def _load(self, transactions): assert len(transactions) >= 2 self.can_change_accounts = all( len(t.splits) == 2 for t in transactions) self.can_change_amount = all(t.can_set_amount for t in transactions) self.date_field.value = date.today() self.description_field.text = '' self.payee_field.text = '' self.checkno_field.text = '' self.from_field.text = '' self.to_field.text = '' self.amount_field.value = 0 self.currency = None first = transactions[0] if allsame(t.date for t in transactions): self.date_field.value = first.date if allsame(t.description for t in transactions): self.description_field.text = first.description if allsame(t.payee for t in transactions): self.payee_field.text = first.payee if allsame(t.checkno for t in transactions): self.checkno_field.text = first.checkno splits = flatten(t.splits for t in transactions) splits = [s for s in splits if s.amount] if splits and allsame(s.amount.currency_code for s in splits): self.currency = splits[0].amount.currency_code else: self.currency = self.document.default_currency try: self.currency_list.select(Currencies.index(self.currency)) except IndexError: pass if self.can_change_accounts: def get_from(t): s1, s2 = t.splits return s1 if s1.amount <= 0 else s2 def get_to(t): s1, s2 = t.splits return s2 if s1.amount <= 0 else s1 def get_name(split): return split.account.name if split.account is not None else '' if allsame(get_name(get_from(t)) for t in transactions): self.from_field.text = get_name(get_from(first)) if allsame(get_name(get_to(t)) for t in transactions): self.to_field.text = get_name(get_to(first)) if self.can_change_amount: if allsame(t.amount for t in transactions): self.amount_field.value = first.amount self._init_checkboxes()
def cook(self, from_date=None, until_date=None): """Cooks raw data into :attr:`transactions`. :param from_date: when set, saves calculation time by re-using existing cooked transactions. :type from_date: ``datetime.date`` :param until_date: because of recurrence, we must always have a date at which we stop cooking. If we don't, we might end up in an infinite loop. If not set, will be the date of the transaction with the highest date. :type until_date: ``datetime.date`` """ # Determine from/until dates if from_date is None: from_date = date.min else: # it's possible that we have to reduce from_date a bit. If a split from before as a # reconciled date >= from_date, we have to set from_date to that split's normal date # We reverse the transactions to correctly detect chained overlappings in date/recdate for txn in reversed(self.transactions): # splits from *cooked* txns for split in txn.splits: rdate = split.reconciliation_date if rdate is not None and rdate >= from_date: from_date = min(from_date, txn.date) self._transactions.sort() # needed in case until_date is None if until_date is None: until_date = self._transactions.last().date if self._transactions else from_date # Clear old cooked data for account in self._accounts: entries = self._accounts.entries_for_account(account) entries.clear(from_date) if from_date == date.min: self.transactions = [] else: self.transactions = [t for t in self.transactions if t.date < from_date] # Cook if self._scheduled is not None: spawns = flatten(recurrence.get_spawns(until_date) for recurrence in self._scheduled) spawns += self._budget_spawns(until_date, spawns) # To ensure that our sort order stay correct and consistent, we assign position values # to our spawns. To ensure that there's no overlap, we start our position counter at # len(transactions) for counter, spawn in enumerate(spawns, start=len(self._transactions)): spawn.position = counter else: spawns = [] txns = list(self._transactions) + spawns # we don't filter out txns > until_date because they might be budgets affecting current data # XXX now that budget's base date is the start date, isn't this untrue? tocook = [t for t in txns if from_date <= t.date] tocook.sort(key=attrgetter('date')) oven_cook_txns(self._accounts, tocook) self.transactions += tocook self._cooked_until = until_date
def __init__(self, context, v): Chain.__init__(self, context) self.__values = flatten(v)