def is_new_company_info(self, company_info): """ Checks if CompanyInfo response has changed since it was pulled the last time. Usually this is taken care of by the LastUpdatedTime filter on the API (only data which has been updated is returned), but CompanyInfo endpoint seems to return all the time. Args: company_info(dict): response from CompanyInfo endpoint Returns: bool: True if the company_info has changed since the last pull """ company_info_updated_at = company_info.get('MetaData', {}).get('LastUpdatedTime') item = Item.query(Item.org_uid == self.org_uid, Item.endpoint == 'CompanyInfo', Item.changeset == -1).get() if item: item_updated_at = item.data.get('MetaData', {}).get('LastUpdatedTime') if company_info_updated_at and company_info_updated_at == item_updated_at: logging.info("CompanyInfo has not been updated, ignoring") return False return True
def count_items(): """ Utility method which returns the number of items in Item datastore kind. Returns: int: the number of items in Item datastore kind """ return len(Item.query().fetch(keys_only=True))
def next(self, payload): """ Processes one batch of missing items, saves them for publishing only if all can be resolved (resolution is attempted in the cache first, then via the API if not in cache). Args: payload(dict): a payload which has been given to the adaptor last time this function ran Returns: (bool, dict): a flag indicating if the sync has finished, and a payload to be passed in on next call """ results = [] missing_item = MissingItem.query( MissingItem.org_uid == self.org_uid).get() if not missing_item: logging.info("no missing items, nothing to process") return True, {} for item in missing_item.missing_items: logging.info("processing missing item: {}".format(item)) # handle items which do not have an ID (CompanyInfo for example) if item['type'] in SKIP_ID_IN_API_GET: item_cache = Item.query(Item.org_uid == self.org_uid, Item.endpoint == item['type'], Item.changeset == -1).get() else: item_cache = Item.query(Item.org_uid == self.org_uid, Item.endpoint == item['type'], Item.item_id == item['id'], Item.changeset == -1).get() if item_cache: data = item_cache.data item_id = item_cache.item_id else: logging.info( "could not find {} with id {} in raw endpoint cache". format(item['type'], item.get('id'))) session = QboApiSession(self.org_uid) data = session.get(self._get_url(item['type'], item.get('id')), headers={'Accept': 'application/json'}) data = data.get('QueryResponse', {}).get(item['type'], {}) if data: data = data[0] item_id = data['Id'] else: message_template = ( "could not find {} with id {} in the api either, " "ignoring and deleting this missing item record") logging.warning( message_template.format(item['type'], item.get('id'))) missing_item.key.delete() return False, {} results.append({ 'endpoint': item['type'], 'item_id': item_id, 'data': data }) item_objects = [] for result in results: message = "saving resolved missing item into raw endpoint cache (type: {}, id: {})" logging.info(message.format(result['endpoint'], result['item_id'])) item_objects.extend( sync_utils.create_items(self.org_uid, self.org.provider, self.org.changeset, result['endpoint'], result['item_id'], result['data'])) sync_utils.save_items(item_objects) logging.info("deleting missing item") missing_item.key.delete() return False, {}