class Effect(db.Model): __tablename__ = 'effect' id = db.Column(db.Integer(), primary_key=True, autoincrement=True) name = db.Column(db.Unicode(64), nullable=False, index=True) prop = db.Column(db.UnicodeText(), nullable=False) raw_duration = db.Column(db.UnicodeText()) start = db.Column(db.UnicodeText(), nullable=False) end = db.Column(db.UnicodeText()) done = db.Column(db.UnicodeText()) _duration_unit_re = re.compile(r'^([\d.]+)\s*([bms])$', re.I) @property def _parsed_duration(self): m = self.unit_re.match(self.raw_duration) if not m: raise ValueError("Duration value is not in the correct format") return float(m.group(1)), m.group(2) def duration_to_seconds(self, bpm, bpmeasure=None): value, unit = self._parsed_duration bpmeasure = bpmeasure or 4 if unit == 's': return value else: beat_len = 60 / bpm if unit == 'b': return value * beat_len elif unit == 'm': return (value * bpmeasure) * beat_len
class Recipe(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(256), index=True, unique=True) ingredients = db.Column(db.UnicodeText()) directions = db.Column(db.UnicodeText()) createdts = db.Column(db.DateTime, index=True, default=datetime.utcnow) def __repr__(self): return "<Recipe {}>".format(self.name)
class Article(db.Model): id = db.Column(db.Integer, primary_key=True) creator = db.Column(db.Integer, index=True) date = db.Column(db.DateTime, default=datetime.utcnow) title = db.Column(db.String(512), index=True, unique=True) brief = db.Column(db.UnicodeText(), index=True) content = db.Column(db.UnicodeText(), index=True) tags = db.Column(db.UnicodeText(), index=True) likes = db.Column(db.Integer, default = 0, index=True) imageurl = db.Column(db.UnicodeText(), index=True) likedusers = db.Column(db.UnicodeText(), index=True) def __repr__(self): return '<Article {} :: {}>'.format(self.id, self.title)
class Meal(db.Model): id = db.Column(db.Integer, primary_key=True) label = db.Column(db.String(64), unique=True) minutes = db.Column(db.Integer) recipe = db.Column(db.UnicodeText()) items = db.relationship('Item', secondary=meal_to_item, backref=db.backref('meals'), lazy='dynamic') user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return '<Meal {label}'.format(label=self.label) def total_cost(self): total_cost = 0 for item in self.items: total_cost += item.cost return total_cost def item_count(self): item_list = list() for item in self.items: item_list += item return len(item_list)
class Reference(db.Model): __tablename__ = '4_references' id = db.Column(db.Integer, primary_key=True) citation_id = db.Column(db.Integer, db.ForeignKey('3_citations.id'), nullable=False) reference_type_id = db.Column(db.Integer, db.ForeignKey('1_reference_types.id'), nullable=False) national_context_id = db.Column(db.Integer, db.ForeignKey('1_national_context.id'), nullable=False) date = db.Column(db.DateTime()) transcription = db.Column(db.UnicodeText()) referents = db.relationship('Referent', backref='reference', lazy=True, cascade="delete") def last_edit(self): edits = sorted([(e.timestamp, e) for e in self.edits], key=operator.itemgetter(0), reverse=True) return edits[0][1] def display_date(self): if self.date: return self.date.strftime('%Y %B %d') else: return '' def __repr__(self): return '<Reference {0}>'.format(self.id)
class Receita(db.Model): __tablename__ = 'receita' id = db.Column(db.Integer, primary_key=True) nome = db.Column(db.String(255)) autor = db.Column(db.String(255)) publicado_em = db.Column(db.DateTime, nullable=False) modo_preparo = db.Column(db.UnicodeText(500)) ingredientes = db.relationship('Ingrediente', secondary=receita_ingrediente, lazy='subquery', backref=db.backref('receita', lazy=True)) def __init__(self, nome, autor, publicado_em, modo_preparo): self.nome = nome self.autor = autor self.publicado_em = publicado_em self.modo_preparo = modo_preparo def __repr__(self): return '{}'.format(self.nome) def serialize(self): return { 'id': self.id, 'nome': self.nome, 'autor': self.autor, 'publicado_em': self.publicado_em }
class Blog(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.UnicodeText()) body = db.Column(db.UnicodeText()) pub_date = db.Column(db.DateTime) owner_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __init__(self, title, body, user, pub_date=None): self.title = title self.body = body if pub_date is None: pub_date = datetime.utcnow() self.pub_date = pub_date self.owner = user def __repr__(self): return '<Blog {0}>'.format(self.title)
class Level(Model): __tablename__ = 'level' id = db.Column(db.BigInteger(), primary_key=True) name = db.Column(db.Unicode(32), unique=True, nullable=False) description = db.Column(db.UnicodeText()) def __str__(self): return self.name
class Feedback(db.Model): id = db.Column(db.Integer, primary_key=True) item = db.Column(db.String(32)) fname = db.Column(db.String(32)) contact = db.Column(db.String(32)) copyright = db.Column(db.Boolean(), nullable=True) privacy = db.Column(db.Boolean(), nullable=True) message = db.Column(db.UnicodeText(), nullable=True) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(120)) timestamp = db.Column(db.DateTime, default=datetime.datetime.now()) content = db.Column(db.UnicodeText()) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return '<Post {title} by {author}>'.format(title=self.title, author=self.author)
class Terms(db.Model): id = db.Column(db.Integer, primary_key=True) word = db.Column(db.Unicode(length=100), index=True, unique=True) definition = db.Column(db.UnicodeText(), nullable=False) deleted = db.Column(db.Boolean(), default=False) created = db.Column(db.DateTime, nullable=True, server_default=db.func.now()) updated = db.Column(db.DateTime, nullable=True, server_default=db.func.now(), server_onupdate=db.func.now())
class SnapshotFailure(db.Model): id = db.Column(db.Integer, primary_key=True) creation_time = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False) symbol = db.Column(db.UnicodeText(), nullable=False) @staticmethod def make(symbol): return SnapshotFailure(symbol=symbol)
class Contact(db.Model): __tablename__ = "contacts" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255)) location = db.Column(db.String(255)) district_name = db.Column(db.String(255)) longitude = db.Column(db.String(255)) latitude = db.Column(db.String(255)) phone_number = db.Column(db.String(255)) activities = db.Column(db.UnicodeText())
class Links(db.Model): id = db.Column(db.Integer, primary_key=True) shortLink = db.Column(db.String(64), index=True) longLink = db.Column(db.UnicodeText()) genTime = db.Column(db.DateTime, index=True, default=datetime.utcnow) def __repr__(self): return '<Short {}>, <Long {}>, <Gen Time {}>'.format( self.shortLink, self.longLink, self.genTime) def generateShortLink(self, id): self.shortLink = short_url.encode_url(id)
class Badge(TimestampMixin, Model): __tablename__ = 'badge' id = db.Column(db.BigInteger(), primary_key=True) foreign_id = db.Column(db.String(64), unique=True) name = db.Column(db.UnicodeText(), nullable=False) level_id = db.Column(db.BigInteger(), db.ForeignKey('level.id', onupdate='CASCADE', ondelete='RESTRICT'), nullable=False) level = db.relationship('Level') real_age = db.Column(db.Integer()) under_18 = db.Column(db.Boolean(), nullable=False, default=False) under_13 = db.Column(db.Boolean(), nullable=False, default=False) print_queued = db.Column(db.Boolean(), nullable=False, default=False, index=True) print_queued_by_id = db.Column( db.BigInteger(), db.ForeignKey('user.id', onupdate='CASCADE', ondelete='SET NULL')) print_queued_by = db.relationship('User') flags = db.relationship('Flag', secondary=BadgeToFlag.__table__) @property def age(self): """\ Returns an adjusted age - a real age, if set, otherwise a fake age corresponding to another age group """ if self.under_13: return 12 elif self.under_18: return 17 return self.real_age @age.setter def age(self, value): if value < 13: self.under_13 = True self.under_18 = True self.real_age = None elif value < 18: self.under_13 = False self.under_18 = True self.real_age = None else: self.under_13 = False self.under_18 = False self.real_age = value
class Task(db.Model, JSONRPCModel, metaclass=RPCModelMeta): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) title = db.Column(db.UnicodeText()) description = db.Column(db.UnicodeText()) due_time = db.Column(db.DateTime(timezone=True), nullable=True) completion_time = db.Column(db.DateTime(timezone=True), nullable=True) def _create_parameters(self): return { "required": { "user_id": None, "title": None, }, "optional": { "description": None, "due_time": JSONRPCUtils.from_iso_str }, } def _update_parameters(self): return { "required": { "target_id": None }, "optional": { "title": None, "description": None, "due_time": JSONRPCUtils.from_iso_str, "completion_time": JSONRPCUtils.from_iso_str, }, } def transform_json_values(self): return { "due_time": JSONRPCUtils.to_iso_str, "completion_time": JSONRPCUtils.to_iso_str, }
class Citation(db.Model): __tablename__ = '3_citations' id = db.Column(db.Integer, primary_key=True) citation_type_id = db.Column(db.Integer, db.ForeignKey('2_citation_types.id'), nullable=False) display = db.Column(db.String(500)) zotero_id = db.Column(db.String(255)) comments = db.Column(db.UnicodeText()) acknowledgements = db.Column(db.String(255)) references = db.relationship('Reference', backref='citation', lazy=True) def __repr__(self): return '<Citation {0}>'.format(self.id)
class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(255)) content = db.Column(db.UnicodeText()) date = db.Column(db.DateTime(), default=datetime.now) imagine = db.Column(db.String(255)) def save(self): if (self.id is not None): db.session.merge(self) else: db.session.add(self) db.session.commit()
class ToDo(db.Model): __tablename__ = 'todo' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.Unicode(255), nullable=False, server_default=u'') description = db.Column(db.UnicodeText(), nullable=False, server_default=u'') created_at = db.Column(db.DateTime(), server_default=db.func.now()) updated_at = db.Column(db.DateTime(), server_default=db.func.now(), server_onupdate=db.func.now()) due_at = db.Column(db.DateTime()) completed = db.Column(db.Boolean(), nullable=False, server_default='0') user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE'))
class Role(RoleMixin, db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.Unicode(80), unique=True) catalog = db.Column(db.Unicode(80)) description = db.Column(db.UnicodeText(256)) def add_user(self, user): user_datastore.add_role_to_user(user, self) db.session.add_all([self, user]) db.session.commit() @staticmethod def create_role(**kwargs): r = user_datastore.create_role(**kwargs) db.session.add(r) db.session.commit() return r @staticmethod def insert_roles(): catalogs = current_app.config['KERNOD_CATALOGS'] for catalog_abbr in catalogs: member = user_datastore.create_role( name='%s_member' % catalog_abbr, catalog=catalog_abbr, description='member on %s' % catalogs[catalog_abbr]) mod = user_datastore.create_role(name='%s_mod' % catalog_abbr, catalog=catalog_abbr, description='moderator on %s' % catalogs[catalog_abbr]) admin = user_datastore.create_role( name='%s_admin' % catalog_abbr, catalog=catalog_abbr, description='administrator on %s' % catalogs[catalog_abbr]) db.session.add_all([member, mod, admin]) try: db.session.commit() except IntegrityError as e: # pragma: no cover import warnings warnings.warn(str(e)) db.session.rollback() def __eq__(self, other): return self.id == other.id def __repr__(self): # pragma: no cover return '<Role %s>' % self.id
class Example(db.Model): id = db.Column(db.Integer, primary_key=True) headline = db.Column(db.Unicode(64)) body = db.Column(db.UnicodeText()) created_on = db.Column(db.DateTime(), default=datetime.utcnow) updated_on = db.Column(db.DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow) def __init__(self, headline="", body=""): self.headline = headline self.body = body def __repr__(self): return '<Example - {}>'.format(self.headline)
class Event(db.Model): __tablename__ = "event" id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(255)) content = db.Column(db.UnicodeText()) date = db.Column(db.DateTime(), default=datetime.now) address = db.Column(db.String(255)) longitude = db.Column(db.String(255)) latitude = db.Column(db.String(255)) def save(self): if (self.id is not None): db.session.merge(self) else: db.session.add(self) db.session.commit()
class Company(db.Model): id = db.Column(db.Integer, primary_key=True) creation_time = db.Column(db.DateTime(timezone=True), server_default=db.func.now(), nullable=False) symbol = db.Column(db.UnicodeText(), nullable=False) def uri(self): return f"/company/{self.id}" def repr_card(self): snapshot = (Snapshot.query.filter_by(company_id=self.id).order_by( Snapshot.creation_time.desc()).first()) return render_template( "models/company/card.html", company=self, snapshot=snapshot, evaluation=snapshot.evaluate(), ) def repr_chart(self): snapshots = (Snapshot.query.filter_by(company_id=self.id).order_by( Snapshot.creation_time.asc()).all()) _graham_numbers = [] for s in snapshots: _graham_numbers.append(s.evaluate().graham_num) _max_graham_number = max(_graham_numbers) graham_number_scale = _max_graham_number * 1.10 x = "" previous_score = None for snapshot in snapshots: x = x + snapshot.repr_tr_chart_score(previous_score=previous_score) _evaluation = snapshot.evaluate() previous_score = _evaluation.score return x @staticmethod def repr_card_grid(companies): return render_template("models/company/card_grid.html", companies=companies) @staticmethod def make(symbol): return Company(symbol=symbol)
class effect_to_effect_group(db.Model): __tablename__ = 'effect_to_effect_group' effect_id = db.Column(db.Integer(), db.ForeignKey('effect.id', onupdate='CASCADE', ondelete='RESTRICT'), primary_key=True) effect = db.relationship('Effect') effect_group_id = db.Column(db.Integer(), db.ForeignKey('effect_group.id', onupdate='CASCADE', ondelete='CASCADE'), primary_key=True) effect_group = db.relationship('EffectGroup') lights = db.Column(db.UnicodeText(), nullable=False, default='*', server_default='*')
class Product(db.Model): __tablename__ = 'product' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode(50), nullable=False, unique=True) description = db.Column(db.UnicodeText()) price = db.Column(db.Numeric(10, 5, asdecimal=True)) category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False) category = db.relationship('Category', backref=db.backref('products', lazy='dynamic'), lazy='select') status = db.Column(db.Enum(ProductStatusEnum, validate_strings=True), nullable=False) rel_tags = db.relationship('Tag', secondary='product_tag', backref='products') tags = association_proxy( 'rel_tags', 'name', creator=lambda name: Tag.query.get_or_create(name=name)) category_name = association_proxy( 'category', 'name', creator=lambda name: Category.query.get_or_create(name=name)) def __repr__(self): return '<Product %r>' % self.name @hybrid_property def sells(self): return (db.session.query(label('count', func.sum( OrderDetail.quantity))).filter( OrderDetail.product == self).scalar()) @sells.expression def sells(cls): return (select([func.coalesce( func.sum(OrderDetail.quantity), 0)]).where(OrderDetail.product_id == cls.id).label('sells'))
class Message(db.Model): __tablename__ = 'messages' mysql_character_set = 'utf8' id = db.Column(db.Integer, primary_key=True) msg = db.Column(db.UnicodeText) created_at = db.Column(db.DateTime) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) room_id = db.Column(db.Integer, db.ForeignKey('rooms.id')) file_id = db.Column(db.Integer, db.ForeignKey('files.id')) images = db.Column(db.UnicodeText()) @property def photos(self): if self.images is None: return {} return json.loads(self.images) @photos.setter def photos(self, photos): self.images = json.dumps(photos)
class JournalContent(db.Model): __tablename__ = 'journal_contents' id = db.Column(db.Integer, primary_key=True) journal_id = db.Column(db.Integer, db.ForeignKey('journals.id')) journal = db.relationship("Journal", back_populates="journal_contents") locale = db.Column(db.String(20), default='en') title = db.Column(db.String(200), default='') content = db.Column(db.UnicodeText(), default='') def __init__(self, title, content, journal, locale): self.title = title self.content = content self.journal = journal self.locale = locale def to_dict(self): return { 'locale': self.locale, 'content': self.content, 'title': self.title } def __repr__(self): return '<JournalContent %r for "%r">' % (self.locale, self.title)
class Location(db.Model): """ Create a Location table """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32), info={'label': "Name"}) # 0 north = db.Column(db.Integer, default=0, info={'label': "North"}) east = db.Column(db.Integer, default=0, info={'label': "East"}) south = db.Column(db.Integer, default=0, info={'label': "South"}) west = db.Column(db.Integer, default=0, info={'label': "West"}) up = db.Column(db.Integer, default=0, info={'label': "Up"}) down = db.Column(db.Integer, default=0, info={'label': "Down"}) deathroom = db.Column(db.Boolean, default=False, info={'label': "Death room"}) nobr = db.Column(db.Boolean, default=False, info={'label': "No brief"}) description = db.Column(db.UnicodeText(), info={'label': "Description"}) __zone = None def openroom(self, mode="r"): # blob = "%s%d" % (ROOMS, -n) # x = fopen(blob, mod) # return x return None def closeroom(self): # logger().debug("<<< fclose(%s)", self) return None @classmethod def starting(cls): return random.choice(STARTING_LOCATIONS) @property def zone(self): if self.__zone is not None: return self.__zone for z in ZONES: if self.id in range(z.min_loc, z.max_loc): self.__zone = z return self.__zone self.__zone = Zone("TCHAN") return self.__zone @property def players(self): return Player.query.all() @property def objects(self): return Item.at_location(self.id) def __repr__(self): return self.name def save(self): db.session.add(self) db.session.commit() def load_exits(self, data): """ lodex """ # for a in range(len(DIRECTIONS)): # self.ex_dat[a] = 0 self.north = -int(data[0]) self.east = -int(data[1]) self.south = -int(data[2]) self.west = -int(data[3]) self.up = -int(data[4]) self.down = -int(data[5]) def load_from_file(self, filename): with open(filename) as f: data = f.readlines() self.load_exits(data) self.name = "%s %d" % (self.zone, self.zone.room_id(self.id)) # self.name = data[6] self.nobr = False self.deathroom = False self.description = "" for s in data[6:]: if s.strip() == "#DIE": self.deathroom = True elif s.strip() == "#NOBR": self.nobr = True else: self.description += s self.getstr() @classmethod def search(cls, id=0): l = cls.query.get(id) if l is not None: return l l = cls(id=id) l.deathroom = False l.nobr = False l.description = "\nYou are on channel %s\n" % (id) return l def list_objects(self, user): """ lisobs """ weather = self.weather res = [] res += self.objects_at( flannel=1, include_destroyed=user.person.is_wizzard, debug=user.debug_mode, user=user ) if weather: res.append(weather) res += self.objects_at( flannel=0, include_destroyed=user.person.is_wizzard, debug=user.debug_mode, user=user ) return res def objects_at(self, **kwargs): """ lojal2 """ user = kwargs.get('user') res = Item.at_location(self.id, **kwargs) if not res: return res if user is not None: user.wd_it = res[-1].name return res def list_people(self, user=None): """ lispeople """ res = Player.query.visible_to(user).all() if not res: return res if user is not None: user.wd_people(res[-1]) return res def lobjsat(self, user): self.aobjsat(1, user) def aobjsat(self, mode, user): """ Carried Loc ! """ res = "" d = 0 e = False f = 0 for c in self.objects: if mode == 1 and not c.iscarrby(self): continue if mode == 3 and not c.iscontin(self): continue e = True o_txt = c.name if user.debug_mode: x = "%d" % (c.id) o_txt += "{%-3s}" % (x) if c.iswornby(self): o_txt += " <worn>" if c.is_dest: o_txt = "(%s)" % (o_txt) o_txt += " " f += len(o_txt) if f > 79: f = 0 res += "\n" res += o_txt d += 4 if not e: return "Nothing\n" res += "\n" return res @property def weather(self): if not self.outdoors: return None return Weather(self.climate) @property def outdoors(self): if self.id in [100, 101, 102]: return True elif self.id == 183: return False elif self.id == 170: return False else: if self.id >= 168 and self.id <= 191: return True elif self.id >= 210 and self.id <= 211: return True elif self.id == 650: return False elif self.id >= 1050 and self.id <= 1100: return False elif self.id >= 600: return True return False @property def climate(self): if self.id > 178 and self.id < 199: return 1 if self.id >= 100 and self.id <= 178: return 2 return 0 @property def dark(self): if self.id == 1100 or self.id == 1101: return False if self.id >= 1113 and self.id <= 1123: return True if self.id < 300 or self.id > 399: return False return True @property def has_light(self): if not self.dark: return True if Item.light_at_location(self.id) is None: return True return False def on_go(self, user, direction): if self.has_intense_heat: if not user.shielded: raise GoError("The intense heat drives you back") else: user.buff.bprintf("The shield protects you from the worst of the lava stream's heat") if self.id <= 0: raise GoError() @property def has_intense_heat(self): return self.id == 139 def exits(self, exit_id): if exit_id == 0: return self.north elif exit_id == 1: return self.east elif exit_id == 2: return self.south elif exit_id == 3: return self.west elif exit_id == 4: return self.up elif exit_id == 5: return self.down return 0
class ConfigTemplate(db.Model): """ ConfigTemplate ============== The configuration template, that defines the content for the configuration generation process. It works with TemplateVariable objects, that stores and annotates the variables used within this template. """ __table_args__ = (db.UniqueConstraint('name', 'project_id'), ) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128), index=True, nullable=False) _template_content = db.Column(db.UnicodeText(), index=True) project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False) project = db.relationship('Project', backref=db.backref('configtemplates', cascade="all, delete-orphan", lazy='dynamic')) last_successful_ftp_export = db.Column(db.DateTime) last_successful_tftp_export = db.Column(db.DateTime) @property def name_slug(self): return Slugify(to_lower=False)(self.name) @property def template_content(self): return self._template_content @template_content.setter def template_content(self, value): # if the template content is changed, drop all associated Template Value Sets if self._template_content != value: for obj in self.template_value_sets.all(): TemplateValueSet.query.filter( TemplateValueSet.id == obj.id).delete() self._template_content = value self._create_variables_from_template_content() def __init__(self, name, project=None, template_content=""): self.name = name self.project = project self.template_content = template_content def __repr__(self): if not self.project: project_name = "None" else: project_name = self.project.name return '<ConfigTemplate %r (%s) in %s>' % (self.name, self.id, project_name) @staticmethod def convert_variable_name(string): """convert the given string to a valid variable name :param string: :return: """ return Slugify(separator="_", to_lower=False)(string) def _create_variables_from_template_content(self): dcg = MakoConfigGenerator(template_string=self.template_content) # the hostname is always defined within a TemplateValueSet, add it with a default description self.update_template_variable( "hostname", "the hostname of the device (also used as name for the template value set)" ) # create new template variables on the Config Template for var_name in dcg.template_variables: if var_name != "hostname": self.update_template_variable(var_name) def rename_variable(self, old_name, new_name): """rename the Template Variables within the Config Template and all associated Template Value Sets :param old_name: :param new_name: :return: """ if old_name not in self.get_template_variable_names(): raise TemplateVariableNotFoundException( "Variable %s not found in config template" % old_name) var_obj = self.get_template_variable_by_name(old_name) var_obj.var_name = new_name # variable renamed, change associated value sets for valueset in self.template_value_sets.all(): old_val = valueset.get_template_value_by_name_as_string(old_name) # drop old variable from value set db.session.delete(valueset.get_template_value_by_name(old_name)) # create new variables with the new name and the old value valueset.update_variable_value(var_name=new_name, value=old_val) def valid_template_value_set_name(self, template_value_set_name): """test if the given Template Value Set name is valid within the Config Template :param template_value_set_name: :return: True if valid, otherwise false """ query_result = self.template_value_sets.all() valid = True if not template_value_set_name: valid = False elif template_value_set_name == "": valid = False for obj in query_result: if obj.hostname == template_value_set_name: valid = False break return valid def get_template_variable_names(self): """get all Template Variable Names of the Config Template :return: """ result = [] for obj in self.variables.all(): result.append(obj.var_name) return result def get_template_variable_by_name(self, var_name): """get a Template Variable by the var_name_slug attribute within the Config Template :param var_name: :return: """ result = TemplateVariable.query.filter_by( var_name_slug=var_name, config_template=self).first() if not result: raise TemplateVariableNotFoundException( "Variable '%s' not found in Template '%s'" % (var_name, self.name)) return result def update_template_variable(self, var_name, description="", auto_convert_var_name=True): """add or update a Template Variable for the Config Template :param var_name: :param description: :param auto_convert_var_name: enables or disables the automatic conversion of the variable names :return: name of the variable that was updated (automatic conversion) """ # convert string if auto_convert_var_name: var_name = self.convert_variable_name(var_name) if var_name not in self.get_template_variable_names(): # variable not found, create new one (automatic conversion is then enforced) var_name = self.convert_variable_name(var_name) new_var = TemplateVariable(self, var_name, description) db.session.add(new_var) db.session.commit() else: # update existing variable tpl_var = TemplateVariable.query.filter_by( var_name_slug=var_name, config_template=self).first() tpl_var.description = description db.session.commit() return var_name def is_variable_defined(self, var_name): """checks if the given variable is defined on the Config Template :param var_name: :return: """ return var_name in self.get_template_variable_names()
class Recipe(db.Model): """ Main model. Workflows : * when you want to add a new one, create an instance, then call add_ingredients, then add_tags. * when you want to edit one, change the fields, then delete the obsolete quantities with delete_quantities, then call add_ingredients. It will update the quantities too. Then call add_tags. TODO call add_ingredients and add_tags in the init ? """ id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(200), index=True) steps = db.Column(db.UnicodeText()) servings = db.Column(db.Integer, default=1) cooking_temperature = db.Column(db.Integer) cooking_time = db.Column(db.Integer) prep_time = db.Column(db.Integer) upcoming = db.Column(db.Boolean, index=True, default=False) upcoming_servings = db.Column(db.Integer, default=1) quantities = db.relationship("Quantity", backref="recipe", lazy="dynamic") tags = db.relationship("Tag", secondary=recipe_tags, backref="recipes") def __repr__(self): return f"<{self.__class__.__name__} '{self.name}'>" def add_tags(self): self.tags.clear() tag_names = set(unidecode(s.lower()) for s in self.name.split()) tag_names.update(unidecode(quantity.ingredient.name.lower()) for quantity in self.quantities) for tag_name in tag_names: tag = Tag.query.filter_by(name=tag_name).first() if tag is None: tag = Tag(name=tag_name) self.tags.append(tag) def add_ingredients(self, ingredients): #TODO rename this, it's more synchronise_ingredients than add_ """ We assume here that ingredients has been already checked ingredients = [ {"name": "carrot", "quantity": 5, "unit": "kg"}, ... ] """ for ingredient in ingredients: ing = Ingredient.query.filter_by(name=ingredient["name"]).first() if ing is None: ing = Ingredient(name=ingredient["name"]) # This little dance is to avoid a warning message by sqlalchemy. # If we don't check for ing.id before querying Quantity, it complains that # we query with a None id, whose behavior might change in future versions. quantity = None if ing.id: quantity = Quantity.query.filter_by(ingredient=ing, recipe=self).first() if quantity: quantity.unit = ingredient["unit"] quantity.quantity = ingredient["quantity"] if not quantity: quantity = Quantity( unit=ingredient["unit"], quantity=ingredient["quantity"], ingredient=ing, recipe=self ) def delete_quantities(self, names): """ When editing a recipe, you want to remove the quantities no longer used. names is an iterable containing all the ingredients' names whose quantities you want to remove """ #TODO do only one ingredient query, and then use the relationship instead of # querying for the quantity for name in names: ing = Ingredient.query.filter_by(name=name).first() quantity = Quantity.query.filter_by(ingredient=ing, recipe=self).first() if quantity: db.session.delete(quantity) def to_dict(self): """ return the recipe as dict following the usual structure { "name": str, "id": int, "upcoming": bool, "upcoming_servings": int, "steps": str, "servings": int, "cooking_temperature": int, "cooking_time": int, "prep_time": int, "ingredients": [ {"name": name, "quantity": quantity, "unit": unit}, ... ] } """ ingredients = self.query.join( Quantity, self.id == Quantity.recipe_id ).join( Ingredient, Quantity.ingredient_id == Ingredient.id ).filter( Recipe.id == self.id ).with_entities( Ingredient.name, Quantity.unit, Quantity.quantity, ).all() logging.debug(ingredients) ingredients_list = [ { "name": ingredient.name, "unit": ingredient.unit, "quantity": ingredient.quantity, } for ingredient in ingredients] result = { "name": self.name, "id": self.id, "upcoming": self.upcoming, "upcoming_servings": self.upcoming_servings, "steps": self.steps, "servings": self.servings, "cooking_temperature": self.cooking_temperature, "cooking_time": self.cooking_time, "prep_time": self.prep_time, "ingredients": ingredients_list, } return result def delete(self): # TODO """ Remove this recipe. If clean=True, remove all the orphan ingredients and quantities """ pass