def serialize(self, serializer): serializer.add_property('slug', self.slug) serializer.add_property('display_name', self.display_name) serializer.add_property('kind', self.kind.value) serializer.add_property('parent', self.parent) serializer.add_property('aliases', self.aliases) serializer.add_property('elements', self.elements) serializer.add_property('conditions', [ObjectSerializer.serialize(condition, serializer.format) for condition in self.conditions]) serializer.add_property('elements_include', self.elements_include) serializer.add_property('elements_exclude', self.elements_exclude) serializer.add_property('last_refresh', str(self.last_refresh) if self.last_refresh is not None else None) serializer.add_property('instructions', [ObjectSerializer.serialize(obj, serializer.format) for obj in self.instructions]) serializer.add_property('components', [ObjectSerializer.serialize(obj, serializer.format) for obj in self.components])
def serialize(self, serializer): serializer.add_property('id', str(self.id)) serializer.add_property('display_name', self.display_name) serializer.add_property( 'items', { slug: ObjectSerializer.serialize(ii, serializer.format) for slug, ii in self.items.items() }) serializer.add_property( 'implicit_items', { slug: ObjectSerializer.serialize(ii, serializer.format) for slug, ii in self.implicit_items.items() })
def update_obj(cls, obj, id_value, id_attr='slug', commit=True): """ Update an existing model based on its current object state. :param obj: The object to delete. :param id_value: The ID of the object we should be updating. :param id_attr: Identity attribute. :param commit: Whether to commit this transaction now or deal with it yourself. Useful for batches. :return: New model. """ with DatabaseService.get_session() as session: model = cls._get_model_safe(session, obj, id_attr, id_value) # This feels unsafe, but should be OK. # https://stackoverflow.com/questions/9667138/how-to-update-sqlalchemy-row-entry for key, value in ObjectSerializer.serialize(obj, 'dict').items(): old_value = getattr(model, key) setattr(model, key, value) if old_value != value: LogService.info("Updating %s: '%s'->'%s'" % (key, old_value, value)) if commit: session.commit() return model
def obj_to_index(cls, obj, format='dict'): base_recipe = ObjectSerializer.serialize(obj, format) base_recipe.update({'alpha': obj.alpha}) tree = IngredientTreeCache.retrieve() specs = base_recipe.pop('specs') searchable_recipes = {} for spec in specs: # Holy F**k this took too long to figure out # https://thispointer.com/python-how-to-copy-a-dictionary-shallow-copy-vs-deep-copy/ searchable = copy.deepcopy(base_recipe) searchable['spec'] = spec searchable_id = '%s::%s' % (searchable['slug'], spec['slug']) searchable_recipes[searchable_id] = searchable # This count is achievable with a filter query in ES. # https://stackoverflow.com/questions/58659527/elastic-search-update-specific-nested-object # { filter: { script: { script: { source: "doc['spec.components.slug'].value.length() == 3" } } } # But it seemed to return some weird results too. Also required fielddata enabled on # the index. Also need to refactor the searchquer builder to deal with a deep parameter. This is # just easier. # # Maybe someday this will also bring back the notion of "countable" ingredients (ie, exclude bitters). # Given the complexity around that (requires parent to lookup, also ZK list of slugs to exclude) # it's not quite worth it right now. searchable['spec']['component_count'] = len(spec['components']) # https://stackoverflow.com/questions/14071038/add-an-element-in-each-dictionary-of-a-list-list-comprehension for component in spec['components']: # the Slug() is needed for the TDFv3 name->slug conversion. component.update({'parents': tree.parents(Slug(component['slug']))}) return [cls._index(meta={'id': key}, **value) for key, value in searchable_recipes.items()]
def serialize(self, serializer): serializer.add_property('id', str(self.id)) serializer.add_property('display_name', self.display_name) serializer.add_property('items', [ ObjectSerializer.serialize(item, serializer.format) for item in self.items ])
def import_(self, filepath): dicts_to_import = RecipeImporter._fetch_data_from_path(filepath) if len(dicts_to_import) > 1: self.delete(delete_all=True) for cocktail_dict in dicts_to_import: try: slug = Slug(cocktail_dict['display_name']) LogService.info("Working %s" % slug) c = CocktailFactory.raw_to_obj(cocktail_dict, slug) except KeyError as e: LogService.error("Something has bad data!") LogService.error(cocktail_dict) LogService.error(e) continue self.delete(cocktail=c) db_obj = CocktailModel(**ObjectSerializer.serialize(c, 'dict')) with self.pgconn.get_session() as session: session.add(db_obj) LogService.info("Successfully [re]created %s" % c.slug) ObjectValidator.validate(db_obj, session=session, fatal=False) Indexers.get_indexer(c).index(c) CocktailScanCache.invalidate()
def serialize(self, serializer): serializer.add_property('slug', self.slug) serializer.add_property('display_name', self.display_name) serializer.add_property('origin', ObjectSerializer.serialize(self.origin, serializer.format)) serializer.add_property('glassware', [ObjectSerializer.serialize(glassware, serializer.format) for glassware in self.glassware]) serializer.add_property('construction', ObjectSerializer.serialize(self.construction, serializer.format)) serializer.add_property('components', [ObjectSerializer.serialize(component, serializer.format) for component in self.components]) serializer.add_property('garnish', [ObjectSerializer.serialize(garnish, serializer.format) for garnish in self.garnish]) serializer.add_property('straw', self.straw) serializer.add_property('citations', [ObjectSerializer.serialize(citation, serializer.format) for citation in self.citations]) serializer.add_property('notes', [ObjectSerializer.serialize(note, serializer.format) for note in self.notes]) serializer.add_property('instructions', [ObjectSerializer.serialize(instruction, serializer.format) for instruction in self.instructions]) serializer.add_property('images', [ObjectSerializer.serialize(image, serializer.format) for image in self.images])
def get(self, slug): """ Get a Construction. :param slug: Construction slug. :return: Serialized Construction object. """ c = ConstructionFactory.produce_obj(id=slug) return ObjectSerializer.serialize(c, 'dict')
def serialize(self, serializer): serializer.add_property('slug', self.slug) serializer.add_property('display_name', self.display_name) serializer.add_property('description', self.description) serializer.add_property('images', [ ObjectSerializer.serialize(i, serializer.format) for i in self.images ])
def get(self, id): """ Get an inventories items from the database. :param id: :return: Serialized List """ lst = ListFactory.produce_obj(id=id) return [ObjectSerializer.serialize(i, 'dict') for i in lst.items]
def get(self, slug): """ Get a single ingredient from the database. :param slug: :return: Serialized Ingredient """ c = IngredientFactory.produce_obj(id=slug) return ObjectSerializer.serialize(c, 'dict')
def get(self, id): """ Get a single List from the database. :param id: :return: Serialized List """ c = ListFactory.produce_obj(id=id) return ObjectSerializer.serialize(c, 'dict')
def get(self, slug): """ Get a glassware. :param slug: glassware slug :return: Serialized glassware object """ c = GlasswareFactory.produce_obj(id=slug) return ObjectSerializer.serialize(c, 'dict')
def get(self, id): """ Get a single object from the database. :param id: GUID of the object. :return: Serialized Object :raises KeyError: not found """ c = InventoryFactory.produce_obj(id=id) return ObjectSerializer.serialize(c, 'dict')
def serialize(self, serializer): serializer.add_property('inventory_id', self.inventory_id) serializer.add_property('cocktail_slug', self.cocktail_slug) serializer.add_property('spec_slug', self.spec_slug) serializer.add_property('components', [ObjectSerializer.serialize(res, serializer.format) for res in self.components]) serializer.add_property('status_count', self.status_count) serializer.add_property('component_count', self.component_count) serializer.add_property('alpha', self.alpha) serializer.add_property('construction_slug', self.construction_slug)
def get(self, slug): """ Get a single cocktail from the database. :param slug: :return: Serialized Cocktail :raises IntegrityError: Duplicate """ c = CocktailFactory.produce_obj(id=slug) return ObjectSerializer.serialize(c, 'dict')
def post(self): """ Insert new Construction. :return: Serialized Construction object. """ c = ConstructionFactory.raw_to_obj(api.payload) ConstructionFactory.insert_obj(obj=c) ConstructionScanCache.invalidate() return ObjectSerializer.serialize(c, 'dict'), 201
def post(self, slug): """ Update a Construction. :param slug: Construction slug. :return: Serialized Construction object. """ c = ConstructionFactory.raw_to_obj(api.payload) ConstructionFactory.update_obj(obj=c, id_value=slug) ConstructionScanCache.invalidate() return ObjectSerializer.serialize(c, 'dict'), 200
def obj_to_index(obj, index_class, format='dict'): """ Serialize an object into a standard form suitable for indexing. :param obj: Serializable object. :param index_class: The ElasticSearch DSL class representing the intended index. :param format: Format of the data to pass to the serializer. :return: Instance of the Index class. """ return index_class(meta={'id': obj.slug}, **ObjectSerializer.serialize(obj, format))
def obj_to_index(cls, obj, format='dict'): """ Serialize an object into a standard form suitable for indexing. :param obj: Serializable object. :param format: Format of the data to pass to the serializer. :return: Instance of the Index class. """ return cls._index(meta={'id': obj.id}, **ObjectSerializer.serialize(obj, format))
def get(self, id, slug): """ Get an inventories item. :param id: :param slug: :return: Serialized List """ lst = ListFactory.produce_obj(id=id) i = lst.get_item(slug) return ObjectSerializer.serialize(i, 'dict')
def obj_to_index(obj, index_class, format='dict'): """ Serialize an object into a standard form suitable for indexing. :param obj: Serializable object. :param index_class: The ElasticSearch DSL class representing the intended index. :param format: Format of the data to pass to the serializer. :return: Instance of the Index class. """ id = "%s::%s::%s" % (obj.inventory_id, obj.cocktail_slug, obj.spec_slug) return index_class(meta={'id': id}, **ObjectSerializer.serialize(obj, format))
def get(self, id): """ Return a fully-expanded inventory including the implicitly included items. :param id: GUID of the object. :return: Serialized Object :raises KeyError: not found """ i = InventoryFactory.produce_obj(id=id, expand=True) InventoryIndexer.index(i) return ObjectSerializer.serialize(i, 'dict')
def serialize(self, serializer): serializer.add_property('slug', self.slug) serializer.add_property('display_name', self.display_name) serializer.add_property('quantity', self.quantity, even_if_empty=False) serializer.add_property('unit', self.unit, even_if_empty=False) serializer.add_property('notes', [ ObjectSerializer.serialize(note, serializer.format) for note in self.notes ]) serializer.add_property('optional', self.optional) serializer.add_property('preparation', self.preparation.slug)
def post(self): """ Create a new glassware. :return: Serialized glassware object. """ c = GlasswareFactory.raw_to_obj(api.payload) GlasswareFactory.insert_obj(obj=c) # Invalidate Cache GlasswareScanCache.invalidate() return ObjectSerializer.serialize(c, 'dict'), 201
def serialize(self, serializer): serializer.add_property('inventory_id', self.inventory_id) serializer.add_property('cocktail_slug', self.cocktail_slug) serializer.add_property('spec_slug', self.spec_slug) serializer.add_property('components', [ ObjectSerializer.serialize(res, serializer.format) for res in self.components ]) serializer.add_property('status_count', self.status_count) serializer.add_property('component_count', self.component_count) serializer.add_property('alpha', self.alpha) serializer.add_property('construction_slug', self.construction_slug) serializer.add_property('citations', [ ObjectSerializer.serialize(citation, serializer.format) for citation in self.citations ]) serializer.add_property('garnish', [ ObjectSerializer.serialize(garnish, serializer.format) for garnish in self.garnish ]) serializer.add_property('generated_at', self.generated_at)
def post(self): """ Create a new List. :return: List you created. """ m = ListFactory.raw_to_obj(api.payload) ListFactory.insert_obj(obj=m) ListIndexer.index(m) # Invalidate Cache ListScanCache.invalidate() return ObjectSerializer.serialize(m, 'dict'), 201
def run(self): args = self._setup_args() self._validate_args(args) # objects = UpneatConnector.get_recipes() objects = MixologyTechConnector( database_path='/home/grant/Desktop/Data.sqlite').get_recipes() for c in objects: content = ruamel.yaml.round_trip_dump( [ObjectSerializer.serialize(c, 'dict')]) filename = "%s.yaml" % c.slug write_file(path="../tortuga/dump/pdtapp/%s" % filename, contents=content)
def post(self): """ Create a new cocktail. :return: Serialized Cocktail object. """ c = CocktailFactory.raw_to_obj(api.payload) CocktailFactory.insert_obj(obj=c) RecipeIndexer.index(c) # Invalidate Cache CocktailScanCache.invalidate() return ObjectSerializer.serialize(c, 'dict'), 201
def get(self, id, slug): """ Return a single inventory item. :param id: GUID of the inventory. :param slug: Slug of the item. :return: InventoryItem """ i = InventoryFactory.produce_obj(id=id, expand=True) ii = i.items.get(slug) if not ii: raise KeyError("Item %s not found in inventory %s." % (slug, id)) return ObjectSerializer.serialize(ii, 'dict')