예제 #1
0
class GenericMedia(Titled, TimeStampped, UserRelated, Tagged):
    file_id = db.Column(
        db.String(64),
        unique=True,
        nullable=False,
        index=True,
        default=lambda: token_urlsafe(NUMBYTES),
    )
    description = db.Column(db.Text,
                            nullable=True,
                            info=dict(lable=lazy_gettext("Description")))

    __depot_args__ = {"upload_storage": "media_storage"}

    @declared_attr
    def uploaded_file(cls):
        depot_args = dict(cls.__depot_args__)
        filters = depot_args.pop("filters", [])
        allowed_files = getattr(cls, "__allowed_file_types__", [])
        if allowed_files:
            filters.insert(0, FileTypeCheckFilter(filetypes=allowed_files))
        return db.Column(
            UploadedFileField(filters=filters, **depot_args),
            nullable=False,
            info=dict(label=lazy_gettext("Select a file")),
        )

    def before_insert(self, mapper, connection):
        tbl = mapper.mapped_table
        sel = db.select([tbl.c.id])
        token = token_urlsafe(14)
        while connection.scalar(
                db.func.count(sel.where(tbl.c.file_id == token))):
            token = token_urlsafe(NUMBYTES)
        filename, ext = os.path.splitext(self.uploaded_file.filename)
        self.file_id = f"{slugify(filename)}-{token}{ext}"

    @classmethod
    def get_upload_storage(cls):
        return (db.inspect(cls).get_property(
            "uploaded_file").columns[0].type._upload_storage)

    @staticmethod
    def deserialize_instance(module, model, **attrs):
        """Custom logic for constructing object from json when adding demo data."""
        with db.session.no_autoflush:
            file = open(
                os.path.join(module.root_path, "fixtures",
                             attrs["uploaded_file"]), "rb")
            attrs["uploaded_file"] = file
            obj = original_deserialize_instance(module, model, **attrs)
            file.close()
        return obj
예제 #2
0
class RichTextPage(Page):
    __contenttype__ = "richtext_page"
    __metadescription_column__ = "content"

    id = db.Column(db.Integer, db.ForeignKey("page.id"), primary_key=True)
    content = db.deferred(
        db.Column(
            db.UnicodeText,
            nullable=False,
            info=dict(
                label="Content", description="Page content", mimetype="text/html"
            ),
        )
    )
예제 #3
0
 def file_value(cls):
     kwargs = getattr(cls, "__file_field_args__", {})
     nullable = kwargs.pop("nullable", True)
     info = kwargs.pop("info", {})
     info["type"] = ((FileIntent, FileStorage), "file")
     return db.Column(UploadedFileField(**kwargs),
                      nullable=nullable,
                      info=info)
예제 #4
0
파일: models.py 프로젝트: ra2003/oy-cms
class Form(Page):
    __contenttype__ = "form"
    id = db.Column(db.Integer, db.ForeignKey("page.id"), primary_key=True)
    submit_text = db.Column(
        db.String(255),
        info=dict(
            label=lazy_gettext("Submit button text"),
            description=lazy_gettext("Text of the submit button in the form"),
        ),
    )
    submit_message = db.Column(
        db.UnicodeText,
        info=dict(
            label=lazy_gettext("After Submit Message"),
            description=lazy_gettext(
                "A Message to display for the user after submitting the form"),
        ),
    )
    fields = db.relationship(Field, backref="form")
예제 #5
0
 def uploaded_file(cls):
     depot_args = dict(cls.__depot_args__)
     filters = depot_args.pop("filters", [])
     allowed_files = getattr(cls, "__allowed_file_types__", [])
     if allowed_files:
         filters.insert(0, FileTypeCheckFilter(filetypes=allowed_files))
     return db.Column(
         UploadedFileField(filters=filters, **depot_args),
         nullable=False,
         info=dict(label=lazy_gettext("Select a file")),
     )
예제 #6
0
class Document(db.Model, GenericMedia):
    id = db.Column(db.Integer, primary_key=True)
    file = synonym("uploaded_file")

    __allowed_file_types__ = ("document",)
    __depot_args__ = {"upload_storage": "document_storage"}

    @property
    def url(self):
        if "media" in current_app.blueprints:
            return url_for("media.documents", file_id=self.file_id)
예제 #7
0
class Image(db.Model, GenericMedia):
    id = db.Column(db.Integer, primary_key=True)

    # Nicer aliases for template designers
    file = synonym("uploaded_file")
    alt = synonym("title")
    caption = synonym("description")

    # Uploaded file arguments
    __allowed_file_types__ = ("raster-image",)
    IMG_SIZES = dict(xs=(64, 64), sm=(128, 128), md=(320, 320), lg=(512, 512))
    __depot_args__ = {
        "upload_storage": "image_storage",
        "upload_type": uploaded_image(thumbnail_sizes=IMG_SIZES),
    }

    @property
    def url(self):
        if "media" in current_app.blueprints:
            return url_for("media.images", file_id=self.file_id)
예제 #8
0
class Redirect(db.Model, SQLAEvent):
    id = db.Column(db.Integer, primary_key=True)
    from_url = db.Column(
        db.String(1024),
        nullable=False,
        unique=True,
        index=True,
        info=dict(
            label=lazy_gettext("Redirect From"),
            description=lazy_gettext("Old URL to redirect from"),
        ),
    )
    to_url = db.Column(
        db.String(1024),
        info=dict(
            label=lazy_gettext("Redirect to"),
            description=lazy_gettext("Redirect to this URL"),
        ),
    )
    to_page_id = db.Column(db.Integer, db.ForeignKey(Page.id))
    permanent = db.Column(
        db.Boolean,
        default=False,
        info=dict(
            label=lazy_gettext("Permanent Redirect"),
            description=lazy_gettext("Check this to make this a permanent redirect"),
        ),
    )

    to_page = db.relationship(
        Page,
        backref="redirects",
        cascade="all",
        info=dict(
            label=lazy_gettext("Select a *Page* to Redirect to"),
            description=lazy_gettext(""),
        ),
    )

    @validates("to_url")
    def norm_tourl(self, key, to_url):
        if to_url is not None:
            return self.normalize_url(to_url)

    @validates("from_url")
    def norm_fromurl(self, key, from_url):
        return self.normalize_url(from_url)

    @property
    def url(self):
        return self.to_url or self.to_page.url

    @staticmethod
    def normalize_url(url):
        """Taken from wagtail CMS."""
        url = url.strip()
        url_parsed = urlparse(url)
        path = url_parsed[2]
        if not path.startswith("/"):
            path = "/" + path
        if path.endswith("/") and len(path) > 1:
            path = path[:-1]
        # Parameters must be sorted alphabetically
        parameters = url_parsed[3]
        parameters_components = parameters.split(";")
        parameters = ";".join(sorted(parameters_components))
        # Query string components must be sorted alphabetically
        query_string = url_parsed[4]
        query_string_components = query_string.split("&")
        query_string = "&".join(sorted(query_string_components))
        if parameters:
            path = path + ";" + parameters
        # Add query string to path
        if query_string:
            path = path + "?" + query_string
        return path

    def __repr__(self):
        return f"<Redirect from: {self.from_url}, to={self.url}, permanent: {self.permanent}>"

    def before_flush(self, session, is_modified):
        if self.to_url and any((self.to_page_id, self.to_page)):
            raise ValueError("Cannot set both URL and Page for the same redirect")
        elif not any((self.to_url, self.to_page, self.to_page_id)):
            raise ValueError("You must provide either a URL or a page to redirect to.")
예제 #9
0
파일: models.py 프로젝트: ra2003/oy-cms
class Field(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(
        db.String(255),
        nullable=False,
        info=dict(
            label=lazy_gettext("Field Name"),
            description=lazy_gettext(
                "This is the same as the column name in the resulting data. It should contain only letters, numbers, and under scors, and should not start with a number"
            ),
        ),
    )
    label = db.Column(
        db.Unicode(255),
        nullable=False,
        info=dict(
            label=lazy_gettext("Field Label"),
            description=lazy_gettext("This will be shown to the users"),
        ),
    )
    description = db.Column(
        db.Unicode(255),
        default="",
        info=dict(
            label=lazy_gettext("Field Description"),
            description=lazy_gettext("A summary about the field"),
        ),
    )
    type = db.Column(
        db.String(50),
        nullable=False,
        info=dict(
            label=lazy_gettext("Field Type"),
            description=lazy_gettext("HTML Type of the field"),
        ),
    )
    choices = db.Column(
        db.Unicode,
        info=dict(
            label=lazy_gettext("Field Choices"),
            description=lazy_gettext("If it is a select"),
        ),
    )
    default = db.Column(
        db.Unicode,
        info=dict(
            label=lazy_gettext("Default Value"),
            description=lazy_gettext("Default value to populate the field"),
        ),
    )
    required = db.Column(
        db.Boolean,
        default=False,
        info=dict(
            label=lazy_gettext("Required"),
            description=lazy_gettext("Whether this field is required or not"),
        ),
    )
    max_length = db.Column(
        db.Integer,
        default=255,
        info=dict(
            label=lazy_gettext("Maximom Length"),
            description=lazy_gettext("Max number of chars the user can enter"),
        ),
    )
    form_id = db.Column(db.Integer, db.ForeignKey("form.id"))

    @validates("type")
    def validate_field_type(self, key, ftype):
        # Bypass validation to be able to install fixtures
        if not current_app._got_first_request:
            return ftype
        if ftype not in current_app.data["available_field_types"]:
            raise ValueError("Field type is not supported.")
        return ftype
예제 #10
0
파일: models.py 프로젝트: ra2003/oy-cms
class FieldEntry(db.Model, DynamicProp):
    id = db.Column(db.Integer, primary_key=True)
    entry_id = db.Column(db.Integer, db.ForeignKey(FormEntry.id))
    entry = db.relationship("FormEntry", backref="fields")
    field_id = db.Column(db.Integer, db.ForeignKey("field.id"))
    field = db.relationship("Field", backref="entries")
예제 #11
0
파일: models.py 프로젝트: ra2003/oy-cms
class FormEntry(TimeStampped, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    form_id = db.Column(db.Integer, db.ForeignKey("form.id"))
    form = db.relationship("Form", backref="entries")