Ejemplo n.º 1
0
class Google(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    token = db.Column(db.JSON, nullable=False)
    email = db.Column(db.String(256))

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User", backref="googles")

    def __init__(self, token=None, email=None, user=None):
        self.token = token
        self.email = email

        self.user = user

    def __str__(self):
        return f"{self.email}@Google"

    def get_raw_session(self, **kwargs):
        client_id = current_app.config["GOOGLE_CLIENT_ID"]
        client_secret = current_app.config["GOOGLE_CLIENT_SECRET"]
        refresh_url = "https://oauth2.googleapis.com/token"

        refresh_kwargs = {
            "client_id": client_id,
            "client_secret": client_secret,
        }

        return OAuth2Session(client_id=client_id,
                             token=self.token,
                             token_updater=self.update_token,
                             auto_refresh_url=refresh_url,
                             auto_refresh_kwargs=refresh_kwargs,
                             **kwargs)

    def update_token(self, token):
        self.token = token
        db.session.commit()

    def get_session(self):
        return GoogleAPISession(self.get_raw_session())

    @classmethod
    def create(cls, google):
        db.session.add(google)
        db.session.commit()

    @classmethod
    def remove(cls, google):
        from life_scheduler.board.models import QuestSource
        sources = QuestSource.query.filter_by(backend_type="google",
                                              backend_id=google.id).all()
        for source in sources:
            db.session.delete(source)

        db.session.delete(google)
        db.session.commit()

    @classmethod
    def get_by_id(cls, i):
        return cls.query.get(i)
Ejemplo n.º 2
0
class ImageGraphSource(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    url = db.Column(db.UnicodeText, nullable=False)
    refresh_rate = db.Column(db.Integer)  # TODO remove
    priority = db.Column(db.Integer)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User",
                           backref=backref("image_graph_sources",
                                           lazy="dynamic"))

    def __init__(self, url=None, user=None):
        self.url = url
        self.user = user

    def set_priority(self, value):
        self.priority = value
        db.session.commit()

    @classmethod
    def get_by_id(cls, source_id):
        return cls.query.get(source_id)

    @classmethod
    def create(cls, source):
        db.session.add(source)
        db.session.commit()

    @classmethod
    def remove(cls, source):
        db.session.delete(source)
        db.session.commit()
Ejemplo n.º 3
0
class QuestOrder(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order = db.Column(db.JSON)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User",
                           backref=backref("quest_order", uselist=False))

    def __init__(self, order=None, user=None):
        self.order = order
        self.user = user

    @classmethod
    def create_or_update(cls, order_dict):
        user = order_dict["user"]
        order = order_dict["order"]

        if user.quest_order is None:
            quest_order = QuestOrder(
                user=user,
                order=order,
            )

            db.session.add(quest_order)
            db.session.commit()
        else:
            user.quest_order.order = order
            db.session.commit()
Ejemplo n.º 4
0
class TrelloTemporaryToken(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    token = db.Column(db.String(256), index=True, unique=True, nullable=False)
    secret = db.Column(db.String(256), nullable=False)
    expires = db.Column(db.DateTime, nullable=True)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User")

    def __init__(self, token=None, secret=None, user=None, expires=None):
        self.token = token
        self.secret = secret
        self.user = user
        self.expires = expires

    def get_raw_session(self, **kwargs):
        client_key = current_app.config["TRELLO_API_KEY"]
        client_secret = current_app.config["TRELLO_API_SECRET"]

        return OAuth1Session(
            client_key=client_key,
            client_secret=client_secret,
            resource_owner_key=self.token,
            resource_owner_secret=self.secret,
            **kwargs
        )

    @classmethod
    def create(cls, trello_oauth_token):
        db.session.add(trello_oauth_token)
        db.session.commit()

    @classmethod
    def get_by_token(cls, token):
        return cls.query.filter_by(token=token).first()
Ejemplo n.º 5
0
class Trello(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    token = db.Column(db.String(256), index=True, unique=True, nullable=False)
    secret = db.Column(db.String(256), nullable=False)
    username = db.Column(db.String(256))

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User", backref="trellos")

    def __init__(self, token, secret, user, username=None):
        self.token = token
        self.secret = secret
        self.user = user
        self.username = username

    def get_raw_session(self, **kwargs):
        client_key = current_app.config["TRELLO_API_KEY"]
        client_secret = current_app.config["TRELLO_API_SECRET"]

        return OAuth1Session(
            client_key=client_key,
            client_secret=client_secret,
            resource_owner_key=self.token,
            resource_owner_secret=self.secret,
            **kwargs
        )

    def get_session(self):
        return TrelloAPISession(self.get_raw_session())

    def __str__(self):
        return f"{self.username}@Trello"

    @classmethod
    def create(cls, trello):
        db.session.add(trello)
        db.session.commit()

    @classmethod
    def remove(cls, trello):
        from life_scheduler.board.models import QuestSource
        sources = QuestSource.query.filter_by(backend_type="trello", backend_id=trello.id).all()
        for source in sources:
            db.session.delete(source)

        db.session.delete(trello)
        db.session.commit()

    @classmethod
    def get_by_token(cls, token):
        return cls.query.filter_by(token=token).first()

    @classmethod
    def get_by_id(cls, i):
        return cls.query.get(i)
Ejemplo n.º 6
0
class QuestSource(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User", backref="quest_sources")

    backend_type = db.Column(db.Unicode(256))
    backend_id = db.Column(db.Integer)
    args = db.Column(db.JSON)

    label_name = db.Column(db.Unicode(128), default="")
    label_fg_color = db.Column(db.Unicode(128), default="white")
    label_bg_color = db.Column(db.Unicode(128), default="gray")

    blacklist = db.Column(db.UnicodeText)

    def __init__(
        self,
        user=None,
        backend_type=None,
        backend_id=None,
        label_name=None,
        label_fg_color=None,
        label_bg_color=None,
    ):
        self.user = user
        self.backend_type = backend_type
        self.backend_id = backend_id
        self.label_name = label_name
        self.label_fg_color = label_fg_color
        self.label_bg_color = label_bg_color

    def get_backend(self):
        if self.backend_type == "trello":
            return Trello.get_by_id(self.backend_id)
        elif self.backend_type == "google":
            return Google.get_by_id(self.backend_id)
        else:
            raise ValueError(f"Unknown backend type: {self.backend_type}")

    def get_manager(self):
        if self.backend_type == "trello":
            from life_scheduler.board.trello_quest_source_manager import TrelloQuestSourceManager
            return TrelloQuestSourceManager(self, **self.args)
        elif self.backend_type == "google":
            from life_scheduler.board.google_quest_source_manager import GoogleQuestSourceManager
            return GoogleQuestSourceManager(self, **self.args)
        else:
            raise ValueError(f"Unknown backend type: {self.backend_type}")

    @property
    def supports_scheduler(self):
        manager = self.get_manager()
        return manager.supports_scheduler

    def set_label_name(self, value):
        self.label_name = value
        db.session.commit()

    def set_label_fg_color(self, value):
        self.label_fg_color = value
        db.session.commit()

    def set_label_bg_color(self, value):
        self.label_bg_color = value
        db.session.commit()

    def set_blacklist(self, value):
        self.blacklist = value
        db.session.commit()

    def validate_quest_dict(self, quest_dict):
        if self.blacklist is not None:
            for line in self.blacklist.splitlines():
                if re.match(f"^{line}$", quest_dict["name"]):
                    return False

        return True

    def __str__(self):
        return str(self.get_manager())

    @classmethod
    def get_by_id(cls, source_id):
        return cls.query.get(source_id)

    @classmethod
    def create(cls, quest):
        db.session.add(quest)
        db.session.commit()

    @classmethod
    def remove(cls, source):
        db.session.delete(source)
        db.session.commit()

    @classmethod
    def register(cls, backend, **kwargs):
        source = cls()

        if isinstance(backend, Trello):
            source.user = backend.user
            source.backend_type = "trello"
            source.backend_id = backend.id
            source.args = kwargs
        elif isinstance(backend, Google):
            source.user = backend.user
            source.backend_type = "google"
            source.backend_id = backend.id
            source.args = kwargs
        else:
            raise ValueError(f"Unknown backend: {backend}")

        cls.create(source)
Ejemplo n.º 7
0
class Quest(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.UnicodeText, nullable=False)
    description = db.Column(db.UnicodeText)

    start_date = db.Column(db.Date)
    start_time = db.Column(db.Time)
    end_date = db.Column(db.Date)
    end_time = db.Column(db.Time)
    deadline = db.Column(db.DateTime)

    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    user = db.relationship("User", backref=backref("quests", lazy="dynamic"))

    source_id = db.Column(db.Integer,
                          db.ForeignKey("quest_source.id"),
                          nullable=False)
    source = db.relationship("QuestSource",
                             backref=backref("quests",
                                             lazy="dynamic",
                                             cascade="all, delete-orphan"))

    external_id = db.Column(db.Unicode(256), index=True)

    labels = db.Column(db.JSON)

    is_archived = db.Column(db.Boolean, default=False, index=True)
    is_done = db.Column(db.Boolean, default=False)

    extra = db.Column(db.JSON)

    def __init__(
        self,
        name=None,
        description=None,
        start_date=None,
        start_time=None,
        start_datetime=None,
        end_date=None,
        end_time=None,
        end_datetime=None,
        deadline=None,
        user=None,
        source=None,
        external_id=None,
        labels=None,
        is_archived=False,
        is_done=False,
        extra=None,
    ):
        self.name = name
        self.description = description

        if start_datetime is not None:
            self.start_datetime = start_datetime
        else:
            self.start_date = start_date
            self.start_time = start_time

        if end_datetime is not None:
            self.end_datetime = end_datetime
        else:
            self.end_date = end_date
            self.end_time = end_time

        self.deadline = deadline

        self.user = user

        self.source = source
        self.external_id = external_id

        self.labels = labels

        self.is_archived = is_archived
        self.is_done = is_done

        self.extra = extra

    def update(self, quest_dict):
        diff = {}
        for key in quest_dict:
            old_value = getattr(self, key)
            if old_value != quest_dict[key]:
                diff[key] = old_value
                setattr(self, key, quest_dict[key])

        db.session.commit()

        return diff

    def set_archived(self, value):
        manager = self.source.get_manager()
        manager.set_quest_archived(self, value)

    def set_done(self, value):
        manager = self.source.get_manager()
        manager.set_quest_done(self, value)

    @property
    def start_datetime(self):
        if self.start_time is not None:
            return datetime.combine(self.start_date, self.start_time)
        return self.start_date

    @property
    def end_datetime(self):
        if self.end_time is not None:
            return datetime.combine(self.end_date, self.end_time)
        return self.end_date

    @property
    def source_url(self):
        manager = self.source.get_manager()
        return manager.get_quest_source_url(self)

    @start_datetime.setter
    def start_datetime(self, value):
        if value is None:
            self.start_date = None
            self.start_time = None
        else:
            self.start_date = value.date()
            self.start_time = value.time()

    @end_datetime.setter
    def end_datetime(self, value):
        if value is None:
            self.start_date = None
            self.start_time = None
        else:
            self.end_date = value.date()
            self.end_time = value.time()

    @classmethod
    def create(cls, quest):
        db.session.add(quest)
        db.session.commit()

    @classmethod
    def create_or_update(cls, quest_dict):
        result = {
            "update": False,
            "invalidated": False,
            "diff": None,
            "quest": None,
        }

        source = quest_dict["source"]
        if not source.validate_quest_dict(quest_dict):
            result["invalidated"] = True

            quest_dict["is_archived"] = True

        old_quest = cls.get_by_external_id(quest_dict["external_id"],
                                           quest_dict["source"])
        if not old_quest:
            quest = Quest(**quest_dict)
            cls.create(quest)
            result["quest"] = quest
        else:
            diff = old_quest.update(quest_dict)

            result["update"] = True
            result["diff"] = diff
            result["quest"] = old_quest

        return result

    @classmethod
    def get_by_external_id(cls, external_id, source):
        return cls.query.filter_by(external_id=external_id,
                                   source=source).first()

    @classmethod
    def get_by_source(cls, source):
        return cls.query.filter_by(source=source).all()

    @classmethod
    def get_active_by_source(cls, source):
        return cls.query.filter_by(source=source).filter_by(
            is_archived=False).all()

    @classmethod
    def get_by_id(cls, quest_id):
        return cls.query.get(quest_id)
Ejemplo n.º 8
0
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True)
    name = db.Column(db.String(120))
    given_name = db.Column(db.String(120))
    family_name = db.Column(db.String(120))
    picture = db.Column(db.String(120))

    timezone = db.Column(db.String(120))

    is_approved = db.Column(db.Boolean, default=False)

    def __init__(self,
                 email=None,
                 name=None,
                 given_name=None,
                 family_name=None,
                 picture=None):
        self.email = email
        self.name = name
        self.given_name = given_name
        self.family_name = family_name
        self.picture = picture

    def set_approved(self, value):
        self.is_approved = value
        db.session.commit()

    def __repr__(self):
        return f"<User {self.email}>"

    @property
    def tz(self):
        return get_timezone(self.timezone)

    def time_from_iso_format(self, iso_string):
        t = time.fromisoformat(iso_string)
        return time.replace(t, tzinfo=self.tz)

    def datetime_from_iso_format(self, iso_string):
        dt = datetime.fromisoformat(iso_string)
        return datetime.replace(dt, tzinfo=self.tz)

    def datetime_now(self):
        return datetime.now(tz=self.tz)

    @classmethod
    def get_or_create(cls, user_dict):
        result = cls.get_by_email(user_dict["email"])

        if not result:
            user = User(**user_dict)
            db.session.add(user)
            db.session.commit()
            result = user

        return result

    @classmethod
    def get_by_email(cls, email):
        result = cls.query.filter_by(email=email).first()

        return result

    @classmethod
    def get_all(cls):
        result = cls.query.all()

        return result