changeset 6119:91b38dc6d891

model: refactor and simplify _get_instance _get_instance is a BaseModel method, but never uses "self". Instead it takes a class argument, which indicates that it's better suited as a classmethod on said classes. Also rename to something more descriptive, remove leading underscore since it's not a private API, and refactor for readability.
author Søren Løvborg <sorenl@unity3d.com>
date Wed, 03 Aug 2016 16:07:39 +0200
parents 3d1fcf67f299
children 471e85b3e766
files kallithea/model/__init__.py kallithea/model/changeset_status.py kallithea/model/comment.py kallithea/model/db.py kallithea/model/gist.py kallithea/model/notification.py kallithea/model/pull_request.py kallithea/model/repo.py kallithea/model/repo_group.py kallithea/model/user_group.py
diffstat 10 files changed, 47 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/model/__init__.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/__init__.py	Wed Aug 03 16:07:39 2016 +0200
@@ -46,7 +46,7 @@
 
 import logging
 from kallithea.model import meta
-from kallithea.lib.utils2 import safe_str, obfuscate_url_pw
+from kallithea.lib.utils2 import obfuscate_url_pw
 
 log = logging.getLogger(__name__)
 
@@ -78,29 +78,6 @@
         else:
             self.sa = meta.Session()
 
-    def _get_instance(self, cls, instance, callback=None):
-        """
-        Gets instance of given cls using some simple lookup mechanism.
-
-        :param cls: class to fetch
-        :param instance: int or Instance
-        :param callback: callback to call if all lookups failed
-        """
-
-        if isinstance(instance, cls):
-            return instance
-        elif isinstance(instance, (int, long)) or safe_str(instance).isdigit():
-            return cls.get(instance)
-        else:
-            if instance is not None:
-                if callback is None:
-                    raise Exception(
-                        'given object must be int, long or Instance of %s '
-                        'got %s, no callback provided' % (cls, type(instance))
-                    )
-                else:
-                    return callback(instance)
-
     def _get_user(self, user):
         """
         Helper method to get user by ID, or username fallback
@@ -108,7 +85,7 @@
         :param user: UserID, username, or User instance
         """
         from kallithea.model.db import User
-        return self._get_instance(User, user,
+        return User.guess_instance(user,
                                   callback=User.get_by_username)
 
     def _get_repo(self, repository):
@@ -118,7 +95,7 @@
         :param repository: RepoID, repository name or Repository Instance
         """
         from kallithea.model.db import Repository
-        return self._get_instance(Repository, repository,
+        return Repository.guess_instance(repository,
                                   callback=Repository.get_by_repo_name)
 
     def _get_perm(self, permission):
@@ -128,5 +105,5 @@
         :param permission: PermissionID, permission_name or Permission instance
         """
         from kallithea.model.db import Permission
-        return self._get_instance(Permission, permission,
+        return Permission.guess_instance(permission,
                                   callback=Permission.get_by_key)
--- a/kallithea/model/changeset_status.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/changeset_status.py	Wed Aug 03 16:07:39 2016 +0200
@@ -50,7 +50,7 @@
         if revision:
             q = q.filter(ChangesetStatus.revision == revision)
         elif pull_request:
-            pull_request = self._get_instance(PullRequest, pull_request)
+            pull_request = PullRequest.guess_instance(pull_request)
             q = q.filter(ChangesetStatus.pull_request == pull_request)
         else:
             raise Exception('Please specify revision or pull_request')
@@ -159,7 +159,7 @@
             revisions = [revision]
         else:
             assert pull_request is not None
-            pull_request = self._get_instance(PullRequest, pull_request)
+            pull_request = PullRequest.guess_instance(pull_request)
             repo = pull_request.org_repo
             q = q.filter(ChangesetStatus.repo == repo)
             q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
--- a/kallithea/model/comment.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/comment.py	Wed Aug 03 16:07:39 2016 +0200
@@ -178,7 +178,7 @@
         if revision is not None:
             comment.revision = revision
         elif pull_request is not None:
-            pull_request = self._get_instance(PullRequest, pull_request)
+            pull_request = PullRequest.guess_instance(pull_request)
             comment.pull_request = pull_request
         else:
             raise Exception('Please specify revision or pull_request_id')
@@ -219,7 +219,7 @@
         return comment
 
     def delete(self, comment):
-        comment = self._get_instance(ChangesetComment, comment)
+        comment = ChangesetComment.guess_instance(comment)
         Session().delete(comment)
 
         return comment
@@ -264,7 +264,7 @@
             q = q.filter(ChangesetComment.revision == revision) \
                 .filter(ChangesetComment.repo_id == repo_id)
         elif pull_request is not None:
-            pull_request = self._get_instance(PullRequest, pull_request)
+            pull_request = PullRequest.guess_instance(pull_request)
             q = q.filter(ChangesetComment.pull_request == pull_request)
         else:
             raise Exception('Please specify either revision or pull_request')
--- a/kallithea/model/db.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/db.py	Wed Aug 03 16:07:39 2016 +0200
@@ -122,6 +122,32 @@
             return cls.query().get(id_)
 
     @classmethod
+    def guess_instance(cls, value, callback=None):
+        """Haphazardly attempt to convert `value` to a `cls` instance.
+
+        If `value` is None or already a `cls` instance, return it. If `value`
+        is a number (or looks like one if you squint just right), assume it's
+        a database primary key and let SQLAlchemy sort things out. Otherwise,
+        fall back to resolving it using `callback` (if specified); this could
+        e.g. be a function that looks up instances by name (though that won't
+        work if the name begins with a digit). Otherwise, raise Exception.
+        """
+
+        if value is None:
+            return None
+        if isinstance(value, cls):
+            return value
+        if isinstance(value, (int, long)) or safe_str(value).isdigit():
+            return cls.get(value)
+        if callback is not None:
+            return callback(value)
+
+        raise Exception(
+            'given object must be int, long or Instance of %s '
+            'got %s, no callback provided' % (cls, type(value))
+        )
+
+    @classmethod
     def get_or_404(cls, id_):
         try:
             id_ = int(id_)
--- a/kallithea/model/gist.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/gist.py	Wed Aug 03 16:07:39 2016 +0200
@@ -53,7 +53,7 @@
 
         :param gist: GistID, gist_access_id, or Gist instance
         """
-        return self._get_instance(Gist, gist, callback=Gist.get_by_access_id)
+        return Gist.guess_instance(gist, callback=Gist.get_by_access_id)
 
     def __delete_gist(self, gist):
         """
--- a/kallithea/model/notification.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/notification.py	Wed Aug 03 16:07:39 2016 +0200
@@ -140,7 +140,7 @@
     def delete(self, user, notification):
         # we don't want to remove actual notification just the assignment
         try:
-            notification = self._get_instance(Notification, notification)
+            notification = Notification.guess_instance(notification)
             user = self._get_user(user)
             if notification and user:
                 obj = UserNotification.query() \
@@ -178,7 +178,7 @@
 
     def mark_read(self, user, notification):
         try:
-            notification = self._get_instance(Notification, notification)
+            notification = Notification.guess_instance(notification)
             user = self._get_user(user)
             if notification and user:
                 obj = UserNotification.query() \
@@ -223,7 +223,7 @@
 
     def get_user_notification(self, user, notification):
         user = self._get_user(user)
-        notification = self._get_instance(Notification, notification)
+        notification = Notification.guess_instance(notification)
 
         return UserNotification.query() \
             .filter(UserNotification.notification == notification) \
--- a/kallithea/model/pull_request.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/pull_request.py	Wed Aug 03 16:07:39 2016 +0200
@@ -197,7 +197,7 @@
 
     def update_reviewers(self, user, pull_request, reviewers_ids):
         reviewers_ids = set(reviewers_ids)
-        pull_request = self._get_instance(PullRequest, pull_request)
+        pull_request = PullRequest.guess_instance(pull_request)
         current_reviewers = PullRequestReviewers.query() \
             .options(joinedload('user')) \
             .filter_by(pull_request=pull_request) \
@@ -220,11 +220,11 @@
                 Session().delete(prr)
 
     def delete(self, pull_request):
-        pull_request = self._get_instance(PullRequest, pull_request)
+        pull_request = PullRequest.guess_instance(pull_request)
         Session().delete(pull_request)
 
     def close_pull_request(self, pull_request):
-        pull_request = self._get_instance(PullRequest, pull_request)
+        pull_request = PullRequest.guess_instance(pull_request)
         pull_request.status = PullRequest.STATUS_CLOSED
         pull_request.updated_on = datetime.datetime.now()
         Session().add(pull_request)
--- a/kallithea/model/repo.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/repo.py	Wed Aug 03 16:07:39 2016 +0200
@@ -59,11 +59,11 @@
     URL_SEPARATOR = Repository.url_sep()
 
     def _get_user_group(self, users_group):
-        return self._get_instance(UserGroup, users_group,
+        return UserGroup.guess_instance(users_group,
                                   callback=UserGroup.get_by_group_name)
 
     def _get_repo_group(self, repo_group):
-        return self._get_instance(RepoGroup, repo_group,
+        return RepoGroup.guess_instance(repo_group,
                                   callback=RepoGroup.get_by_group_name)
 
     def _create_default_perms(self, repository, private):
--- a/kallithea/model/repo_group.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/repo_group.py	Wed Aug 03 16:07:39 2016 +0200
@@ -44,11 +44,11 @@
 class RepoGroupModel(BaseModel):
 
     def _get_user_group(self, users_group):
-        return self._get_instance(UserGroup, users_group,
+        return UserGroup.guess_instance(users_group,
                                   callback=UserGroup.get_by_group_name)
 
     def _get_repo_group(self, repo_group):
-        return self._get_instance(RepoGroup, repo_group,
+        return RepoGroup.guess_instance(repo_group,
                                   callback=RepoGroup.get_by_group_name)
 
     @LazyProperty
--- a/kallithea/model/user_group.py	Wed Aug 03 17:01:57 2016 +0200
+++ b/kallithea/model/user_group.py	Wed Aug 03 16:07:39 2016 +0200
@@ -40,7 +40,7 @@
 class UserGroupModel(BaseModel):
 
     def _get_user_group(self, user_group):
-        return self._get_instance(UserGroup, user_group,
+        return UserGroup.guess_instance(user_group,
                                   callback=UserGroup.get_by_group_name)
 
     def _create_default_perms(self, user_group):