Example #1
0
class DateMixin(object):

    created = db.Column(db.TIMESTAMP, default=datetime.utcnow,
                        server_default=text('CURRENT_TIMESTAMP'))

    updated = db.Column(db.TIMESTAMP, default=datetime.utcnow,
                        onupdate=datetime.utcnow)
Example #2
0
class Template(BaseModel, DateMixin):
    """ Template model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36), unique=True, nullable=False,
                     default=generate_uuid)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    label = db.Column(db.String(128), nullable=False)
    text = db.Column(db.Text, nullable=False)


    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'label': self.label,
            'text': self.text,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
Example #3
0
class Gammu(BaseModel):
    """ Gammu model """

    id = db.Column(mysql.INTEGER(10), primary_key=True)
    version = db.Column('Version',
                        mysql.INTEGER,
                        nullable=False,
                        server_default='0')
    info = db.Column('Info', mysql.TEXT)

    @classmethod
    def update_version(cls, version, library_version=None):
        """
        Updating gammu version
        :param version: {str} gammu db version
        :param library_version: {str} gammu library version
        """
        versions = cls.query.all()

        assert version is not None
        assert len(versions) <= 1, 'Gammu cannot have set multiple DB version'

        if not len(versions):
            gammu = Gammu()
            db.session.add(gammu)
        else:
            gammu = versions[0]

        gammu.version = version
        gammu.info = library_version
Example #4
0
class Deamon(BaseModel):
    """ Deamon model """

    __tablename__ = 'deamons'

    id = db.Column('ID', mysql.INTEGER(10), primary_key=True)
    start = db.Column('Start', mysql.TEXT, nullable=False)
    info = db.Column('Info', mysql.TEXT, nullable=False)
Example #5
0
class UserToken(BaseModel, DateMixin):
    """ User token model """

    token = db.Column(mysql.CHAR(64),
                      nullable=False,
                      default=generate_uuid,
                      primary_key=True)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    info = db.Column(mysql.TEXT)
    agent = db.Column(mysql.VARCHAR(128))
Example #6
0
class UserForgotPassword(BaseModel, DateMixin):
    """ User forgot passowrd model """

    __tablename__ = "user_forgotPassword"

    # TODO(vojta) replace uuid by some generated hash
    token = db.Column(mysql.CHAR(64),
                      nullable=False,
                      default=generate_uuid,
                      primary_key=True)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    expired = db.Column(db.TIMESTAMP)
Example #7
0
class Application(BaseModel, DateMixin):
    """ Application model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    uuid = db.Column(mysql.CHAR(36), unique=True, nullable=False,
                     default=generate_uuid)
    label = db.Column(db.String(32), nullable=False)
    token = db.Column(db.String(32), unique=True, nullable=False)
    prefix = db.Column(db.String(5), unique=True)
    callbackUrl = db.Column(db.String(128))
    note = db.Column(db.String(255))

    outbox = relationship("Outbox", backref='application', lazy='dynamic')
    inbox = relationship("Inbox", backref='application', lazy='dynamic')
    sent_items = relationship("SentItem", backref='application', lazy='dynamic')


    def __init__(self, **kwargs):
        """
        Create token on inicialization
        """
        super(Application, self).__init__(**kwargs)
        # generate token
        self.regenerate_token()


    def regenerate_token(self):
        """
        Regenerate token for API access
        """
        self.token = os.urandom(16).encode('hex')


    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'label': self.label,
            'token': self.token,
            'prefix': self.prefix,
            'callbackUrl': self.callbackUrl,
            'note': self.note,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
Example #8
0
class Tag(BaseModel, DateMixin):
    """ Tag model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    reference = db.Column(db.String(32), nullable=False)
    _label = db.Column("label", db.String(32), nullable=False)
    note = db.Column(db.String(255))

    @property
    def label(self):
        """
        Getting label
        :return: {str} label
        """
        return self._label

    @label.setter
    def label(self, value):
        """
        Setter for label which automatically set reference
        :param value: {str} label
        """
        self._label = value
        self.reference = slugify(value, to_lower=True)

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'reference': self.reference,
            'label': self.label,
            'note': self.note,
            'numberOfContacts': len(self.contacts), # TODO(vojta) lazy dynamic,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
class OutboxMultipart(BaseModel):
    """ Outbox multipart model """

    __tablename__ = "outbox_multipart"

    id = db.Column(mysql.INTEGER(10, unsigned=True),
                   ForeignKey('outbox.id',
                              onupdate="CASCADE",
                              ondelete="CASCADE"),
                   primary_key=True)
    sequencePosition = db.Column(mysql.INTEGER(11), primary_key=True)

    coding = db.Column(db.Enum('Default_No_Compression',
                               'Unicode_No_Compression', '8bit',
                               'Default_Compression', 'Unicode_Compression'),
                       server_default='Default_No_Compression',
                       nullable=False)
    text = db.Column(mysql.TEXT)
    textEncoded = db.Column(mysql.TEXT)
    udh = db.Column(mysql.TEXT)
    klass = db.Column('class', mysql.INTEGER, server_default='-1')

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'position': self.sequencePosition,
            'text': self.text
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
Example #10
0
class Outbox(BaseModel, DateMixin):
    """ Outbox model """

    EIGHT_BIT = '8bit'
    DEFAULT_COMPRESSION = 'Default_Compression'
    DEFAULT_NO_COMPRESSION = 'Default_No_Compression'
    UNICODE_COMPRESSION = 'Unicode_Compression'
    UNICODE_NO_COMPRESSION = 'Unicode_No_Compression'

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    applicationId = db.Column(mysql.INTEGER(10, unsigned=True),
                              ForeignKey('application.id'))

    group = db.Column(db.String(8))

    creator = db.Column(mysql.TEXT, nullable=False)
    phone = db.Column(db.String(255))

    destinationNumber = db.Column(db.String(20), nullable=False)

    coding = db.Column(db.Enum('Default_No_Compression',
                               'Unicode_No_Compression', '8bit',
                               'Default_Compression', 'Unicode_Compression'),
                       server_default='Default_No_Compression',
                       nullable=False)
    text = db.Column(mysql.TEXT, nullable=False)
    textEncoded = db.Column(mysql.TEXT)
    multipart = db.Column(db.Enum("false", "true"), server_default='false')
    udh = db.Column(mysql.TEXT)
    klass = db.Column('class', mysql.INTEGER, server_default='-1')

    deliveryReport = db.Column(db.Enum("default", "yes", "no"),
                               server_default='default')
    relativeValidity = db.Column(mysql.INTEGER, server_default='-1')

    sent = db.Column("send", db.TIMESTAMP, default=datetime.utcnow)
    sendTimeout = db.Column(db.TIMESTAMP, default=datetime.utcnow)
    sendBefore = db.Column(db.TIME, nullable=False, server_default='23:59:59')
    sendAfter = db.Column(db.TIME, nullable=False, server_default='00:00:00')

    contact = db.relationship(
        'Contact',
        primaryjoin="and_(Contact.phoneNumber==Outbox.destinationNumber,"
        "Contact.userId==Outbox.userId)",
        foreign_keys=[destinationNumber],
        uselist=False)

    multiparts = db.relationship('OutboxMultipart',
                                 primaryjoin="OutboxMultipart.id==Outbox.id",
                                 foreign_keys=[id],
                                 uselist=True)

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'destinationNumber': self.destinationNumber,
            'contact': self.contact.to_dict() if self.contact else None,
            'application': self.application.to_dict() if self.application \
                                                      else None,
            'text': self.text,
            'multiparts': [multipart.to_dict() for multipart in self.multiparts],
            'send': self.sent.isoformat(sep=' ') if self.sent else None,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}

    @classmethod
    def get_all(cls, user_id, application_id=None):
        """
        Get grouped messages
        :param user_id: {int} user identifier
        :param application_id: {int} application identifier
        :return: {list}
        """
        groups = cls.query \
                  .with_entities(
                    cls.id,
                    cls.applicationId,
                    cls.group,
                    cls.text,
                    cls.sent,
                    cls.created,
                    cls.updated,
                    func.count(cls.id)
                  ) \
                  .filter(cls.group != None) \
                  .filter(cls.userId == user_id) \
                  .filter(cls.applicationId == application_id) \
                  .order_by(cls.sent.desc()) \
                  .group_by(cls.group) \
                  .all()

        payload = []
        for identifier, appId, group, message, send, created, updated, respondents in groups:
            multiparts = OutboxMultipart.query.filter_by(id=identifier).all()
            app = Application.get_one(id=appId) if appId else None
            message = "%s%s" % (message, "".join([m.text for m in multiparts]))

            payload.append({
                'id':
                group,
                'text':
                message,
                'multiparts':
                [multipart.to_dict() for multipart in multiparts],
                'application':
                app.to_dict() if app else None,
                'countOfRespondents':
                respondents,
                'send':
                send.isoformat(sep=' ') if send else None,
                'created':
                created.isoformat(sep=' ') if created else None,
                'updated':
                updated.isoformat(sep=' ') if updated else None
            })

        return payload

    @classmethod
    def get(cls, group, user_id, application_id=None):
        """
        :param group: {str} group id
        :param user_id: {int} user identifier
        :param application_id: {int} application identifier
        :return: {list}
        """
        items = cls.query \
                 .filter(cls.group == group) \
                 .filter(cls.userId == user_id) \
                 .filter(cls.applicationId == application_id) \
                 .order_by(cls.sent.desc()) \
                 .all()
        if not items:
            return None

        app = items[0].application
        send = items[0].sent
        created = items[0].created
        updated = items[0].updated
        contacts = [i.contact.to_dict() for i in items if i.contact]
        phone_numbers = [i.destinationNumber for i in items if not i.contact]
        multiparts = OutboxMultipart.query.filter_by(id=items[0].id).all()
        message = "%s%s" % (items[0].text, "".join(
            [m.text for m in multiparts]))

        return {
            'id': group,
            'application': app.to_dict() if app else None,
            'contacts': contacts,
            'phoneNumbers': phone_numbers,
            'text': message,
            'multiparts': [multipart.to_dict() for multipart in multiparts],
            'send': send.isoformat(sep=' ') if send else None,
            'countOfRespondents': len(contacts) + len(phone_numbers),
            'created': created.isoformat(sep=' ') if created else None,
            'updated': updated.isoformat(sep=' ') if updated else None
        }

    @classmethod
    def send(cls,
             destination_number,
             message,
             user=None,
             application_id=None,
             group=None,
             send=datetime.utcnow(),
             send_timeout=None,
             contact=None,
             send_before=None,
             send_after=None,
             flash=False,
             coding=DEFAULT_NO_COMPRESSION):
        """
        Put to queue message to send
        :param destination_number: {str} phone number
        :param message: {str} body of text message
        :param user: {server.models.User} user instance
        :param application_id: {int} application identifier
        :param send: {datetime.datetime} when message should be dispatched
        :param send_timeout: {datetime.datetime} datetime for how long it should
                             be timeouted
        :param send_before: {datetime.datetime} send before
        :param send_after: {datetime.datetime} send after
        :param flash: {boolean} if message is type flash or not
        :param coding: {str} coding of text message
        """
        assert message is not None
        assert destination_number is not None
        assert type(message) == str or type(message) == unicode
        assert type(destination_number) == str or type(
            destination_number) == unicode

        # defining if message is type of flash or not, 0 flash, 1 not flash
        klass = str(int(not flash))

        # get max message length depends by coding
        udh_length = 7
        if coding == cls.DEFAULT_NO_COMPRESSION:
            max_msg_length = 160
        elif coding == cls.UNICODE_NO_COMPRESSION:
            max_msg_length = 60
        else:
            raise Exception('Not supported coding')  # TODO(vojta) better exp

        # replacing first name and last name in message
        message = message \
                    .replace('{firstName}', contact.firstName if contact else '') \
                    .replace('{lastName}', contact.lastName if contact else '')

        # get message length depends by coding
        msg_length = cls.get_message_length(message, coding)

        # if message length is greater then max length, we need to split it
        # to multiparts
        # NOTICE(vojta) inspired by Kalkun
        # https://github.com/back2arie/Kalkun/blob/master/application/models/gateway/gammu_model.php
        if msg_length > max_msg_length:
            multipart_length = max_msg_length - udh_length
            udh = "050003{hex}".format(
                hex=str(hex(randint(0, 255)).split('x')[1]).ljust(2, "0"))
            multiparts = cls.get_message_multipart(message, multipart_length)
            part = str(len(multiparts)).rjust(2, "0")

            outbox = Outbox(userId=user.id if user else None,
                            applicationId=application_id,
                            group=group,
                            coding=coding,
                            text=multiparts[0],
                            udh="{udh}{part}01".format(udh=udh, part=part),
                            klass=klass,
                            multipart="true",
                            deliveryReport="no",
                            destinationNumber=destination_number,
                            relativeValidity=-1,
                            creator=user.id if user is not None else '',
                            sent=send,
                            sendTimeout=send_timeout,
                            sendBefore=send_before,
                            sendAfter=send_after)
            # TODO(vojta) is there better way how to get ID of new inserted item ?
            db.session.add(outbox)
            db.session.commit()
            db.session.refresh(outbox)

            # add other parts of the message to database
            for index, message in enumerate(multiparts[1:]):
                position = index + 2
                multipart = OutboxMultipart(id=outbox.id,
                                            sequencePosition=position,
                                            coding=coding,
                                            text=message,
                                            klass=klass,
                                            udh="{udh}{part}{position}".format(
                                                udh=udh,
                                                part=part,
                                                position=str(position).rjust(
                                                    2, "0")))

                db.session.add(multipart)
            db.session.commit()

        else:
            # message with length lower or equal max length
            outbox = Outbox(userId=user.id if user else None,
                            applicationId=application_id,
                            group=group,
                            coding=coding,
                            text=message,
                            klass=klass,
                            deliveryReport="no",
                            destinationNumber=destination_number,
                            relativeValidity=-1,
                            sent=send,
                            creator=user.id if user is not None else '',
                            sendTimeout=send_timeout,
                            sendBefore=send_before,
                            sendAfter=send_after)
            db.session.add(outbox)
            db.session.commit()
            db.session.refresh(outbox)

        return outbox

    @classmethod
    def get_message_multipart(cls,
                              message,
                              length,
                              coding=DEFAULT_NO_COMPRESSION):
        """
        :param message: {str} message text
        :param length: {int} length of multipart message
        :param coding: {str} coding of the message
        :return: {list} list of multipart messages
        """
        multiparts = []

        if coding == cls.DEFAULT_NO_COMPRESSION:
            multiparts = [u""]
            part = 0
            char_left = length

            for char in message:
                value = 2 if is_special_char(char) else 1
                if value <= char_left:
                    multiparts[part] = u"{0}{1}".format(multiparts[part], char)
                    char_left = char_left - value
                else:
                    part = part + 1
                    multiparts.append(char)
                    char_left = length - value

        else:  # TODO(vojta) handle unicode
            pass

        return multiparts

    @classmethod
    def get_message_length(cls, message, coding=DEFAULT_NO_COMPRESSION):
        """
        :param message: {str} message text
        :param coding: {str} coding of the message
        :return: {int} length of message depends by chars type
        """
        length = 0
        if coding == cls.DEFAULT_NO_COMPRESSION:
            for char in message:
                if is_special_char(char):
                    length = length + 2
                else:
                    length = length + 1
        else:  # TODO(vojta) handle unicode
            pass

        return length
Example #11
0
class Contact(BaseModel, DateMixin):
    """ Contact model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))

    firstName = db.Column(db.String(16), nullable=False)
    lastName = db.Column(db.String(16), nullable=False)
    phoneNumber = db.Column(db.String(14))
    email = db.Column(db.String(128))
    note = db.Column(db.String(255))

    _tags = db.relationship("Tag",
                            secondary=relations.contact_on_tags,
                            backref="contacts",
                            lazy="dynamic")

    @property
    def tags(self):
        """
        Return list of the tags
        :return: {list}
        """
        return [tag.label for tag in self._tags.all()]

    @tags.setter
    def tags(self, items):
        """
        Saves list of tags
        :param items: {list} list of tags
        """
        if items is None:
            items = []

        tags = []
        for label in items:
            dummy = Tag(label=label)
            tag = Tag.get_or_create(reference=dummy.reference,
                                    userId=self.userId)
            tag.label = label
            tag.userId = self.userId
            tags.append(tag)

        self._tags = tags

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'firstName': self.firstName,
            'lastName': self.lastName,
            'phoneNumber': self.phoneNumber,
            'email': self.email,
            'note': self.note,
            'tags': self.tags,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
Example #12
0
class Inbox(BaseModel, DateMixin):
    """ Inbox model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    userId = db.Column(mysql.INTEGER(10, unsigned=True), ForeignKey('user.id'))
    applicationId = db.Column(mysql.INTEGER(10, unsigned=True),
                              ForeignKey('application.id'))
    recipient = db.Column(db.String(64))
    senderNumber = db.Column(db.String(20))
    smscNumber = db.Column(db.String(20))

    processed = db.Column(db.Boolean, server_default='0')
    coding = db.Column(db.Enum('Default_No_Compression',
                               'Unicode_No_Compression', '8bit',
                               'Default_Compression', 'Unicode_Compression'),
                       server_default='Default_No_Compression',
                       nullable=False)
    text = db.Column(mysql.TEXT, nullable=False)
    textEncoded = db.Column(mysql.TEXT, nullable=False)
    udh = db.Column(mysql.TEXT, nullable=False)
    klass = db.Column('class',
                      mysql.INTEGER,
                      nullable=False,
                      server_default='-1')

    received = db.Column(db.TIMESTAMP)

    contact = db.relationship(
        'Contact',
        primaryjoin="and_(Contact.phoneNumber==Inbox.senderNumber, "
        "Contact.userId==Inbox.userId)",
        foreign_keys=[senderNumber])

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'senderNumber': self.senderNumber,
            'processed': bool(self.processed),
            'contact': self.contact.to_dict() if self.contact else None,
            'application': self.application.to_dict() if self.application \
                                                      else None,
            'text': self.text,
            'received': self.received.isoformat(sep=' ') if self.received else None,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}

    @classmethod
    def convert_multipart_messages(cls):
        """
        Converting multipart messages to single row in table
        """
        # looking for distinct UDHs
        udhs = db.session.query(func.substr(cls.udh, 1, 10)) \
                         .filter(cls.udh.like("%01")) \
                         .filter(cls.processed==False) \
                         .all()
        udhs = [udh[0] for udh in udhs]

        # iterating over UDHs, looking for messages and merging that to single
        # one row
        for udh in udhs:
            messages = cls.query.filter(cls.udh.like("%s%%" % udh)) \
                                .filter(cls.processed==False) \
                                .order_by(cls.udh.asc()) \
                                .all()
            if not len(messages):
                break

            # creating new single message instead of multiple messages
            inbox = cls(text="".join([m.text for m in messages]),
                        textEncoded="".join([m.textEncoded for m in messages]),
                        recipient=messages[0].recipient,
                        senderNumber=messages[0].senderNumber,
                        smscNumber=messages[0].smscNumber,
                        processed=False,
                        udh="",
                        klass=messages[0].klass,
                        received=messages[0].received)
            db.session.add(inbox)

            # delete multiparts messages
            for message in messages:
                db.session.delete(message)
Example #13
0
class Phone(BaseModel, DateMixin):
    """ Phone model """

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    hostname = db.Column(db.String(64))
    imei = db.Column(db.String(35), nullable=False)
    netCode = db.Column(db.String(10))
    netName = db.Column(db.String(35))
    battery = db.Column(mysql.INTEGER)
    signal = db.Column(mysql.INTEGER)
    client = db.Column(mysql.TEXT)

    sent = db.Column(mysql.INTEGER, nullable=False, server_default='0')
    received = db.Column(mysql.INTEGER, nullable=False, server_default='0')
    send = db.Column(db.Enum("yes", "no"), default='no', nullable=False)
    receive = db.Column(db.Enum("yes", "no"), default='no', nullable=False)
    timeout = db.Column(db.TIMESTAMP)

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'hostname': self.hostname,
            'imei': self.imei,
            'netCode': self.netCode,
            'netName': self.netName,
            'battery': self.battery,
            'signal': self.signal,
            'client': self.client,
            'sent': self.sent,
            'received': self.received,
            'sendEnabled': True if self.send == 'yes' else False,
            'receiveEnabled': True if self.receive == 'yes' else False,
            'lastActivity': self.timeout.isoformat(sep=' ') if self.timeout \
                                                            else None,
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}
Example #14
0
# -*- coding: utf-8 -*-
# http://google-styleguide.googlecode.com/svn/trunk/pyguide.html

from smsgw.core import db
from sqlalchemy.dialects.mysql import INTEGER

contact_on_tags = db.Table(
    'contact_tag',
    db.Column('contactId',
              INTEGER(10, unsigned=True),
              db.ForeignKey('contact.id'),
              nullable=False,
              primary_key=True),
    db.Column('tagId',
              INTEGER(10, unsigned=True),
              db.ForeignKey('tag.id'),
              nullable=False,
              primary_key=True))
Example #15
0
class User(BaseModel, DateMixin):
    """ User model """

    ROLE_ADMIN = 'admin'
    ROLE_USER = '******'

    id = db.Column(mysql.INTEGER(10, unsigned=True), primary_key=True)
    uuid = db.Column(mysql.CHAR(36),
                     unique=True,
                     nullable=False,
                     default=generate_uuid)
    email = db.Column(db.String(128),
                      unique=True,
                      nullable=False,
                      server_default="")
    _password = db.Column('password', db.String(60), nullable=False)
    firstName = db.Column(db.String(16))
    lastName = db.Column(db.String(16))
    company = db.Column(db.String(32))
    _timeZoneCode = db.Column("timeZoneCode",
                              db.String(100),
                              default='Europe/Prague')
    role = db.Column('role',
                     db.Enum("user", "admin"),
                     default='user',
                     nullable=False)
    isActive = db.Column(db.Boolean, default=True)

    tokens = relationship("UserToken", backref='user', lazy='dynamic')
    templates = relationship("Template", backref='user', lazy='dynamic')
    contacts = relationship("Contact", backref='user', lazy='dynamic')
    tags = relationship("Tag", backref='user', lazy='dynamic')
    applications = relationship("Application", backref='user', lazy='dynamic')
    outbox = relationship("Outbox", backref='user', lazy='dynamic')
    inbox = relationship("Inbox", backref='user', lazy='dynamic')
    sent_items = relationship("SentItem", backref='user', lazy='dynamic')

    @property
    def password(self):
        """
        Get user password
        :return: {str} hash
        """
        return self._password

    @password.setter
    def password(self, password):
        """
        Set user password as bcrypt hash
        :param password: {str}
        """
        if password is not None:
            self._password = bcrypt.generate_password_hash(password, 12)

    @property
    def timeZoneCode(self):
        """
        Get user timezone code
        :return: {str} Region/Location
        """
        return self._timeZoneCode if self._timeZoneCode is not None else "UTC"

    @timeZoneCode.setter
    def timeZoneCode(self, value):
        """
        Set user timezone code
        :param value: {str} Region/Location
        :raise: {UnknownTimeZoneError} when timezone code is invalid
        """
        self._timeZoneCode = timezone(value).zone

    def compare_password(self, password):
        """
        Comparing bcrypt hash with specified password
        :param password: {str} password
        :retur: {bool}
        """
        return bcrypt.check_password_hash(self.password.encode('utf8'),
                                          password)

    def is_admin(self):
        """
        Returning if user has administration role
        """
        return (self.role == User.ROLE_ADMIN)

    @classmethod
    def is_exists_by_email(cls, email):
        """
        Checking if user with specified emails is exists
        :param email: {str} user email
        """
        return cls.query \
                .with_entities(cls.id) \
                .filter_by(email=email) \
                .first()

    def to_dict(self, properties=None):
        """
        To dictionary
        :param properties: {list} of required properties
        :return: {dict}
        """
        dict = {
            'id': self.id,
            'uuid': self.uuid,
            'email': self.email,
            'firstName': self.firstName,
            'lastName': self.lastName,
            'company': self.company,
            'role': self.role,
            'isActive': self.isActive,
            'numbers': {
                'contacts': self.contacts.count(),
                'sent': self.sent_items.count(),
                'tags': self.tags.count(),
                'outbox': self.outbox.count(),
                'inbox': self.inbox.count(),
                'templates': self.templates.count(),
                'applications': self.applications.count()
            },
            'created': self.created.isoformat(sep=' ') if self.created \
                                                       else None,
            'updated': self.updated.isoformat(sep=' ') if self.updated \
                                                       else None
        }

        if properties is None:
            properties = dict.keys()

        return {key: dict.get(key) for key in properties}