class Dataview(db.Model): """ The dataset is the core entity of any access to data. All requests to the actual data store are routed through it, as well as data loading and model generation. """ __tablename__ = 'dataview' id = Column(Integer, primary_key=True) title = Column(Unicode(500)) description = Column(Unicode()) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) urlhash = Column(Unicode(2000), default=make_uuid) datasets = relationship(Dataset, secondary=dataview_dataset_table, backref=backref('dataviews', lazy='dynamic')) account_id = Column(Integer, ForeignKey('account.id')) account = relationship(Account, backref=backref("dataviews")) cloned_dataview_id = Column(Integer, ForeignKey('dataview.id')) settings = Column(MutableDict.as_mutable(JSONType), default=dict) def __init__(self, data=None): self.urlhash = make_uuid() if not data: return self.title = data.get("title") self.description = data.get("description") if current_user.is_authenticated(): self.account = current_user self.settings = data.get("settings", {}) self.cloned_dataview_id = data.get("cloned_dataview_id", None) def __repr__(self): return "<Dataview(%r,%r)>" % (self.id, self.title) def update(self, data): #not to update name self.title = data.get("title") self.description = data.get("description") self.datasets = data.get("datasets") self.settings = data.get("settings", {}) def as_dict(self): return { 'title': self.title, 'description': self.description, 'settings': self.settings } @classmethod def clone_dataview(cls, theobj): fields = ['title', 'description', 'settings', 'datasets', 'settings'] classobj = cls() for field in fields: setattr(classobj, field, getattr(theobj, field)) classobj.cloned_dataview_id = theobj.id db.session.add(classobj) db.session.commit() return classobj @classmethod def all_by_account(cls, account, order=True): """ Query available datasets based on dataset visibility. """ return db.session.query(cls).filter_by(account_id=account.id).all() @classmethod def all(cls, order=True): """ Query available datasets based on dataset visibility. """ q = db.session.query(cls) if order: q = q.order_by(cls.title.asc()) return q @classmethod def by_urlhash(cls, urlhash): return db.session.query(cls).filter_by(urlhash=urlhash).first() @classmethod def by_user_settings(cls, settings, account_id): return db.session.query(cls).filter_by(settings=settings, account_id=account_id).first() @classmethod def by_id(cls, id): return db.session.query(cls).filter_by(id=id).first()
def upgrade(): schema = context.get_context().config.get_main_option('schema') parentschema = context.get_context().config.get_main_option('parentschema') srid = context.get_context().config.get_main_option('srid') engine = op.get_bind().engine if op.get_context().dialect.has_table(engine, 'functionality', schema=schema): # pragma: nocover return op.create_table( 'functionality', Column('id', Integer, primary_key=True), Column('name', Unicode, nullable=False), Column('value', Unicode, nullable=False), Column('description', Unicode), schema=schema, ) op.create_table( 'treeitem', Column('type', String(10), nullable=False), Column('id', Integer, primary_key=True), Column('name', Unicode), Column('order', Integer, nullable=False), Column('metadataURL', Unicode), schema=schema, ) op.create_table( 'restrictionarea', Column('id', Integer, primary_key=True), Column('name', Unicode), Column('description', Unicode), Column('readwrite', Boolean, default=False), schema=schema, ) op.execute("SELECT AddGeometryColumn('%(schema)s', 'restrictionarea', " "'area', %(srid)s, 'POLYGON', 2)" % { 'schema': schema, 'srid': srid }) op.create_table( 'shorturl', Column('id', Integer, primary_key=True), Column('url', Unicode(1000)), Column('ref', String(20), index=True, unique=True, nullable=False), Column('creator_email', Unicode(200)), Column('creation', DateTime), Column('last_hit', DateTime), Column('nb_hits', Integer), schema=schema + "_static", ) op.create_table( 'role', Column('id', Integer, primary_key=True), Column('name', Unicode, unique=True, nullable=False), Column('description', Unicode), schema=schema, ) op.execute("SELECT AddGeometryColumn('%(schema)s', 'role', " "'extent', %(srid)s, 'POLYGON', 2)" % { 'schema': schema, 'srid': srid }) role = Table( 'role', MetaData(), Column('name', Unicode, unique=True, nullable=False), schema=schema, ) op.bulk_insert(role, [{'name': 'role_admin'}]) op.create_table( 'layer', Column('id', Integer, ForeignKey(schema + '.treeitem.id'), primary_key=True), Column('public', Boolean, default=True), Column('inMobileViewer', Boolean, default=True), Column('inDesktopViewer', Boolean, default=True), Column('isChecked', Boolean, default=True), Column('icon', Unicode), Column('layerType', Unicode(12)), Column('url', Unicode), Column('imageType', Unicode(10)), Column('style', Unicode), Column('dimensions', Unicode), Column('matrixSet', Unicode), Column('wmsUrl', Unicode), Column('wmsLayers', Unicode), Column('queryLayers', Unicode), Column('kml', Unicode), Column('isSingleTile', Boolean), Column('legend', Boolean, default=True), Column('legendImage', Unicode), Column('legendRule', Unicode), Column('isLegendExpanded', Boolean, default=False), Column('minResolution', Float), Column('maxResolution', Float), Column('disclaimer', Unicode), Column('identifierAttributeField', Unicode), Column('geoTable', Unicode), Column('excludeProperties', Unicode), Column('timeMode', Unicode(8)), schema=schema, ) op.create_table( 'role_restrictionarea', Column('role_id', Integer, ForeignKey(schema + '.role.id'), primary_key=True), Column('restrictionarea_id', Integer, ForeignKey(schema + '.restrictionarea.id'), primary_key=True), schema=schema, ) op.create_table( 'tsearch', Column('id', Integer, primary_key=True), Column('label', Unicode), Column('layer_name', Unicode), Column('role_id', Integer, ForeignKey(schema + '.role.id'), nullable=True), Column('public', Boolean, server_default='true'), Column('ts', TsVector), Column('params', Unicode, nullable=True), schema=schema, ) op.execute("SELECT AddGeometryColumn('%(schema)s', 'tsearch', 'the_geom', " "%(srid)s, 'GEOMETRY', 2)" % { 'schema': schema, 'srid': srid }) op.create_index('tsearch_ts_idx', 'tsearch', ['ts'], schema=schema, postgresql_using='gin') op.create_table( 'treegroup', Column('id', Integer, ForeignKey(schema + '.treeitem.id'), primary_key=True), schema=schema, ) op.create_table( 'user', Column('type', String(10), nullable=False), Column('id', Integer, primary_key=True), Column('username', Unicode, unique=True, nullable=False), Column('password', Unicode, nullable=False), Column('email', Unicode, nullable=False), Column('is_password_changed', Boolean, default=False), Column('role_id', Integer, ForeignKey(schema + '.role.id'), nullable=False), schema=schema, ) if parentschema is not None and parentschema is not "": # pragma: nocover op.add_column('user', Column('parent_role_id', Integer, ForeignKey(parentschema + '.role.id')), schema=schema) op.execute( "INSERT INTO %(schema)s.user (type, username, email, password, role_id) " "(SELECT 'user', 'admin', '*****@*****.**', '%(pass)s', r.id " "FROM %(schema)s.role AS r " "WHERE r.name = 'role_admin')" % { 'schema': schema, 'pass': sha1('admin').hexdigest() }) op.create_table( 'role_functionality', Column('role_id', Integer, ForeignKey(schema + '.role.id'), primary_key=True), Column('functionality_id', Integer, ForeignKey(schema + '.functionality.id'), primary_key=True), schema=schema, ) op.create_table( 'user_functionality', Column('user_id', Integer, ForeignKey(schema + '.user.id'), primary_key=True), Column('functionality_id', Integer, ForeignKey(schema + '.functionality.id'), primary_key=True), schema=schema, ) op.create_table( 'layergroup', Column('id', Integer, ForeignKey(schema + '.treegroup.id'), primary_key=True), Column('isExpanded', Boolean), Column('isInternalWMS', Boolean), # children have radio button instance of check box Column('isBaseLayer', Boolean), schema=schema, ) op.create_table( 'layer_restrictionarea', Column('layer_id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True), Column('restrictionarea_id', Integer, ForeignKey(schema + '.restrictionarea.id'), primary_key=True), schema=schema, ) op.create_table( 'layergroup_treeitem', Column('treegroup_id', Integer, ForeignKey(schema + '.treegroup.id'), primary_key=True), Column('treeitem_id', Integer, ForeignKey(schema + '.treeitem.id'), primary_key=True), schema=schema, ) op.create_table( 'theme', Column('id', Integer, ForeignKey(schema + '.treegroup.id'), primary_key=True), Column('icon', Unicode), Column('inMobileViewer', Boolean, default=False), Column('inDesktopViewer', Boolean, default=True), schema=schema, ) op.create_table( 'theme_functionality', Column('theme_id', Integer, ForeignKey(schema + '.theme.id'), primary_key=True), Column('functionality_id', Integer, ForeignKey(schema + '.functionality.id'), primary_key=True), schema=schema, )
class Author(_Base, SelectMixin): """ Author names for a PubMed record. Attributes: pmid the record this author belongs to pos the order/position of the name in the PubMed record (starting from 1) name an author's last name or the collective's name (never empty) initials an author's initials * forename the expansion of the initials known to PubMed * suffix an author name's suffix * * empty string if explicitly non-existent, NULL if unknown Primary Key: ``(pmid, pos)`` """ __tablename__ = 'authors' pmid = Column(BigInteger, ForeignKey('citations.pmid', ondelete="CASCADE"), primary_key=True) pos = Column(SmallInteger, CheckConstraint("pos > 0"), primary_key=True) name = Column(UnicodeText, CheckConstraint("name <> ''"), nullable=False) initials = Column(Unicode(length=128), nullable=True) forename = Column(Unicode(length=256), nullable=True) suffix = Column(Unicode(length=128), nullable=True) def __init__(self, pmid: int, pos: int, name: str, initials: str = None, forename: str = None, suffix: str = None): assert pmid > 0, pmid assert pos > 0, pos assert name, repr(name) self.pmid = pmid self.pos = pos self.name = name self.initials = initials self.forename = forename self.suffix = suffix def __str__(self): return "{}\t{}\t{}\t{}\t{}\t{}\n".format(NULL(self.pmid), NULL(self.pos), STRING(self.name), NULL(self.initials), NULL(self.forename), NULL(self.suffix)) def __repr__(self): return "Author<{}:{}>".format(self.pmid, self.pos) def __eq__(self, other): return isinstance(other, Author) and \ self.pmid == other.pmid and \ self.pos == other.pos and \ self.name == other.name and \ self.initials == other.initials and \ self.forename == other.forename and \ self.suffix == other.suffix def fullName(self): """ Return the full name of this author (using forename or initials, last, and suffix). """ name = [] if self.forename: name.append(self.forename) elif self.initials: name.append(self.initials) name.append(self.name) if self.suffix: name.append(self.suffix) return ' '.join(name) def shortName(self): """Return the short name of this author (using initials and last).""" name = [] if self.initials: name.append(self.initials) elif self.forename: name.append(''.join([n[0] for n in self.forename.split()])) name.append(self.name) return ' '.join(name)
class IGCFile(db.Model): __tablename__ = "igc_files" id = db.Column(Integer, autoincrement=True, primary_key=True) owner_id = db.Column(Integer, db.ForeignKey("users.id"), nullable=False) owner = db.relationship("User", innerjoin=True) time_created = db.Column(DateTime, nullable=False, default=datetime.utcnow) filename = db.Column(String(), nullable=False) md5 = db.Column(String(32), nullable=False, unique=True) logger_id = db.Column(String(3)) logger_manufacturer_id = db.Column(String(3)) registration = db.Column(Unicode(32)) competition_id = db.Column(Unicode(5)) model = db.Column(Unicode(64)) date_utc = db.Column(Date, nullable=False) def __repr__(self): return unicode_to_str("<IGCFile: id=%d filename='%s'>" % (self.id, self.filename)) @classmethod def by_md5(cls, _md5): return cls.query(md5=_md5).first() def is_writable(self, user): return user and (self.owner_id == user.id or self.pilot_id == user.id or user.is_manager()) def may_delete(self, user): return user and user.is_manager() def update_igc_headers(self): path = files.filename_to_path(self.filename) igc_headers = read_igc_headers(path) if igc_headers is None: return if "manufacturer_id" in igc_headers: self.logger_manufacturer_id = igc_headers["manufacturer_id"] if "logger_id" in igc_headers: self.logger_id = igc_headers["logger_id"] if "date_utc" in igc_headers: self.date_utc = igc_headers["date_utc"] if "model" in igc_headers and (igc_headers["model"] is None or 0 < len(igc_headers["model"]) < 64): self.model = igc_headers["model"] if "reg" in igc_headers and (igc_headers["reg"] is None or 0 < len(igc_headers["reg"]) < 32): self.registration = igc_headers["reg"] if "cid" in igc_headers and (igc_headers["cid"] is None or 0 < len(igc_headers["cid"]) < 5): self.competition_id = igc_headers["cid"] def guess_registration(self): from skylines.model.flight import Flight # try to find another flight with the same logger and use it's aircraft registration if self.logger_id is not None and self.logger_manufacturer_id is not None: logger_id = self.logger_id logger_manufacturer_id = self.logger_manufacturer_id result = (Flight.query().join(IGCFile).filter( db.func.upper(IGCFile.logger_manufacturer_id) == db.func.upper( logger_manufacturer_id)).filter( db.func.upper(IGCFile.logger_id) == db.func.upper( logger_id)).filter( Flight.registration == None).order_by( Flight.id.desc())) if self.logger_manufacturer_id.startswith("X"): result = result.filter(Flight.pilot == self.owner) result = result.first() if result and result.registration: return result.registration return None def guess_model(self): from skylines.model import Flight, AircraftModel # first try to find the reg number in the database if self.registration is not None: glider_reg = self.registration result = (Flight.query().filter( db.func.upper(Flight.registration) == db.func.upper( glider_reg)).order_by(Flight.id.desc()).first()) if result and result.model_id: return result.model_id # try to find another flight with the same logger and use it's aircraft type if self.logger_id is not None and self.logger_manufacturer_id is not None: logger_id = self.logger_id logger_manufacturer_id = self.logger_manufacturer_id result = (Flight.query().join(IGCFile).filter( db.func.upper(IGCFile.logger_manufacturer_id) == db.func.upper(logger_manufacturer_id)).filter( db.func.upper(IGCFile.logger_id) == db.func.upper( logger_id)).filter(Flight.model_id == None).order_by( Flight.id.desc())) if self.logger_manufacturer_id.startswith("X"): result = result.filter(Flight.pilot == self.owner) result = result.first() if result and result.model_id: return result.model_id if self.model is not None: glider_type = self.model.lower() # otherwise, try to guess the glider model by the glider type igc header text_fragments = [ "%{}%".format(v) for v in re.sub(r"[^a-z]", " ", glider_type).split() ] digit_fragments = [ "%{}%".format(v) for v in re.sub(r"[^0-9]", " ", glider_type).split() ] if not text_fragments and not digit_fragments: return None glider_type_clean = re.sub(r"[^a-z0-9]", "", glider_type) result = (AircraftModel.query().filter( and_( db.func.regexp_replace(db.func.lower(AircraftModel.name), "[^a-z]", " ").like( db.func.any(text_fragments)), db.func.regexp_replace(db.func.lower(AircraftModel.name), "[^0-9]", " ").like( db.func.all(digit_fragments)), )).order_by( db.func.levenshtein( db.func.regexp_replace( db.func.lower(AircraftModel.name), "[^a-z0-9]", ""), glider_type_clean, ))) if result.first(): return result.first().id # nothing found return None
import os from datetime import datetime from sqlalchemy import Table, ForeignKey, Column, not_ from sqlalchemy.types import Unicode, Integer, DateTime from sqlalchemy.orm import mapper, relation, synonym from mediacore.model.meta import DBSession, metadata from mediacore.lib.compat import any, sha1 from mediacore.plugin import events users = Table( 'users', metadata, Column('user_id', Integer, autoincrement=True, primary_key=True), Column('user_name', Unicode(16), unique=True, nullable=False), Column('email_address', Unicode(255), unique=True, nullable=False), Column('display_name', Unicode(255)), Column('password', Unicode(80)), Column('created', DateTime, default=datetime.now), mysql_engine='InnoDB', mysql_charset='utf8', ) users_groups = Table( 'users_groups', metadata, Column('user_id', Integer, ForeignKey('users.user_id', onupdate="CASCADE", ondelete="CASCADE")), Column(
class User(DeclarativeBase): """Reasonably basic User definition. Probably would want additional attributes. """ __tablename__ = 'tg_user' user_id = Column(Integer, autoincrement=True, primary_key=True) user_name = Column(Unicode(16), unique=True, nullable=False) email_address = Column(Unicode(255), unique=True, nullable=False, info={'rum': { 'field': 'Email' }}) display_name = Column(Unicode(255)) _password = Column('password', Unicode(80), info={'rum': { 'field': 'Password' }}) created = Column(DateTime, default=datetime.now) def __repr__(self): return '<User: email="%s", display name="%s">' % (self.email_address, self.display_name) def __unicode__(self): return self.display_name or self.user_name @property def permissions(self): perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms @classmethod def by_email_address(cls, email): """A class method that can be used to search users based on their email addresses since it is unique. """ return DBSession.query(cls).filter(cls.email_address == email).first() @classmethod def by_user_name(cls, username): """A class method that permits to search users based on their user_name attribute. """ return DBSession.query(cls).filter(cls.user_name == username).first() def _set_password(self, password): """Hash password on the fly.""" hashed_password = password if isinstance(password, unicode): password_8bit = password.encode('UTF-8') else: password_8bit = password salt = sha1() salt.update(os.urandom(60)) hash = sha1() hash.update(password_8bit + salt.hexdigest()) hashed_password = salt.hexdigest() + hash.hexdigest() # make sure the hased password is an UTF-8 object at the end of the # process because SQLAlchemy _wants_ a unicode object for Unicode columns if not isinstance(hashed_password, unicode): hashed_password = hashed_password.decode('UTF-8') self._password = hashed_password def _get_password(self): """returns password """ return self._password password = synonym('_password', descriptor=property(_get_password, _set_password)) def validate_password(self, password): """Check the password against existing credentials. :param password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type password: unicode object. :return: Whether the password is valid. :rtype: bool """ hashed_pass = sha1() hashed_pass.update(password + self.password[:40]) return self.password[40:] == hashed_pass.hexdigest()
class Flight(db.Model): __tablename__ = 'flights' id = db.Column(Integer, autoincrement=True, primary_key=True) time_created = db.Column(DateTime, nullable=False, default=datetime.utcnow) time_modified = db.Column(DateTime, nullable=False, default=datetime.utcnow) pilot_id = db.Column( Integer, db.ForeignKey('users.id', ondelete='SET NULL'), index=True) pilot = db.relationship('User', foreign_keys=[pilot_id]) # Fallback if the pilot is not registered pilot_name = db.Column(Unicode(255)) co_pilot_id = db.Column( Integer, db.ForeignKey('users.id', ondelete='SET NULL'), index=True) co_pilot = db.relationship('User', foreign_keys=[co_pilot_id]) # Fallback if the co-pilot is not registered co_pilot_name = db.Column(Unicode(255)) club_id = db.Column( Integer, db.ForeignKey('clubs.id', ondelete='SET NULL'), index=True) club = db.relationship('Club', backref='flights') model_id = db.Column(Integer, db.ForeignKey('models.id', ondelete='SET NULL')) model = db.relationship('AircraftModel') registration = db.Column(Unicode(32)) competition_id = db.Column(Unicode(5)) # The date of the flight in local time instead of UTC. Used for scoring. date_local = db.Column(Date, nullable=False, index=True) takeoff_time = db.Column(DateTime, nullable=False, index=True) scoring_start_time = db.Column(DateTime, nullable=True) scoring_end_time = db.Column(DateTime, nullable=True) landing_time = db.Column(DateTime, nullable=False) takeoff_location_wkt = db.Column( 'takeoff_location', Geometry('POINT', srid=4326)) landing_location_wkt = db.Column( 'landing_location', Geometry('POINT', srid=4326)) takeoff_airport_id = db.Column( Integer, db.ForeignKey('airports.id', ondelete='SET NULL')) takeoff_airport = db.relationship('Airport', foreign_keys=[takeoff_airport_id]) landing_airport_id = db.Column( Integer, db.ForeignKey('airports.id', ondelete='SET NULL')) landing_airport = db.relationship('Airport', foreign_keys=[landing_airport_id]) timestamps = deferred(db.Column( postgresql.ARRAY(DateTime), nullable=False), group='path') locations = deferred(db.Column( Geometry('LINESTRING', srid=4326), nullable=False), group='path') olc_classic_distance = db.Column(Integer) olc_triangle_distance = db.Column(Integer) olc_plus_score = db.Column(Float) igc_file_id = db.Column( Integer, db.ForeignKey('igc_files.id', ondelete='CASCADE'), nullable=False) igc_file = db.relationship('IGCFile', backref='flights', innerjoin=True) qnh = db.Column(Float) needs_analysis = db.Column(Boolean, nullable=False, default=True) # Privacy level of the flight class PrivacyLevel: PUBLIC = 0 LINK_ONLY = 1 PRIVATE = 2 privacy_level = db.Column( SmallInteger, nullable=False, default=PrivacyLevel.PUBLIC) ############################## def __repr__(self): return ('<Flight: id=%s, modified=%s>' % (self.id, self.time_modified)).encode('unicode_escape') ############################## @hybrid_property def duration(self): return self.landing_time - self.takeoff_time @hybrid_property def year(self): return self.date_local.year @hybrid_property def index_score(self): if self.model and self.model.dmst_index > 0: return self.olc_plus_score * 100 / self.model.dmst_index else: return self.olc_plus_score @index_score.expression def index_score(cls): return case([(AircraftModel.dmst_index > 0, cls.olc_plus_score * 100 / AircraftModel.dmst_index)], else_=cls.olc_plus_score) @year.expression def year(cls): return db.func.date_part('year', cls.date_local) @property def takeoff_location(self): if self.takeoff_location_wkt is None: return None coords = to_shape(self.takeoff_location_wkt) return Location(latitude=coords.y, longitude=coords.x) @takeoff_location.setter def takeoff_location(self, location): if location is None: self.takeoff_location_wkt = None else: self.takeoff_location_wkt = location.to_wkt_element() @property def landing_location(self): if self.landing_location_wkt is None: return None coords = to_shape(self.landing_location_wkt) return Location(latitude=coords.y, longitude=coords.x) @landing_location.setter def landing_location(self, location): if location is None: self.landing_location_wkt = None else: self.landing_location_wkt = location.to_wkt_element() @classmethod def by_md5(cls, _md5): file = IGCFile.by_md5(_md5) if file is None: return None return cls.query().filter_by(igc_file=file).first() # Permissions ################ @hybrid_method def is_viewable(self, user): return (self.privacy_level == Flight.PrivacyLevel.PUBLIC or self.privacy_level == Flight.PrivacyLevel.LINK_ONLY or self.is_writable(user)) @is_viewable.expression def is_viewable_expression(cls, user): return or_(cls.privacy_level == Flight.PrivacyLevel.PUBLIC, cls.privacy_level == Flight.PrivacyLevel.LINK_ONLY, cls.is_writable(user)) @hybrid_method def is_listable(self, user): return (self.privacy_level == Flight.PrivacyLevel.PUBLIC or self.is_writable(user)) @is_listable.expression def is_listable_expression(cls, user): return or_(cls.privacy_level == Flight.PrivacyLevel.PUBLIC, cls.is_writable(user)) @hybrid_method def is_rankable(self): return self.privacy_level == Flight.PrivacyLevel.PUBLIC @hybrid_method def is_writable(self, user): return user and \ (self.igc_file.owner_id == user.id or self.pilot_id == user.id or user.is_manager()) @is_writable.expression def is_writable_expression(self, user): return user and ( user.is_manager() or or_( IGCFile.owner_id == user.id, self.pilot_id == user.id ) ) @hybrid_method def may_delete(self, user): return user and (self.igc_file.owner_id == user.id or user.is_manager()) ############################## @classmethod def get_largest(cls): """Returns a query object ordered by distance""" return cls.query().order_by(cls.olc_classic_distance.desc()) def get_optimised_contest_trace(self, contest_type, trace_type): from skylines.model.trace import Trace return Trace.query(contest_type=contest_type, trace_type=trace_type, flight=self).first() def get_contest_speed(self, contest_type, trace_type): contest = self.get_optimised_contest_trace(contest_type, trace_type) return contest and contest.speed def get_contest_legs(self, contest_type, trace_type): return ContestLeg.query(contest_type=contest_type, trace_type=trace_type, flight=self) \ .filter(ContestLeg.end_time - ContestLeg.start_time > timedelta(0)) \ .order_by(ContestLeg.start_time) @property def speed(self): return self.get_contest_speed('olc_plus', 'classic') @property def has_phases(self): return bool(self._phases) @property def phases(self): return [p for p in self._phases if not p.aggregate] def delete_phases(self): self._phases = [] @property def circling_performance(self): from skylines.model.flight_phase import FlightPhase stats = [p for p in self._phases if (p.aggregate and p.phase_type == FlightPhase.PT_CIRCLING and p.duration.total_seconds() > 0)] order = [FlightPhase.CD_TOTAL, FlightPhase.CD_LEFT, FlightPhase.CD_RIGHT, FlightPhase.CD_MIXED] stats.sort(lambda a, b: cmp(order.index(a.circling_direction), order.index(b.circling_direction))) return stats @property def cruise_performance(self): from skylines.model.flight_phase import FlightPhase return [p for p in self._phases if p.aggregate and p.phase_type == FlightPhase.PT_CRUISE] def update_flight_path(self): from skylines.lib.xcsoar_ import flight_path from skylines.lib.datetime import from_seconds_of_day # Run the IGC file through the FlightPath utility path = flight_path(self.igc_file, qnh=self.qnh) if len(path) < 2: return False # Save the timestamps of the coordinates date_utc = self.igc_file.date_utc self.timestamps = \ [from_seconds_of_day(date_utc, c.seconds_of_day) for c in path] # Convert the coordinate into a list of tuples coordinates = [(c.location['longitude'], c.location['latitude']) for c in path] # Create a shapely LineString object from the coordinates linestring = LineString(coordinates) # Save the new path as WKB self.locations = from_shape(linestring, srid=4326) return True
class Theme(DatabaseObject): """ Holds theme related settings """ uuid = Column(String(36), unique=True, nullable=False, default=lambda: uuid4()) _name = Column(Unicode(64), unique=True, nullable=False) files = relationship("ThemeFile", lazy="joined") @classmethod def all(cls): """ Return all objects """ return dbsession.query(cls).all() @classmethod def by_id(cls, _id): """ Return the object whose id is _id """ return dbsession.query(cls).filter_by(id=_id).first() @classmethod def by_uuid(cls, _uuid): """ Return the object whose uuid is _uuid """ return dbsession.query(cls).filter_by(uuid=_uuid).first() @classmethod def by_name(cls, name): """ Return the object whose name is _name """ return dbsession.query(cls).filter_by(_name=str(name)).first() @classmethod def _filter_string(cls, string, extra_chars=""): """ Remove any non-white listed chars from a string """ char_white_list = ascii_letters + digits + extra_chars return "".join([char for char in string if char in char_white_list]) @property def name(self): return self._name @name.setter def name(self, value): self._name = self._filter_string(value, ".") def is_sequence(self, arg): return (not hasattr(arg, "strip") and hasattr(arg, "__getitem__") or hasattr(arg, "__iter__")) def __iter__(self): try: for _file in self.files: yield _file except: logging.error("Problem with theme - reloading...") themefile = relationship("ThemeFile", lazy="joined") if self.is_sequence(themefile): self.files = themefile for _file in self.files: yield _file else: logging.error( "Error with theme relationship. Returning default Cyborg theme" ) yield "cyborg.min.css"
from mediacore.lib.util import calculate_popularity from mediacore.lib.xhtml import line_break_xhtml, strip_xhtml from mediacore.model import SLUG_LENGTH, _mtm_count_property, _properties_dict_from_labels, MatchAgainstClause from mediacore.model.meta import DBSession, metadata from mediacore.model.authors import Author from mediacore.model.categories import Category, CategoryList, categories from mediacore.model.comments import Comment, CommentQuery, comments from mediacore.model.tags import Tag, TagList, tags, extract_tags, fetch_and_create_tags from mediacore.plugin import events media = Table('media', metadata, Column('id', Integer, autoincrement=True, primary_key=True, doc=\ """The primary key ID."""), Column('type', Unicode(8), doc=\ """Indicates whether the media is to be considered audio or video. If this object has no files, the type is None. See :meth:`Media.update_type` for details on how this is determined."""), Column('slug', Unicode(SLUG_LENGTH), unique=True, nullable=False, doc=\ """A unique URL-friendly permalink string for looking up this object. Be sure to call :func:`mediacore.model.get_available_slug` to ensure the slug is unique."""), Column('podcast_id', Integer, ForeignKey('podcasts.id', onupdate='CASCADE', ondelete='SET NULL'), doc=\ """The primary key of a podcast to publish this media under."""), Column('reviewed', Boolean, default=False, nullable=False, doc=\
def upgrade(): schema = context.get_context().config.get_main_option('schema') engine = op.get_bind().engine if type(engine).__name__ != 'MockConnection' and \ op.get_context().dialect.has_table( engine, 'interface', schema=schema): # pragma: no cover return op.drop_table('user_functionality', schema=schema) op.create_table( 'interface', Column('id', Integer, primary_key=True), Column('name', Unicode), Column('description', Unicode), schema=schema, ) op.create_table( 'interface_layer', Column('interface_id', Integer, ForeignKey(schema + '.interface.id'), primary_key=True), Column('layer_id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True), schema=schema, ) op.create_table( 'interface_theme', Column('interface_id', Integer, ForeignKey(schema + '.interface.id'), primary_key=True), Column('theme_id', Integer, ForeignKey(schema + '.theme.id'), primary_key=True), schema=schema, ) op.create_table( 'layerv1', Column('id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True), Column('is_checked', Boolean, default=True), Column('icon', Unicode), Column('layer_type', Unicode(12)), Column('url', Unicode), Column('image_type', Unicode(10)), Column('style', Unicode), Column('dimensions', Unicode), Column('matrix_set', Unicode), Column('wms_url', Unicode), Column('wms_layers', Unicode), Column('query_layers', Unicode), Column('kml', Unicode), Column('is_single_tile', Boolean), Column('legend', Boolean, default=True), Column('legend_image', Unicode), Column('legend_rule', Unicode), Column('is_legend_expanded', Boolean, default=False), Column('min_resolution', Float), Column('max_resolution', Float), Column('disclaimer', Unicode), Column('identifier_attribute_field', Unicode), Column('exclude_properties', Unicode), Column('time_mode', Unicode(8)), schema=schema, ) op.execute("UPDATE ONLY %(schema)s.treeitem SET type = 'layerv1' " "WHERE type='layer'" % {'schema': schema}) op.execute( 'INSERT INTO %(schema)s.layerv1 (' 'id, is_checked, icon, layer_type, url, image_type, style, dimensions, matrix_set, ' 'wms_url, wms_layers, query_layers, kml, is_single_tile, legend, ' 'legend_image, legend_rule, is_legend_expanded, min_resolution, max_resolution, ' 'disclaimer, identifier_attribute_field, exclude_properties, time_mode) ' '(SELECT ' 'id, "isChecked" AS is_checked, icon, "layerType" AS layer_type, url, ' '"imageType" AS image_type, style, dimensions, "matrixSet" AS matrix_set, ' '"wmsUrl" AS wms_url, "wmsLayers" AS wms_layers, "queryLayers" AS query_layers, kml, ' '"isSingleTile" AS is_single_tile, legend, "legendImage" AS legend_image, ' '"legendRule" AS legend_rule, "isLegendExpanded" AS is_legend_expanded, ' '"minResolution" AS min_resolution, "maxResolution" AS max_resolution, disclaimer, ' '"identifierAttributeField" AS identifier_attribute_field, ' '"excludeProperties" AS exclude_properties, "timeMode" AS time_mode ' 'FROM %(schema)s.layer)' % {'schema': schema}) op.drop_column('layer', 'isChecked', schema=schema) op.drop_column('layer', 'icon', schema=schema) op.drop_column('layer', 'layerType', schema=schema) op.drop_column('layer', 'url', schema=schema) op.drop_column('layer', 'imageType', schema=schema) op.drop_column('layer', 'style', schema=schema) op.drop_column('layer', 'dimensions', schema=schema) op.drop_column('layer', 'matrixSet', schema=schema) op.drop_column('layer', 'wmsUrl', schema=schema) op.drop_column('layer', 'wmsLayers', schema=schema) op.drop_column('layer', 'queryLayers', schema=schema) op.drop_column('layer', 'kml', schema=schema) op.drop_column('layer', 'isSingleTile', schema=schema) op.drop_column('layer', 'legend', schema=schema) op.drop_column('layer', 'legendImage', schema=schema) op.drop_column('layer', 'legendRule', schema=schema) op.drop_column('layer', 'isLegendExpanded', schema=schema) op.drop_column('layer', 'minResolution', schema=schema) op.drop_column('layer', 'maxResolution', schema=schema) op.drop_column('layer', 'disclaimer', schema=schema) op.drop_column('layer', 'identifierAttributeField', schema=schema) op.drop_column('layer', 'excludeProperties', schema=schema) op.drop_column('layer', 'timeMode', schema=schema) interface = Table( 'interface', MetaData(), Column('name', Unicode), schema=schema, ) op.bulk_insert(interface, [ { 'name': 'main' }, { 'name': 'mobile' }, { 'name': 'edit' }, { 'name': 'routing' }, ]) op.execute( 'INSERT INTO %(schema)s.interface_layer (layer_id, interface_id) ' '(SELECT l.id AS layer_id, i.id AS interface_id ' 'FROM %(schema)s.layer AS l, %(schema)s.interface AS i ' 'WHERE i.name in (\'main\', \'edit\', \'routing\') AND l."inDesktopViewer")' % {'schema': schema}) op.execute( 'INSERT INTO %(schema)s.interface_layer (layer_id, interface_id) ' '(SELECT l.id AS layer_id, i.id AS interface_id ' 'FROM %(schema)s.layer AS l, %(schema)s.interface AS i ' 'WHERE i.name = \'mobile\' AND l."inMobileViewer")' % {'schema': schema}) op.execute( 'INSERT INTO %(schema)s.interface_theme (theme_id, interface_id) ' '(SELECT l.id AS theme_id, i.id AS interface_id ' 'FROM %(schema)s.theme AS l, %(schema)s.interface AS i ' 'WHERE i.name in (\'main\', \'edit\', \'routing\') AND l."inDesktopViewer")' % {'schema': schema}) op.execute( 'INSERT INTO %(schema)s.interface_theme (theme_id, interface_id) ' '(SELECT l.id AS theme_id, i.id AS interface_id ' 'FROM %(schema)s.theme AS l, %(schema)s.interface AS i ' 'WHERE i.name = \'mobile\' AND l."inMobileViewer")' % {'schema': schema}) op.drop_column('layer', 'inMobileViewer', schema=schema) op.drop_column('layer', 'inDesktopViewer', schema=schema) op.alter_column('layer', 'geoTable', new_column_name='geo_table', schema=schema) op.drop_column('theme', 'inMobileViewer', schema=schema) op.drop_column('theme', 'inDesktopViewer', schema=schema) op.alter_column('treeitem', 'metadataURL', new_column_name='metadata_url', schema=schema) op.alter_column('layergroup', 'isExpanded', new_column_name='is_expanded', schema=schema) op.alter_column('layergroup', 'isInternalWMS', new_column_name='is_internal_wms', schema=schema) op.alter_column('layergroup', 'isBaseLayer', new_column_name='is_base_layer', schema=schema) op.create_table( 'layer_internal_wms', Column('id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True), Column('layer', Unicode), Column('image_type', Unicode(10)), Column('style', Unicode), Column('time_mode', Unicode(8)), schema=schema, ) op.create_table( 'layer_external_wms', Column('id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True), Column('url', Unicode), Column('layer', Unicode), Column('image_type', Unicode(10)), Column('style', Unicode), Column('is_single_tile', Boolean), Column('time_mode', Unicode(8)), schema=schema, ) op.create_table( 'layer_wmts', Column( 'id', Integer, ForeignKey(schema + '.layer.id'), primary_key=True, ), Column('url', Unicode), Column('layer', Unicode), Column('style', Unicode), Column('matrix_set', Unicode), schema=schema, ) op.create_table( 'ui_metadata', Column('id', Integer, primary_key=True), Column('name', Unicode), Column('value', Unicode), Column('description', Unicode), Column('item_id', Integer, ForeignKey(schema + '.treeitem.id'), nullable=False), schema=schema, ) op.create_table( 'wmts_dimension', Column('id', Integer, primary_key=True), Column('name', Unicode), Column('value', Unicode), Column('description', Unicode), Column('layer_id', Integer, ForeignKey(schema + '.layer_wmts.id'), nullable=False), schema=schema, )
class Box(DatabaseObject): ''' Box definition ''' uuid = Column(String(36), unique=True, nullable=False, default=lambda: str(uuid4()) ) corporation_id = Column(Integer, ForeignKey('corporation.id'), nullable=False ) category_id = Column(Integer, ForeignKey('category.id'), nullable=True ) _name = Column(Unicode(32), unique=True, nullable=False) _operating_system = Column(Unicode(16)) _description = Column(Unicode(1024)) _difficulty = Column(Unicode(16)) game_level_id = Column( Integer, ForeignKey('game_level.id'), nullable=False) _avatar = Column(String(64)) garbage = Column(String(32), unique=True, nullable=False, default=lambda: urandom(16).encode('hex') ) teams = relationship("Team", secondary=team_to_box, backref=backref("box", lazy="select") ) hints = relationship("Hint", backref=backref("box", lazy="select"), cascade="all,delete,delete-orphan" ) flags = relationship("Flag", backref=backref("box", lazy="select"), cascade="all,delete,delete-orphan", order_by="desc(-Flag._order)", ) flag_submission_type = Column(Enum(FlagsSubmissionType), default=FlagsSubmissionType.CLASSIC) ip_addresses = relationship("IpAddress", backref=backref("box", lazy="select"), cascade="all,delete,delete-orphan" ) @classmethod def all(cls): ''' Returns a list of all objects in the database ''' return dbsession.query(cls).all() @classmethod def by_id(cls, _id): ''' Returns a the object with id of _id ''' return dbsession.query(cls).filter_by(id=_id).first() @classmethod def by_uuid(cls, _uuid): ''' Return and object based on a uuid ''' return dbsession.query(cls).filter_by(uuid=unicode(_uuid)).first() @classmethod def by_name(cls, name): ''' Return the box object whose name is "name" ''' return dbsession.query(cls).filter_by(_name=unicode(name)).first() @classmethod def by_category(cls, _cat_id): ''' Return the box object whose category is "_cat_id" ''' return dbsession.query(cls).filter_by(category_id=int(_cat_id)).all() @classmethod def by_garbage(cls, _garbage): return dbsession.query(cls).filter_by(garbage=_garbage).first() @classmethod def by_ip_address(cls, ip_addr): ''' Returns a box object based on an ip address, supports both ipv4 and ipv6 ''' ip = IpAddress.by_address(ip_addr) return ip.box if ip is not None else None @classmethod def flaglist(self, box_id=None): flags = self.by_id(box_id).flags flaglist = OrderedDict() for flag in flags: flaglist[flag.uuid] = flag.name return flaglist @property def name(self): return self._name @name.setter def name(self, value): if not 3 <= len(unicode(value)) <= 32: raise ValidationError("Name must be 3 - 32 characters") self._name = unicode(value) @property def operating_system(self): return self._operating_system if self._operating_system else '?' @operating_system.setter def operating_system(self, value): self._operating_system = unicode(value) @property def description(self): if self._description is None: self._description = "" ls = [] if 0 < len(self._description): text = self._description.replace("\r\n", "\n").strip() ls.append("%s" % text) else: ls.append("No information on file.") if self.difficulty != "Unknown": ls.append("Reported Difficulty: %s" % self.difficulty) if ls[-1] and not ls[-1].encode('utf8').endswith("\n"): ls[-1] = ls[-1] + "\n" return unicode("\n\n".join(ls)) @description.setter def description(self, value): if value is None: return "" if 1025 < len(value): raise ValidationError("Description cannot be greater than 1024 characters") self._description = unicode(value) @property def difficulty(self): return self._difficulty if self._difficulty and len(self._difficulty) else u"Unknown" @difficulty.setter def difficulty(self, value): if value is None: return if 17 < len(value): raise ValidationError("Difficulty cannot be greater than 16 characters") self._difficulty = unicode(value) @property def avatar(self): if self._avatar is not None: return self._avatar else: avatar = get_new_avatar('box') if not avatar.startswith("default_"): self._avatar = avatar dbsession.add(self) dbsession.commit() return avatar @avatar.setter def avatar(self, image_data): if self.uuid is None: self.uuid = str(uuid4()) if len(image_data) < (1024 * 1024): ext = imghdr.what("", h=image_data) if ext in ['png', 'jpeg', 'gif', 'bmp'] and not is_xss_image(image_data): if self._avatar is not None and os.path.exists(options.avatar_dir + '/upload/' + self._avatar): os.unlink(options.avatar_dir + '/upload/' + self._avatar) file_path = str(options.avatar_dir + '/upload/' + self.uuid + '.' + ext) image = Image.open(StringIO.StringIO(image_data)) cover = resizeimage.resize_cover(image, [500, 250]) cover.save(file_path, image.format) self._avatar = 'upload/' + self.uuid + '.' + ext else: raise ValidationError( "Invalid image format, avatar must be: .png .jpeg .gif or .bmp") else: raise ValidationError("The image is too large") @property def ipv4s(self): ''' Return a list of all ipv4 addresses ''' return filter(lambda ip: ip.version == 4, self.ip_addresses) @property def ipv6s(self): ''' Return a list of all ipv6 addresses ''' return filter(lambda ip: ip.version == 6, self.ip_addresses) @property def visable_ips(self): return filter(lambda ip: ip.visable is True, self.ip_addresses) @property def source_code(self): return SourceCode.by_box_id(self.id) def get_garbage_cfg(self): return "[Bot]\nname = %s\ngarbage = %s\n" % ( self.name.encode('hex'), self.garbage ) def to_xml(self, parent): ''' Convert object to XML ''' box_elem = ET.SubElement(parent, "box") box_elem.set("gamelevel", str(self.game_level.number)) ET.SubElement(box_elem, "name").text = self.name ET.SubElement( box_elem, "operatingsystem").text = self._operating_system ET.SubElement(box_elem, "description").text = self._description ET.SubElement(box_elem, "flag_submission_type").text = FlagsSubmissionType(self.flag_submission_type).name ET.SubElement(box_elem, "difficulty").text = self._difficulty ET.SubElement(box_elem, "garbage").text = self.garbage if self.category_id: ET.SubElement(box_elem, "category").text = Category.by_id(self.category_id).category flags_elem = ET.SubElement(box_elem, "flags") flags_elem.set("count", str(len(self.flags))) for flag in self.flags: flag.to_xml(flags_elem) hints_elem = ET.SubElement(box_elem, "hints") count = 0 for hint in self.hints: if hint.flag_id is None: hint.to_xml(hints_elem) count += 1 hints_elem.set("count", str(count)) ips_elem = ET.SubElement(box_elem, "ipaddresses") ips_elem.set("count", str(len(self.ip_addresses))) for ip in self.ip_addresses: ip.to_xml(ips_elem) avatarfile = os.path.join(options.avatar_dir, self.avatar) if self.avatar and os.path.isfile(avatarfile): with open(avatarfile, mode='rb') as _avatar: data = _avatar.read() ET.SubElement(box_elem, "avatar").text = data.encode('base64') else: ET.SubElement(box_elem, "avatar").text = "none" def to_dict(self): ''' Returns editable data as a dictionary ''' corp = Corporation.by_id(self.corporation_id) game_level = GameLevel.by_id(self.game_level_id) cat = Category.by_id(self.category_id) if cat: category = cat.uuid else: category = "" return { 'name': self.name, 'uuid': self.uuid, 'corporation': corp.uuid, 'category': category, 'operating_system': self.operating_system, 'description': self._description, 'difficulty': self.difficulty, 'game_level': game_level.uuid, 'flag_submission_type': self.flag_submission_type, 'flaglist': self.flaglist(self.id) } def __repr__(self): return u'<Box - name: %s>' % (self.name,) def __str__(self): return self.name.encode('ascii', 'ignore')
def downgrade(): schema = context.get_context().config.get_main_option('schema') op.drop_table('wmts_dimension', schema=schema) op.drop_table('ui_metadata', schema=schema) op.drop_table('layer_wmts', schema=schema) op.drop_table('layer_external_wms', schema=schema) op.drop_table('layer_internal_wms', schema=schema) op.add_column('layer', Column('inMobileViewer', Boolean, default=False), schema=schema) op.add_column('layer', Column('inDesktopViewer', Boolean, default=True), schema=schema) op.alter_column('layer', 'geo_table', new_column_name='geoTable', schema=schema) op.add_column('theme', Column('inMobileViewer', Boolean, default=False), schema=schema) op.add_column('theme', Column('inDesktopViewer', Boolean, default=True), schema=schema) op.alter_column('treeitem', 'metadata_url', new_column_name='metadataURL', schema=schema) op.alter_column('layergroup', 'is_expanded', new_column_name='isExpanded', schema=schema) op.alter_column('layergroup', 'is_internal_wms', new_column_name='isInternalWMS', schema=schema) op.alter_column('layergroup', 'is_base_layer', new_column_name='isBaseLayer', schema=schema) op.execute('UPDATE ONLY %(schema)s.theme AS t ' 'SET "inDesktopViewer" = FALSE' % {'schema': schema}) op.execute('UPDATE ONLY %(schema)s.layer AS t ' 'SET "inDesktopViewer" = FALSE' % {'schema': schema}) op.execute( 'UPDATE ONLY %(schema)s.theme AS t ' 'SET "inMobileViewer" = TRUE ' 'FROM %(schema)s.interface AS i, %(schema)s.interface_theme AS it ' 'WHERE i.name = \'mobile\' AND i.id = it.interface_id AND it.theme_id = t.id' % {'schema': schema}) op.execute( 'UPDATE ONLY %(schema)s.theme AS t ' 'SET "inDesktopViewer" = TRUE ' 'FROM %(schema)s.interface AS i, %(schema)s.interface_theme AS it ' 'WHERE i.name = \'main\' AND i.id = it.interface_id AND it.theme_id = t.id' % {'schema': schema}) op.execute( 'UPDATE ONLY %(schema)s.layer AS l ' 'SET "inMobileViewer" = TRUE ' 'FROM %(schema)s.interface AS i, %(schema)s.interface_layer AS il ' 'WHERE i.name = \'mobile\' AND i.id = il.interface_id AND il.layer_id = l.id' % {'schema': schema}) op.execute( 'UPDATE ONLY %(schema)s.layer AS l ' 'SET "inDesktopViewer" = TRUE ' 'FROM %(schema)s.interface AS i, %(schema)s.interface_layer AS il ' 'WHERE i.name = \'main\' AND i.id = il.interface_id AND il.layer_id = l.id' % {'schema': schema}) op.add_column('layer', Column('timeMode', Unicode(8)), schema=schema) op.add_column('layer', Column('excludeProperties', Unicode), schema=schema) op.add_column('layer', Column('identifierAttributeField', Unicode), schema=schema) op.add_column('layer', Column('disclaimer', Unicode), schema=schema) op.add_column('layer', Column('maxResolution', Float), schema=schema) op.add_column('layer', Column('minResolution', Float), schema=schema) op.add_column('layer', Column('isLegendExpanded', Boolean, default=False), schema=schema) op.add_column('layer', Column('legendRule', Unicode), schema=schema) op.add_column('layer', Column('legendImage', Unicode), schema=schema) op.add_column('layer', Column('legend', Boolean, default=True), schema=schema) op.add_column('layer', Column('isSingleTile', Boolean, default=False), schema=schema) op.add_column('layer', Column('kml', Unicode), schema=schema) op.add_column('layer', Column('queryLayers', Unicode), schema=schema) op.add_column('layer', Column('wmsLayers', Unicode), schema=schema) op.add_column('layer', Column('wmsUrl', Unicode), schema=schema) op.add_column('layer', Column('matrixSet', Unicode), schema=schema) op.add_column('layer', Column('dimensions', Unicode), schema=schema) op.add_column('layer', Column('style', Unicode), schema=schema) op.add_column('layer', Column('imageType', Unicode(10)), schema=schema) op.add_column('layer', Column('url', Unicode), schema=schema) op.add_column('layer', Column('layerType', Unicode(12)), schema=schema) op.add_column('layer', Column('icon', Unicode), schema=schema) op.add_column('layer', Column('isChecked', Boolean, default=True), schema=schema) op.execute( 'UPDATE %(schema)s.layer AS l SET (' 'id, "isChecked", icon, "layerType", url, "imageType", style, dimensions, "matrixSet", ' '"wmsUrl", "wmsLayers", "queryLayers", kml, "isSingleTile", legend, "legendImage", ' '"legendRule", "isLegendExpanded", "minResolution", "maxResolution", disclaimer, ' '"identifierAttributeField", "excludeProperties", "timeMode"' ') = (' 'o.id, o.is_checked, o.icon, o.layer_type, o.url, o.image_type, o.style, o.dimensions, ' 'o.matrix_set, o.wms_url, o.wms_layers, o.query_layers, o.kml, o.is_single_tile, ' 'o.legend, o.legend_image, o.legend_rule, o.is_legend_expanded, o.min_resolution, ' 'o.max_resolution, o.disclaimer, o.identifier_attribute_field, o.exclude_properties, ' 'o.time_mode ' ') FROM %(schema)s.layerv1 AS o WHERE o.id = l.id' % {'schema': schema}) op.drop_table('layerv1', schema=schema) op.drop_table('interface_theme', schema=schema) op.drop_table('interface_layer', schema=schema) op.drop_table('interface', schema=schema) op.create_table( 'user_functionality', Column('user_id', Integer, ForeignKey(schema + '.user.id'), primary_key=True), Column('functionality_id', Integer, ForeignKey(schema + '.functionality.id'), primary_key=True), schema=schema, )
class User(DeclarativeBase): """ User definition. This is the user definition used by :mod:`repoze.who`, which requires at least the ``user_name`` column. """ __tablename__ = 'tg_user' user_id = Column(Integer, autoincrement=True, primary_key=True) user_name = Column(Unicode(16), unique=True, nullable=False) email_address = Column(Unicode(255), unique=True, nullable=False) display_name = Column(Unicode(255)) _password = Column('password', Unicode(128)) created = Column(DateTime, default=datetime.now) def __repr__(self): return '<User: name=%s, email=%s, display=%s>' % (repr( self.user_name), repr(self.email_address), repr(self.display_name)) def __unicode__(self): return self.display_name or self.user_name @property def permissions(self): """Return a set with all permissions granted to the user.""" perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms @classmethod def by_email_address(cls, email): """Return the user object whose email address is ``email``.""" return DBSession.query(cls).filter_by(email_address=email).first() @classmethod def by_user_name(cls, username): """Return the user object whose user name is ``username``.""" return DBSession.query(cls).filter_by(user_name=username).first() @classmethod def _hash_password(cls, password): salt = sha256() salt.update(os.urandom(60)) salt = salt.hexdigest() hash = sha256() # Make sure password is a str because we cannot hash unicode objects hash.update((password + salt).encode('utf-8')) hash = hash.hexdigest() password = salt + hash # Make sure the hashed password is a unicode object at the end of the # process because SQLAlchemy _wants_ unicode objects for Unicode cols password = password.decode('utf-8') return password def _set_password(self, password): """Hash ``password`` on the fly and store its hashed version.""" self._password = self._hash_password(password) def _get_password(self): """Return the hashed version of the password.""" return self._password password = synonym('_password', descriptor=property(_get_password, _set_password)) def validate_password(self, password): """ Check the password against existing credentials. :param password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type password: unicode object. :return: Whether the password is valid. :rtype: bool """ hash = sha256() hash.update((password + self.password[:64]).encode('utf-8')) return self.password[64:] == hash.hexdigest()
class GameLevel(DatabaseObject): """ Game Level definition """ uuid = Column(String(36), unique=True, nullable=False, default=lambda: str(uuid4())) next_level_id = Column(Integer, ForeignKey("game_level.id")) _number = Column(Integer, unique=True, nullable=False) _buyout = Column(Integer, nullable=False) _type = Column(Unicode(16), nullable=False, default=u"buyout") _reward = Column(Integer, nullable=False, default=0) _name = Column(Unicode(32), nullable=True) boxes = relationship( "Box", backref=backref("game_level", lazy="select"), cascade="all,delete,delete-orphan", ) @classmethod def all(cls): """ Returns a list of all objects in the database """ return dbsession.query(cls).order_by(asc(cls._number)).all() @classmethod def count(cls): return dbsession.query(cls).count() @classmethod def by_id(cls, _id): """ Returns a the object with id of _id """ return dbsession.query(cls).filter_by(id=_id).first() @classmethod def by_uuid(cls, _uuid): """ Return and object based on a _uuid """ return dbsession.query(cls).filter_by(uuid=_uuid).first() @classmethod def by_number(cls, number): """ Returns a the object with number of number """ return dbsession.query(cls).filter_by(_number=abs(int(number))).first() @classmethod def last_level(cls, number): """ Returns the prior level """ return dbsession.query(cls).filter_by( next_level_id=int(number)).first() @property def number(self): return self._number @number.setter def number(self, value): try: if self.by_number(value) is None: self._number = abs(int(value)) else: raise ValidationError("Game level number must be unique") except ValueError: raise ValidationError("Game level number must be an integer") @property def buyout(self): return self._buyout @buyout.setter def buyout(self, value): try: self._buyout = abs(int(value)) except ValueError: raise ValidationError("Buyout value must be an integer") @property def reward(self): return self._reward @reward.setter def reward(self, value): try: self._reward = abs(int(value)) except ValueError: raise ValidationError("Reward value must be an integer") @property def name(self): if self._name: return str(self._name) else: return "Level #" + str(self.number) @name.setter def name(self, value): if len(value) <= 32: self._name = value else: raise ValidationError("Max name length is 32") @property def type(self): return self._type @type.setter def type(self, value): if value is None: return try: self._type = str(value) except ValueError: raise ValidationError("type value must be an string") @property def flags(self): """ Return all flags for the level """ _flags = [] for box in self.boxes: _flags += box.flags return _flags def to_xml(self, parent): level_elem = ET.SubElement(parent, "gamelevel") ET.SubElement(level_elem, "number").text = str(self.number) ET.SubElement(level_elem, "buyout").text = str(self.buyout) ET.SubElement(level_elem, "type").text = str(self._type) ET.SubElement(level_elem, "reward").text = str(self._reward) ET.SubElement(level_elem, "name").text = str(self._name) def to_dict(self): """ Return public data as dict """ last = GameLevel.last_level(self.id) if last: last_level = last.number else: last_level = "" return { "uuid": self.uuid, "number": self.number, "name": self.name, "buyout": self.buyout, "type": self.type, "reward": self.reward, "last_level": last_level, } def __next__(self): """ Return the next level, or None """ if self.next_level_id is not None: return self.by_id(self.next_level_id) else: return None def __str__(self): return "GameLevel #%d" % self.number def __cmp__(self, other): if self.number < other.number: return -1 else: return 1 def __eq__(self, other): return self.__cmp__(other) == 0 def __ne__(self, other): return self.__cmp__(other) != 0 def __gt__(self, other): return self.__cmp__(other) > 0 def __lt__(self, other): return self.__cmp__(other) < 0 def __ge__(self, other): return self.__cmp__(other) >= 0 def __le__(self, other): return self.__cmp__(other) <= 0 def __repr__(self): return "<GameLevel number: %d, buyout: %d, next: id(%s)>" % ( self.number, self.buyout, self.next_level_id, ) def __hash__(self): return hash(self.uuid)
class MorphemeLanguageModelBackup(Base): __tablename__ = 'morphemelanguagemodelbackup' def __repr__(self): return '<MorphemeLanguageModelBackup (%s)>' % self.id id = Column(Integer, Sequence('morphemelanguagemodelbackup_seq_id', optional=True), primary_key=True) morphemelanguagemodel_id = Column(Integer) UUID = Column(Unicode(36)) name = Column(Unicode(255)) description = Column(UnicodeText) corpus = Column(UnicodeText) enterer = Column(UnicodeText) modifier = Column(UnicodeText) datetime_entered = Column(DateTime) datetime_modified = Column(DateTime, default=now) generate_succeeded = Column(Boolean, default=False) generate_message = Column(Unicode(255)) generate_attempt = Column(Unicode(36)) # a UUID perplexity = Column(Float, default=0.0) perplexity_attempt = Column(Unicode(36)) # a UUID perplexity_computed = Column(Boolean, default=False) toolkit = Column(Unicode(10)) order = Column(Integer) smoothing = Column(Unicode(30)) vocabulary_morphology = Column(UnicodeText) restricted = Column(Boolean) categorial = Column(Boolean) def vivify(self, morpheme_language_model_dict): """The vivify method gives life to a morpheme language model backup by specifying its attributes using the to-be-backed-up morpheme language model (morpheme_language_model_dict) The relational attributes of the to-be-backed-up morpheme language model are converted into (truncated) JSON objects. """ self.UUID = morpheme_language_model_dict['UUID'] self.morphemelanguagemodel_id = morpheme_language_model_dict['id'] self.name = morpheme_language_model_dict['name'] self.description = morpheme_language_model_dict['description'] self.corpus = unicode( json.dumps(morpheme_language_model_dict['corpus'])) self.enterer = unicode( json.dumps(morpheme_language_model_dict['enterer'])) self.modifier = unicode( json.dumps(morpheme_language_model_dict['modifier'])) self.datetime_entered = morpheme_language_model_dict[ 'datetime_entered'] self.datetime_modified = morpheme_language_model_dict[ 'datetime_modified'] self.generate_succeeded = morpheme_language_model_dict[ 'generate_succeeded'] self.generate_message = morpheme_language_model_dict[ 'generate_message'] self.generate_attempt = morpheme_language_model_dict[ 'generate_attempt'] self.perplexity = morpheme_language_model_dict['perplexity'] self.perplexity_attempt = morpheme_language_model_dict[ 'perplexity_attempt'] self.perplexity_computed = morpheme_language_model_dict[ 'perplexity_computed'] self.toolkit = morpheme_language_model_dict['toolkit'] self.order = morpheme_language_model_dict['order'] self.smoothing = morpheme_language_model_dict['smoothing'] self.vocabulary_morphology = unicode( json.dumps(morpheme_language_model_dict['vocabulary_morphology'])) self.restricted = morpheme_language_model_dict['restricted'] self.categorial = morpheme_language_model_dict['categorial'] def get_dict(self): return { 'id': self.id, 'morphemelanguagemodel_id': self.morphemelanguagemodel_id, 'UUID': self.UUID, 'name': self.name, 'corpus': self.json_loads(self.corpus), 'description': self.description, 'enterer': self.json_loads(self.enterer), 'modifier': self.json_loads(self.modifier), 'datetime_entered': self.datetime_entered, 'datetime_modified': self.datetime_modified, 'generate_succeeded': self.generate_succeeded, 'generate_message': self.generate_message, 'perplexity': self.perplexity, 'perplexity_attempt': self.perplexity_attempt, 'perplexity_computed': self.perplexity_computed, 'generate_attempt': self.generate_attempt, 'toolkit': self.toolkit, 'order': self.order, 'smoothing': self.smoothing, 'vocabulary_morphology': self.json_loads(self.vocabulary_morphology), 'restricted': self.restricted, 'categorial': self.categorial }
class CustomSearch(DeclarativeBase): __tablename__ = 'custom_search' #Columns id = Column(Integer,Sequence('csid_seq'),primary_key=True) name=Column(Unicode(255)) user_name = Column(Unicode(255)) #login name created_date = Column(DateTime) # Datetime modified_date = Column(DateTime) # Datetime description=Column(Text) condition=Column(Text) # property= Column(Unicode(255)) # filter= Column(Unicode(255)) # value= Column(Unicode(255)) node_level= Column(Unicode(50)) #dc or sp level lists_level=Column(Unicode(50)) #vms or servers max_count=Column(Unicode(50)) # no of rows to be returned def __init__(self): pass ###makes query for custom search.......... def make_query(self,class_name,DEC,property,lists_level): if lists_level==constants.VMS: conditions=self.make_vmsearch_query(class_name,DEC,property) elif lists_level==constants.SERVERS: conditions=self.make_serversearch_query(class_name,DEC,property) return conditions ###making custom query for SERVERS level def make_serversearch_query(self,class_name,DEC,property): condition="" joins=[] filters=[] dec_val="" lists=DEC[2:] i=0 for x in lists: if i > 0 : dec_val+=" " dec_val+=x i+=1 if property == constants.MEMUTIL_VALUE: condition = self.get_custom_condition('class_name.host_mem', DEC[1] , dec_val) filters.append(eval(condition)) elif property == constants.CPUUTIL_VALUE: condition = self.get_custom_condition('class_name.host_cpu', DEC[1] , dec_val) filters.append(eval(condition)) elif property == constants.STRGUTIL_VALUE: condition = self.get_custom_condition('class_name.gb_poolused', DEC[1] , dec_val) filters.append(eval(condition)) elif property ==constants.SP_VALUE: condition = self.get_custom_condition('Entity.name', DEC[1] , dec_val) filters.append(class_name.entity_id.in_( DBSession.query(EntityRelation.dest_id).filter(EntityRelation.src_id.in_( DBSession.query(Entity.entity_id).filter(eval(condition)) )) )) elif property ==constants.PLTFM_VALUE: joins.append((ManagedNode,ManagedNode.id==class_name.entity_id)) condition = self.get_custom_condition('ManagedNode.type', DEC[1] , dec_val) filters.append(eval(condition)) elif property == constants.SRVR_STATUS_VALUE: joins.append((AvailState,AvailState.entity_id==class_name.entity_id)) if DEC[2] == "down": filters.append(AvailState.avail_state == ManagedNode.DOWN) else: filters.append(AvailState.avail_state == ManagedNode.UP) elif property ==constants.SRVR_NAME_VALUE: joins.append((ManagedNode,ManagedNode.id==class_name.entity_id)) condition = self.get_custom_condition('ManagedNode.hostname', DEC[1] , dec_val) filters.append(eval(condition)) elif property ==constants.SB_VALUE: joins.append((ManagedNode,ManagedNode.id==class_name.entity_id)) if DEC[2] == "yes": filters.append(ManagedNode.standby_status == ManagedNode.STANDBY) else: filters.append(ManagedNode.standby_status == None) return dict(filters=filters,joins=joins) ###making custom query for VMS level def make_vmsearch_query(self,class_name,DEC,property): condition="" dec_val="" lists=DEC[2:] i=0 for x in lists: if i > 0 : dec_val+=" " dec_val+=x i+=1 # print dec_val joins=[] filters=[] if property == constants.MEMUTIL_VALUE: condition = self.get_custom_condition('class_name.mem_util', DEC[1] , dec_val) filters.append(eval(condition)) elif property == constants.CPUUTIL_VALUE: condition = self.get_custom_condition('class_name.cpu_util', DEC[1] , dec_val) filters.append(eval(condition)) elif property == constants.STRGUTIL_VALUE: condition = self.get_custom_condition('class_name.gb_poolused', DEC[1] , dec_val) filters.append(eval(condition)) elif property ==constants.SP_VALUE: condition = self.get_custom_condition('Entity.name', DEC[1] , dec_val) filters.append(class_name.entity_id.in_( DBSession.query(EntityRelation.dest_id).filter(EntityRelation.src_id.in_( DBSession.query(EntityRelation.dest_id).filter(EntityRelation.src_id.in_( DBSession.query(Entity.entity_id).filter(eval(condition)) )) )) )) elif property ==constants.TEMPLATE_VALUE: condition = self.get_custom_condition('Image.name', DEC[1] , dec_val) filters.append(class_name.entity_id.in_( DBSession.query(VM.id).filter(VM.image_id.in_(\ DBSession.query(Image.id).filter(eval(condition)) )) )) elif property ==constants.OS_VALUE: joins.append((VM,VM.id==class_name.entity_id)) db_type=get_dbtype() if db_type==constants.ORACLE: condition = self.get_custom_condition('func.concat(func.concat(VM.os_name," "),VM.os_version)', DEC[1] , dec_val) else: condition = self.get_custom_condition('func.concat(VM.os_name," ",VM.os_version)', DEC[1] , dec_val) filters.append(eval(condition)) elif property ==constants.SRVR_NAME_VALUE: condition = self.get_custom_condition('Entity.name', DEC[1] , dec_val) filters.append(class_name.entity_id.in_( DBSession.query(EntityRelation.dest_id).filter(EntityRelation.src_id.in_( DBSession.query(Entity.entity_id).filter(eval(condition)) )) )) elif property ==constants.VM_STATUS_VALUE: joins.append((VM,VM.id==class_name.entity_id)) joins.append((AvailState,AvailState.entity_id==class_name.entity_id)) if DEC[2] == "down": filters.append(AvailState.avail_state == VM.SHUTDOWN) else: filters.append(AvailState.avail_state != VM.SHUTDOWN) elif property ==constants.VM_NAME_VALUE: joins.append((VM,VM.id==class_name.entity_id)) condition = self.get_custom_condition('VM.name', DEC[1] , dec_val) filters.append(eval(condition)) return dict(filters=filters,joins=joins) def get_custom_condition(self, class_col, op, value): condn = "" if op == 'like': condn = class_col+".like('%"+value+"%')" else: condn = class_col + " " + op + " '"+ value +"'" return condn
Column( 'user_id', UUID, ForeignKey( 'user.user_id', onupdate="CASCADE", ondelete="CASCADE") ), Column( 'group_id', Integer, ForeignKey( 'group.group_id', onupdate="CASCADE", ondelete="CASCADE") ), ) # the group table group = Table( 'group', metadata, Column("group_id", Integer, autoincrement=True, primary_key=True), Column("group_name", Unicode(16), unique=True), Column("display_name", Unicode(255)), Column("created", DateTime, default=datetime.datetime.now), ) # the user table user = Table( 'user', metadata, Column("user_id", UUID, primary_key=True, default=uuid4), Column("user_name", Unicode(16), unique=True), Column("email_address", Unicode(255), unique=True), Column("display_name", Unicode(255)), Column('password', Unicode(80)), Column("created", DateTime, default=datetime.datetime.now), )
class User(DeclarativeBase): """ User definition. This is the user definition used by :mod:`repoze.who`, which requires at least the ``email`` column. """ MIN_PASSWORD_LENGTH = 6 MAX_PASSWORD_LENGTH = 512 MAX_HASHED_PASSWORD_LENGTH = 128 MIN_PUBLIC_NAME_LENGTH = 3 MAX_PUBLIC_NAME_LENGTH = 255 MIN_EMAIL_LENGTH = 3 MAX_EMAIL_LENGTH = 255 MIN_USERNAME_LENGTH = 3 MAX_USERNAME_LENGTH = 255 MAX_IMPORTED_FROM_LENGTH = 32 MAX_TIMEZONE_LENGTH = 32 MIN_LANG_LENGTH = 2 MAX_LANG_LENGTH = 3 MAX_AUTH_TOKEN_LENGTH = 255 MAX_RESET_PASSWORD_TOKEN_HASH_LENGTH = 255 DEFAULT_ALLOWED_SPACE = 0 USERNAME_OR_EMAIL_REQUIRED_CONSTRAINT_NAME = "ck_users_username_email" __tablename__ = "users" # INFO - G.M - 2018-10-24 - force table to use utf8 instead of # utf8bm4 for mysql only in order to avoid max length of key issue with # long varchar in utf8bm4 column. This issue is related to email # field and is uniqueness. As far we search, there is to be no way to apply # mysql specific (which is ignored by other database) # collation only on email field. __table_args__ = ( CheckConstraint( "NOT (email IS NULL AND username IS NULL)", name=USERNAME_OR_EMAIL_REQUIRED_CONSTRAINT_NAME, ), { "mysql_charset": "utf8", "mysql_collate": "utf8_general_ci" }, ) user_id = Column(Integer, Sequence("seq__users__user_id"), autoincrement=True, primary_key=True) email = Column(Unicode(MAX_EMAIL_LENGTH), unique=True, nullable=True) username = Column(Unicode(MAX_USERNAME_LENGTH), unique=True, nullable=True) display_name = Column(Unicode(MAX_PUBLIC_NAME_LENGTH)) _password = Column("password", Unicode(MAX_HASHED_PASSWORD_LENGTH), nullable=True) created = Column(DateTime, default=datetime.utcnow) is_active = Column(Boolean, default=True, nullable=False) is_deleted = Column( Boolean, default=False, nullable=False, server_default=sqlalchemy.sql.expression.literal(False), ) imported_from = Column(Unicode(MAX_IMPORTED_FROM_LENGTH), nullable=True) # timezone as tz database format timezone = Column(Unicode(MAX_TIMEZONE_LENGTH), nullable=False, server_default="") # lang in iso639 format auth_type = Column(Enum(AuthType), nullable=False, server_default=AuthType.INTERNAL.name) lang = Column(Unicode(MAX_LANG_LENGTH), nullable=True, default=None) # TODO - G.M - 04-04-2018 - [auth] Check if this is already needed # with new auth system # TODO - G.M - 2018-08-22 - Think about hash instead of direct token auth_token = Column(Unicode(MAX_AUTH_TOKEN_LENGTH)) auth_token_created = Column(DateTime) reset_password_token_hash = Column( Unicode(MAX_RESET_PASSWORD_TOKEN_HASH_LENGTH), nullable=True, default=None) reset_password_token_created = Column(DateTime, nullable=True, default=None) allowed_space = Column(BigInteger, nullable=False, server_default=str(DEFAULT_ALLOWED_SPACE)) profile = Column(Enum(Profile), nullable=False, server_default=Profile.NOBODY.name) @hybrid_property def email_address(self): return self.email @property def public_name(self) -> str: return self.display_name @property def avatar_url(self) -> typing.Optional[str]: # TODO - G-M - 20-04-2018 - [Avatar] Add user avatar feature return None def __repr__(self): return "<User: email=%s, username=%s display=%s>" % ( repr(self.email), repr(self.username), repr(self.display_name), ) def __unicode__(self): return self.display_name or self.email or self.username @classmethod def by_email_address(cls, email, dbsession): """Return the user object whose email address is ``email``.""" return dbsession.query(cls).filter_by(email=email).first() @classmethod def by_username(cls, username, dbsession): """Return the user object whose user name is ``username``.""" return dbsession.query(cls).filter_by(username=username).first() @property def login(self) -> str: """Return email or username if no email""" return self.email or self.username def _set_password(self, cleartext_password: typing.Optional[str]) -> None: """ Set ciphertext password from cleartext password. Hash cleartext password on the fly, Store its ciphertext version, """ if cleartext_password is None: self._password = None else: self._password = self._hash(cleartext_password) def _get_password(self) -> str: """Return the hashed version of the password.""" return self._password password = synonym("_password", descriptor=property(_get_password, _set_password)) def validate_password(self, cleartext_password: typing.Optional[str]) -> bool: """ Check the password against existing credentials. :param cleartext_password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type cleartext_password: unicode object. :return: Whether the password is valid. :rtype: bool """ if not self.password: return False return self._validate_hash(self.password, cleartext_password) def get_display_name(self, remove_email_part: bool = False) -> str: """ Get a name to display from corresponding display_name, username or email. :param remove_email_part: If True and display name based on email, remove @xxx.xxx part of email in returned value :return: display name based on user name or email. """ if self.display_name: return self.display_name if self.username: return self.username if remove_email_part: at_pos = self.email.index("@") return self.email[0:at_pos] return self.email def get_role(self, workspace: "Workspace") -> int: for role in self.roles: if role.workspace == workspace: return role.role return UserRoleInWorkspace.NOT_APPLICABLE def get_active_roles(self) -> ["UserRoleInWorkspace"]: """ :return: list of roles of the user for all not-deleted workspaces """ roles = [] for role in self.roles: if not role.workspace.is_deleted: roles.append(role) return roles # Tokens ### def reset_tokens(self): self._generate_auth_token() # disable reset_password token self.reset_password_token_hash = None self.reset_password_token_created = None # Reset Password Tokens # def generate_reset_password_token(self) -> str: ( reset_password_token, self.reset_password_token_created, self.reset_password_token_hash, ) = self._generate_token(create_hash=True) return reset_password_token def validate_reset_password_token(self, token, validity_seconds) -> bool: if not self.reset_password_token_created: raise InvalidResetPasswordToken( "reset password token is unvalid due to unknown creation date") if not self._validate_date(self.reset_password_token_created, validity_seconds): raise ExpiredResetPasswordToken("reset password token has expired") if not self._validate_hash(self.reset_password_token_hash, token): raise InvalidResetPasswordToken("reset password token is unvalid") return True # Auth Token # # TODO - G.M - 04-04-2018 - [auth] Check if this is already needed # with new auth system def _generate_auth_token(self) -> str: self.auth_token, self.auth_token_created, _ = self._generate_token() return self.auth_token # TODO - G.M - 2018-08-23 - Should we store hash instead of direct stored # auth token ? def validate_auth_token(self, token, validity_seconds) -> bool: return self.ensure_auth_token(validity_seconds) == token def ensure_auth_token(self, validity_seconds) -> str: """ Create auth_token if None, regenerate auth_token if too old. auth_token validity is set in :return: actual valid auth token """ if not self.auth_token or not self.auth_token_created: self._generate_auth_token() return self.auth_token if not self._validate_date(self.auth_token_created, validity_seconds): self._generate_auth_token() return self.auth_token # Utils functions # @classmethod def _hash(cls, cleartext_password_or_token: str) -> str: salt = sha256() salt.update(os.urandom(60)) salt = salt.hexdigest() hashed = sha256() # Make sure password is a str because we cannot hash unicode objects hashed.update((cleartext_password_or_token + salt).encode("utf-8")) hashed = hashed.hexdigest() ciphertext_password = salt + hashed # Make sure the hashed password is a unicode object at the end of the # process because SQLAlchemy _wants_ unicode objects for Unicode cols # FIXME - D.A. - 2013-11-20 - The following line has been removed since using python3. Is this normal ?! # password = password.decode('utf-8') return ciphertext_password @classmethod def _validate_hash(cls, hashed: str, cleartext_password_or_token: str) -> bool: result = False if hashed: new_hash = sha256() new_hash.update( (cleartext_password_or_token + hashed[:64]).encode("utf-8")) result = hashed[64:] == new_hash.hexdigest() return result @classmethod def _generate_token( cls, create_hash=False ) -> typing.Union[str, datetime, typing.Optional[str]]: token = str(uuid.uuid4().hex) creation_datetime = datetime.utcnow() hashed_token = None if create_hash: hashed_token = cls._hash(token) return token, creation_datetime, hashed_token @classmethod def _validate_date(cls, date: datetime, validity_seconds: int) -> bool: if not date: return False now_seconds = time.mktime(datetime.utcnow().timetuple()) auth_token_seconds = time.mktime(date.timetuple()) difference = now_seconds - auth_token_seconds if difference > validity_seconds: return False return True
from sqlalchemy import Column, sql, Table from sqlalchemy.orm import column_property, dynamic_loader, mapper from sqlalchemy.types import Boolean, DateTime, Integer, Unicode from mediacore.lib.storage import StorageEngine from mediacore.model.media import MediaFile, MediaFileQuery, media_files from mediacore.model.meta import metadata from mediacore.model.util import JSONType log = logging.getLogger(__name__) storage = Table( 'storage', metadata, Column('id', Integer, primary_key=True, autoincrement=True), Column('engine_type', Unicode(30), nullable=False), Column('display_name', Unicode(100), nullable=False, unique=True), Column('enabled', Boolean, nullable=False, default=True), Column('created_on', DateTime, nullable=False, default=datetime.now), Column('modified_on', DateTime, nullable=False, default=datetime.now, onupdate=datetime.now), Column('data', JSONType, nullable=False, default=dict), mysql_engine='InnoDB', mysql_charset='utf8', ) storage_mapper = mapper( StorageEngine,
class User(ModelMixin, Base): """ The application's User model. """ __tablename__ = 'users' ## Columns ## id = Column(Integer, primary_key=True) _email = Column('email', Unicode(255), unique=True, nullable=False) _password = Column('password', Unicode(60)) role = Column(Unicode(20)) api_token = Column(Unicode(40), default=generate_secret) password_reset_token = Column(Unicode(40), default=generate_secret) password_reset_sent = Column(DateTime) last_login = Column(DateTime) updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) created = Column(DateTime, default=datetime.utcnow) ## Associations ## profile = relationship('UserProfile', backref='user', uselist=False, cascade='all, delete-orphan') ## Classmethods ## @classmethod def by_email(cls, email): """ Return the object whose email address is ``email``. If no object is found, a ``NoResultFound`` is raised. """ return cls.filter_by(email=email).one() ## Instance methods ## def check_password(self, value): return crypt.check(self.password, value) ## Object properties ## @property def full_name(self): return self.profile.full_name @property def authorization_token(self): return native_(b64encode("%s:%s" % (self.email, self.api_token))) @hybrid_property def email(self): return self._email.lower() @email.setter def email(self, value): self._email = value.lower() @email.comparator def email(cls): return CaseInsensitiveComparator(cls._email) @hybrid_property def password(self): return self._password @password.setter def password(self, value): self._password = crypt.encode(value) ## Special methods ## def __init__(self, email='', password=None, role='user', profile=None): self.email = email self.password = password or generate_secret() self.role = role self.profile = profile def __repr__(self): return '<User: %s>' % (self.email)
def downgrade(): op.alter_column(table_name='packages', column_name='name', type_=Unicode(50))
class User(DeclarativeBase): """ User definition. This is the user definition used by :mod:`repoze.who`, which requires at least the ``email`` column. """ __tablename__ = 'users' user_id = Column(Integer, Sequence('seq__users__user_id'), autoincrement=True, primary_key=True) email = Column(Unicode(255), unique=True, nullable=False) display_name = Column(Unicode(255)) _password = Column('password', Unicode(128)) created = Column(DateTime, default=datetime.utcnow) is_active = Column(Boolean, default=True, nullable=False) imported_from = Column(Unicode(32), nullable=True) timezone = Column(Unicode(255), nullable=False, server_default='') # TODO - G.M - 04-04-2018 - [auth] Check if this is already needed # with new auth system auth_token = Column(Unicode(255)) auth_token_created = Column(DateTime) @hybrid_property def email_address(self): return self.email def __repr__(self): return '<User: email=%s, display=%s>' % (repr( self.email), repr(self.display_name)) def __unicode__(self): return self.display_name or self.email @property def permissions(self): """Return a set with all permissions granted to the user.""" perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms @property def profile(self) -> Profile: profile_id = 0 if len(self.groups) > 0: profile_id = max(group.group_id for group in self.groups) return Profile(profile_id) # TODO - G-M - 20-04-2018 - [Calendar] Replace this in context model object # @property # def calendar_url(self) -> str: # # TODO - 20160531 - Bastien: Cyclic import if import in top of file # from tracim.lib.calendar import CalendarManager # calendar_manager = CalendarManager(None) # # return calendar_manager.get_user_calendar_url(self.user_id) @classmethod def by_email_address(cls, email, dbsession): """Return the user object whose email address is ``email``.""" return dbsession.query(cls).filter_by(email=email).first() @classmethod def by_user_name(cls, username, dbsession): """Return the user object whose user name is ``username``.""" return dbsession.query(cls).filter_by(email=username).first() @classmethod def _hash_password(cls, cleartext_password: str) -> str: salt = sha256() salt.update(os.urandom(60)) salt = salt.hexdigest() hash = sha256() # Make sure password is a str because we cannot hash unicode objects hash.update((cleartext_password + salt).encode('utf-8')) hash = hash.hexdigest() ciphertext_password = salt + hash # Make sure the hashed password is a unicode object at the end of the # process because SQLAlchemy _wants_ unicode objects for Unicode cols # FIXME - D.A. - 2013-11-20 - The following line has been removed since using python3. Is this normal ?! # password = password.decode('utf-8') return ciphertext_password def _set_password(self, cleartext_password: str) -> None: """ Set ciphertext password from cleartext password. Hash cleartext password on the fly, Store its ciphertext version, """ self._password = self._hash_password(cleartext_password) def _get_password(self) -> str: """Return the hashed version of the password.""" return self._password password = synonym('_password', descriptor=property(_get_password, _set_password)) def validate_password(self, cleartext_password: str) -> bool: """ Check the password against existing credentials. :param cleartext_password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type cleartext_password: unicode object. :return: Whether the password is valid. :rtype: bool """ result = False if self.password: hash = sha256() hash.update( (cleartext_password + self.password[:64]).encode('utf-8')) result = self.password[64:] == hash.hexdigest() return result def get_display_name(self, remove_email_part: bool = False) -> str: """ Get a name to display from corresponding member or email. :param remove_email_part: If True and display name based on email, remove @xxx.xxx part of email in returned value :return: display name based on user name or email. """ if self.display_name: return self.display_name else: if remove_email_part: at_pos = self.email.index('@') return self.email[0:at_pos] return self.email def get_role(self, workspace: 'Workspace') -> int: for role in self.roles: if role.workspace == workspace: return role.role return UserRoleInWorkspace.NOT_APPLICABLE def get_active_roles(self) -> ['UserRoleInWorkspace']: """ :return: list of roles of the user for all not-deleted workspaces """ roles = [] for role in self.roles: if not role.workspace.is_deleted: roles.append(role) return roles # TODO - G.M - 04-04-2018 - [auth] Check if this is already needed # with new auth system def ensure_auth_token(self, validity_seconds, session) -> None: """ Create auth_token if None, regenerate auth_token if too much old. auth_token validity is set in :return: """ if not self.auth_token or not self.auth_token_created: self.auth_token = str(uuid.uuid4()) self.auth_token_created = datetime.utcnow() session.flush() return now_seconds = time.mktime(datetime.utcnow().timetuple()) auth_token_seconds = time.mktime(self.auth_token_created.timetuple()) difference = now_seconds - auth_token_seconds if difference > validity_seconds: self.auth_token = str(uuid.uuid4()) self.auth_token_created = datetime.utcnow() session.flush()
from datetime import datetime from sqlalchemy import Table, ForeignKey, Column, sql from sqlalchemy.types import BigInteger, Boolean, DateTime, Integer, Unicode, UnicodeText from sqlalchemy.orm import mapper, relation, backref, synonym, composite, column_property, validates, interfaces, Query from mediadrop.model import AuthorWithIP from mediadrop.model.meta import DBSession, metadata from mediadrop.plugin import events comments = Table( 'comments', metadata, Column('id', Integer, autoincrement=True, primary_key=True), Column('media_id', Integer, ForeignKey('media.id', onupdate='CASCADE', ondelete='CASCADE')), Column('subject', Unicode(100)), Column('created_on', DateTime, default=datetime.now, nullable=False), Column('modified_on', DateTime, default=datetime.now, onupdate=datetime.now, nullable=False), Column('reviewed', Boolean, default=False, nullable=False), Column('publishable', Boolean, default=False, nullable=False), Column('author_name', Unicode(50), nullable=False), Column('author_email', Unicode(255)), Column('author_ip', BigInteger, nullable=False), Column('body', UnicodeText, nullable=False), mysql_engine='InnoDB', mysql_charset='utf8', )
""" # revision identifiers, used by Alembic. revision = 'e1488bb4dd' down_revision = '47f9265e77e5' from alembic.op import execute, inline_literal from sqlalchemy import and_ from sqlalchemy.types import Integer, Unicode, UnicodeText from sqlalchemy.schema import Column, MetaData, Table # -- table definition --------------------------------------------------------- metadata = MetaData() settings = Table('settings', metadata, Column('id', Integer, autoincrement=True, primary_key=True), Column('key', Unicode(255), nullable=False, unique=True), Column('value', UnicodeText), mysql_engine='InnoDB', mysql_charset='utf8', ) # ----------------------------------------------------------------------------- def upgrade(): update_setting(u'general_site_name', u'MediaCore', u'MediaDrop') update_settings_key( u'appearance_display_mediacore_footer', u'appearance_display_mediadrop_footer') update_settings_key( u'appearance_display_mediacore_credits', u'appearance_display_mediadrop_credits')
class User(DeclarativeBase): """ User definition. This is the user definition used by :mod:`repoze.who`, which requires at least the ``user_name`` column. """ __tablename__ = 'tg_user' #{ Columns user_id = Column(Integer, autoincrement=True, primary_key=True) user_name = Column(Unicode(16), unique=True, nullable=False) email_address = Column(Unicode(255), unique=True, nullable=False, info={'rum': { 'field': 'Email' }}) display_name = Column(Unicode(255)) _password = Column('password', Unicode(80), info={'rum': { 'field': 'Password' }}) created = Column(DateTime, default=datetime.now) #{ Special methods def __repr__(self): return '<User: email="%s", display name="%s">' % (self.email_address, self.display_name) def __unicode__(self): return self.display_name or self.user_name #{ Getters and setters @property def permissions(self): """Return a set of strings for the permissions granted.""" perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms @classmethod def by_email_address(cls, email): """Return the user object whose email address is ``email``.""" return DBSession.query(cls).filter(cls.email_address == email).first() @classmethod def by_user_name(cls, username): """Return the user object whose user name is ``username``.""" return DBSession.query(cls).filter(cls.user_name == username).first() def _set_password(self, password): """Hash ``password`` on the fly and store its hashed version.""" hashed_password = password if isinstance(password, unicode): password_8bit = password.encode('UTF-8') else: password_8bit = password salt = sha1() salt.update(os.urandom(60)) hash = sha1() hash.update(password_8bit + salt.hexdigest()) hashed_password = salt.hexdigest() + hash.hexdigest() # Make sure the hashed password is an UTF-8 object at the end of the # process because SQLAlchemy _wants_ a unicode object for Unicode # columns if not isinstance(hashed_password, unicode): hashed_password = hashed_password.decode('UTF-8') self._password = hashed_password def _get_password(self): """Return the hashed version of the password.""" return self._password password = synonym('_password', descriptor=property(_get_password, _set_password)) #} def validate_password(self, password): """ Check the password against existing credentials. :param password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type password: unicode object. :return: Whether the password is valid. :rtype: bool """ hashed_pass = sha1() hashed_pass.update(password + self.password[:40]) return self.password[40:] == hashed_pass.hexdigest()
class WallOfSheep(DatabaseObject): ''' Stores a record of cracked passwords, and publically displays them for all to see. ''' preimage = Column(Unicode(32), nullable=False) value = Column(Integer, nullable=False) victim_id = Column(Integer, ForeignKey('user.id'), nullable=False) cracker_id = Column(Integer, ForeignKey('user.id'), nullable=False) @classmethod def all(cls): ''' Returns all team objects ''' return dbsession.query(cls).all() @classmethod def all_order_created(cls): ''' Returns all team objects ''' return dbsession.query(cls).order_by(desc(cls.created)).all() @classmethod def all_order_value(cls): ''' Returns all team objects ''' return dbsession.query(cls).order_by(desc(cls.value)).all() @classmethod def by_id(cls, _id): ''' Returns a the object with id of _id ''' return dbsession.query(cls).filter_by(id=_id).first() @classmethod def by_victim_id(cls, _id): ''' Returns all entries for a _id ''' return dbsession.query(cls).filter_by(victim_id=_id).all() @classmethod def by_cracker_id(cls, _id): ''' Returns all entries for cracker_id ''' return dbsession.query(cls).filter_by(cracker_id=_id).all() @classmethod def count_cracked_by(cls, _id): return dbsession.query(cls).filter_by(cracker_id=_id).count() @classmethod def leaderboard(cls, order_by='passwords'): ''' Creates an ordered list of tuples, for each user and the number of password they've cracked ''' orders = {'passwords': 1, 'cash': 2} leaders = [] for user in User.all_users(): if 0 < cls.count_cracked_by(user.id): leaders.append(( user, cls.count_cracked_by(user.id), sum(cls.by_cracker_id(user.id)), )) if order_by not in orders: order_by = 'passwords' leaders.sort(key=lambda stats: stats[orders[order_by]], reverse=True) return leaders @property def victim(self): ''' Returns display name of user ''' return User.by_id(self.victim_id) @property def cracker(self): ''' Returns display name of cracker ''' return User.by_id(self.cracker_id) def __cmp__(self, other): ''' Used for sorting ''' return len(self) - len(other) def __repr__(self): return '<WallOfSheep - preimage: %s, victim_id: %d>' % ( self.preimage, self.victim_id, ) def __len__(self): return len(self.preimage) def __radd__(self, other): return self.value + other def __add__(self, other): return self.value + other.value
class Identifier(_Base, SelectMixin): """ All known unique IDs for a PubMed record. Attributes: pmid the record this alternate ID belongs to namespace the type of ID (doi, pii, pmc, pubmed, etc.) value the actual ID string Primary Key: ``(pmid, namespace)`` """ __tablename__ = 'identifiers' pmid = Column(BigInteger, ForeignKey('citations.pmid', ondelete="CASCADE"), primary_key=True) namespace = Column(Unicode(length=32), CheckConstraint("namespace <> ''"), primary_key=True) value = Column(Unicode(length=256), CheckConstraint("value <> ''"), nullable=False) def __init__(self, pmid: int, namespace: str, value: str): assert pmid > 0, pmid assert namespace assert value self.pmid = pmid self.namespace = namespace self.value = value def __str__(self): return '{}\t{}\t{}\n'.format(NULL(self.pmid), NULL(self.namespace), STRING(self.value)) def __repr__(self): return "Identifier<{}:{}>".format(self.pmid, self.namespace) def __eq__(self, other): return isinstance(other, Identifier) and \ self.pmid == other.pmid and \ self.namespace == other.namespace and \ self.value == other.value @classmethod def pmid2doi(cls, pmid: int): """Convert a PMID to a DOI (or ``None`` if no mapping is found).""" c = cls.__table__.c query = select([c.value], (c.namespace == 'doi') & (c.pmid == pmid)) return _fetch_first(query) @classmethod def doi2pmid(cls, doi: str): """Convert a DOI to a PMID (or ``None`` if no mapping is found).""" c = cls.__table__.c query = select([c.pmid], (c.namespace == 'doi') & (c.value == doi)) return _fetch_first(query) @classmethod def mapDois2Pmids(cls, dois: list): """ Return a mapping :class:`dict` for a list of DOIs to their PMIDs (or and empty :class:`dict` if no mapping is found). If for a given DOI no mapping exists, it is no included in the returned dictionary. """ if not len(dois): return {} c = cls.__table__.c query = select([c.value, c.pmid], (c.namespace == 'doi') & c.value.in_(dois)) mappings = _fetch_all(query) return dict(mappings) if mappings is not None else {} @classmethod def mapPmids2Dois(cls, pmids: list): """ Return a mapping :class:`dict` for a list of PMIDs to their DOIs (or and empty :class:`dict` if no mapping is found). If for a given PMID no mapping exists, it is no included in the returned dictionary. """ if not len(pmids): return {} t = cls.__table__ query = select([t.c.pmid, t.c.value], (t.c.namespace == 'doi') & t.c.pmid.in_(pmids)) mappings = _fetch_all(query) return dict(mappings) if mappings is not None else {}
class User(DeclarativeBase): """ User definition. This is the user definition used by :mod:`repoze.who`, which requires at least the ``user_name`` column. In addition, we specify all the local user information that we will be storing. """ __tablename__ = 'tg_user' ##{B:Columns} user_id = Column(Integer, autoincrement=True, primary_key=True) user_name = Column(Unicode(16), unique=True, nullable=False) email_address = Column(Unicode(1024), unique=True, nullable=False) display_name = Column(Unicode(255)) title = Column(Unicode(64)) streetaddress = Column(Unicode(255)) city = Column(Unicode(255)) state_province = Column(Unicode(255)) postal_code = Column(Unicode(12)) country = Column(Unicode(32)) phones = Column(Unicode(1024)) # JSON Encoded logo = Column(LargeBinary(1024*256)) callingcard = Column(LargeBinary(1024*256)) photo = Column(LargeBinary(1024*256)) external_links = Column(Unicode(1024*256)) # JSON Encoded default_summary = Column(Unicode(8192)) analyticsid = Column(Unicode(32)) _password = Column('password', Unicode(128), info={'rum': {'field':'Password'}}) created = Column(DateTime, default=datetime.now) jobs = relationship("JobHistory", backref="user", order_by="JobHistory.order") skillgroups = relationship("SkillGroups", backref="user", order_by="SkillGroups.order") projects = relationship("ProjectHistory", backref="user", order_by="ProjectHistory.order") education = relationship("Education", backref="user", order_by="Education.order") awards = relationship("Award", backref="user", order_by="Award.order") resumes = relationship("Resume", backref="user", order_by="Resume.name") ##{E:Columns} #{ Special methods def __repr__(self): return ('<User: name=%s, email=%s, display=%s>' % ( self.user_name, self.email_address, self.display_name)).encode('utf-8') def __unicode__(self): return self.display_name or self.user_name #{ Getters and setters @property def permissions(self): """Return a set with all permissions granted to the user.""" perms = set() for g in self.groups: perms = perms | set(g.permissions) return perms @classmethod def by_email_address(cls, email): """Return the user object whose email address is ``email``.""" return DBSession.query(cls).filter_by(email_address=email).first() @classmethod def by_user_name(cls, username): """Return the user object whose user name is ``username``.""" return DBSession.query(cls).filter_by(user_name=username).first() @classmethod def _hash_password(cls, password): # Make sure password is a str because we cannot hash unicode objects if isinstance(password, unicode): password = password.encode('utf-8') salt = sha256() salt.update(os.urandom(60)) hash = sha256() hash.update(password + salt.hexdigest()) password = salt.hexdigest() + hash.hexdigest() # Make sure the hashed password is a unicode object at the end of the # process because SQLAlchemy _wants_ unicode objects for Unicode cols if not isinstance(password, unicode): password = password.decode('utf-8') return password def _set_password(self, password): """Hash ``password`` on the fly and store its hashed version.""" self._password = self._hash_password(password) def _get_password(self): """Return the hashed version of the password.""" return self._password password = synonym('_password', descriptor=property(_get_password, _set_password)) #} def validate_password(self, password): """ Check the password against existing credentials. :param password: the password that was provided by the user to try and authenticate. This is the clear text version that we will need to match against the hashed one in the database. :type password: unicode object. :return: Whether the password is valid. :rtype: bool """ hash = sha256() if isinstance(password, unicode): password = password.encode('utf-8') hash.update(password + str(self.password[:64])) return self.password[64:] == hash.hexdigest() def phones_to_string(self): phones = simplejson.loads(self.phones) return ", ".join(["%s: %s" % (x, phones[x]) for x in sorted(phones)]) def phones_to_dict(self): return simplejson.loads(self.phones) def links_to_dict(self): return simplejson.loads(self.external_links)
class Section(_Base, SelectMixin): """ The text sections of the records. Attributes: pmid the record's identifier (PubMed ID) source the abstract's source (see `Abstract.SOURCES`) seq the sequence of sections in the abstract (starting from 1) name the name of the section (Abstract, Background, Methods, Unassigned, ...) label section label as defined by the publisher (if any) content the text content of the section truncated if the text content was truncated by PubMed that means the content contained the string "(ABSTRACT TRUNCATED AT 250 WORDS)" at its end; this message is removed by the parser Primary Key: ``(pmid, source, seq)`` """ __tablename__ = 'sections' __table_args__ = (ForeignKeyConstraint( ('pmid', 'source'), ('abstracts.pmid', 'abstracts.source'), ondelete="CASCADE"), ) SOURCES = frozenset( {'NLM', 'AAMC', 'AIDS', 'KIE', 'PIP', 'NASA', 'Publisher'}) pmid = Column(BigInteger, ForeignKey('citations.pmid', ondelete="CASCADE"), primary_key=True) source = Column(Enum(*SOURCES, name='source'), primary_key=True) seq = Column(SmallInteger, CheckConstraint("seq > 0"), primary_key=True) name = Column(Unicode(length=64), CheckConstraint("name <> ''"), nullable=False) label = Column(Unicode(length=256), CheckConstraint("label <> ''"), nullable=True) content = Column(UnicodeText, CheckConstraint("content <> ''"), nullable=False) truncated = Column(Boolean, nullable=False, default=False) def __init__(self, pmid: int, source: str, seq: int, name: str, content: str, label: str = None, truncated: bool = False): assert pmid > 0, pmid assert source in Section.SOURCES, repr(source) assert seq > 0, seq assert name, repr(name) assert content, repr(content) assert label is None or label, repr(label) self.pmid = pmid self.source = source self.seq = seq self.name = name self.label = label self.content = content self.truncated = bool(truncated) def __str__(self): return '{}\t{}\t{}\t{}\t{}\t{}\t{}\n'.format( NULL(self.pmid), NULL(self.source), NULL(self.seq), NULL(self.name), NULL(self.label), STRING(self.content), 'T' if self.truncated else 'F') def __repr__(self): return "Section<{}:{}:{}>".format(self.pmid, self.source, self.seq) def __eq__(self, other): return isinstance(other, Section) and \ self.pmid == other.pmid and \ self.source == other.source and \ self.seq == other.seq and \ self.name == other.name and \ self.label == other.label and \ self.content == other.content and \ self.truncated == other.truncated
class CrmAccount(Base): __tablename__ = 'crm_accounts' id = Column(Integer, autoincrement=True, primary_key=True) first_name = Column(Unicode(64)) last_name = Column(Unicode(64)) customer = Column(Unicode(255)) title = Column(Unicode(32)) created = Column(DateTime,default=datetime.date(datetime.now())) last_modified = Column(DateTime,default=datetime.date(datetime.now())) email = Column(Unicode(128)) address = Column(Unicode(255)) address_2 = Column(Unicode(255)) city = Column(Unicode(64)) state = Column(Unicode(32)) zip = Column(Unicode(15)) country = Column(Unicode(64)) url = Column(Unicode(128)) tel = Column(Unicode(15)) tel_ext = Column(Unicode(6)) mobile = Column(Unicode(15)) active = Column(Boolean, default=True) lat_lon = Column(Unicode(100), default=u"0,0") crm_campaign_id = Column(Integer, ForeignKey('crm_campaigns.id', onupdate="CASCADE")) user_id = Column(Integer) customer_id = Column(Integer, ForeignKey('customers.id', onupdate="CASCADE")) crm_account_status_type_id = Column(Integer, ForeignKey('crm_account_status_types.id', onupdate="CASCADE")) crm_lead_type_id = Column(Integer, ForeignKey('crm_lead_types.id', onupdate="CASCADE")) def __init__(self, _first_name=None,_last_name=None,_email=None): self.first_name = _first_name self.last_name = _last_name self.email = _email def __str__(self): return '<%s>' % self.__class__.__name__ def __repr__(self): return '<%s %r>' % (self.__class__, self.__dict__)