From 95250e01e5c7e648b0102c966057f916f05aa285 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Kadl=C4=8D=C3=ADk?= <frostyx@email.cz>
Date: Mon, 7 Jan 2019 23:18:34 +0100
Subject: [PATCH] [frontend] replace the private getters/setters with
 getattr/setattr

---
 frontend/coprs_frontend/coprs/models.py | 127 +++++++++++---------------------
 1 file changed, 41 insertions(+), 86 deletions(-)

diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py
index 0c5dbf0e..1a284199 100644
--- a/frontend/coprs_frontend/coprs/models.py
+++ b/frontend/coprs_frontend/coprs/models.py
@@ -26,6 +26,41 @@ gi.require_version('Modulemd', '1.0')
 from gi.repository import Modulemd
 
 
+class Private(object):
+    """
+    This is an abstract base class for all models, that separate part of their
+    data to a private table. Its purpose is to provide the private columns as
+    a part of the model and abstract the programmer from distinguishing
+    whether the particular attribute is stored as private or not.
+
+    A model need to inherit this class and set the ``private_model`` attribute.
+    """
+    private_model = None
+
+    @property
+    def private_attributes(self):
+        columns = self.private_model.__table__.columns.keys()
+        columns.remove("id")
+        return columns
+
+    def __getattr__(self, attr):
+        if attr not in self.private_attributes:
+            raise AttributeError("Can't get {} attribute".format(attr))
+        if not self.private:
+            return None
+        return getattr(self.private, attr)
+
+    def __setattr__(self, attr, value):
+        if attr in dir(self.__class__) + ["_sa_instance_state"]:
+            super(Private, self).__setattr__(attr, value)
+            return
+        if attr not in self.private_attributes:
+            raise AttributeError("Can't set {} attribute".format(attr))
+        if not self.private:
+            self.__dict__["private"] = UserPrivate()
+        setattr(self.private, attr, value)
+
+
 class CoprSearchRelatedData(object):
     def get_search_related_copr_id(self):
         raise "Not Implemented"
@@ -53,7 +88,7 @@ class UserPrivate(db.Model, helpers.Serializer):
     user = db.relationship("User", back_populates="private")
 
 
-class User(db.Model, helpers.Serializer):
+class User(db.Model, Private, helpers.Serializer):
     """
     Represents user of the copr frontend
     """
@@ -78,66 +113,7 @@ class User(db.Model, helpers.Serializer):
 
     # private info
     private = db.relationship("UserPrivate", uselist=False, back_populates="user")
-
-    @property
-    def mail(self):
-        if self.private:
-            return self.private.mail
-        return None
-
-    @property
-    def timezone(self):
-        if self.private:
-            return self.private.timezone
-        return None
-
-    @property
-    def api_login(self):
-        if self.private:
-            return self.private.api_login
-        return None
-
-    @property
-    def api_token(self):
-        if self.private:
-            return self.private.api_token
-        return None
-
-    @property
-    def api_token_expiration(self):
-        if self.private:
-            return self.private.api_token_expiration
-        return None
-
-    @mail.setter
-    def mail(self, value):
-        if not self.private:
-            self.private = UserPrivate()
-        self.private.mail = value
-
-    @timezone.setter
-    def timezone(self, value):
-        if not self.private:
-            self.private = UserPrivate()
-        self.private.timezone = value
-
-    @api_login.setter
-    def api_login(self, value):
-        if not self.private:
-            self.private = UserPrivate()
-        self.private.api_login = value
-
-    @api_token.setter
-    def api_token(self, value):
-        if not self.private:
-            self.private = UserPrivate()
-        self.private.api_token = value
-
-    @api_token_expiration.setter
-    def api_token_expiration(self, value):
-        if not self.private:
-            self.private = UserPrivate()
-        self.private.api_token_expiration = value
+    private_model = UserPrivate
 
     @property
     def name(self):
@@ -273,11 +249,13 @@ class CoprPrivate(db.Model, helpers.Serializer):
     copr = db.relationship("Copr", back_populates="private")
 
 
-class Copr(db.Model, helpers.Serializer, CoprSearchRelatedData):
+class Copr(db.Model, Private, helpers.Serializer, CoprSearchRelatedData):
     """
     Represents a single copr (personal repo with builds, mock chroots, etc.).
     """
 
+    #__tablename__ = "copr"
+
     id = db.Column(db.Integer, primary_key=True)
     # name of the copr, no fancy chars (checked by forms)
     name = db.Column(db.String(100), nullable=False)
@@ -333,36 +311,13 @@ class Copr(db.Model, helpers.Serializer, CoprSearchRelatedData):
 
     # private info
     private = db.relationship("CoprPrivate", uselist=False, back_populates="copr")
+    private_model = CoprPrivate
 
     __mapper_args__ = {
         "order_by": created_on.desc()
     }
 
     @property
-    def webhook_secret(self):
-        if self.private:
-            return self.private.webhook_secret
-        return None
-
-    @property
-    def scm_api_auth_json(self):
-        if self.private:
-            return self.private.scm_api_auth_json
-        return None
-
-    @webhook_secret.setter
-    def webhook_secret(self, value):
-        if not self.private:
-            self.private = CoprPrivate()
-        self.private.webhook_secret = value
-
-    @scm_api_auth_json.setter
-    def scm_api_auth_json(self, value):
-        if not self.private:
-            self.private = CoprPrivate()
-        self.private.scm_api_auth_json = value
-
-    @property
     def main_dir(self):
         """
         Return main copr dir for a Copr
-- 
2.13.6

