class SearchLog(db.Model): __tablename__ = 'search_logs' id = db.Column(db.Integer, primary_key=True) time = db.Column(db.DateTime, default=datetime.datetime.utcnow, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=backref('search_logs', cascade="all,delete,delete-orphan"))
class SearchLogGeometry(db.Model): __tablename__ = 'search_log_geometries' id = db.Column(db.Integer, primary_key=True) search_log_id = db.Column(db.Integer, db.ForeignKey('search_logs.id'), nullable=False) search_log = db.relationship('SearchLog', backref=backref( 'geometries', cascade="all,delete,delete-orphan")) geometry = db.Column(Geometry('POLYGON', srid=3857)) identifier = db.Column(db.String)
class WFSSession(db.Model): __tablename__ = 'wfs_sessions' id = db.Column(db.Integer, primary_key=True) active = db.Column(db.Boolean, default=True) layer = db.Column(db.String, nullable=False) url = db.Column(db.String, nullable=False) start_edit = db.Column(db.DateTime, default=datetime.utcnow) last_update = db.Column(db.DateTime, default=None) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=backref('wfs_sessions', cascade="all,delete,delete-orphan")) @classmethod def by_active_user_layer(cls, layer, user): q = WFSSession.query.filter_by(user=user, active=True, layer=layer) return q.first() def update(self): self.last_update = datetime.utcnow()
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) # login data email = db.Column(db.String(), unique=True, nullable=False) password = db.Column(db.String()) # address and personal data title = db.Column(db.String()) firstname = db.Column(db.String()) lastname = db.Column(db.String()) address = db.Column(db.String()) address_extend = db.Column(db.String()) zipcode = db.Column(db.String()) city = db.Column(db.String()) federal_state = db.Column(db.String()) country = db.Column(db.String()) phone = db.Column(db.String()) fax = db.Column(db.String()) company_name = db.Column(db.String()) company_number = db.Column(db.String()) commercial_register_number = db.Column(db.String()) # type from user e.g. customer, consultant etc. type = db.Column(db.Integer, default=0) # system data registered = db.Column(db.DateTime, default=datetime.datetime.utcnow) last_login = db.Column(db.DateTime, default=None) active = db.Column(db.Boolean, default=False, nullable=False) verified = db.Column(db.Boolean, default=False, nullable=False) authproxy_token = db.Column(db.String(32), unique=True, default=lambda: uuid.uuid4().hex) email_verification = db.relationship('EmailVerification', backref='user', uselist=False, cascade='all,delete,delete-orphan') def __init__(self, email, password=None): self.email = email self.password = None if password: self.update_password(password) class Type(object): CUSTOMER = 0 #landwirte SERVICE_PROVIDER = 1 #dienstleister CONSULTANT = 50 #berater ADMIN = 99 @classmethod def as_string(self, type): _types = { 0: _('customer'), 1: _('service_provider'), 50: _('consultant'), 99: _('admin'), } return _types[type or 0] @property def type_name(self): return self.Type.as_string(self.type) @property def is_customer(self): return True if self.type == self.Type.CUSTOMER else False @property def is_service_provider(self): return True if self.type == self.Type.SERVICE_PROVIDER else False @property def is_consultant(self): return True if self.type == self.Type.CONSULTANT else False @property def is_admin(self): return True if self.type == self.Type.ADMIN else False @property def realname(self): return '%s %s %s' % (self.title_name, self.firstname, self.lastname) @property def title_name(self): salutations = current_app.config['SALUTATIONS'] for salutation in salutations: if salutation[0] == self.title: return salutation[1] return '' @property def federal_state_name(self): federal_states = current_app.config['FEDERAL_STATES'] for federal_state in federal_states: if federal_state[0] == self.federal_state: return federal_state[1] return '' @classmethod def from_dict(cls, data): user = User(data['email'], data['password']) for name, value in data.iteritems(): if hasattr(user, name): setattr(user, name, value) return user @classmethod def by_email(cls, email): q = User.query.filter(func.lower(cls.email) == func.lower(email)) return q.first() @classmethod def by_id(cls, id): q = User.query.filter(User.id == id) return q.first() @classmethod def by_authproxy_token(cls, authproxy_token): q = User.query.filter(User.authproxy_token == authproxy_token) return q.first() @classmethod def all_admins(cls): q = cls.query.filter(cls.type == cls.Type.ADMIN) return q.all() def update_password(self, password): if not password: raise ValueError("Password must be non empty.") password = str(password) rounds = current_app.config.get('BCRYPT_LOG_ROUNDS', 10) self.password = bcrypt.hashpw(password, bcrypt.gensalt(rounds)) def check_password(self, password): if not self.password: return False return bcrypt.hashpw(password, self.password) == self.password def update_last_login(self): self.last_login = datetime.datetime.utcnow() def is_active(self): return self.active def get_id(self): assert self.id is not None return self.id def set_user_data(self, data): self.title = data['title'] self.firstname = data['firstname'] self.lastname = data['lastname'] self.address = data['address'] self.address_extend = data['address_extend'] self.company_name = data['company_name'] self.zipcode = data['zipcode'] self.city = data['city'] self.federal_state = data['federal_state'] self.phone = data['phone'] self.fax = data['fax'] self.company_number = data.get('company_number') self.commercial_register_number = data.get( 'commercial_register_number') def __repr__(self): return '<User email=%s type=%s>' % (self.email, self.type)
class EmailVerification(db.Model): __tablename__ = 'password_recovery' id = db.Column(db.Integer, primary_key=True) hash = db.Column(db.String(36), unique=True, nullable=False) type = db.Column(db.String(10), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) valid_till = db.Column( db.DateTime, default=lambda: datetime.datetime.utcnow() + RECOVER_VALID_FOR) @classmethod def by_hash(cls, hash): q = EmailVerification.query.filter(EmailVerification.hash == hash) recover = q.first() if recover: if datetime.datetime.utcnow() < recover.valid_till: return recover db.session.remove(recover) db.session.commit() @classmethod def recover(cls, user): return EmailVerification(user=user, hash=str(uuid.uuid4()), type='recover') @classmethod def verify(cls, user): return EmailVerification(user=user, hash=str(uuid.uuid4()), type='verify') @classmethod def verify_import(cls, user): return EmailVerification(user=user, hash=str(uuid.uuid4()), type='import') @property def is_recover(self): return self.type == 'recover' @property def is_verify(self): return self.type == 'verify' @property def is_import(self): return self.type == 'import' @property def url(self): if self.type == 'recover': return url_for('user.recover_password', uuid=self.hash, _external=True) if self.type == 'verify': return url_for('user.verify', uuid=self.hash, _external=True) if self.type == 'import': return url_for('user.new_password', uuid=self.hash, _external=True) raise AssertionError('unknown verification type: %s', self.type)
class Log(db.Model): __tablename__ = 'logs' id = db.Column(db.Integer, primary_key=True) time = db.Column(db.DateTime, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship('User', backref=backref('logs', cascade="all,delete,delete-orphan")) action = db.Column(db.String(24), nullable=False) geometry = db.Column(Geometry('MULTIPOLYGON', srid=4326)) format = db.Column(db.String) srs = db.Column(db.String) mapping = db.Column(db.String) source = db.Column(db.String) layer = db.Column(db.String) zoom_level_start = db.Column(db.Integer) zoom_level_end = db.Column(db.Integer) refreshed = db.Column(db.Boolean) @property def geometry_as_geojson(self): if self.geometry is not None: geom = json.dumps(shapely.geometry.mapping(to_shape( self.geometry))) return geom return False
class WMS(db.Model): __tablename__ = 'wms' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False, unique=True) url = db.Column(db.String(256), nullable=False) username = db.Column(db.String(64)) password = db.Column(db.String(64)) title = db.Column(db.String) layer = db.Column(db.String(256), nullable=False) format = db.Column(db.String, nullable=False) srs = db.Column(db.String(64), default="EPSG:3857") version = db.Column(db.String, default="1.1.1") view_coverage = db.Column(Geometry('POLYGON', srid=4326)) view_level_start = db.Column(db.Integer) view_level_end = db.Column(db.Integer) is_background_layer = db.Column(db.Boolean(), default=False) is_overlay = db.Column(db.Boolean(), default=True) is_transparent = db.Column(db.Boolean(), default=True) is_visible = db.Column(db.Boolean(), default=True) is_public = db.Column(db.Boolean(), default=False) is_accessible = db.Column(db.Boolean(), default=True) is_protected = db.Column(db.Boolean(), default=True) @classmethod def by_id(cls, id): q = cls.query.filter(cls.id == id) return q.first_or_404() @classmethod def by_name(cls, name): q = cls.query.filter(cls.name == name) return q.first_or_404()
class WMTS(db.Model): __tablename__ = 'wmts' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False, unique=True) url = db.Column(db.String(256), nullable=False) username = db.Column(db.String(64)) password = db.Column(db.String(64)) title = db.Column(db.String) format = db.Column(db.String, nullable=False) max_tiles = db.Column(db.Integer) view_coverage = db.Column(Geometry('POLYGON', srid=4326)) view_level_start = db.Column(db.Integer) view_level_end = db.Column(db.Integer) # used in context document # used on for gbi-client for export in mapproxy mbtiles etc. is_overlay = db.Column(db.Boolean(), default=True) # used in context document # gbi-client use user and password from context document if it is false is_protected = db.Column(db.Boolean(), default=True) # used on geobox editor and for sorting on context document # gbi-client: the first layer of the contxt document is background layer is_background_layer = db.Column(db.Boolean(), default=False) # used on geobox editor is_transparent = db.Column(db.Boolean(), default=True) is_visible = db.Column(db.Boolean(), default=True) # if it is public the complete view coverage added to the context document # if not only the geometry from the user is allowed is_public = db.Column(db.Boolean(), default=False) # access map without authproxy is_accessible = db.Column(db.Boolean(), default=False) @classmethod def by_id(cls, id): q = cls.query.filter(cls.id == id) return q.first_or_404() @classmethod def by_name(cls, name): q = cls.query.filter(cls.name == name) return q.first_or_404() @property def bbox(self): if self.view_coverage != '': geometry = to_shape(self.view_coverage) return transform_bbox(from_srs=4326, to_srs=3857, bbox=geometry.bounds) return False def client_url(self, external=False): if self.is_public and self.is_accessible: return self.url.rstrip('/') + '/' if external: return url_for('authproxy.tile_proxy', user_token=g.user.authproxy_token, _external=True).rstrip('/') + '/' + self.url return url_for('authproxy.tile_proxy').rstrip('/') + '/' + self.url
class WFS(db.Model): __tablename__ = 'wfs' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False, unique=True) url = db.Column(db.String(256), nullable=False) host = db.Column(db.String(256), nullable=False) geometry = db.Column(db.String(256), nullable=False) layer = db.Column(db.String(256), nullable=False) srs = db.Column(db.String(64)) ns_prefix = db.Column(db.String(64)) ns_uri = db.Column(db.String(64)) search_property = db.Column(db.String) max_features = db.Column(db.Integer) username = db.Column(db.String(64)) password = db.Column(db.String(64)) is_protected = db.Column(db.Boolean(), default=True) @classmethod def by_id(cls, id): q = cls.query.filter(cls.id == id) return q.first_or_404() @classmethod def by_name(cls, name): q = cls.query.filter(cls.name == name) return q.first_or_404()