14.2.53. camcops_server.cc_modules.cc_blob

camcops_server/cc_modules/cc_blob.py


Copyright (C) 2012-2019 Rudolf Cardinal (rudolf@pobox.com).

This file is part of CamCOPS.

CamCOPS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

CamCOPS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with CamCOPS. If not, see <http://www.gnu.org/licenses/>.


BLOB (binary large object) handling.

class camcops_server.cc_modules.cc_blob.Blob(**kwargs)[source]

Class representing a binary large object (BLOB).

Has helper functions for PNG image processing.

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

classmethod get_contemporaneous_blob_by_client_info(dbsession: sqlalchemy.orm.session.Session, device_id: int, clientpk: int, era: str, referrer_added_utc: pendulum.datetime.DateTime, referrer_removed_utc: Union[pendulum.datetime.DateTime, NoneType]) → Union[_ForwardRef('Blob'), NoneType][source]

Returns a contemporaneous Blob object, or None.

Use particularly to look up BLOBs matching old task records.

classmethod get_current_blob_by_client_info(dbsession: sqlalchemy.orm.session.Session, device_id: int, clientpk: int, era: str) → Union[_ForwardRef('Blob'), NoneType][source]

Returns the current Blob object, or None.

get_data_url() → str[source]

Returns a data URL encapsulating the BLOB, or ‘’.

get_img_html() → str[source]

Returns an HTML IMG tag encoding the BLOB, or ‘’.

get_rotated_image() → Union[bytes, NoneType][source]

Returns a binary image, having rotated if necessary, or None.

get_xml_element(req: CamcopsRequest) → camcops_server.cc_modules.cc_xml.XmlElement[source]

Returns an camcops_server.cc_modules.cc_xml.XmlElement representing this BLOB.

task_ancestor() → Union[_ForwardRef('Task'), NoneType][source]

Returns the specific ancestor task of this object.

classmethod task_ancestor_class() → Union[typing.Type[_ForwardRef('Task')], NoneType][source]

Returns the class of the ancestral task.

If the descendant can descend from lots of types of task (rare; only applies to camcops_server.cc_modules.cc_blob.Blob and camcops_server.cc_modules.cc_summaryelement.ExtraSummaryTable), returns None.

class camcops_server.cc_modules.cc_blob.BlobTests(*args, echo: bool = False, database_on_disk: bool = True, **kwargs)[source]

Unit tests.

Parameters:
  • echo – Turn on SQL echo?
  • database_on_disk – Use on-disk (rather than in-memory) SQLite database? Allows dumping of contents.
camcops_server.cc_modules.cc_blob.blob_relationship(classname: str, blob_id_col_attr_name: str, read_only: bool = True) → sqlalchemy.orm.relationships.RelationshipProperty[source]

Simplifies creation of BLOB relationships. In a class definition, use like this:

class Something(Base):

    photo_blobid = CamcopsColumn(
        "photo_blobid", Integer,
        is_blob_id_field=True, blob_field_xml_name="photo_blob"
    )

    photo = blob_relationship("Something", "photo_blobid")

    # ... can't use Something directly as it's not yet been fully
    #     defined, but we want the convenience of defining this
    #     relationship here without the need to use metaclasses.
    # ... SQLAlchemy's primaryjoin uses Python-side names (class and
    #     attribute), rather than SQL-side names (table and column),
    #     at least for its fancier things:
    # http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html#relationship-primaryjoin  # noqa

Note that this refers to the CURRENT version of the BLOB. If there is
an editing chain, older BLOB versions are not retrieved.

Compare :class:`camcops_server.cc_modules.cc_task.TaskHasPatientMixin`,
which uses the same strategy, as do several other similar functions.
camcops_server.cc_modules.cc_blob.get_blob_img_html(blob: Union[camcops_server.cc_modules.cc_blob.Blob, NoneType], html_if_missing: str = '<i>(No picture)</i>') → str[source]

For the specified BLOB, get an HTML IMG tag with embedded data, or an HTML error message.