class Layer(TreeItem): __tablename__ = 'layer' __table_args__ = {'schema': _schema} __mapper_args__ = { 'polymorphic_identity': 'layer' # needed for _identity_class } id = Column(Integer, ForeignKey(_schema + '.treeitem.id'), primary_key=True) public = Column(Boolean, default=True, info={'colanderalchemy': { 'title': _('Public') }}) geo_table = Column(Unicode, info={'colanderalchemy': { 'title': _('Geo table') }}) exclude_properties = Column( Unicode, info={'colanderalchemy': { 'title': _('Exclude properties') }}) def __init__(self, name: str = '', public: bool = True) -> None: TreeItem.__init__(self, name=name) self.public = public
class LayerGroup(TreeGroup): __tablename__ = 'layergroup' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('Layers group'), 'plural': _('Layers groups') } __mapper_args__ = {'polymorphic_identity': 'group'} __c2cgeoform_config__ = {'duplicate': True} id = Column(Integer, ForeignKey(_schema + '.treegroup.id'), primary_key=True, info={ 'colanderalchemy': { 'missing': colander.drop, 'widget': HiddenWidget() } }) is_expanded = Column( Boolean, info={'colanderalchemy': { 'title': _('Expanded'), 'column': 2 }}) # shouldn't be used in V3 def __init__(self, name: str = '', is_expanded: bool = False) -> None: TreeGroup.__init__(self, name=name) self.is_expanded = is_expanded
class Metadata(Base): __tablename__ = 'metadata' __table_args__ = {'schema': _schema} id = Column(Integer, primary_key=True, info={'colanderalchemy': { 'widget': HiddenWidget() }}) name = Column(Unicode, info={'colanderalchemy': { 'title': _('Name'), }}) value = Column(Unicode, info={'colanderalchemy': {'exclude': True}}) description = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Description'), 'widget': TextAreaWidget() } }) item_id = Column('item_id', Integer, ForeignKey(_schema + '.treeitem.id'), nullable=False, info={ 'colanderalchemy': { 'exclude': True }, 'c2cgeoform': { 'duplicate': False } }) item = relationship( 'TreeItem', info={ 'c2cgeoform': { 'duplicate': False }, 'colanderalchemy': { 'exclude': True } }, backref=backref( 'metadatas', cascade='save-update,merge,delete,delete-orphan,expunge', order_by='Metadata.name', info={ 'colanderalchemy': { 'title': _('Metadatas'), 'exclude': True } })) def __init__(self, name: str = '', value: str = '') -> None: self.name = name self.value = value def __unicode__(self) -> str: # pragma: no cover return '{0!s}: {1!s}'.format(self.name or '', self.value or '')
class LayerGroup(TreeGroup): __tablename__ = "layergroup" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("Layers group"), "plural": _("Layers groups") } __mapper_args__ = {"polymorphic_identity": "group"} __c2cgeoform_config__ = {"duplicate": True} id = Column( Integer, ForeignKey(_schema + ".treegroup.id"), primary_key=True, info={"colanderalchemy": { "missing": drop, "widget": HiddenWidget() }}, ) is_expanded = Column( Boolean, info={"colanderalchemy": { "title": _("Expanded"), "column": 2 }}) # shouldn't be used in V3 def __init__(self, name: str = "", is_expanded: bool = False) -> None: TreeGroup.__init__(self, name=name) self.is_expanded = is_expanded
class Layer(TreeItem): __tablename__ = "layer" __table_args__ = {"schema": _schema} __mapper_args__ = { "polymorphic_identity": "layer" } # needed for _identity_class id = Column( Integer, ForeignKey(_schema + ".treeitem.id"), primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}, ) public = Column(Boolean, default=True, info={"colanderalchemy": { "title": _("Public") }}) geo_table = Column(Unicode, info={"colanderalchemy": { "title": _("Geo table") }}) exclude_properties = Column( Unicode, info={"colanderalchemy": { "title": _("Exclude properties") }}) def __init__(self, name: str = "", public: bool = True) -> None: TreeItem.__init__(self, name=name) self.public = public
class Functionality(Base): __tablename__ = 'functionality' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('Functionality'), 'plural': _('Functionalities') } __c2cgeoform_config__ = { 'duplicate': True } id = Column(Integer, primary_key=True, info={ 'colanderalchemy': { 'widget': HiddenWidget() } }) name = Column(Unicode, nullable=False, info={ 'colanderalchemy': {'title': _('Name')} }) description = Column(Unicode, info={ 'colanderalchemy': {'title': _('Description')} }) value = Column(Unicode, nullable=False, info={ 'colanderalchemy': {'title': _('Value')} }) def __init__(self, name: str='', value: str='', description: str='') -> None: self.name = name self.value = value self.description = description def __unicode__(self) -> str: return '{0!s} - {1!s}'.format(self.name or '', self.value or '') # pragma: no cover
class Dimension(Base): __tablename__ = 'dimension' __table_args__ = {'schema': _schema} id = Column(Integer, primary_key=True, info={'colanderalchemy': {'widget': HiddenWidget()}}) name = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Name') } }) value = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Value') } }) description = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Description'), 'widget': TextAreaWidget() } }) layer_id = Column('layer_id', Integer, ForeignKey(_schema + '.layer.id'), nullable=False, info={ 'colanderalchemy': { 'exclude': True }, 'c2cgeoform': { 'duplicate': False }}) layer = relationship( 'DimensionLayer', info={'c2cgeoform': {'duplicate': False}, 'colanderalchemy': {'exclude': True} }, backref=backref( 'dimensions', cascade='save-update,merge,delete,delete-orphan,expunge', info={ 'colanderalchemy': { 'title': _('Dimensions'), 'exclude': True } } ) ) def __init__(self, name: str='', value: str='', layer: str=None) -> None: self.name = name self.value = value if layer is not None: self.layer = layer def __unicode__(self) -> str: # pragma: no cover return self.name or ''
class TreeItem(Base): __tablename__ = 'treeitem' __table_args__ = ( UniqueConstraint('type', 'name'), { 'schema': _schema }, ) # type: Union[Tuple, Dict[str, Any]] item_type = Column('type', String(10), nullable=False, info={'colanderalchemy': { 'exclude': True }}) __mapper_args__ = {'polymorphic_on': item_type} id = Column(Integer, primary_key=True) name = Column(Unicode, nullable=False, info={'colanderalchemy': { 'title': _('Name') }}) metadata_url = Column( Unicode, info={'colanderalchemy': { 'title': _('Metadata URL') }}) # should not be used in V2 description = Column(Unicode, info={'colanderalchemy': { 'title': _('Description') }}) @property # Better: def parents(self) -> List[TreeGroup]: # pragma: no cover def parents(self) -> List['TreeItem']: # pragma: no cover return [c.group for c in self.parents_relation] def is_in_interface(self, name: str) -> bool: if not hasattr(self, 'interfaces'): # pragma: no cover return False for interface in self.interfaces: if interface.name == name: return True return False def get_metadatas(self, name: str) -> List['Metadata']: # pragma: no cover return [ metadata for metadata in self.metadatas if metadata.name == name ] def __init__(self, name: str = '') -> None: self.name = name
class TreeItem(Base): __tablename__ = "treeitem" __table_args__: Union[Tuple, Dict[str, Any]] = ( UniqueConstraint("type", "name"), { "schema": _schema }, ) item_type = Column("type", String(10), nullable=False, info={"colanderalchemy": { "exclude": True }}) __mapper_args__ = {"polymorphic_on": item_type} id = Column(Integer, primary_key=True) name = Column(Unicode, nullable=False, info={"colanderalchemy": { "title": _("Name") }}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) @property # Better: def parents(self) -> List[TreeGroup]: def parents(self) -> List["TreeItem"]: return [c.treegroup for c in self.parents_relation] def is_in_interface(self, name: str) -> bool: if not hasattr(self, "interfaces"): return False for interface in self.interfaces: if interface.name == name: return True return False def get_metadatas(self, name: str) -> List["Metadata"]: return [ metadata for metadata in self.metadatas if metadata.name == name ] def __init__(self, name: str = "") -> None: self.name = name
class LayerVectorTiles(DimensionLayer): __tablename__ = "layer_vectortiles" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("Vector Tiles Layer"), "plural": _("Vector Tiles Layers") } __c2cgeoform_config__ = {"duplicate": True} __mapper_args__ = {"polymorphic_identity": "l_mvt"} id = Column( Integer, ForeignKey(_schema + ".layer.id"), primary_key=True, info={"colanderalchemy": { "missing": None, "widget": HiddenWidget() }}, ) style = Column( Unicode, nullable=False, info={ "colanderalchemy": { "title": _("Style"), "description": "The path to json style. Example: https://url/style.json", "column": 2, } }, ) xyz = Column( Unicode, nullable=True, info={ "colanderalchemy": { "title": _("Raster URL"), "description": "The raster url. Example: https://url/{z}/{x}/{y}.png", "column": 2, } }, )
class Theme(TreeGroup): __tablename__ = 'theme' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = {'title': _('Theme'), 'plural': _('Themes')} __mapper_args__ = {'polymorphic_identity': 'theme'} __c2cgeoform_config__ = {'duplicate': True} id = Column(Integer, ForeignKey(_schema + '.treegroup.id'), primary_key=True, info={ 'colanderalchemy': { 'missing': colander.drop, 'widget': HiddenWidget() } }) ordering = Column(Integer, nullable=False, info={ 'colanderalchemy': { 'title': _('Order'), 'widget': HiddenWidget() } }) public = Column(Boolean, default=True, nullable=False, info={'colanderalchemy': { 'title': _('Public') }}) icon = Column(Unicode, info={'colanderalchemy': {'title': _('Icon')}}) # functionality functionalities = relationship('Functionality', secondary=theme_functionality, cascade='save-update,merge,refresh-expire', info={ 'colanderalchemy': { 'exclude': True, 'title': _('Functionalities') } }) # restricted to role restricted_roles = relationship( 'Role', secondary=restricted_role_theme, cascade='save-update,merge,refresh-expire', info={'colanderalchemy': { 'exclude': True, 'title': _('Roles') }}) def __init__(self, name: str = '', ordering: int = 100, icon: str = '') -> None: TreeGroup.__init__(self, name=name) self.ordering = ordering self.icon = icon
class LayerWMTS(DimensionLayer): __tablename__ = 'layer_wmts' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('WMTS Layer'), 'plural': _('WMTS Layers') } __c2cgeoform_config__ = { 'duplicate': True } __mapper_args__ = {'polymorphic_identity': 'l_wmts'} id = Column(Integer, ForeignKey(_schema + '.layer.id'), primary_key=True, info={ 'colanderalchemy': { 'missing': None, 'widget': HiddenWidget() }}) url = Column(Unicode, nullable=False, info={ 'colanderalchemy': { 'title': _('GetCapabilities URL'), 'column': 2 }}) layer = Column(Unicode, nullable=False, info={ 'colanderalchemy': { 'title': _('WMTS layer name'), 'column': 2 }}) style = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Style'), 'column': 2 }}) matrix_set = Column(Unicode, info={ 'colanderalchemy': { 'title': _('Matrix set'), 'column': 2 }}) image_type = Column( Enum( 'image/jpeg', 'image/png', native_enum=False ), nullable=False, info={ 'colanderalchemy': { 'title': _('Image type'), 'column': 2, 'widget': SelectWidget(values=( ('image/jpeg', 'image/jpeg'), ('image/png', 'image/png'))) }}) def __init__(self, name: str='', public: bool=True, image_type: str='image/png') -> None: DimensionLayer.__init__(self, name=name, public=public) self.image_type = image_type @staticmethod def get_default(dbsession: Session) -> DimensionLayer: return dbsession.query(LayerWMTS).filter(LayerWMTS.name == 'wmts-defaults').one_or_none()
class Functionality(Base): __tablename__ = "functionality" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("Functionality"), "plural": _("Functionalities") } __c2cgeoform_config__ = {"duplicate": True} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, nullable=False, info={"colanderalchemy": { "title": _("Name") }}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) value = Column(Unicode, nullable=False, info={"colanderalchemy": { "title": _("Value") }}) def __init__(self, name: str = "", value: str = "", description: str = "") -> None: self.name = name self.value = value self.description = description def __str__(self) -> str: return "{} - {}".format(self.name or "", self.value or "") # pragma: no cover
class OAuth2Client(Base): # type: ignore """The oauth2_client table representation.""" __tablename__ = "oauth2_client" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("OAuth2 Client"), "plural": _("OAuth2 Clients") } __c2cgeoform_config__ = {"duplicate": True} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) client_id = Column( Unicode, unique=True, info={ "colanderalchemy": { "title": _("Client ID"), "description": _("The client identifier as e.-g. 'qgis'."), } }, ) secret = Column( Unicode, info={ "colanderalchemy": { "title": _("Secret"), "description": _("The secret."), } }, ) redirect_uri = Column( Unicode, info={ "colanderalchemy": { "title": _("Redirect URI"), "description": _(""" URI where user should be redirected after authentication as e.-g. 'http://127.0.0.1:7070/' in case of QGIS desktop. """), } }, )
class User(Base): __tablename__ = "user" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = {"title": _("User"), "plural": _("Users")} __c2cgeoform_config__ = {"duplicate": True} item_type = Column("type", String(10), nullable=False, info={"colanderalchemy": { "widget": HiddenWidget() }}) __mapper_args__ = { "polymorphic_on": item_type, "polymorphic_identity": "user" } id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) username = Column(Unicode, unique=True, nullable=False, info={"colanderalchemy": { "title": _("Username") }}) _password = Column("password", Unicode, nullable=False, info={"colanderalchemy": { "exclude": True }}) temp_password = Column("temp_password", Unicode, nullable=True, info={"colanderalchemy": { "exclude": True }}) tech_data = Column(MutableDict.as_mutable(HSTORE), info={"colanderalchemy": { "exclude": True }}) email = Column( Unicode, nullable=False, info={"colanderalchemy": { "title": _("Email"), "validator": Email() }}) is_password_changed = Column(Boolean, default=False, info={ "colanderalchemy": { "title": _("The user changed his password") } }) settings_role_id = Column( Integer, info={ "colanderalchemy": { "title": _("Settings from role"), "description": "Only used for settings not for permissions", "widget": RelationSelect2Widget(Role, "id", "name", order_by="name", default_value=("", _("- Select -"))), } }, ) settings_role = relationship( Role, foreign_keys="User.settings_role_id", primaryjoin="Role.id==User.settings_role_id", info={ "colanderalchemy": { "title": _("Settings role"), "exclude": True } }, ) roles = relationship( Role, secondary=user_role, secondaryjoin=Role.id == user_role.c.role_id, backref=backref("users", order_by="User.username", info={"colanderalchemy": { "exclude": True }}), info={"colanderalchemy": { "title": _("Roles"), "exclude": True }}, ) last_login = Column( DateTime(timezone=True), info={ "colanderalchemy": { "title": _("Last login"), "missing": drop, "widget": DateTimeInputWidget(readonly=True), } }, ) expire_on = Column( DateTime(timezone=True), info={"colanderalchemy": { "title": _("Expiration date") }}) deactivated = Column(Boolean, default=False, info={"colanderalchemy": { "title": _("Deactivated") }}) def __init__( self, username: str = "", password: str = "", email: str = "", is_password_changed: bool = False, settings_role: Role = None, roles: List[Role] = None, expire_on: datetime = None, deactivated: bool = False, ) -> None: self.username = username self.password = password self.tech_data = {} self.email = email self.is_password_changed = is_password_changed if settings_role: self.settings_role = settings_role self.roles = roles or [] self.expire_on = expire_on self.deactivated = deactivated @property def password(self) -> str: """returns password""" return self._password # type: ignore @password.setter def password(self, password: str) -> None: """encrypts password on the fly.""" self._password = self.__encrypt_password(password) def set_temp_password(self, password: str) -> None: """encrypts password on the fly.""" self.temp_password = self.__encrypt_password(password) @staticmethod def __encrypt_password_legacy(password: str) -> str: """Hash the given password with SHA1.""" return sha1(password.encode("utf8")).hexdigest() # nosec @staticmethod def __encrypt_password(password: str) -> str: return crypt.crypt(password, crypt.METHOD_SHA512) def validate_password(self, passwd: str) -> bool: """Check the password against existing credentials. this method _MUST_ return a boolean. @param passwd: 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 (possibly) encrypted one in the database. """ if self._password.startswith("$"): # new encryption method if compare_hash(self._password, crypt.crypt(passwd, self._password)): return True else: # legacy encryption method if compare_hash(self._password, self.__encrypt_password_legacy(passwd)): # convert to the new encryption method self._password = self.__encrypt_password(passwd) return True if (self.temp_password is not None and self.temp_password != "" and compare_hash(self.temp_password, crypt.crypt(passwd, self.temp_password))): self._password = self.temp_password self.temp_password = None self.is_password_changed = False return True return False def expired(self) -> bool: return self.expire_on is not None and self.expire_on < datetime.now( pytz.utc) def update_last_login(self) -> None: self.last_login = datetime.now(pytz.utc) def __str__(self) -> str: return self.username or ""
class LayerWMS(DimensionLayer): __tablename__ = "layer_wms" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("WMS Layer"), "plural": _("WMS Layers") } __c2cgeoform_config__ = {"duplicate": True} __mapper_args__ = {"polymorphic_identity": "l_wms"} id = Column( Integer, ForeignKey(_schema + ".layer.id", ondelete="CASCADE"), primary_key=True, info={"colanderalchemy": { "missing": None, "widget": HiddenWidget() }}, ) ogc_server_id = Column( Integer, ForeignKey(_schema + ".ogc_server.id"), nullable=False, info={ "colanderalchemy": { "title": _("OGC server"), "column": 2, "widget": RelationSelect2Widget(OGCServer, "id", "name", order_by="name", default_value=("", _("- Select -"))), } }, ) layer = Column( Unicode, nullable=False, info={"colanderalchemy": { "title": _("WMS layer name"), "column": 2 }}) style = Column( Unicode, info={"colanderalchemy": { "title": _("Style"), "column": 2 }}) valid = Column( Boolean, info={ "colanderalchemy": { "title": _("Valid"), "column": 2, "widget": CheckboxWidget(readonly=True) } }, ) invalid_reason = Column( Unicode, info={ "colanderalchemy": { "title": _("Reason why I am not valid"), "column": 2, "widget": TextInputWidget(readonly=True), } }, ) time_mode = Column( Enum("disabled", "value", "range", native_enum=False), default="disabled", nullable=False, info={ "colanderalchemy": { "title": _("Time mode"), "column": 2, "widget": SelectWidget(values=(("disabled", _("Disabled")), ("value", _("Value")), ("range", _("Range")))), } }, ) time_widget = Column( Enum("slider", "datepicker", native_enum=False), default="slider", nullable=False, info={ "colanderalchemy": { "title": _("Time widget"), "column": 2, "widget": SelectWidget(values=(("slider", _("Slider")), ("datepicker", _("Datepicker")))), } }, ) # relationship with OGCServer ogc_server = relationship( "OGCServer", info={"colanderalchemy": { "title": _("OGC server"), "exclude": True }}) def __init__( self, name: str = "", layer: str = "", public: bool = True, time_mode: str = "disabled", time_widget: str = "slider", ) -> None: DimensionLayer.__init__(self, name=name, public=public) self.layer = layer self.time_mode = time_mode self.time_widget = time_widget @staticmethod def get_default(dbsession: Session) -> Optional[DimensionLayer]: return cast( Optional[DimensionLayer], dbsession.query(LayerWMS).filter( LayerWMS.name == "wms-defaults").one_or_none(), )
class LayerWMTS(DimensionLayer): __tablename__ = "layer_wmts" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("WMTS Layer"), "plural": _("WMTS Layers") } __c2cgeoform_config__ = {"duplicate": True} __mapper_args__ = {"polymorphic_identity": "l_wmts"} id = Column( Integer, ForeignKey(_schema + ".layer.id"), primary_key=True, info={"colanderalchemy": { "missing": None, "widget": HiddenWidget() }}, ) url = Column(Unicode, nullable=False, info={ "colanderalchemy": { "title": _("GetCapabilities URL"), "column": 2 } }) layer = Column( Unicode, nullable=False, info={"colanderalchemy": { "title": _("WMTS layer name"), "column": 2 }}) style = Column( Unicode, info={"colanderalchemy": { "title": _("Style"), "column": 2 }}) matrix_set = Column( Unicode, info={"colanderalchemy": { "title": _("Matrix set"), "column": 2 }}) image_type = Column( Enum("image/jpeg", "image/png", native_enum=False), nullable=False, info={ "colanderalchemy": { "title": _("Image type"), "column": 2, "widget": SelectWidget(values=(("image/jpeg", "image/jpeg"), ("image/png", "image/png"))), } }, ) def __init__(self, name: str = "", public: bool = True, image_type: str = "image/png") -> None: DimensionLayer.__init__(self, name=name, public=public) self.image_type = image_type @staticmethod def get_default(dbsession: Session) -> Optional[DimensionLayer]: return cast( Optional[DimensionLayer], dbsession.query(LayerWMTS).filter( LayerWMTS.name == "wmts-defaults").one_or_none(), )
class Role(Base): __tablename__ = 'role' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = {'title': _('Role'), 'plural': _('Roles')} __c2cgeoform_config__ = {'duplicate': True} id = Column(Integer, primary_key=True, info={'colanderalchemy': { 'widget': HiddenWidget() }}) name = Column(Unicode, unique=True, nullable=False, info={'colanderalchemy': { 'title': _('Name') }}) description = Column(Unicode, info={'colanderalchemy': { 'title': _('Description') }}) extent = Column(Geometry('POLYGON', srid=_srid), info={ 'colanderalchemy': { 'typ': colander_ext.Geometry('POLYGON', srid=_srid, map_srid=3857) } }) # functionality functionalities = relationship('Functionality', secondary=role_functionality, cascade='save-update,merge,refresh-expire', info={ 'colanderalchemy': { 'exclude': True, 'title': _('Functionalities') } }) def __init__(self, name: str = '', description: str = '', functionalities: List[Functionality] = None, extent: Geometry = None) -> None: if functionalities is None: functionalities = [] self.name = name self.functionalities = functionalities self.extent = extent self.description = description def __unicode__(self) -> str: return self.name or '' # pragma: no cover @property def bounds(self) -> None: if self.extent is None: return None return to_shape(self.extent).bounds
class OGCServer(Base): __tablename__ = "ogc_server" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("OGC Server"), "plural": _("OGC Servers") } __c2cgeoform_config__ = {"duplicate": True} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, nullable=False, unique=True, info={"colanderalchemy": { "title": _("Name") }}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) url = Column(Unicode, nullable=False, info={"colanderalchemy": { "title": _("Basic URL") }}) url_wfs = Column(Unicode, info={"colanderalchemy": { "title": _("WFS URL") }}) type = Column( Enum( OGCSERVER_TYPE_MAPSERVER, OGCSERVER_TYPE_QGISSERVER, OGCSERVER_TYPE_GEOSERVER, OGCSERVER_TYPE_ARCGIS, OGCSERVER_TYPE_OTHER, native_enum=False, ), nullable=False, info={ "colanderalchemy": { "title": _("Server type"), "widget": SelectWidget(values=( (OGCSERVER_TYPE_MAPSERVER, OGCSERVER_TYPE_MAPSERVER), (OGCSERVER_TYPE_QGISSERVER, OGCSERVER_TYPE_QGISSERVER), (OGCSERVER_TYPE_GEOSERVER, OGCSERVER_TYPE_GEOSERVER), (OGCSERVER_TYPE_ARCGIS, OGCSERVER_TYPE_ARCGIS), (OGCSERVER_TYPE_OTHER, OGCSERVER_TYPE_OTHER), )), } }, ) image_type = Column( Enum("image/jpeg", "image/png", native_enum=False), nullable=False, info={ "colanderalchemy": { "title": _("Image type"), "widget": SelectWidget(values=(("image/jpeg", "image/jpeg"), ("image/png", "image/png"))), "column": 2, } }, ) auth = Column( Enum( OGCSERVER_AUTH_NOAUTH, OGCSERVER_AUTH_STANDARD, OGCSERVER_AUTH_GEOSERVER, OGCSERVER_AUTH_PROXY, native_enum=False, ), nullable=False, info={ "colanderalchemy": { "title": _("Authentication type"), "widget": SelectWidget(values=( (OGCSERVER_AUTH_NOAUTH, OGCSERVER_AUTH_NOAUTH), (OGCSERVER_AUTH_STANDARD, OGCSERVER_AUTH_STANDARD), (OGCSERVER_AUTH_GEOSERVER, OGCSERVER_AUTH_GEOSERVER), (OGCSERVER_AUTH_PROXY, OGCSERVER_AUTH_PROXY), )), "column": 2, } }, ) wfs_support = Column( Boolean, info={"colanderalchemy": { "title": _("WFS support"), "column": 2 }}) is_single_tile = Column( Boolean, info={"colanderalchemy": { "title": _("Single tile"), "column": 2 }}) def __init__( self, name: str = "", description: Optional[str] = None, url: str = "https://wms.example.com", url_wfs: str = None, type_: str = "mapserver", image_type: str = "image/png", auth: str = "Standard auth", wfs_support: bool = True, is_single_tile: bool = False, ) -> None: self.name = name self.description = description self.url = url self.url_wfs = url_wfs self.type = type_ self.image_type = image_type self.auth = auth self.wfs_support = wfs_support self.is_single_tile = is_single_tile def __str__(self) -> str: return self.name or "" def url_description(self, request: pyramid.request.Request) -> str: errors: Set[str] = set() url = get_url2(self.name, self.url, request, errors) return url.url() if url else "\n".join(errors) def url_wfs_description(self, request: pyramid.request.Request) -> Optional[str]: if not self.url_wfs: return self.url_description(request) errors: Set[str] = set() url = get_url2(self.name, self.url_wfs, request, errors) return url.url() if url else "\n".join(errors)
class LayergroupTreeitem(Base): __tablename__ = 'layergroup_treeitem' __table_args__ = {'schema': _schema} # required by formalchemy id = Column(Integer, primary_key=True, info={'colanderalchemy': { 'widget': HiddenWidget() }}) description = Column(Unicode, info={'colanderalchemy': {'exclude': True}}) treegroup_id = Column(Integer, ForeignKey(_schema + '.treegroup.id'), info={'colanderalchemy': { 'exclude': True }}) treegroup = relationship( 'TreeGroup', backref=backref( 'children_relation', order_by='LayergroupTreeitem.ordering', cascade='save-update,merge,delete,delete-orphan,expunge', info={ 'colanderalchemy': { 'title': _('Children'), 'exclude': True }, }), primaryjoin='LayergroupTreeitem.treegroup_id==TreeGroup.id', info={ 'colanderalchemy': { 'exclude': True }, 'c2cgeoform': { 'duplicate': False } }) treeitem_id = Column(Integer, ForeignKey(_schema + '.treeitem.id'), info={'colanderalchemy': { 'widget': HiddenWidget() }}) treeitem = relationship( 'TreeItem', backref=backref('parents_relation', cascade='save-update,merge,delete,delete-orphan', info={ 'colanderalchemy': { 'title': _('Parents'), 'exclude': True }, 'c2cgeoform': { 'duplicate': False } }), primaryjoin='LayergroupTreeitem.treeitem_id==TreeItem.id', info={ 'colanderalchemy': { 'exclude': True }, 'c2cgeoform': { 'duplicate': False } }) ordering = Column(Integer, info={'colanderalchemy': { 'widget': HiddenWidget() }}) def __init__(self, group: 'TreeGroup' = None, item: TreeItem = None, ordering: int = 0) -> None: self.treegroup = group self.treeitem = item self.ordering = ordering
class Theme(TreeGroup): __tablename__ = "theme" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = {"title": _("Theme"), "plural": _("Themes")} __mapper_args__ = {"polymorphic_identity": "theme"} __c2cgeoform_config__ = {"duplicate": True} id = Column( Integer, ForeignKey(_schema + ".treegroup.id"), primary_key=True, info={"colanderalchemy": { "missing": drop, "widget": HiddenWidget() }}, ) ordering = Column(Integer, nullable=False, info={ "colanderalchemy": { "title": _("Order"), "widget": HiddenWidget() } }) public = Column(Boolean, default=True, nullable=False, info={"colanderalchemy": { "title": _("Public") }}) icon = Column(Unicode, info={"colanderalchemy": {"title": _("Icon")}}) # functionality functionalities = relationship( "Functionality", secondary=theme_functionality, cascade="save-update,merge,refresh-expire", info={ "colanderalchemy": { "exclude": True, "title": _("Functionalities") } }, ) # restricted to role restricted_roles = relationship( "Role", secondary=restricted_role_theme, cascade="save-update,merge,refresh-expire", info={"colanderalchemy": { "exclude": True, "title": _("Roles") }}, ) def __init__(self, name: str = "", ordering: int = 100, icon: str = "") -> None: TreeGroup.__init__(self, name=name) self.ordering = ordering self.icon = icon
class OGCServer(Base): __tablename__ = 'ogc_server' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('OGC Server'), 'plural': _('OGC Servers') } __c2cgeoform_config__ = {'duplicate': True} id = Column(Integer, primary_key=True, info={'colanderalchemy': { 'widget': HiddenWidget() }}) name = Column(Unicode, info={'colanderalchemy': {'title': _('Name')}}) description = Column(Unicode, info={'colanderalchemy': { 'title': _('Description') }}) url = Column(Unicode, nullable=False, info={'colanderalchemy': { 'title': _('Basic URL') }}) url_wfs = Column(Unicode, info={'colanderalchemy': { 'title': _('WFS URL') }}) type = Column(Enum(OGCSERVER_TYPE_MAPSERVER, OGCSERVER_TYPE_QGISSERVER, OGCSERVER_TYPE_GEOSERVER, OGCSERVER_TYPE_ARCGIS, OGCSERVER_TYPE_OTHER, native_enum=False), nullable=False, info={ 'colanderalchemy': { 'title': _('Server type'), 'widget': SelectWidget(values=((OGCSERVER_TYPE_MAPSERVER, OGCSERVER_TYPE_MAPSERVER), (OGCSERVER_TYPE_QGISSERVER, OGCSERVER_TYPE_QGISSERVER), (OGCSERVER_TYPE_GEOSERVER, OGCSERVER_TYPE_GEOSERVER), (OGCSERVER_TYPE_ARCGIS, OGCSERVER_TYPE_ARCGIS), (OGCSERVER_TYPE_OTHER, OGCSERVER_TYPE_OTHER))) } }) image_type = Column(Enum('image/jpeg', 'image/png', native_enum=False), nullable=False, info={ 'colanderalchemy': { 'title': _('Image type'), 'widget': SelectWidget(values=(('image/jpeg', 'image/jpeg'), ('image/png', 'image/png'))), 'column': 2 } }) auth = Column(Enum(OGCSERVER_AUTH_NOAUTH, OGCSERVER_AUTH_STANDARD, OGCSERVER_AUTH_GEOSERVER, OGCSERVER_AUTH_PROXY, native_enum=False), nullable=False, info={ 'colanderalchemy': { 'title': _('Authentication type'), 'widget': SelectWidget(values=((OGCSERVER_AUTH_NOAUTH, OGCSERVER_AUTH_NOAUTH), (OGCSERVER_AUTH_STANDARD, OGCSERVER_AUTH_STANDARD), (OGCSERVER_AUTH_GEOSERVER, OGCSERVER_AUTH_GEOSERVER), (OGCSERVER_AUTH_PROXY, OGCSERVER_AUTH_PROXY))), 'column': 2 } }) wfs_support = Column( Boolean, info={'colanderalchemy': { 'title': _('WFS support'), 'column': 2 }}) is_single_tile = Column( Boolean, info={'colanderalchemy': { 'title': _('Single tile'), 'column': 2 }}) def __init__(self, name: str = '', description: Optional[str] = None, url: str = 'https://wms.example.com', url_wfs: str = None, type_: str = 'mapserver', image_type: str = 'image/png', auth: str = 'Standard auth', wfs_support: bool = True, is_single_tile: bool = False) -> None: self.name = name self.description = description self.url = url self.url_wfs = url_wfs self.type = type_ self.image_type = image_type self.auth = auth self.wfs_support = wfs_support self.is_single_tile = is_single_tile def __unicode__(self) -> str: return self.name or '' # pragma: no cover
class LayergroupTreeitem(Base): __tablename__ = "layergroup_treeitem" __table_args__ = {"schema": _schema} # required by formalchemy id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) description = Column(Unicode, info={"colanderalchemy": {"exclude": True}}) treegroup_id = Column( Integer, ForeignKey(_schema + ".treegroup.id"), nullable=False, info={"colanderalchemy": { "exclude": True }}, ) treegroup = relationship( "TreeGroup", backref=backref( "children_relation", order_by="LayergroupTreeitem.ordering", cascade="save-update,merge,delete,delete-orphan,expunge", info={ "colanderalchemy": { "title": _("Children"), "exclude": True } }, ), primaryjoin="LayergroupTreeitem.treegroup_id==TreeGroup.id", info={ "colanderalchemy": { "exclude": True }, "c2cgeoform": { "duplicate": False } }, ) treeitem_id = Column( Integer, ForeignKey(_schema + ".treeitem.id"), nullable=False, info={"colanderalchemy": { "widget": HiddenWidget() }}, ) treeitem = relationship( "TreeItem", backref=backref( "parents_relation", cascade="save-update,merge,delete,delete-orphan", info={ "colanderalchemy": { "title": _("Parents"), "exclude": True }, "c2cgeoform": { "duplicate": False }, }, ), primaryjoin="LayergroupTreeitem.treeitem_id==TreeItem.id", info={ "colanderalchemy": { "exclude": True }, "c2cgeoform": { "duplicate": False } }, ) ordering = Column(Integer, info={"colanderalchemy": { "widget": HiddenWidget() }}) def __init__(self, group: "TreeGroup" = None, item: TreeItem = None, ordering: int = 0) -> None: self.treegroup = group self.treeitem = item self.ordering = ordering
class Dimension(Base): __tablename__ = "dimension" __table_args__ = {"schema": _schema} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, info={"colanderalchemy": {"title": _("Name")}}) value = Column(Unicode, info={"colanderalchemy": {"title": _("Value")}}) field = Column(Unicode, info={"colanderalchemy": {"title": _("Field")}}) description = Column(Unicode, info={ "colanderalchemy": { "title": _("Description"), "widget": TextAreaWidget() } }) layer_id = Column( "layer_id", Integer, ForeignKey(_schema + ".layer.id"), nullable=False, info={ "colanderalchemy": { "exclude": True }, "c2cgeoform": { "duplicate": False } }, ) layer = relationship( "DimensionLayer", info={ "c2cgeoform": { "duplicate": False }, "colanderalchemy": { "exclude": True } }, backref=backref( "dimensions", cascade="save-update,merge,delete,delete-orphan,expunge", info={ "colanderalchemy": { "title": _("Dimensions"), "exclude": True } }, ), ) def __init__(self, name: str = "", value: str = "", layer: str = None, field: str = None, description: str = None) -> None: self.name = name self.value = value self.field = field if layer is not None: self.layer = layer self.description = description def __str__(self) -> str: return self.name or ""
class Role(Base): __tablename__ = "role" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = {"title": _("Role"), "plural": _("Roles")} __c2cgeoform_config__ = {"duplicate": True} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, unique=True, nullable=False, info={"colanderalchemy": { "title": _("Name") }}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) extent = Column( Geometry("POLYGON", srid=_srid), info={ "colanderalchemy": { "typ": ColanderGeometry("POLYGON", srid=_srid, map_srid=_admin_config["map_srid"]), "widget": MapWidget(map_options=_map_config), } }, ) # functionality functionalities = relationship( "Functionality", secondary=role_functionality, cascade="save-update,merge,refresh-expire", info={ "colanderalchemy": { "exclude": True, "title": _("Functionalities") } }, ) def __init__( self, name: str = "", description: str = "", functionalities: List[Functionality] = None, extent: Geometry = None, ) -> None: if functionalities is None: functionalities = [] self.name = name self.functionalities = functionalities self.extent = extent self.description = description def __str__(self) -> str: return self.name or "" @property def bounds(self) -> Optional[Tuple[float, float, float, float]]: # TODO if self.extent is None: return None return cast(Tuple[float, float, float, float], to_shape(self.extent).bounds)
class Metadata(Base): __tablename__ = "metadata" __table_args__ = {"schema": _schema} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, info={"colanderalchemy": {"title": _("Name")}}) value = Column(Unicode, info={"colanderalchemy": {"exclude": True}}) description = Column(Unicode, info={ "colanderalchemy": { "title": _("Description"), "widget": TextAreaWidget() } }) item_id = Column( "item_id", Integer, ForeignKey(_schema + ".treeitem.id"), nullable=False, info={ "colanderalchemy": { "exclude": True }, "c2cgeoform": { "duplicate": False } }, ) item = relationship( "TreeItem", info={ "c2cgeoform": { "duplicate": False }, "colanderalchemy": { "exclude": True } }, backref=backref( "metadatas", cascade="save-update,merge,delete,delete-orphan,expunge", order_by="Metadata.name", info={ "colanderalchemy": { "title": _("Metadatas"), "exclude": True } }, ), ) def __init__(self, name: str = "", value: str = "", description: str = None) -> None: self.name = name self.value = value self.description = description def __str__(self) -> str: return "{}: {}".format(self.name or "", self.value or "")
class Interface(Base): __tablename__ = "interface" __table_args__ = {"schema": _schema} __c2cgeoform_config__ = {"duplicate": True} __colanderalchemy_config__ = { "title": _("Interface"), "plural": _("Interfaces") } id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, info={"colanderalchemy": {"title": _("Name")}}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) # relationship with Layer and Theme layers = relationship( "Layer", secondary=interface_layer, cascade="save-update,merge,refresh-expire", info={ "colanderalchemy": { "title": _("Layers"), "exclude": True }, "c2cgeoform": { "duplicate": False } }, backref=backref("interfaces", info={ "colanderalchemy": { "title": _("Interfaces"), "exclude": True } }), ) theme = relationship( "Theme", secondary=interface_theme, cascade="save-update,merge,refresh-expire", info={ "colanderalchemy": { "title": _("Themes"), "exclude": True }, "c2cgeoform": { "duplicate": False } }, backref=backref("interfaces", info={ "colanderalchemy": { "title": _("Interfaces"), "exclude": True } }), ) def __init__(self, name: str = "", description: str = "") -> None: self.name = name self.description = description def __str__(self) -> str: return self.name or ""
class RestrictionArea(Base): __tablename__ = "restrictionarea" __table_args__ = {"schema": _schema} __colanderalchemy_config__ = { "title": _("Restriction area"), "plural": _("Restriction areas") } __c2cgeoform_config__ = {"duplicate": True} id = Column(Integer, primary_key=True, info={"colanderalchemy": { "widget": HiddenWidget() }}) name = Column(Unicode, info={"colanderalchemy": {"title": _("Name")}}) description = Column(Unicode, info={"colanderalchemy": { "title": _("Description") }}) readwrite = Column(Boolean, default=False, info={"colanderalchemy": { "title": _("Read/write") }}) area = Column( Geometry("POLYGON", srid=_srid), info={ "colanderalchemy": { "typ": ColanderGeometry("POLYGON", srid=_srid, map_srid=_map_config["srid"]), "widget": MapWidget(map_options=_map_config), } }, ) # relationship with Role and Layer roles = relationship( "Role", secondary=role_ra, info={"colanderalchemy": { "title": _("Roles"), "exclude": True }}, cascade="save-update,merge,refresh-expire", backref=backref("restrictionareas", info={ "colanderalchemy": { "exclude": True, "title": _("Restriction areas") } }), ) layers = relationship( "Layer", secondary=layer_ra, order_by=Layer.name, info={"colanderalchemy": { "title": _("Layers"), "exclude": True }}, cascade="save-update,merge,refresh-expire", backref=backref("restrictionareas", info={ "colanderalchemy": { "title": _("Restriction areas"), "exclude": True } }), ) def __init__( self, name: str = "", description: str = "", layers: List[Layer] = None, roles: List[Role] = None, area: Geometry = None, readwrite: bool = False, ) -> None: if layers is None: layers = [] if roles is None: roles = [] self.name = name self.description = description self.layers = layers self.roles = roles self.area = area self.readwrite = readwrite def __str__(self) -> str: return self.name or ""
class LayerWMS(DimensionLayer): __tablename__ = 'layer_wms' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('WMS Layer'), 'plural': _('WMS Layers') } __c2cgeoform_config__ = {'duplicate': True} __mapper_args__ = {'polymorphic_identity': 'l_wms'} id = Column( Integer, ForeignKey(_schema + '.layer.id', ondelete='CASCADE'), primary_key=True, info={'colanderalchemy': { 'missing': None, 'widget': HiddenWidget() }}) ogc_server_id = Column(Integer, ForeignKey(_schema + '.ogc_server.id'), nullable=False, info={ 'colanderalchemy': { 'title': _('OGC server'), 'column': 2, 'widget': deform_ext.RelationSelect2Widget( OGCServer, 'id', 'name', order_by='name', default_value=('', _('- Select -'))) } }) layer = Column( Unicode, nullable=False, info={'colanderalchemy': { 'title': _('WMS layer name'), 'column': 2 }}) style = Column( Unicode, info={'colanderalchemy': { 'title': _('Style'), 'column': 2 }}) time_mode = Column(Enum('disabled', 'value', 'range', native_enum=False), default='disabled', nullable=False, info={ 'colanderalchemy': { 'title': _('Time mode'), 'column': 2, 'widget': SelectWidget(values=(('disabled', _('Disabled')), ('value', _('Value')), ('range', _('Range')))) } }) time_widget = Column(Enum('slider', 'datepicker', native_enum=False), default='slider', nullable=False, info={ 'colanderalchemy': { 'title': _('Time widget'), 'column': 2, 'widget': SelectWidget(values=(('slider', _('Slider')), ('datepicker', _('Datepicker')))) } }) # relationship with OGCServer ogc_server = relationship( 'OGCServer', info={'colanderalchemy': { 'title': _('OGC server'), 'exclude': True }}) def __init__(self, name: str = '', layer: str = '', public: bool = True, time_mode: str = 'disabled', time_widget: str = 'slider') -> None: DimensionLayer.__init__(self, name=name, public=public) self.layer = layer self.time_mode = time_mode self.time_widget = time_widget @staticmethod def get_default(dbsession: Session) -> DimensionLayer: return dbsession.query(LayerWMS).filter( LayerWMS.name == 'wms-defaults').one_or_none()
class RestrictionArea(Base): __tablename__ = 'restrictionarea' __table_args__ = {'schema': _schema} __colanderalchemy_config__ = { 'title': _('Restriction area'), 'plural': _('Restriction areas') } __c2cgeoform_config__ = {'duplicate': True} id = Column(Integer, primary_key=True, info={'colanderalchemy': { 'widget': HiddenWidget() }}) area = Column(Geometry('POLYGON', srid=_srid), info={ 'colanderalchemy': { 'typ': colander_ext.Geometry('POLYGON', srid=_srid, map_srid=3857) } }) name = Column(Unicode, info={'colanderalchemy': {'title': _('Name')}}) description = Column(Unicode, info={'colanderalchemy': { 'title': _('Description') }}) readwrite = Column(Boolean, default=False, info={'colanderalchemy': { 'title': _('Read/write') }}) # relationship with Role and Layer roles = relationship( 'Role', secondary=role_ra, info={'colanderalchemy': { 'title': _('Roles'), 'exclude': True }}, cascade='save-update,merge,refresh-expire', backref=backref('restrictionareas', info={ 'colanderalchemy': { 'exclude': True, 'title': _('Restriction areas') } })) layers = relationship( 'Layer', secondary=layer_ra, info={'colanderalchemy': { 'title': _('Layers'), 'exclude': True }}, cascade='save-update,merge,refresh-expire', backref=backref('restrictionareas', info={ 'colanderalchemy': { 'title': _('Restriction areas'), 'exclude': True } })) def __init__(self, name: str = '', description: str = '', layers: List[Layer] = None, roles: List[Role] = None, area: Geometry = None, readwrite: bool = False) -> None: if layers is None: layers = [] if roles is None: roles = [] self.name = name self.description = description self.layers = layers self.roles = roles self.area = area self.readwrite = readwrite def __unicode__(self) -> str: # pragma: no cover return self.name or ''