Show More
@@ -319,6 +319,7 b' class CommentsModel(BaseModel):' | |||||
319 | repo=repo.repo_id, |
|
319 | repo=repo.repo_id, | |
320 | user=user.user_id, |
|
320 | user=user.user_id, | |
321 | )) |
|
321 | )) | |
|
322 | ||||
322 | is_draft = validated_kwargs['is_draft'] |
|
323 | is_draft = validated_kwargs['is_draft'] | |
323 |
|
324 | |||
324 | comment = ChangesetComment() |
|
325 | comment = ChangesetComment() |
This diff has been collapsed as it changes many lines, (757 lines changed) Show them Hide them | |||||
@@ -25,7 +25,6 b' import re' | |||||
25 | import os |
|
25 | import os | |
26 | import time |
|
26 | import time | |
27 | import string |
|
27 | import string | |
28 | import hashlib |
|
|||
29 | import logging |
|
28 | import logging | |
30 | import datetime |
|
29 | import datetime | |
31 | import uuid |
|
30 | import uuid | |
@@ -36,14 +35,15 b' import traceback' | |||||
36 | import collections |
|
35 | import collections | |
37 |
|
36 | |||
38 | from sqlalchemy import ( |
|
37 | from sqlalchemy import ( | |
39 | or_, and_, not_, func, cast, TypeDecorator, event, |
|
38 | or_, and_, not_, func, cast, TypeDecorator, event, select, | |
|
39 | true, false, null, | |||
40 | Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, |
|
40 | Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, | |
41 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
41 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, | |
42 | Text, Float, PickleType, BigInteger) |
|
42 | Text, Float, PickleType, BigInteger) | |
43 |
from sqlalchemy.sql.expression import |
|
43 | from sqlalchemy.sql.expression import case | |
44 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover |
|
44 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover | |
45 | from sqlalchemy.orm import ( |
|
45 | from sqlalchemy.orm import ( | |
46 | relationship, lazyload, joinedload, class_mapper, validates, aliased) |
|
46 | relationship, lazyload, joinedload, class_mapper, validates, aliased, load_only) | |
47 | from sqlalchemy.ext.declarative import declared_attr |
|
47 | from sqlalchemy.ext.declarative import declared_attr | |
48 | from sqlalchemy.ext.hybrid import hybrid_property |
|
48 | from sqlalchemy.ext.hybrid import hybrid_property | |
49 | from sqlalchemy.exc import IntegrityError # pragma: no cover |
|
49 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
@@ -61,8 +61,9 b' from rhodecode.lib.utils2 import (' | |||||
61 | str2bool, safe_str, get_commit_safe, sha1_safe, |
|
61 | str2bool, safe_str, get_commit_safe, sha1_safe, | |
62 | time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, |
|
62 | time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, | |
63 | glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) |
|
63 | glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) | |
64 |
from rhodecode.lib.jsonalchemy import |
|
64 | from rhodecode.lib.jsonalchemy import ( | |
65 | JsonRaw |
|
65 | MutationObj, MutationList, JsonType, JsonRaw) | |
|
66 | from rhodecode.lib.hash_utils import sha1 | |||
66 | from rhodecode.lib import ext_json |
|
67 | from rhodecode.lib import ext_json | |
67 | from rhodecode.lib import enc_utils |
|
68 | from rhodecode.lib import enc_utils | |
68 | from rhodecode.lib.ext_json import json |
|
69 | from rhodecode.lib.ext_json import json | |
@@ -81,7 +82,7 b' log = logging.getLogger(__name__)' | |||||
81 | # this is propagated from .ini file rhodecode.encrypted_values.secret or |
|
82 | # this is propagated from .ini file rhodecode.encrypted_values.secret or | |
82 | # beaker.session.secret if first is not set. |
|
83 | # beaker.session.secret if first is not set. | |
83 | # and initialized at environment.py |
|
84 | # and initialized at environment.py | |
84 | ENCRYPTION_KEY = '' |
|
85 | ENCRYPTION_KEY: bytes = b'' | |
85 |
|
86 | |||
86 | # used to sort permissions by types, '#' used here is not allowed to be in |
|
87 | # used to sort permissions by types, '#' used here is not allowed to be in | |
87 | # usernames, and it's very early in sorted string.printable table. |
|
88 | # usernames, and it's very early in sorted string.printable table. | |
@@ -166,6 +167,7 b' class EncryptedTextValue(TypeDecorator):' | |||||
166 | This column is intelligent so if value is in unencrypted form it return |
|
167 | This column is intelligent so if value is in unencrypted form it return | |
167 | unencrypted form, but on save it always encrypts |
|
168 | unencrypted form, but on save it always encrypts | |
168 | """ |
|
169 | """ | |
|
170 | cache_ok = True | |||
169 | impl = Text |
|
171 | impl = Text | |
170 |
|
172 | |||
171 | def process_bind_param(self, value, dialect): |
|
173 | def process_bind_param(self, value, dialect): | |
@@ -184,7 +186,8 b' class EncryptedTextValue(TypeDecorator):' | |||||
184 | 'ie. not starting with enc$ or enc2$') |
|
186 | 'ie. not starting with enc$ or enc2$') | |
185 |
|
187 | |||
186 | algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' |
|
188 | algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' | |
187 |
|
|
189 | bytes_val = enc_utils.encrypt_value(value, enc_key=ENCRYPTION_KEY, algo=algo) | |
|
190 | return safe_str(bytes_val) | |||
188 |
|
191 | |||
189 | def process_result_value(self, value, dialect): |
|
192 | def process_result_value(self, value, dialect): | |
190 | """ |
|
193 | """ | |
@@ -195,9 +198,11 b' class EncryptedTextValue(TypeDecorator):' | |||||
195 | if not value: |
|
198 | if not value: | |
196 | return value |
|
199 | return value | |
197 |
|
200 | |||
198 |
enc_strict_mode = |
|
201 | enc_strict_mode = rhodecode.ConfigGet().get_bool('rhodecode.encrypted_values.strict', missing=True) | |
199 |
|
202 | |||
200 |
|
|
203 | bytes_val = enc_utils.decrypt_value(value, enc_key=ENCRYPTION_KEY, strict_mode=enc_strict_mode) | |
|
204 | ||||
|
205 | return safe_str(bytes_val) | |||
201 |
|
206 | |||
202 |
|
207 | |||
203 | class BaseModel(object): |
|
208 | class BaseModel(object): | |
@@ -250,6 +255,29 b' class BaseModel(object):' | |||||
250 | return Session().query(cls) |
|
255 | return Session().query(cls) | |
251 |
|
256 | |||
252 | @classmethod |
|
257 | @classmethod | |
|
258 | def select(cls, custom_cls=None): | |||
|
259 | """ | |||
|
260 | stmt = cls.select().where(cls.user_id==1) | |||
|
261 | # optionally | |||
|
262 | stmt = cls.select(User.user_id).where(cls.user_id==1) | |||
|
263 | result = cls.execute(stmt) | cls.scalars(stmt) | |||
|
264 | """ | |||
|
265 | ||||
|
266 | if custom_cls: | |||
|
267 | stmt = select(custom_cls) | |||
|
268 | else: | |||
|
269 | stmt = select(cls) | |||
|
270 | return stmt | |||
|
271 | ||||
|
272 | @classmethod | |||
|
273 | def execute(cls, stmt): | |||
|
274 | return Session().execute(stmt) | |||
|
275 | ||||
|
276 | @classmethod | |||
|
277 | def scalars(cls, stmt): | |||
|
278 | return Session().scalars(stmt) | |||
|
279 | ||||
|
280 | @classmethod | |||
253 | def get(cls, id_): |
|
281 | def get(cls, id_): | |
254 | if id_: |
|
282 | if id_: | |
255 | return cls.query().get(id_) |
|
283 | return cls.query().get(id_) | |
@@ -296,14 +324,12 b' class BaseModel(object):' | |||||
296 | 'value %s found with same name: %r', |
|
324 | 'value %s found with same name: %r', | |
297 | attr_name, value, exist_in_session) |
|
325 | attr_name, value, exist_in_session) | |
298 |
|
326 | |||
|
327 | @property | |||
|
328 | def cls_name(self): | |||
|
329 | return self.__class__.__name__ | |||
|
330 | ||||
299 | def __repr__(self): |
|
331 | def __repr__(self): | |
300 | if hasattr(self, '__str__'): |
|
332 | return f'<DB:{self.cls_name}>' | |
301 | # python repr needs to return str |
|
|||
302 | try: |
|
|||
303 | return self.__str__() |
|
|||
304 | except UnicodeDecodeError: |
|
|||
305 | pass |
|
|||
306 | return f'<DB:{self.__class__.__name__}>' |
|
|||
307 |
|
333 | |||
308 |
|
334 | |||
309 | class RhodeCodeSetting(Base, BaseModel): |
|
335 | class RhodeCodeSetting(Base, BaseModel): | |
@@ -384,9 +410,9 b' class RhodeCodeSetting(Base, BaseModel):' | |||||
384 | .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ |
|
410 | .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ | |
385 | .all() |
|
411 | .all() | |
386 |
|
412 | |||
387 |
def __ |
|
413 | def __repr__(self): | |
388 | return "<%s('%s:%s[%s]')>" % ( |
|
414 | return "<%s('%s:%s[%s]')>" % ( | |
389 |
self. |
|
415 | self.cls_name, | |
390 | self.app_settings_name, self.app_settings_value, |
|
416 | self.app_settings_name, self.app_settings_value, | |
391 | self.app_settings_type |
|
417 | self.app_settings_type | |
392 | ) |
|
418 | ) | |
@@ -398,6 +424,7 b' class RhodeCodeUi(Base, BaseModel):' | |||||
398 | UniqueConstraint('ui_key'), |
|
424 | UniqueConstraint('ui_key'), | |
399 | base_table_args |
|
425 | base_table_args | |
400 | ) |
|
426 | ) | |
|
427 | # Sync those values with vcsserver.config.hooks | |||
401 |
|
428 | |||
402 | HOOK_REPO_SIZE = 'changegroup.repo_size' |
|
429 | HOOK_REPO_SIZE = 'changegroup.repo_size' | |
403 | # HG |
|
430 | # HG | |
@@ -436,8 +463,8 b' class RhodeCodeUi(Base, BaseModel):' | |||||
436 | ui_active = Column( |
|
463 | ui_active = Column( | |
437 | "ui_active", Boolean(), nullable=True, unique=None, default=True) |
|
464 | "ui_active", Boolean(), nullable=True, unique=None, default=True) | |
438 |
|
465 | |||
439 |
def __ |
|
466 | def __repr__(self): | |
440 |
return '<%s[%s]%s=>%s]>' % (self. |
|
467 | return '<%s[%s]%s=>%s]>' % (self.cls_name, self.ui_section, | |
441 | self.ui_key, self.ui_value) |
|
468 | self.ui_key, self.ui_value) | |
442 |
|
469 | |||
443 |
|
470 | |||
@@ -466,7 +493,7 b' class RepoRhodeCodeSetting(Base, BaseMod' | |||||
466 | "app_settings_type", String(255), nullable=True, unique=None, |
|
493 | "app_settings_type", String(255), nullable=True, unique=None, | |
467 | default=None) |
|
494 | default=None) | |
468 |
|
495 | |||
469 | repository = relationship('Repository') |
|
496 | repository = relationship('Repository', viewonly=True) | |
470 |
|
497 | |||
471 | def __init__(self, repository_id, key='', val='', type='unicode'): |
|
498 | def __init__(self, repository_id, key='', val='', type='unicode'): | |
472 | self.repository_id = repository_id |
|
499 | self.repository_id = repository_id | |
@@ -508,9 +535,9 b' class RepoRhodeCodeSetting(Base, BaseMod' | |||||
508 | % (SETTINGS_TYPES.keys(), val)) |
|
535 | % (SETTINGS_TYPES.keys(), val)) | |
509 | self._app_settings_type = val |
|
536 | self._app_settings_type = val | |
510 |
|
537 | |||
511 |
def __ |
|
538 | def __repr__(self): | |
512 | return "<%s('%s:%s:%s[%s]')>" % ( |
|
539 | return "<%s('%s:%s:%s[%s]')>" % ( | |
513 |
self. |
|
540 | self.cls_name, self.repository.repo_name, | |
514 | self.app_settings_name, self.app_settings_value, |
|
541 | self.app_settings_name, self.app_settings_value, | |
515 | self.app_settings_type |
|
542 | self.app_settings_type | |
516 | ) |
|
543 | ) | |
@@ -540,11 +567,11 b' class RepoRhodeCodeUi(Base, BaseModel):' | |||||
540 | ui_active = Column( |
|
567 | ui_active = Column( | |
541 | "ui_active", Boolean(), nullable=True, unique=None, default=True) |
|
568 | "ui_active", Boolean(), nullable=True, unique=None, default=True) | |
542 |
|
569 | |||
543 | repository = relationship('Repository') |
|
570 | repository = relationship('Repository', viewonly=True) | |
544 |
|
571 | |||
545 |
def __ |
|
572 | def __repr__(self): | |
546 | return '<%s[%s:%s]%s=>%s]>' % ( |
|
573 | return '<%s[%s:%s]%s=>%s]>' % ( | |
547 |
self. |
|
574 | self.cls_name, self.repository.repo_name, | |
548 | self.ui_section, self.ui_key, self.ui_value) |
|
575 | self.ui_section, self.ui_key, self.ui_value) | |
549 |
|
576 | |||
550 |
|
577 | |||
@@ -580,55 +607,51 b' class User(Base, BaseModel):' | |||||
580 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
607 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
581 | _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data |
|
608 | _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data | |
582 |
|
609 | |||
583 | user_log = relationship('UserLog') |
|
610 | user_log = relationship('UserLog', back_populates='user') | |
584 | user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') |
|
611 | user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') | |
585 |
|
612 | |||
586 | repositories = relationship('Repository') |
|
613 | repositories = relationship('Repository', back_populates='user') | |
587 | repository_groups = relationship('RepoGroup') |
|
614 | repository_groups = relationship('RepoGroup', back_populates='user') | |
588 | user_groups = relationship('UserGroup') |
|
615 | user_groups = relationship('UserGroup', back_populates='user') | |
589 |
|
616 | |||
590 | user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') |
|
617 | user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all', back_populates='follows_user') | |
591 | followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') |
|
618 | followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all', back_populates='user') | |
592 |
|
619 | |||
593 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') |
|
620 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') | |
594 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') |
|
621 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan', back_populates='user') | |
595 | user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') |
|
622 | user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan', back_populates='user') | |
596 |
|
623 | |||
597 | group_member = relationship('UserGroupMember', cascade='all') |
|
624 | group_member = relationship('UserGroupMember', cascade='all', back_populates='user') | |
598 |
|
625 | |||
599 | notifications = relationship('UserNotification', cascade='all') |
|
626 | notifications = relationship('UserNotification', cascade='all', back_populates='user') | |
600 | # notifications assigned to this user |
|
627 | # notifications assigned to this user | |
601 | user_created_notifications = relationship('Notification', cascade='all') |
|
628 | user_created_notifications = relationship('Notification', cascade='all', back_populates='created_by_user') | |
602 | # comments created by this user |
|
629 | # comments created by this user | |
603 | user_comments = relationship('ChangesetComment', cascade='all') |
|
630 | user_comments = relationship('ChangesetComment', cascade='all', back_populates='author') | |
604 | # user profile extra info |
|
631 | # user profile extra info | |
605 | user_emails = relationship('UserEmailMap', cascade='all') |
|
632 | user_emails = relationship('UserEmailMap', cascade='all', back_populates='user') | |
606 | user_ip_map = relationship('UserIpMap', cascade='all') |
|
633 | user_ip_map = relationship('UserIpMap', cascade='all', back_populates='user') | |
607 | user_auth_tokens = relationship('UserApiKeys', cascade='all') |
|
634 | user_auth_tokens = relationship('UserApiKeys', cascade='all', back_populates='user') | |
608 | user_ssh_keys = relationship('UserSshKeys', cascade='all') |
|
635 | user_ssh_keys = relationship('UserSshKeys', cascade='all', back_populates='user') | |
609 |
|
636 | |||
610 | # gists |
|
637 | # gists | |
611 | user_gists = relationship('Gist', cascade='all') |
|
638 | user_gists = relationship('Gist', cascade='all', back_populates='owner') | |
612 | # user pull requests |
|
639 | # user pull requests | |
613 | user_pull_requests = relationship('PullRequest', cascade='all') |
|
640 | user_pull_requests = relationship('PullRequest', cascade='all', back_populates='author') | |
614 |
|
641 | |||
615 | # external identities |
|
642 | # external identities | |
616 | external_identities = relationship( |
|
643 | external_identities = relationship('ExternalIdentity', primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade='all') | |
617 | 'ExternalIdentity', |
|
|||
618 | primaryjoin="User.user_id==ExternalIdentity.local_user_id", |
|
|||
619 | cascade='all') |
|
|||
620 | # review rules |
|
644 | # review rules | |
621 | user_review_rules = relationship('RepoReviewRuleUser', cascade='all') |
|
645 | user_review_rules = relationship('RepoReviewRuleUser', cascade='all', back_populates='user') | |
622 |
|
646 | |||
623 | # artifacts owned |
|
647 | # artifacts owned | |
624 | artifacts = relationship('FileStore', primaryjoin='FileStore.user_id==User.user_id') |
|
648 | artifacts = relationship('FileStore', primaryjoin='FileStore.user_id==User.user_id', back_populates='upload_user') | |
625 |
|
649 | |||
626 | # no cascade, set NULL |
|
650 | # no cascade, set NULL | |
627 | scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_user_id==User.user_id') |
|
651 | scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_user_id==User.user_id', cascade='', back_populates='user') | |
628 |
|
652 | |||
629 |
|
653 | def __repr__(self): | ||
630 | def __str__(self): |
|
654 | return f"<{self.cls_name}('id={self.user_id}, username={self.username}')>" | |
631 | return f"<{self.__class__.__name__}('id:{self.user_id}:{self.username}')>" |
|
|||
632 |
|
655 | |||
633 | @hybrid_property |
|
656 | @hybrid_property | |
634 | def email(self): |
|
657 | def email(self): | |
@@ -856,7 +879,7 b' class User(Base, BaseModel):' | |||||
856 |
|
879 | |||
857 | @property |
|
880 | @property | |
858 | def username_and_name(self): |
|
881 | def username_and_name(self): | |
859 |
return ' |
|
882 | return f'{self.username} ({self.first_name} {self.last_name})' | |
860 |
|
883 | |||
861 | @property |
|
884 | @property | |
862 | def username_or_name_or_email(self): |
|
885 | def username_or_name_or_email(self): | |
@@ -865,20 +888,20 b' class User(Base, BaseModel):' | |||||
865 |
|
888 | |||
866 | @property |
|
889 | @property | |
867 | def full_name(self): |
|
890 | def full_name(self): | |
868 |
return ' |
|
891 | return f'{self.first_name} {self.last_name}' | |
869 |
|
892 | |||
870 | @property |
|
893 | @property | |
871 | def full_name_or_username(self): |
|
894 | def full_name_or_username(self): | |
872 |
return (' |
|
895 | return (f'{self.first_name} {self.last_name}' | |
873 | if (self.first_name and self.last_name) else self.username) |
|
896 | if (self.first_name and self.last_name) else self.username) | |
874 |
|
897 | |||
875 | @property |
|
898 | @property | |
876 | def full_contact(self): |
|
899 | def full_contact(self): | |
877 |
return ' |
|
900 | return f'{self.first_name} {self.last_name} <{self.email}>' | |
878 |
|
901 | |||
879 | @property |
|
902 | @property | |
880 | def short_contact(self): |
|
903 | def short_contact(self): | |
881 |
return ' |
|
904 | return f'{self.first_name} {self.last_name}' | |
882 |
|
905 | |||
883 | @property |
|
906 | @property | |
884 | def is_admin(self): |
|
907 | def is_admin(self): | |
@@ -910,74 +933,73 b' class User(Base, BaseModel):' | |||||
910 | if not isinstance(val, dict): |
|
933 | if not isinstance(val, dict): | |
911 | raise Exception('user_data must be dict, got %s' % type(val)) |
|
934 | raise Exception('user_data must be dict, got %s' % type(val)) | |
912 | try: |
|
935 | try: | |
913 | self._user_data = json.dumps(val) |
|
936 | self._user_data = safe_bytes(json.dumps(val)) | |
914 | except Exception: |
|
937 | except Exception: | |
915 | log.error(traceback.format_exc()) |
|
938 | log.error(traceback.format_exc()) | |
916 |
|
939 | |||
917 | @classmethod |
|
940 | @classmethod | |
918 | def get_by_username(cls, username, case_insensitive=False, |
|
941 | def get_by_username(cls, username, case_insensitive=False, | |
919 |
cache |
|
942 | cache=False): | |
920 | session = Session() |
|
|||
921 |
|
943 | |||
922 | if case_insensitive: |
|
944 | if case_insensitive: | |
923 |
q = cls. |
|
945 | q = cls.select().where( | |
924 | func.lower(cls.username) == func.lower(username)) |
|
946 | func.lower(cls.username) == func.lower(username)) | |
925 | else: |
|
947 | else: | |
926 |
q = cls. |
|
948 | q = cls.select().where(cls.username == username) | |
927 |
|
949 | |||
928 | if cache: |
|
950 | if cache: | |
929 | if identity_cache: |
|
951 | hash_key = _hash_key(username) | |
930 | val = cls.identity_cache(session, 'username', username) |
|
952 | q = q.options( | |
931 | if val: |
|
953 | FromCache("sql_cache_short", f"get_user_by_name_{hash_key}")) | |
932 | return val |
|
954 | ||
933 | else: |
|
955 | return cls.execute(q).scalar_one_or_none() | |
934 | cache_key = "get_user_by_name_%s" % _hash_key(username) |
|
|||
935 | q = q.options( |
|
|||
936 | FromCache("sql_cache_short", cache_key)) |
|
|||
937 |
|
||||
938 | return q.scalar() |
|
|||
939 |
|
956 | |||
940 | @classmethod |
|
957 | @classmethod | |
941 | def get_by_auth_token(cls, auth_token, cache=False): |
|
958 | def get_by_auth_token(cls, auth_token, cache=False): | |
942 | q = UserApiKeys.query()\ |
|
959 | ||
943 | .filter(UserApiKeys.api_key == auth_token)\ |
|
960 | q = cls.select(User)\ | |
944 |
. |
|
961 | .join(UserApiKeys)\ | |
945 | UserApiKeys.expires >= time.time())) |
|
962 | .where(UserApiKeys.api_key == auth_token)\ | |
|
963 | .where(or_(UserApiKeys.expires == -1, | |||
|
964 | UserApiKeys.expires >= time.time())) | |||
|
965 | ||||
946 | if cache: |
|
966 | if cache: | |
947 | q = q.options( |
|
967 | q = q.options( | |
948 | FromCache("sql_cache_short", f"get_auth_token_{auth_token}")) |
|
968 | FromCache("sql_cache_short", f"get_auth_token_{auth_token}")) | |
949 |
|
969 | |||
950 | match = q.first() |
|
970 | matched_user = cls.execute(q).scalar_one_or_none() | |
951 | if match: |
|
971 | ||
952 |
|
|
972 | return matched_user | |
953 |
|
973 | |||
954 | @classmethod |
|
974 | @classmethod | |
955 | def get_by_email(cls, email, case_insensitive=False, cache=False): |
|
975 | def get_by_email(cls, email, case_insensitive=False, cache=False): | |
956 |
|
976 | |||
957 | if case_insensitive: |
|
977 | if case_insensitive: | |
958 |
q = cls. |
|
978 | q = cls.select().where(func.lower(cls.email) == func.lower(email)) | |
959 |
|
||||
960 | else: |
|
979 | else: | |
961 |
q = cls. |
|
980 | q = cls.select().where(cls.email == email) | |
962 |
|
981 | |||
963 | email_key = _hash_key(email) |
|
|||
964 | if cache: |
|
982 | if cache: | |
|
983 | email_key = _hash_key(email) | |||
965 | q = q.options( |
|
984 | q = q.options( | |
966 | FromCache("sql_cache_short", f"get_email_key_{email_key}")) |
|
985 | FromCache("sql_cache_short", f"get_email_key_{email_key}")) | |
967 |
|
986 | |||
968 | ret = q.scalar() |
|
987 | ret = cls.execute(q).scalar_one_or_none() | |
|
988 | ||||
969 | if ret is None: |
|
989 | if ret is None: | |
970 |
q = UserEmailMap |
|
990 | q = cls.select(UserEmailMap) | |
971 | # try fetching in alternate email map |
|
991 | # try fetching in alternate email map | |
972 | if case_insensitive: |
|
992 | if case_insensitive: | |
973 |
q = q. |
|
993 | q = q.where(func.lower(UserEmailMap.email) == func.lower(email)) | |
974 | else: |
|
994 | else: | |
975 |
q = q. |
|
995 | q = q.where(UserEmailMap.email == email) | |
976 | q = q.options(joinedload(UserEmailMap.user)) |
|
996 | q = q.options(joinedload(UserEmailMap.user)) | |
977 | if cache: |
|
997 | if cache: | |
978 | q = q.options( |
|
998 | q = q.options( | |
979 | FromCache("sql_cache_short", f"get_email_map_key_{email_key}")) |
|
999 | FromCache("sql_cache_short", f"get_email_map_key_{email_key}")) | |
980 | ret = getattr(q.scalar(), 'user', None) |
|
1000 | ||
|
1001 | result = cls.execute(q).scalar_one_or_none() | |||
|
1002 | ret = getattr(result, 'user', None) | |||
981 |
|
1003 | |||
982 | return ret |
|
1004 | return ret | |
983 |
|
1005 | |||
@@ -1023,10 +1045,8 b' class User(Base, BaseModel):' | |||||
1023 |
|
1045 | |||
1024 | @classmethod |
|
1046 | @classmethod | |
1025 | def get_first_super_admin(cls): |
|
1047 | def get_first_super_admin(cls): | |
1026 | user = User.query()\ |
|
1048 | stmt = cls.select().where(User.admin == true()).order_by(User.user_id.asc()) | |
1027 | .filter(User.admin == true()) \ |
|
1049 | user = cls.scalars(stmt).first() | |
1028 | .order_by(User.user_id.asc()) \ |
|
|||
1029 | .first() |
|
|||
1030 |
|
1050 | |||
1031 | if user is None: |
|
1051 | if user is None: | |
1032 | raise Exception('FATAL: Missing administrative account!') |
|
1052 | raise Exception('FATAL: Missing administrative account!') | |
@@ -1064,6 +1084,7 b' class User(Base, BaseModel):' | |||||
1064 | # A call to refresh() ensures that the |
|
1084 | # A call to refresh() ensures that the | |
1065 | # latest state from the database is used. |
|
1085 | # latest state from the database is used. | |
1066 | Session().refresh(user) |
|
1086 | Session().refresh(user) | |
|
1087 | ||||
1067 | return user |
|
1088 | return user | |
1068 |
|
1089 | |||
1069 | @classmethod |
|
1090 | @classmethod | |
@@ -1168,17 +1189,17 b' class UserApiKeys(Base, BaseModel):' | |||||
1168 | repo_id = Column( |
|
1189 | repo_id = Column( | |
1169 | 'repo_id', Integer(), ForeignKey('repositories.repo_id'), |
|
1190 | 'repo_id', Integer(), ForeignKey('repositories.repo_id'), | |
1170 | nullable=True, unique=None, default=None) |
|
1191 | nullable=True, unique=None, default=None) | |
1171 | repo = relationship('Repository', lazy='joined') |
|
1192 | repo = relationship('Repository', lazy='joined', back_populates='scoped_tokens') | |
1172 |
|
1193 | |||
1173 | repo_group_id = Column( |
|
1194 | repo_group_id = Column( | |
1174 | 'repo_group_id', Integer(), ForeignKey('groups.group_id'), |
|
1195 | 'repo_group_id', Integer(), ForeignKey('groups.group_id'), | |
1175 | nullable=True, unique=None, default=None) |
|
1196 | nullable=True, unique=None, default=None) | |
1176 | repo_group = relationship('RepoGroup', lazy='joined') |
|
1197 | repo_group = relationship('RepoGroup', lazy='joined') | |
1177 |
|
1198 | |||
1178 | user = relationship('User', lazy='joined') |
|
1199 | user = relationship('User', lazy='joined', back_populates='user_auth_tokens') | |
1179 |
|
1200 | |||
1180 |
def __ |
|
1201 | def __repr__(self): | |
1181 |
return f"<{self. |
|
1202 | return f"<{self.cls_name}('{self.role}')>" | |
1182 |
|
1203 | |||
1183 | def __json__(self): |
|
1204 | def __json__(self): | |
1184 | data = { |
|
1205 | data = { | |
@@ -1260,6 +1281,7 b' class UserEmailMap(Base, BaseModel):' | |||||
1260 | __tablename__ = 'user_email_map' |
|
1281 | __tablename__ = 'user_email_map' | |
1261 | __table_args__ = ( |
|
1282 | __table_args__ = ( | |
1262 | Index('uem_email_idx', 'email'), |
|
1283 | Index('uem_email_idx', 'email'), | |
|
1284 | Index('uem_user_id_idx', 'user_id'), | |||
1263 | UniqueConstraint('email'), |
|
1285 | UniqueConstraint('email'), | |
1264 | base_table_args |
|
1286 | base_table_args | |
1265 | ) |
|
1287 | ) | |
@@ -1268,7 +1290,7 b' class UserEmailMap(Base, BaseModel):' | |||||
1268 | email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
1290 | email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
1269 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) |
|
1291 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) | |
1270 | _email = Column("email", String(255), nullable=True, unique=False, default=None) |
|
1292 | _email = Column("email", String(255), nullable=True, unique=False, default=None) | |
1271 | user = relationship('User', lazy='joined') |
|
1293 | user = relationship('User', lazy='joined', back_populates='user_emails') | |
1272 |
|
1294 | |||
1273 | @validates('_email') |
|
1295 | @validates('_email') | |
1274 | def validate_email(self, key, email): |
|
1296 | def validate_email(self, key, email): | |
@@ -1300,7 +1322,7 b' class UserIpMap(Base, BaseModel):' | |||||
1300 | ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) |
|
1322 | ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) | |
1301 | active = Column("active", Boolean(), nullable=True, unique=None, default=True) |
|
1323 | active = Column("active", Boolean(), nullable=True, unique=None, default=True) | |
1302 | description = Column("description", String(10000), nullable=True, unique=None, default=None) |
|
1324 | description = Column("description", String(10000), nullable=True, unique=None, default=None) | |
1303 | user = relationship('User', lazy='joined') |
|
1325 | user = relationship('User', lazy='joined', back_populates='user_ip_map') | |
1304 |
|
1326 | |||
1305 | @hybrid_property |
|
1327 | @hybrid_property | |
1306 | def description_safe(self): |
|
1328 | def description_safe(self): | |
@@ -1309,7 +1331,7 b' class UserIpMap(Base, BaseModel):' | |||||
1309 |
|
1331 | |||
1310 | @classmethod |
|
1332 | @classmethod | |
1311 | def _get_ip_range(cls, ip_addr): |
|
1333 | def _get_ip_range(cls, ip_addr): | |
1312 |
net = ipaddress.ip_network(safe_ |
|
1334 | net = ipaddress.ip_network(safe_str(ip_addr), strict=False) | |
1313 | return [str(net.network_address), str(net.broadcast_address)] |
|
1335 | return [str(net.network_address), str(net.broadcast_address)] | |
1314 |
|
1336 | |||
1315 | def __json__(self): |
|
1337 | def __json__(self): | |
@@ -1318,8 +1340,8 b' class UserIpMap(Base, BaseModel):' | |||||
1318 | 'ip_range': self._get_ip_range(self.ip_addr), |
|
1340 | 'ip_range': self._get_ip_range(self.ip_addr), | |
1319 | } |
|
1341 | } | |
1320 |
|
1342 | |||
1321 |
def __ |
|
1343 | def __repr__(self): | |
1322 |
return "< |
|
1344 | return f"<{self.cls_name}('user_id={self.user_id} => ip={self.ip_addr}')>" | |
1323 |
|
1345 | |||
1324 |
|
1346 | |||
1325 | class UserSshKeys(Base, BaseModel): |
|
1347 | class UserSshKeys(Base, BaseModel): | |
@@ -1343,7 +1365,7 b' class UserSshKeys(Base, BaseModel):' | |||||
1343 | accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) |
|
1365 | accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) | |
1344 | user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) |
|
1366 | user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) | |
1345 |
|
1367 | |||
1346 | user = relationship('User', lazy='joined') |
|
1368 | user = relationship('User', lazy='joined', back_populates='user_ssh_keys') | |
1347 |
|
1369 | |||
1348 | def __json__(self): |
|
1370 | def __json__(self): | |
1349 | data = { |
|
1371 | data = { | |
@@ -1380,10 +1402,11 b' class UserLog(Base, BaseModel):' | |||||
1380 | version = Column("version", String(255), nullable=True, default=VERSION_1) |
|
1402 | version = Column("version", String(255), nullable=True, default=VERSION_1) | |
1381 | user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) |
|
1403 | user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) | |
1382 | action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) |
|
1404 | action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) | |
1383 |
|
1405 | user = relationship('User', cascade='', back_populates='user_log') | ||
1384 |
|
1406 | repository = relationship('Repository', cascade='', back_populates='logs') | ||
1385 | def __str__(self): |
|
1407 | ||
1386 | return f"<{self.__class__.__name__}('id:{self.repository_name}:{self.action}')>" |
|
1408 | def __repr__(self): | |
|
1409 | return f"<{self.cls_name}('id:{self.repository_name}:{self.action}')>" | |||
1387 |
|
1410 | |||
1388 | def __json__(self): |
|
1411 | def __json__(self): | |
1389 | return { |
|
1412 | return { | |
@@ -1404,9 +1427,6 b' class UserLog(Base, BaseModel):' | |||||
1404 | def action_as_day(self): |
|
1427 | def action_as_day(self): | |
1405 | return datetime.date(*self.action_date.timetuple()[:3]) |
|
1428 | return datetime.date(*self.action_date.timetuple()[:3]) | |
1406 |
|
1429 | |||
1407 | user = relationship('User') |
|
|||
1408 | repository = relationship('Repository', cascade='') |
|
|||
1409 |
|
||||
1410 |
|
1430 | |||
1411 | class UserGroup(Base, BaseModel): |
|
1431 | class UserGroup(Base, BaseModel): | |
1412 | __tablename__ = 'users_groups' |
|
1432 | __tablename__ = 'users_groups' | |
@@ -1423,15 +1443,16 b' class UserGroup(Base, BaseModel):' | |||||
1423 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
1443 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
1424 | _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data |
|
1444 | _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data | |
1425 |
|
1445 | |||
1426 | members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") |
|
1446 | members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined", back_populates='users_group') | |
1427 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') |
|
1447 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all', back_populates='users_group') | |
1428 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') |
|
1448 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all', back_populates='users_group') | |
1429 | users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') |
|
1449 | users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all', back_populates='users_group') | |
1430 | user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') |
|
1450 | user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all', back_populates='user_group') | |
1431 | user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm ', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') |
|
1451 | ||
1432 |
|
1452 | user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all', back_populates='target_user_group') | ||
1433 | user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') |
|
1453 | ||
1434 | user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") |
|
1454 | user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all', back_populates='users_group') | |
|
1455 | user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id", back_populates='user_groups') | |||
1435 |
|
1456 | |||
1436 | @classmethod |
|
1457 | @classmethod | |
1437 | def _load_group_data(cls, column): |
|
1458 | def _load_group_data(cls, column): | |
@@ -1472,8 +1493,8 b' class UserGroup(Base, BaseModel):' | |||||
1472 | def sync(self): |
|
1493 | def sync(self): | |
1473 | return self._load_sync(self.group_data) |
|
1494 | return self._load_sync(self.group_data) | |
1474 |
|
1495 | |||
1475 |
def __ |
|
1496 | def __repr__(self): | |
1476 |
return f"<{self. |
|
1497 | return f"<{self.cls_name}('id:{self.users_group_id}:{self.users_group_name}')>" | |
1477 |
|
1498 | |||
1478 | @classmethod |
|
1499 | @classmethod | |
1479 | def get_by_group_name(cls, group_name, cache=False, |
|
1500 | def get_by_group_name(cls, group_name, cache=False, | |
@@ -1624,8 +1645,8 b' class UserGroupMember(Base, BaseModel):' | |||||
1624 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
1645 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
1625 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
1646 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
1626 |
|
1647 | |||
1627 | user = relationship('User', lazy='joined') |
|
1648 | user = relationship('User', lazy='joined', back_populates='group_member') | |
1628 | users_group = relationship('UserGroup') |
|
1649 | users_group = relationship('UserGroup', back_populates='members') | |
1629 |
|
1650 | |||
1630 | def __init__(self, gr_id='', u_id=''): |
|
1651 | def __init__(self, gr_id='', u_id=''): | |
1631 | self.users_group_id = gr_id |
|
1652 | self.users_group_id = gr_id | |
@@ -1650,7 +1671,7 b' class RepositoryField(Base, BaseModel):' | |||||
1650 | field_type = Column("field_type", String(255), nullable=False, unique=None) |
|
1671 | field_type = Column("field_type", String(255), nullable=False, unique=None) | |
1651 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
1672 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
1652 |
|
1673 | |||
1653 | repository = relationship('Repository') |
|
1674 | repository = relationship('Repository', back_populates='extra_fields') | |
1654 |
|
1675 | |||
1655 | @property |
|
1676 | @property | |
1656 | def field_key_prefixed(self): |
|
1677 | def field_key_prefixed(self): | |
@@ -1745,44 +1766,48 b' class Repository(Base, BaseModel):' | |||||
1745 | "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, |
|
1766 | "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, | |
1746 | unique=False, default=None) |
|
1767 | unique=False, default=None) | |
1747 |
|
1768 | |||
1748 | user = relationship('User', lazy='joined') |
|
1769 | user = relationship('User', lazy='joined', back_populates='repositories') | |
1749 | fork = relationship('Repository', remote_side=repo_id, lazy='joined') |
|
1770 | fork = relationship('Repository', remote_side=repo_id, lazy='joined') | |
1750 | group = relationship('RepoGroup', lazy='joined') |
|
1771 | group = relationship('RepoGroup', lazy='joined') | |
1751 | repo_to_perm = relationship( |
|
1772 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
1752 | 'UserRepoToPerm', cascade='all', |
|
1773 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all', back_populates='repository') | |
1753 | order_by='UserRepoToPerm.repo_to_perm_id') |
|
|||
1754 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') |
|
|||
1755 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
1774 | stats = relationship('Statistics', cascade='all', uselist=False) | |
1756 |
|
1775 | |||
1757 | followers = relationship( |
|
1776 | followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all', back_populates='follows_repository') | |
1758 | 'UserFollowing', |
|
1777 | extra_fields = relationship('RepositoryField', cascade="all, delete-orphan", back_populates='repository') | |
1759 | primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', |
|
1778 | ||
1760 | cascade='all') |
|
1779 | logs = relationship('UserLog', back_populates='repository') | |
1761 | extra_fields = relationship( |
|
1780 | ||
1762 | 'RepositoryField', cascade="all, delete-orphan") |
|
1781 | comments = relationship('ChangesetComment', cascade="all, delete-orphan", back_populates='repo') | |
1763 | logs = relationship('UserLog') |
|
1782 | ||
1764 | comments = relationship( |
|
|||
1765 | 'ChangesetComment', cascade="all, delete-orphan") |
|
|||
1766 | pull_requests_source = relationship( |
|
1783 | pull_requests_source = relationship( | |
1767 | 'PullRequest', |
|
1784 | 'PullRequest', | |
1768 | primaryjoin='PullRequest.source_repo_id==Repository.repo_id', |
|
1785 | primaryjoin='PullRequest.source_repo_id==Repository.repo_id', | |
1769 |
cascade="all, delete-orphan" |
|
1786 | cascade="all, delete-orphan", | |
|
1787 | #back_populates="pr_source" | |||
|
1788 | ) | |||
1770 | pull_requests_target = relationship( |
|
1789 | pull_requests_target = relationship( | |
1771 | 'PullRequest', |
|
1790 | 'PullRequest', | |
1772 | primaryjoin='PullRequest.target_repo_id==Repository.repo_id', |
|
1791 | primaryjoin='PullRequest.target_repo_id==Repository.repo_id', | |
1773 |
cascade="all, delete-orphan" |
|
1792 | cascade="all, delete-orphan", | |
|
1793 | #back_populates="pr_target" | |||
|
1794 | ) | |||
|
1795 | ||||
1774 | ui = relationship('RepoRhodeCodeUi', cascade="all") |
|
1796 | ui = relationship('RepoRhodeCodeUi', cascade="all") | |
1775 | settings = relationship('RepoRhodeCodeSetting', cascade="all") |
|
1797 | settings = relationship('RepoRhodeCodeSetting', cascade="all") | |
1776 | integrations = relationship('Integration', cascade="all, delete-orphan") |
|
1798 | integrations = relationship('Integration', cascade="all, delete-orphan", back_populates='repo') | |
1777 |
|
1799 | |||
1778 | scoped_tokens = relationship('UserApiKeys', cascade="all") |
|
1800 | scoped_tokens = relationship('UserApiKeys', cascade="all", back_populates='repo') | |
1779 |
|
1801 | |||
1780 | # no cascade, set NULL |
|
1802 | # no cascade, set NULL | |
1781 | artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_id==Repository.repo_id') |
|
1803 | artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_id==Repository.repo_id', viewonly=True) | |
1782 |
|
1804 | |||
1783 |
|
1805 | review_rules = relationship('RepoReviewRule') | ||
1784 | def __str__(self): |
|
1806 | user_branch_perms = relationship('UserToRepoBranchPermission') | |
1785 | return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, self.repo_name) |
|
1807 | user_group_branch_perms = relationship('UserGroupToRepoBranchPermission') | |
|
1808 | ||||
|
1809 | def __repr__(self): | |||
|
1810 | return "<%s('%s:%s')>" % (self.cls_name, self.repo_id, self.repo_name) | |||
1786 |
|
1811 | |||
1787 | @hybrid_property |
|
1812 | @hybrid_property | |
1788 | def description_safe(self): |
|
1813 | def description_safe(self): | |
@@ -1864,7 +1889,7 b' class Repository(Base, BaseModel):' | |||||
1864 | @repo_name.setter |
|
1889 | @repo_name.setter | |
1865 | def repo_name(self, value): |
|
1890 | def repo_name(self, value): | |
1866 | self._repo_name = value |
|
1891 | self._repo_name = value | |
1867 |
self.repo_name_hash = |
|
1892 | self.repo_name_hash = sha1(safe_bytes(value)) | |
1868 |
|
1893 | |||
1869 | @classmethod |
|
1894 | @classmethod | |
1870 | def normalize_repo_name(cls, repo_name): |
|
1895 | def normalize_repo_name(cls, repo_name): | |
@@ -1922,10 +1947,8 b' class Repository(Base, BaseModel):' | |||||
1922 |
|
1947 | |||
1923 | :param cls: |
|
1948 | :param cls: | |
1924 | """ |
|
1949 | """ | |
1925 | q = Session().query(RhodeCodeUi)\ |
|
1950 | from rhodecode.lib.utils import get_rhodecode_base_path | |
1926 | .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) |
|
1951 | return get_rhodecode_base_path() | |
1927 | q = q.options(FromCache("sql_cache_short", "repository_repo_path")) |
|
|||
1928 | return q.one().ui_value |
|
|||
1929 |
|
1952 | |||
1930 | @classmethod |
|
1953 | @classmethod | |
1931 | def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), |
|
1954 | def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), | |
@@ -2039,7 +2062,7 b' class Repository(Base, BaseModel):' | |||||
2039 | path = self.repo_full_path |
|
2062 | path = self.repo_full_path | |
2040 | return os.path.join( |
|
2063 | return os.path.join( | |
2041 | os.path.dirname(path), |
|
2064 | os.path.dirname(path), | |
2042 |
'.__shadow_diff_cache_repo_{ |
|
2065 | f'.__shadow_diff_cache_repo_{self.repo_id}') | |
2043 |
|
2066 | |||
2044 | def cached_diffs(self): |
|
2067 | def cached_diffs(self): | |
2045 | diff_cache_dir = self.cached_diffs_dir |
|
2068 | diff_cache_dir = self.cached_diffs_dir | |
@@ -2048,16 +2071,17 b' class Repository(Base, BaseModel):' | |||||
2048 | return [] |
|
2071 | return [] | |
2049 |
|
2072 | |||
2050 | def shadow_repos(self): |
|
2073 | def shadow_repos(self): | |
2051 |
shadow_repos_pattern = '.__shadow_repo_{ |
|
2074 | shadow_repos_pattern = f'.__shadow_repo_{self.repo_id}' | |
2052 | return [ |
|
2075 | return [ | |
2053 | x for x in os.listdir(os.path.dirname(self.repo_full_path)) |
|
2076 | x for x in os.listdir(os.path.dirname(self.repo_full_path)) | |
2054 |
if x.startswith(shadow_repos_pattern) |
|
2077 | if x.startswith(shadow_repos_pattern) | |
|
2078 | ] | |||
2055 |
|
2079 | |||
2056 | def get_new_name(self, repo_name): |
|
2080 | def get_new_name(self, repo_name): | |
2057 | """ |
|
2081 | """ | |
2058 | returns new full repository name based on assigned group and new new |
|
2082 | returns new full repository name based on assigned group and new new | |
2059 |
|
2083 | |||
2060 |
:param |
|
2084 | :param repo_name: | |
2061 | """ |
|
2085 | """ | |
2062 | path_prefix = self.group.full_path_splitted if self.group else [] |
|
2086 | path_prefix = self.group.full_path_splitted if self.group else [] | |
2063 | return self.NAME_SEP.join(path_prefix + [repo_name]) |
|
2087 | return self.NAME_SEP.join(path_prefix + [repo_name]) | |
@@ -2225,15 +2249,6 b' class Repository(Base, BaseModel):' | |||||
2225 | def getlock(cls, repo): |
|
2249 | def getlock(cls, repo): | |
2226 | return repo.locked |
|
2250 | return repo.locked | |
2227 |
|
2251 | |||
2228 | def is_user_lock(self, user_id): |
|
|||
2229 | if self.lock[0]: |
|
|||
2230 | lock_user_id = safe_int(self.lock[0]) |
|
|||
2231 | user_id = safe_int(user_id) |
|
|||
2232 | # both are ints, and they are equal |
|
|||
2233 | return all([lock_user_id, user_id]) and lock_user_id == user_id |
|
|||
2234 |
|
||||
2235 | return False |
|
|||
2236 |
|
||||
2237 | def get_locking_state(self, action, user_id, only_when_enabled=True): |
|
2252 | def get_locking_state(self, action, user_id, only_when_enabled=True): | |
2238 | """ |
|
2253 | """ | |
2239 | Checks locking on this repository, if locking is enabled and lock is |
|
2254 | Checks locking on this repository, if locking is enabled and lock is | |
@@ -2432,9 +2447,10 b' class Repository(Base, BaseModel):' | |||||
2432 | updated_on |
|
2447 | updated_on | |
2433 |
|
2448 | |||
2434 | """ |
|
2449 | """ | |
2435 |
from rhodecode.lib.vcs.backends.base import BaseC |
|
2450 | from rhodecode.lib.vcs.backends.base import BaseCommit | |
2436 | from rhodecode.lib.vcs.utils.helpers import parse_datetime |
|
2451 | from rhodecode.lib.vcs.utils.helpers import parse_datetime | |
2437 | empty_date = datetime.datetime.fromtimestamp(0) |
|
2452 | empty_date = datetime.datetime.fromtimestamp(0) | |
|
2453 | repo_commit_count = 0 | |||
2438 |
|
2454 | |||
2439 | if cs_cache is None: |
|
2455 | if cs_cache is None: | |
2440 | # use no-cache version here |
|
2456 | # use no-cache version here | |
@@ -2447,10 +2463,11 b' class Repository(Base, BaseModel):' | |||||
2447 | if not empty: |
|
2463 | if not empty: | |
2448 | cs_cache = scm_repo.get_commit( |
|
2464 | cs_cache = scm_repo.get_commit( | |
2449 | pre_load=["author", "date", "message", "parents", "branch"]) |
|
2465 | pre_load=["author", "date", "message", "parents", "branch"]) | |
|
2466 | repo_commit_count = scm_repo.count() | |||
2450 | else: |
|
2467 | else: | |
2451 | cs_cache = EmptyCommit() |
|
2468 | cs_cache = EmptyCommit() | |
2452 |
|
2469 | |||
2453 |
if isinstance(cs_cache, BaseC |
|
2470 | if isinstance(cs_cache, BaseCommit): | |
2454 | cs_cache = cs_cache.__json__() |
|
2471 | cs_cache = cs_cache.__json__() | |
2455 |
|
2472 | |||
2456 | def is_outdated(new_cs_cache): |
|
2473 | def is_outdated(new_cs_cache): | |
@@ -2471,6 +2488,9 b' class Repository(Base, BaseModel):' | |||||
2471 | if last_change_timestamp > current_timestamp and not empty: |
|
2488 | if last_change_timestamp > current_timestamp and not empty: | |
2472 | cs_cache['date'] = _current_datetime |
|
2489 | cs_cache['date'] = _current_datetime | |
2473 |
|
2490 | |||
|
2491 | # also store size of repo | |||
|
2492 | cs_cache['repo_commit_count'] = repo_commit_count | |||
|
2493 | ||||
2474 | _date_latest = parse_datetime(cs_cache.get('date') or empty_date) |
|
2494 | _date_latest = parse_datetime(cs_cache.get('date') or empty_date) | |
2475 | cs_cache['updated_on'] = time.time() |
|
2495 | cs_cache['updated_on'] = time.time() | |
2476 | self.changeset_cache = cs_cache |
|
2496 | self.changeset_cache = cs_cache | |
@@ -2580,7 +2600,7 b' class Repository(Base, BaseModel):' | |||||
2580 | # allows override global config |
|
2600 | # allows override global config | |
2581 | full_cache = vcs_full_cache |
|
2601 | full_cache = vcs_full_cache | |
2582 | else: |
|
2602 | else: | |
2583 |
full_cache = |
|
2603 | full_cache = rhodecode.ConfigGet().get_bool('vcs_full_cache') | |
2584 | # if cache is NOT defined use default global, else we have a full |
|
2604 | # if cache is NOT defined use default global, else we have a full | |
2585 | # control over cache behaviour |
|
2605 | # control over cache behaviour | |
2586 | if cache is None and full_cache and not config: |
|
2606 | if cache is None and full_cache and not config: | |
@@ -2593,7 +2613,7 b' class Repository(Base, BaseModel):' | |||||
2593 | def _get_instance_cached(self): |
|
2613 | def _get_instance_cached(self): | |
2594 | from rhodecode.lib import rc_cache |
|
2614 | from rhodecode.lib import rc_cache | |
2595 |
|
2615 | |||
2596 |
cache_namespace_uid = ' |
|
2616 | cache_namespace_uid = f'repo_instance.{self.repo_id}' | |
2597 | invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( |
|
2617 | invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( | |
2598 | repo_id=self.repo_id) |
|
2618 | repo_id=self.repo_id) | |
2599 | region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) |
|
2619 | region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) | |
@@ -2655,6 +2675,7 b' class Repository(Base, BaseModel):' | |||||
2655 |
|
2675 | |||
2656 | result = super(Repository, self).get_dict() |
|
2676 | result = super(Repository, self).get_dict() | |
2657 | result['repo_name'] = result.pop('_repo_name', None) |
|
2677 | result['repo_name'] = result.pop('_repo_name', None) | |
|
2678 | result.pop('_changeset_cache', '') | |||
2658 | return result |
|
2679 | return result | |
2659 |
|
2680 | |||
2660 |
|
2681 | |||
@@ -2683,22 +2704,21 b' class RepoGroup(Base, BaseModel):' | |||||
2683 | personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) |
|
2704 | personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) | |
2684 | _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data |
|
2705 | _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data | |
2685 |
|
2706 | |||
2686 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
2707 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id', back_populates='group') | |
2687 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') |
|
2708 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all', back_populates='group') | |
2688 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
2709 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
2689 | user = relationship('User') |
|
2710 | user = relationship('User', back_populates='repository_groups') | |
2690 | integrations = relationship('Integration', cascade="all, delete-orphan") |
|
2711 | integrations = relationship('Integration', cascade="all, delete-orphan", back_populates='repo_group') | |
2691 |
|
2712 | |||
2692 | # no cascade, set NULL |
|
2713 | # no cascade, set NULL | |
2693 | scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_group_id==RepoGroup.group_id') |
|
2714 | scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_group_id==RepoGroup.group_id', viewonly=True) | |
2694 |
|
2715 | |||
2695 | def __init__(self, group_name='', parent_group=None): |
|
2716 | def __init__(self, group_name='', parent_group=None): | |
2696 | self.group_name = group_name |
|
2717 | self.group_name = group_name | |
2697 | self.parent_group = parent_group |
|
2718 | self.parent_group = parent_group | |
2698 |
|
2719 | |||
2699 |
def __ |
|
2720 | def __repr__(self): | |
2700 | return "<%s('id:%s:%s')>" % ( |
|
2721 | return f"<{self.cls_name}('id:{self.group_id}:{self.group_name}')>" | |
2701 | self.__class__.__name__, self.group_id, self.group_name) |
|
|||
2702 |
|
2722 | |||
2703 | @hybrid_property |
|
2723 | @hybrid_property | |
2704 | def group_name(self): |
|
2724 | def group_name(self): | |
@@ -2766,7 +2786,10 b' class RepoGroup(Base, BaseModel):' | |||||
2766 | @classmethod |
|
2786 | @classmethod | |
2767 | def _generate_choice(cls, repo_group): |
|
2787 | def _generate_choice(cls, repo_group): | |
2768 | from webhelpers2.html import literal as _literal |
|
2788 | from webhelpers2.html import literal as _literal | |
2769 | _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) |
|
2789 | ||
|
2790 | def _name(k): | |||
|
2791 | return _literal(cls.CHOICES_SEPARATOR.join(k)) | |||
|
2792 | ||||
2770 | return repo_group.group_id, _name(repo_group.full_path_splitted) |
|
2793 | return repo_group.group_id, _name(repo_group.full_path_splitted) | |
2771 |
|
2794 | |||
2772 | @classmethod |
|
2795 | @classmethod | |
@@ -2776,7 +2799,7 b' class RepoGroup(Base, BaseModel):' | |||||
2776 |
|
2799 | |||
2777 | repo_groups = [] |
|
2800 | repo_groups = [] | |
2778 | if show_empty_group: |
|
2801 | if show_empty_group: | |
2779 |
repo_groups = [(-1, |
|
2802 | repo_groups = [(-1, '-- %s --' % _('No parent'))] | |
2780 |
|
2803 | |||
2781 | repo_groups.extend([cls._generate_choice(x) for x in groups]) |
|
2804 | repo_groups.extend([cls._generate_choice(x) for x in groups]) | |
2782 |
|
2805 | |||
@@ -2798,7 +2821,7 b' class RepoGroup(Base, BaseModel):' | |||||
2798 | if cache: |
|
2821 | if cache: | |
2799 | name_key = _hash_key(group_name) |
|
2822 | name_key = _hash_key(group_name) | |
2800 | gr = gr.options( |
|
2823 | gr = gr.options( | |
2801 |
FromCache("sql_cache_short", "get_group_ |
|
2824 | FromCache("sql_cache_short", f"get_group_{name_key}")) | |
2802 | return gr.scalar() |
|
2825 | return gr.scalar() | |
2803 |
|
2826 | |||
2804 | @classmethod |
|
2827 | @classmethod | |
@@ -3107,6 +3130,7 b' class RepoGroup(Base, BaseModel):' | |||||
3107 | # keep compatibility with the code which uses `group_name` field. |
|
3130 | # keep compatibility with the code which uses `group_name` field. | |
3108 | result = super(RepoGroup, self).get_dict() |
|
3131 | result = super(RepoGroup, self).get_dict() | |
3109 | result['group_name'] = result.pop('_group_name', None) |
|
3132 | result['group_name'] = result.pop('_group_name', None) | |
|
3133 | result.pop('_changeset_cache', '') | |||
3110 | return result |
|
3134 | return result | |
3111 |
|
3135 | |||
3112 |
|
3136 | |||
@@ -3230,9 +3254,9 b' class Permission(Base, BaseModel):' | |||||
3230 | permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None) |
|
3254 | permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None) | |
3231 | permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) |
|
3255 | permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) | |
3232 |
|
3256 | |||
3233 |
def __ |
|
3257 | def __repr__(self): | |
3234 | return "<%s('%s:%s')>" % ( |
|
3258 | return "<%s('%s:%s')>" % ( | |
3235 |
self. |
|
3259 | self.cls_name, self.permission_id, self.permission_name | |
3236 | ) |
|
3260 | ) | |
3237 |
|
3261 | |||
3238 | @classmethod |
|
3262 | @classmethod | |
@@ -3404,11 +3428,11 b' class UserRepoToPerm(Base, BaseModel):' | |||||
3404 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3428 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3405 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
3429 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
3406 |
|
3430 | |||
3407 | user = relationship('User') |
|
3431 | user = relationship('User', back_populates="repo_to_perm") | |
3408 | repository = relationship('Repository') |
|
3432 | repository = relationship('Repository', back_populates="repo_to_perm") | |
3409 | permission = relationship('Permission') |
|
3433 | permission = relationship('Permission') | |
3410 |
|
3434 | |||
3411 | branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined') |
|
3435 | branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined', back_populates='user_repo_to_perm') | |
3412 |
|
3436 | |||
3413 | @classmethod |
|
3437 | @classmethod | |
3414 | def create(cls, user, repository, permission): |
|
3438 | def create(cls, user, repository, permission): | |
@@ -3419,7 +3443,7 b' class UserRepoToPerm(Base, BaseModel):' | |||||
3419 | Session().add(n) |
|
3443 | Session().add(n) | |
3420 | return n |
|
3444 | return n | |
3421 |
|
3445 | |||
3422 |
def __ |
|
3446 | def __repr__(self): | |
3423 | return f'<{self.user} => {self.repository} >' |
|
3447 | return f'<{self.user} => {self.repository} >' | |
3424 |
|
3448 | |||
3425 |
|
3449 | |||
@@ -3435,8 +3459,8 b' class UserUserGroupToPerm(Base, BaseMode' | |||||
3435 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3459 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3436 | user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
3460 | user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
3437 |
|
3461 | |||
3438 | user = relationship('User') |
|
3462 | user = relationship('User', back_populates='user_group_to_perm') | |
3439 | user_group = relationship('UserGroup') |
|
3463 | user_group = relationship('UserGroup', back_populates='user_user_group_to_perm') | |
3440 | permission = relationship('Permission') |
|
3464 | permission = relationship('Permission') | |
3441 |
|
3465 | |||
3442 | @classmethod |
|
3466 | @classmethod | |
@@ -3448,7 +3472,7 b' class UserUserGroupToPerm(Base, BaseMode' | |||||
3448 | Session().add(n) |
|
3472 | Session().add(n) | |
3449 | return n |
|
3473 | return n | |
3450 |
|
3474 | |||
3451 |
def __ |
|
3475 | def __repr__(self): | |
3452 | return f'<{self.user} => {self.user_group} >' |
|
3476 | return f'<{self.user} => {self.user_group} >' | |
3453 |
|
3477 | |||
3454 |
|
3478 | |||
@@ -3463,10 +3487,10 b' class UserToPerm(Base, BaseModel):' | |||||
3463 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
3487 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
3464 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3488 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3465 |
|
3489 | |||
3466 | user = relationship('User') |
|
3490 | user = relationship('User', back_populates='user_perms') | |
3467 | permission = relationship('Permission', lazy='joined') |
|
3491 | permission = relationship('Permission', lazy='joined') | |
3468 |
|
3492 | |||
3469 |
def __ |
|
3493 | def __repr__(self): | |
3470 | return f'<{self.user} => {self.permission} >' |
|
3494 | return f'<{self.user} => {self.permission} >' | |
3471 |
|
3495 | |||
3472 |
|
3496 | |||
@@ -3482,10 +3506,10 b' class UserGroupRepoToPerm(Base, BaseMode' | |||||
3482 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3506 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3483 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
3507 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
3484 |
|
3508 | |||
3485 | users_group = relationship('UserGroup') |
|
3509 | users_group = relationship('UserGroup', back_populates='users_group_repo_to_perm') | |
3486 | permission = relationship('Permission') |
|
3510 | permission = relationship('Permission') | |
3487 | repository = relationship('Repository') |
|
3511 | repository = relationship('Repository', back_populates='users_group_to_perm') | |
3488 | user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') |
|
3512 | user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all', back_populates='user_group_repo_to_perm') | |
3489 |
|
3513 | |||
3490 | @classmethod |
|
3514 | @classmethod | |
3491 | def create(cls, users_group, repository, permission): |
|
3515 | def create(cls, users_group, repository, permission): | |
@@ -3496,8 +3520,8 b' class UserGroupRepoToPerm(Base, BaseMode' | |||||
3496 | Session().add(n) |
|
3520 | Session().add(n) | |
3497 | return n |
|
3521 | return n | |
3498 |
|
3522 | |||
3499 |
def __ |
|
3523 | def __repr__(self): | |
3500 |
return '<UserGroupRepoToPerm: |
|
3524 | return f'<UserGroupRepoToPerm:{self.users_group} => {self.repository} >' | |
3501 |
|
3525 | |||
3502 |
|
3526 | |||
3503 | class UserGroupUserGroupToPerm(Base, BaseModel): |
|
3527 | class UserGroupUserGroupToPerm(Base, BaseModel): | |
@@ -3513,7 +3537,7 b' class UserGroupUserGroupToPerm(Base, Bas' | |||||
3513 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3537 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3514 | user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
3538 | user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
3515 |
|
3539 | |||
3516 | target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') |
|
3540 | target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id', back_populates='user_group_user_group_to_perm') | |
3517 | user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') |
|
3541 | user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') | |
3518 | permission = relationship('Permission') |
|
3542 | permission = relationship('Permission') | |
3519 |
|
3543 | |||
@@ -3526,8 +3550,8 b' class UserGroupUserGroupToPerm(Base, Bas' | |||||
3526 | Session().add(n) |
|
3550 | Session().add(n) | |
3527 | return n |
|
3551 | return n | |
3528 |
|
3552 | |||
3529 |
def __ |
|
3553 | def __repr__(self): | |
3530 |
return '<UserGroupUserGroup: |
|
3554 | return f'<UserGroupUserGroup:{self.target_user_group} => {self.user_group} >' | |
3531 |
|
3555 | |||
3532 |
|
3556 | |||
3533 | class UserGroupToPerm(Base, BaseModel): |
|
3557 | class UserGroupToPerm(Base, BaseModel): | |
@@ -3541,7 +3565,7 b' class UserGroupToPerm(Base, BaseModel):' | |||||
3541 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
3565 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
3542 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3566 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3543 |
|
3567 | |||
3544 | users_group = relationship('UserGroup') |
|
3568 | users_group = relationship('UserGroup', back_populates='users_group_to_perm') | |
3545 | permission = relationship('Permission') |
|
3569 | permission = relationship('Permission') | |
3546 |
|
3570 | |||
3547 |
|
3571 | |||
@@ -3557,8 +3581,8 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
3557 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
3581 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
3558 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3582 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3559 |
|
3583 | |||
3560 | user = relationship('User') |
|
3584 | user = relationship('User', back_populates='repo_group_to_perm') | |
3561 | group = relationship('RepoGroup') |
|
3585 | group = relationship('RepoGroup', back_populates='repo_group_to_perm') | |
3562 | permission = relationship('Permission') |
|
3586 | permission = relationship('Permission') | |
3563 |
|
3587 | |||
3564 | @classmethod |
|
3588 | @classmethod | |
@@ -3583,9 +3607,9 b' class UserGroupRepoGroupToPerm(Base, Bas' | |||||
3583 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
3607 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
3584 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
3608 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
3585 |
|
3609 | |||
3586 | users_group = relationship('UserGroup') |
|
3610 | users_group = relationship('UserGroup', back_populates='users_group_repo_group_to_perm') | |
3587 | permission = relationship('Permission') |
|
3611 | permission = relationship('Permission') | |
3588 | group = relationship('RepoGroup') |
|
3612 | group = relationship('RepoGroup', back_populates='users_group_to_perm') | |
3589 |
|
3613 | |||
3590 | @classmethod |
|
3614 | @classmethod | |
3591 | def create(cls, user_group, repository_group, permission): |
|
3615 | def create(cls, user_group, repository_group, permission): | |
@@ -3596,7 +3620,7 b' class UserGroupRepoGroupToPerm(Base, Bas' | |||||
3596 | Session().add(n) |
|
3620 | Session().add(n) | |
3597 | return n |
|
3621 | return n | |
3598 |
|
3622 | |||
3599 |
def __ |
|
3623 | def __repr__(self): | |
3600 | return '<UserGroupRepoGroupToPerm:%s => %s >' % (self.users_group, self.group) |
|
3624 | return '<UserGroupRepoGroupToPerm:%s => %s >' % (self.users_group, self.group) | |
3601 |
|
3625 | |||
3602 |
|
3626 | |||
@@ -3609,11 +3633,11 b' class Statistics(Base, BaseModel):' | |||||
3609 | stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
3633 | stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
3610 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) |
|
3634 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) | |
3611 | stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) |
|
3635 | stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) | |
3612 | commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data |
|
3636 | commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) #JSON data | |
3613 | commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data |
|
3637 | commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) #JSON data | |
3614 | languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data |
|
3638 | languages = Column("languages", LargeBinary(1000000), nullable=False) #JSON data | |
3615 |
|
3639 | |||
3616 | repository = relationship('Repository', single_parent=True) |
|
3640 | repository = relationship('Repository', single_parent=True, viewonly=True) | |
3617 |
|
3641 | |||
3618 |
|
3642 | |||
3619 | class UserFollowing(Base, BaseModel): |
|
3643 | class UserFollowing(Base, BaseModel): | |
@@ -3630,10 +3654,10 b' class UserFollowing(Base, BaseModel):' | |||||
3630 | follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) |
|
3654 | follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) | |
3631 | follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) |
|
3655 | follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) | |
3632 |
|
3656 | |||
3633 | user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') |
|
3657 | user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id', back_populates='followings') | |
3634 |
|
3658 | |||
3635 | follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') |
|
3659 | follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') | |
3636 | follows_repository = relationship('Repository', order_by='Repository.repo_name') |
|
3660 | follows_repository = relationship('Repository', order_by='Repository.repo_name', back_populates='followers') | |
3637 |
|
3661 | |||
3638 | @classmethod |
|
3662 | @classmethod | |
3639 | def get_repo_followers(cls, repo_id): |
|
3663 | def get_repo_followers(cls, repo_id): | |
@@ -3667,9 +3691,9 b' class CacheKey(Base, BaseModel):' | |||||
3667 | # first key should be same for all entries, since all workers should share it |
|
3691 | # first key should be same for all entries, since all workers should share it | |
3668 | self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() |
|
3692 | self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() | |
3669 |
|
3693 | |||
3670 |
def __ |
|
3694 | def __repr__(self): | |
3671 | return "<%s('%s:%s[%s]')>" % ( |
|
3695 | return "<%s('%s:%s[%s]')>" % ( | |
3672 |
self. |
|
3696 | self.cls_name, | |
3673 | self.cache_id, self.cache_key, self.cache_active) |
|
3697 | self.cache_id, self.cache_key, self.cache_active) | |
3674 |
|
3698 | |||
3675 | def _cache_key_partition(self): |
|
3699 | def _cache_key_partition(self): | |
@@ -3756,13 +3780,13 b' class ChangesetComment(Base, BaseModel):' | |||||
3756 | base_table_args, |
|
3780 | base_table_args, | |
3757 | ) |
|
3781 | ) | |
3758 |
|
3782 | |||
3759 |
COMMENT_OUTDATED = |
|
3783 | COMMENT_OUTDATED = 'comment_outdated' | |
3760 |
COMMENT_TYPE_NOTE = |
|
3784 | COMMENT_TYPE_NOTE = 'note' | |
3761 |
COMMENT_TYPE_TODO = |
|
3785 | COMMENT_TYPE_TODO = 'todo' | |
3762 | COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] |
|
3786 | COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] | |
3763 |
|
3787 | |||
3764 |
OP_IMMUTABLE = |
|
3788 | OP_IMMUTABLE = 'immutable' | |
3765 |
OP_CHANGEABLE = |
|
3789 | OP_CHANGEABLE = 'changeable' | |
3766 |
|
3790 | |||
3767 | comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) |
|
3791 | comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) | |
3768 | repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) |
|
3792 | repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) | |
@@ -3787,12 +3811,12 b' class ChangesetComment(Base, BaseModel):' | |||||
3787 | resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') |
|
3811 | resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') | |
3788 | resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') |
|
3812 | resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') | |
3789 |
|
3813 | |||
3790 | author = relationship('User', lazy='select') |
|
3814 | author = relationship('User', lazy='select', back_populates='user_comments') | |
3791 | repo = relationship('Repository') |
|
3815 | repo = relationship('Repository', back_populates='comments') | |
3792 | status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='select') |
|
3816 | status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='select', back_populates='comment') | |
3793 | pull_request = relationship('PullRequest', lazy='select') |
|
3817 | pull_request = relationship('PullRequest', lazy='select', back_populates='comments') | |
3794 | pull_request_version = relationship('PullRequestVersion', lazy='select') |
|
3818 | pull_request_version = relationship('PullRequestVersion', lazy='select') | |
3795 | history = relationship('ChangesetCommentHistory', cascade='all, delete-orphan', lazy='select', order_by='ChangesetCommentHistory.version') |
|
3819 | history = relationship('ChangesetCommentHistory', cascade='all, delete-orphan', lazy='select', order_by='ChangesetCommentHistory.version', back_populates="comment") | |
3796 |
|
3820 | |||
3797 | @classmethod |
|
3821 | @classmethod | |
3798 | def get_users(cls, revision=None, pull_request_id=None): |
|
3822 | def get_users(cls, revision=None, pull_request_id=None): | |
@@ -3803,8 +3827,7 b' class ChangesetComment(Base, BaseModel):' | |||||
3803 | :param cls: |
|
3827 | :param cls: | |
3804 | :param revision: |
|
3828 | :param revision: | |
3805 | """ |
|
3829 | """ | |
3806 |
q = Session().query(User) |
|
3830 | q = Session().query(User).join(ChangesetComment.author) | |
3807 | .join(ChangesetComment.author) |
|
|||
3808 | if revision: |
|
3831 | if revision: | |
3809 | q = q.filter(cls.revision == revision) |
|
3832 | q = q.filter(cls.revision == revision) | |
3810 | elif pull_request_id: |
|
3833 | elif pull_request_id: | |
@@ -3813,6 +3836,8 b' class ChangesetComment(Base, BaseModel):' | |||||
3813 |
|
3836 | |||
3814 | @classmethod |
|
3837 | @classmethod | |
3815 | def get_index_from_version(cls, pr_version, versions=None, num_versions=None): |
|
3838 | def get_index_from_version(cls, pr_version, versions=None, num_versions=None): | |
|
3839 | if pr_version is None: | |||
|
3840 | return 0 | |||
3816 |
|
3841 | |||
3817 | if versions is not None: |
|
3842 | if versions is not None: | |
3818 | num_versions = [x.pull_request_version_id for x in versions] |
|
3843 | num_versions = [x.pull_request_version_id for x in versions] | |
@@ -3858,10 +3883,14 b' class ChangesetComment(Base, BaseModel):' | |||||
3858 | """ |
|
3883 | """ | |
3859 | Checks if comment is made from previous version than given |
|
3884 | Checks if comment is made from previous version than given | |
3860 | """ |
|
3885 | """ | |
|
3886 | cur_ver = 0 | |||
|
3887 | if self.pull_request_version: | |||
|
3888 | cur_ver = self.pull_request_version.pull_request_version_id or cur_ver | |||
|
3889 | ||||
3861 | if version is None: |
|
3890 | if version is None: | |
3862 |
return |
|
3891 | return cur_ver != version | |
3863 |
|
3892 | |||
3864 |
return |
|
3893 | return cur_ver < version | |
3865 |
|
3894 | |||
3866 | def older_than_version_js(self, version): |
|
3895 | def older_than_version_js(self, version): | |
3867 | """ |
|
3896 | """ | |
@@ -3909,7 +3938,7 b' class ChangesetComment(Base, BaseModel):' | |||||
3909 | if self.status_change: |
|
3938 | if self.status_change: | |
3910 | return self.status_change[0].status_lbl |
|
3939 | return self.status_change[0].status_lbl | |
3911 |
|
3940 | |||
3912 |
def __ |
|
3941 | def __repr__(self): | |
3913 | if self.comment_id: |
|
3942 | if self.comment_id: | |
3914 | return f'<DB:Comment #{self.comment_id}>' |
|
3943 | return f'<DB:Comment #{self.comment_id}>' | |
3915 | else: |
|
3944 | else: | |
@@ -3956,7 +3985,7 b' class ChangesetCommentHistory(Base, Base' | |||||
3956 | deleted = Column('deleted', Boolean(), default=False) |
|
3985 | deleted = Column('deleted', Boolean(), default=False) | |
3957 |
|
3986 | |||
3958 | author = relationship('User', lazy='joined') |
|
3987 | author = relationship('User', lazy='joined') | |
3959 | comment = relationship('ChangesetComment', cascade="all, delete") |
|
3988 | comment = relationship('ChangesetComment', cascade="all, delete", back_populates="history") | |
3960 |
|
3989 | |||
3961 | @classmethod |
|
3990 | @classmethod | |
3962 | def get_version(cls, comment_id): |
|
3991 | def get_version(cls, comment_id): | |
@@ -3983,7 +4012,7 b' class ChangesetStatus(Base, BaseModel):' | |||||
3983 | STATUS_APPROVED = 'approved' |
|
4012 | STATUS_APPROVED = 'approved' | |
3984 | STATUS_REJECTED = 'rejected' |
|
4013 | STATUS_REJECTED = 'rejected' | |
3985 | STATUS_UNDER_REVIEW = 'under_review' |
|
4014 | STATUS_UNDER_REVIEW = 'under_review' | |
3986 | CheckConstraint, |
|
4015 | ||
3987 | STATUSES = [ |
|
4016 | STATUSES = [ | |
3988 | (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default |
|
4017 | (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default | |
3989 | (STATUS_APPROVED, _("Approved")), |
|
4018 | (STATUS_APPROVED, _("Approved")), | |
@@ -4003,12 +4032,11 b' class ChangesetStatus(Base, BaseModel):' | |||||
4003 |
|
4032 | |||
4004 | author = relationship('User', lazy='select') |
|
4033 | author = relationship('User', lazy='select') | |
4005 | repo = relationship('Repository', lazy='select') |
|
4034 | repo = relationship('Repository', lazy='select') | |
4006 | comment = relationship('ChangesetComment', lazy='select') |
|
4035 | comment = relationship('ChangesetComment', lazy='select', back_populates='status_change') | |
4007 | pull_request = relationship('PullRequest', lazy='select') |
|
4036 | pull_request = relationship('PullRequest', lazy='select', back_populates='statuses') | |
4008 |
|
4037 | |||
4009 |
|
4038 | def __repr__(self): | ||
4010 | def __str__(self): |
|
4039 | return f"<{self.cls_name}('{self.status}[v{self.version}]:{self.author}')>" | |
4011 | return f"<{self.__class__.__name__}('{self.status}[v{self.version}]:{self.author}')>" |
|
|||
4012 |
|
4040 | |||
4013 | @classmethod |
|
4041 | @classmethod | |
4014 | def get_status_lbl(cls, value): |
|
4042 | def get_status_lbl(cls, value): | |
@@ -4052,7 +4080,7 b' class _SetState(object):' | |||||
4052 |
|
4080 | |||
4053 | def __exit__(self, exc_type, exc_val, exc_tb): |
|
4081 | def __exit__(self, exc_type, exc_val, exc_tb): | |
4054 | if exc_val is not None or exc_type is not None: |
|
4082 | if exc_val is not None or exc_type is not None: | |
4055 |
log.error(traceback.format_ |
|
4083 | log.error(traceback.format_tb(exc_tb)) | |
4056 | return None |
|
4084 | return None | |
4057 |
|
4085 | |||
4058 | self.set_pr_state(self._org_state) |
|
4086 | self.set_pr_state(self._org_state) | |
@@ -4080,15 +4108,15 b' class _PullRequestBase(BaseModel):' | |||||
4080 | """ |
|
4108 | """ | |
4081 |
|
4109 | |||
4082 | # .status values |
|
4110 | # .status values | |
4083 |
STATUS_NEW = |
|
4111 | STATUS_NEW = 'new' | |
4084 |
STATUS_OPEN = |
|
4112 | STATUS_OPEN = 'open' | |
4085 |
STATUS_CLOSED = |
|
4113 | STATUS_CLOSED = 'closed' | |
4086 |
|
4114 | |||
4087 | # available states |
|
4115 | # available states | |
4088 |
STATE_CREATING = |
|
4116 | STATE_CREATING = 'creating' | |
4089 |
STATE_UPDATING = |
|
4117 | STATE_UPDATING = 'updating' | |
4090 |
STATE_MERGING = |
|
4118 | STATE_MERGING = 'merging' | |
4091 |
STATE_CREATED = |
|
4119 | STATE_CREATED = 'created' | |
4092 |
|
4120 | |||
4093 | title = Column('title', Unicode(255), nullable=True) |
|
4121 | title = Column('title', Unicode(255), nullable=True) | |
4094 | description = Column( |
|
4122 | description = Column( | |
@@ -4126,6 +4154,14 b' class _PullRequestBase(BaseModel):' | |||||
4126 | 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), |
|
4154 | 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), | |
4127 | nullable=False) |
|
4155 | nullable=False) | |
4128 |
|
4156 | |||
|
4157 | @declared_attr | |||
|
4158 | def pr_source(cls): | |||
|
4159 | return relationship( | |||
|
4160 | 'Repository', | |||
|
4161 | primaryjoin=f'{cls.__name__}.source_repo_id==Repository.repo_id', | |||
|
4162 | overlaps="pull_requests_source" | |||
|
4163 | ) | |||
|
4164 | ||||
4129 | _source_ref = Column('org_ref', Unicode(255), nullable=False) |
|
4165 | _source_ref = Column('org_ref', Unicode(255), nullable=False) | |
4130 |
|
4166 | |||
4131 | @hybrid_property |
|
4167 | @hybrid_property | |
@@ -4161,6 +4197,14 b' class _PullRequestBase(BaseModel):' | |||||
4161 | 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), |
|
4197 | 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), | |
4162 | nullable=False) |
|
4198 | nullable=False) | |
4163 |
|
4199 | |||
|
4200 | @declared_attr | |||
|
4201 | def pr_target(cls): | |||
|
4202 | return relationship( | |||
|
4203 | 'Repository', | |||
|
4204 | primaryjoin=f'{cls.__name__}.target_repo_id==Repository.repo_id', | |||
|
4205 | overlaps="pull_requests_target" | |||
|
4206 | ) | |||
|
4207 | ||||
4164 | _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) |
|
4208 | _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) | |
4165 |
|
4209 | |||
4166 | # TODO: dan: rename column to last_merge_source_rev |
|
4210 | # TODO: dan: rename column to last_merge_source_rev | |
@@ -4226,7 +4270,7 b' class _PullRequestBase(BaseModel):' | |||||
4226 |
|
4270 | |||
4227 | @revisions.setter |
|
4271 | @revisions.setter | |
4228 | def revisions(self, val): |
|
4272 | def revisions(self, val): | |
4229 |
self._revisions = |
|
4273 | self._revisions = ':'.join(val) | |
4230 |
|
4274 | |||
4231 | @hybrid_property |
|
4275 | @hybrid_property | |
4232 | def last_merge_status(self): |
|
4276 | def last_merge_status(self): | |
@@ -4238,13 +4282,19 b' class _PullRequestBase(BaseModel):' | |||||
4238 |
|
4282 | |||
4239 | @declared_attr |
|
4283 | @declared_attr | |
4240 | def author(cls): |
|
4284 | def author(cls): | |
4241 |
return relationship( |
|
4285 | return relationship( | |
|
4286 | 'User', lazy='joined', | |||
|
4287 | #TODO, problem that is somehow :? | |||
|
4288 | #back_populates='user_pull_requests' | |||
|
4289 | ) | |||
4242 |
|
4290 | |||
4243 | @declared_attr |
|
4291 | @declared_attr | |
4244 | def source_repo(cls): |
|
4292 | def source_repo(cls): | |
4245 | return relationship( |
|
4293 | return relationship( | |
4246 | 'Repository', |
|
4294 | 'Repository', | |
4247 |
primaryjoin=' |
|
4295 | primaryjoin=f'{cls.__name__}.source_repo_id==Repository.repo_id', | |
|
4296 | #back_populates='' | |||
|
4297 | ) | |||
4248 |
|
4298 | |||
4249 | @property |
|
4299 | @property | |
4250 | def source_ref_parts(self): |
|
4300 | def source_ref_parts(self): | |
@@ -4254,7 +4304,8 b' class _PullRequestBase(BaseModel):' | |||||
4254 | def target_repo(cls): |
|
4304 | def target_repo(cls): | |
4255 | return relationship( |
|
4305 | return relationship( | |
4256 | 'Repository', |
|
4306 | 'Repository', | |
4257 |
primaryjoin=' |
|
4307 | primaryjoin=f'{cls.__name__}.target_repo_id==Repository.repo_id' | |
|
4308 | ) | |||
4258 |
|
4309 | |||
4259 | @property |
|
4310 | @property | |
4260 | def target_ref_parts(self): |
|
4311 | def target_ref_parts(self): | |
@@ -4294,7 +4345,7 b' class _PullRequestBase(BaseModel):' | |||||
4294 | merge_data = { |
|
4345 | merge_data = { | |
4295 | 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), |
|
4346 | 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), | |
4296 | 'reference': ( |
|
4347 | 'reference': ( | |
4297 |
pull_request.shadow_merge_ref. |
|
4348 | pull_request.shadow_merge_ref.asdict() | |
4298 | if pull_request.shadow_merge_ref else None), |
|
4349 | if pull_request.shadow_merge_ref else None), | |
4299 | } |
|
4350 | } | |
4300 |
|
4351 | |||
@@ -4370,15 +4421,16 b' class PullRequest(Base, _PullRequestBase' | |||||
4370 | pull_request_id = Column( |
|
4421 | pull_request_id = Column( | |
4371 | 'pull_request_id', Integer(), nullable=False, primary_key=True) |
|
4422 | 'pull_request_id', Integer(), nullable=False, primary_key=True) | |
4372 |
|
4423 | |||
4373 |
def __ |
|
4424 | def __repr__(self): | |
4374 | if self.pull_request_id: |
|
4425 | if self.pull_request_id: | |
4375 | return f'<DB:PullRequest #{self.pull_request_id}>' |
|
4426 | return f'<DB:PullRequest #{self.pull_request_id}>' | |
4376 | else: |
|
4427 | else: | |
4377 | reviewers = relationship('PullRequestReviewers', cascade="all, delete-orphan") |
|
4428 | return f'<DB:PullRequest at {id(self)!r}>' | |
4378 | statuses = relationship('ChangesetStatus', cascade="all, delete-orphan") |
|
4429 | ||
4379 |
|
|
4430 | reviewers = relationship('PullRequestReviewers', cascade="all, delete-orphan", back_populates='pull_request') | |
4380 |
|
|
4431 | statuses = relationship('ChangesetStatus', cascade="all, delete-orphan", back_populates='pull_request') | |
4381 | lazy='dynamic') |
|
4432 | comments = relationship('ChangesetComment', cascade="all, delete-orphan", back_populates='pull_request') | |
|
4433 | versions = relationship('PullRequestVersion', cascade="all, delete-orphan", lazy='dynamic', back_populates='pull_request') | |||
4382 |
|
4434 | |||
4383 | @classmethod |
|
4435 | @classmethod | |
4384 | def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, |
|
4436 | def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, | |
@@ -4405,7 +4457,7 b' class PullRequest(Base, _PullRequestBase' | |||||
4405 | raise AttributeError( |
|
4457 | raise AttributeError( | |
4406 | '%s object has no attribute %s' % (self, item)) |
|
4458 | '%s object has no attribute %s' % (self, item)) | |
4407 |
|
4459 | |||
4408 |
def __ |
|
4460 | def __repr__(self): | |
4409 | pr_id = self.attrs.get('pull_request_id') |
|
4461 | pr_id = self.attrs.get('pull_request_id') | |
4410 | return f'<DB:PullRequestDisplay #{pr_id}>' |
|
4462 | return f'<DB:PullRequestDisplay #{pr_id}>' | |
4411 |
|
4463 | |||
@@ -4533,14 +4585,11 b' class PullRequestVersion(Base, _PullRequ' | |||||
4533 | base_table_args, |
|
4585 | base_table_args, | |
4534 | ) |
|
4586 | ) | |
4535 |
|
4587 | |||
4536 | pull_request_version_id = Column( |
|
4588 | pull_request_version_id = Column('pull_request_version_id', Integer(), nullable=False, primary_key=True) | |
4537 | 'pull_request_version_id', Integer(), nullable=False, primary_key=True) |
|
4589 | pull_request_id = Column('pull_request_id', Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) | |
4538 | pull_request_id = Column( |
|
4590 | pull_request = relationship('PullRequest', back_populates='versions') | |
4539 | 'pull_request_id', Integer(), |
|
4591 | ||
4540 | ForeignKey('pull_requests.pull_request_id'), nullable=False) |
|
4592 | def __repr__(self): | |
4541 | pull_request = relationship('PullRequest') |
|
|||
4542 |
|
||||
4543 | def __str__(self): |
|
|||
4544 | if self.pull_request_version_id: |
|
4593 | if self.pull_request_version_id: | |
4545 | return f'<DB:PullRequestVersion #{self.pull_request_version_id}>' |
|
4594 | return f'<DB:PullRequestVersion #{self.pull_request_version_id}>' | |
4546 | else: |
|
4595 | else: | |
@@ -4551,10 +4600,6 b' class PullRequestVersion(Base, _PullRequ' | |||||
4551 | return self.pull_request.reviewers |
|
4600 | return self.pull_request.reviewers | |
4552 |
|
4601 | |||
4553 | @property |
|
4602 | @property | |
4554 | def reviewers(self): |
|
|||
4555 | return self.pull_request.reviewers |
|
|||
4556 |
|
||||
4557 | @property |
|
|||
4558 | def versions(self): |
|
4603 | def versions(self): | |
4559 | return self.pull_request.versions |
|
4604 | return self.pull_request.versions | |
4560 |
|
4605 | |||
@@ -4580,8 +4625,8 b' class PullRequestReviewers(Base, BaseMod' | |||||
4580 | __table_args__ = ( |
|
4625 | __table_args__ = ( | |
4581 | base_table_args, |
|
4626 | base_table_args, | |
4582 | ) |
|
4627 | ) | |
4583 |
ROLE_REVIEWER = |
|
4628 | ROLE_REVIEWER = 'reviewer' | |
4584 |
ROLE_OBSERVER = |
|
4629 | ROLE_OBSERVER = 'observer' | |
4585 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] |
|
4630 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] | |
4586 |
|
4631 | |||
4587 | @hybrid_property |
|
4632 | @hybrid_property | |
@@ -4613,7 +4658,7 b' class PullRequestReviewers(Base, BaseMod' | |||||
4613 | role = Column('role', Unicode(255), nullable=True, default=ROLE_REVIEWER) |
|
4658 | role = Column('role', Unicode(255), nullable=True, default=ROLE_REVIEWER) | |
4614 |
|
4659 | |||
4615 | user = relationship('User') |
|
4660 | user = relationship('User') | |
4616 | pull_request = relationship('PullRequest') |
|
4661 | pull_request = relationship('PullRequest', back_populates='reviewers') | |
4617 |
|
4662 | |||
4618 | rule_data = Column( |
|
4663 | rule_data = Column( | |
4619 | 'rule_data_json', |
|
4664 | 'rule_data_json', | |
@@ -4643,8 +4688,8 b' class PullRequestReviewers(Base, BaseMod' | |||||
4643 |
|
4688 | |||
4644 | return qry.all() |
|
4689 | return qry.all() | |
4645 |
|
4690 | |||
4646 |
def __ |
|
4691 | def __repr__(self): | |
4647 |
return f"<{self. |
|
4692 | return f"<{self.cls_name}('id:{self.pull_requests_reviewers_id}')>" | |
4648 |
|
4693 | |||
4649 |
|
4694 | |||
4650 | class Notification(Base, BaseModel): |
|
4695 | class Notification(Base, BaseModel): | |
@@ -4654,13 +4699,13 b' class Notification(Base, BaseModel):' | |||||
4654 | base_table_args, |
|
4699 | base_table_args, | |
4655 | ) |
|
4700 | ) | |
4656 |
|
4701 | |||
4657 |
TYPE_CHANGESET_COMMENT = |
|
4702 | TYPE_CHANGESET_COMMENT = 'cs_comment' | |
4658 |
TYPE_MESSAGE = |
|
4703 | TYPE_MESSAGE = 'message' | |
4659 |
TYPE_MENTION = |
|
4704 | TYPE_MENTION = 'mention' | |
4660 |
TYPE_REGISTRATION = |
|
4705 | TYPE_REGISTRATION = 'registration' | |
4661 |
TYPE_PULL_REQUEST = |
|
4706 | TYPE_PULL_REQUEST = 'pull_request' | |
4662 |
TYPE_PULL_REQUEST_COMMENT = |
|
4707 | TYPE_PULL_REQUEST_COMMENT = 'pull_request_comment' | |
4663 |
TYPE_PULL_REQUEST_UPDATE = |
|
4708 | TYPE_PULL_REQUEST_UPDATE = 'pull_request_update' | |
4664 |
|
4709 | |||
4665 | notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) |
|
4710 | notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) | |
4666 | subject = Column('subject', Unicode(512), nullable=True) |
|
4711 | subject = Column('subject', Unicode(512), nullable=True) | |
@@ -4669,9 +4714,8 b' class Notification(Base, BaseModel):' | |||||
4669 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
4714 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
4670 | type_ = Column('type', Unicode(255)) |
|
4715 | type_ = Column('type', Unicode(255)) | |
4671 |
|
4716 | |||
4672 | created_by_user = relationship('User') |
|
4717 | created_by_user = relationship('User', back_populates='user_created_notifications') | |
4673 | notifications_to_users = relationship('UserNotification', lazy='joined', |
|
4718 | notifications_to_users = relationship('UserNotification', lazy='joined', cascade="all, delete-orphan", back_populates='notification') | |
4674 | cascade="all, delete-orphan") |
|
|||
4675 |
|
4719 | |||
4676 | @property |
|
4720 | @property | |
4677 | def recipients(self): |
|
4721 | def recipients(self): | |
@@ -4720,9 +4764,8 b' class UserNotification(Base, BaseModel):' | |||||
4720 | read = Column('read', Boolean, default=False) |
|
4764 | read = Column('read', Boolean, default=False) | |
4721 | sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) |
|
4765 | sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) | |
4722 |
|
4766 | |||
4723 | user = relationship('User', lazy="joined") |
|
4767 | user = relationship('User', lazy="joined", back_populates='notifications') | |
4724 | notification = relationship('Notification', lazy="joined", |
|
4768 | notification = relationship('Notification', lazy="joined", order_by=lambda: Notification.created_on.desc(), back_populates='notifications_to_users') | |
4725 | order_by=lambda: Notification.created_on.desc(),) |
|
|||
4726 |
|
4769 | |||
4727 | def mark_as_read(self): |
|
4770 | def mark_as_read(self): | |
4728 | self.read = True |
|
4771 | self.read = True | |
@@ -4796,12 +4839,12 b' class Gist(Base, BaseModel):' | |||||
4796 | base_table_args |
|
4839 | base_table_args | |
4797 | ) |
|
4840 | ) | |
4798 |
|
4841 | |||
4799 |
GIST_PUBLIC = |
|
4842 | GIST_PUBLIC = 'public' | |
4800 |
GIST_PRIVATE = |
|
4843 | GIST_PRIVATE = 'private' | |
4801 |
DEFAULT_FILENAME = |
|
4844 | DEFAULT_FILENAME = 'gistfile1.txt' | |
4802 |
|
4845 | |||
4803 |
ACL_LEVEL_PUBLIC = |
|
4846 | ACL_LEVEL_PUBLIC = 'acl_public' | |
4804 |
ACL_LEVEL_PRIVATE = |
|
4847 | ACL_LEVEL_PRIVATE = 'acl_private' | |
4805 |
|
4848 | |||
4806 | gist_id = Column('gist_id', Integer(), primary_key=True) |
|
4849 | gist_id = Column('gist_id', Integer(), primary_key=True) | |
4807 | gist_access_id = Column('gist_access_id', Unicode(250)) |
|
4850 | gist_access_id = Column('gist_access_id', Unicode(250)) | |
@@ -4813,9 +4856,9 b' class Gist(Base, BaseModel):' | |||||
4813 | modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) |
|
4856 | modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
4814 | acl_level = Column('acl_level', Unicode(128), nullable=True) |
|
4857 | acl_level = Column('acl_level', Unicode(128), nullable=True) | |
4815 |
|
4858 | |||
4816 | owner = relationship('User') |
|
4859 | owner = relationship('User', back_populates='user_gists') | |
4817 |
|
4860 | |||
4818 |
def __ |
|
4861 | def __repr__(self): | |
4819 | return f'<Gist:[{self.gist_type}]{self.gist_access_id}>' |
|
4862 | return f'<Gist:[{self.gist_type}]{self.gist_access_id}>' | |
4820 |
|
4863 | |||
4821 | @hybrid_property |
|
4864 | @hybrid_property | |
@@ -4901,13 +4944,13 b' class ExternalIdentity(Base, BaseModel):' | |||||
4901 | base_table_args |
|
4944 | base_table_args | |
4902 | ) |
|
4945 | ) | |
4903 |
|
4946 | |||
4904 |
external_id = Column('external_id', Unicode(255), default= |
|
4947 | external_id = Column('external_id', Unicode(255), default='', primary_key=True) | |
4905 |
external_username = Column('external_username', Unicode(1024), default= |
|
4948 | external_username = Column('external_username', Unicode(1024), default='') | |
4906 | local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) |
|
4949 | local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) | |
4907 |
provider_name = Column('provider_name', Unicode(255), default= |
|
4950 | provider_name = Column('provider_name', Unicode(255), default='', primary_key=True) | |
4908 |
access_token = Column('access_token', String(1024), default= |
|
4951 | access_token = Column('access_token', String(1024), default='') | |
4909 |
alt_token = Column('alt_token', String(1024), default= |
|
4952 | alt_token = Column('alt_token', String(1024), default='') | |
4910 |
token_secret = Column('token_secret', String(1024), default= |
|
4953 | token_secret = Column('token_secret', String(1024), default='') | |
4911 |
|
4954 | |||
4912 | @classmethod |
|
4955 | @classmethod | |
4913 | def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): |
|
4956 | def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): | |
@@ -4970,21 +5013,16 b' class Integration(Base, BaseModel):' | |||||
4970 | integration_type = Column('integration_type', String(255)) |
|
5013 | integration_type = Column('integration_type', String(255)) | |
4971 | enabled = Column('enabled', Boolean(), nullable=False) |
|
5014 | enabled = Column('enabled', Boolean(), nullable=False) | |
4972 | name = Column('name', String(255), nullable=False) |
|
5015 | name = Column('name', String(255), nullable=False) | |
4973 | child_repos_only = Column('child_repos_only', Boolean(), nullable=False, |
|
5016 | child_repos_only = Column('child_repos_only', Boolean(), nullable=False, default=False) | |
4974 | default=False) |
|
|||
4975 |
|
5017 | |||
4976 | settings = Column( |
|
5018 | settings = Column( | |
4977 | 'settings_json', MutationObj.as_mutable( |
|
5019 | 'settings_json', MutationObj.as_mutable( | |
4978 | JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) |
|
5020 | JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) | |
4979 | repo_id = Column( |
|
5021 | repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) | |
4980 | 'repo_id', Integer(), ForeignKey('repositories.repo_id'), |
|
5022 | repo = relationship('Repository', lazy='joined', back_populates='integrations') | |
4981 | nullable=True, unique=None, default=None) |
|
5023 | ||
4982 | repo = relationship('Repository', lazy='joined') |
|
5024 | repo_group_id = Column('repo_group_id', Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) | |
4983 |
|
5025 | repo_group = relationship('RepoGroup', lazy='joined', back_populates='integrations') | ||
4984 | repo_group_id = Column( |
|
|||
4985 | 'repo_group_id', Integer(), ForeignKey('groups.group_id'), |
|
|||
4986 | nullable=True, unique=None, default=None) |
|
|||
4987 | repo_group = relationship('RepoGroup', lazy='joined') |
|
|||
4988 |
|
5026 | |||
4989 | @property |
|
5027 | @property | |
4990 | def scope(self): |
|
5028 | def scope(self): | |
@@ -4999,7 +5037,7 b' class Integration(Base, BaseModel):' | |||||
4999 | return 'root_repos' |
|
5037 | return 'root_repos' | |
5000 | return 'global' |
|
5038 | return 'global' | |
5001 |
|
5039 | |||
5002 |
def __ |
|
5040 | def __repr__(self): | |
5003 | return '<Integration(%r, %r)>' % (self.integration_type, self.scope) |
|
5041 | return '<Integration(%r, %r)>' % (self.integration_type, self.scope) | |
5004 |
|
5042 | |||
5005 |
|
5043 | |||
@@ -5008,8 +5046,8 b' class RepoReviewRuleUser(Base, BaseModel' | |||||
5008 | __table_args__ = ( |
|
5046 | __table_args__ = ( | |
5009 | base_table_args |
|
5047 | base_table_args | |
5010 | ) |
|
5048 | ) | |
5011 |
ROLE_REVIEWER = |
|
5049 | ROLE_REVIEWER = 'reviewer' | |
5012 |
ROLE_OBSERVER = |
|
5050 | ROLE_OBSERVER = 'observer' | |
5013 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] |
|
5051 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] | |
5014 |
|
5052 | |||
5015 | repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) |
|
5053 | repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) | |
@@ -5017,7 +5055,7 b' class RepoReviewRuleUser(Base, BaseModel' | |||||
5017 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) |
|
5055 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) | |
5018 | mandatory = Column("mandatory", Boolean(), nullable=False, default=False) |
|
5056 | mandatory = Column("mandatory", Boolean(), nullable=False, default=False) | |
5019 | role = Column('role', Unicode(255), nullable=True, default=ROLE_REVIEWER) |
|
5057 | role = Column('role', Unicode(255), nullable=True, default=ROLE_REVIEWER) | |
5020 | user = relationship('User') |
|
5058 | user = relationship('User', back_populates='user_review_rules') | |
5021 |
|
5059 | |||
5022 | def rule_data(self): |
|
5060 | def rule_data(self): | |
5023 | return { |
|
5061 | return { | |
@@ -5033,8 +5071,8 b' class RepoReviewRuleUserGroup(Base, Base' | |||||
5033 | ) |
|
5071 | ) | |
5034 |
|
5072 | |||
5035 | VOTE_RULE_ALL = -1 |
|
5073 | VOTE_RULE_ALL = -1 | |
5036 |
ROLE_REVIEWER = |
|
5074 | ROLE_REVIEWER = 'reviewer' | |
5037 |
ROLE_OBSERVER = |
|
5075 | ROLE_OBSERVER = 'observer' | |
5038 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] |
|
5076 | ROLES = [ROLE_REVIEWER, ROLE_OBSERVER] | |
5039 |
|
5077 | |||
5040 | repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) |
|
5078 | repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) | |
@@ -5070,12 +5108,12 b' class RepoReviewRule(Base, BaseModel):' | |||||
5070 | 'repo_review_rule_id', Integer(), primary_key=True) |
|
5108 | 'repo_review_rule_id', Integer(), primary_key=True) | |
5071 | repo_id = Column( |
|
5109 | repo_id = Column( | |
5072 | "repo_id", Integer(), ForeignKey('repositories.repo_id')) |
|
5110 | "repo_id", Integer(), ForeignKey('repositories.repo_id')) | |
5073 |
repo = relationship('Repository', back |
|
5111 | repo = relationship('Repository', back_populates='review_rules') | |
5074 |
|
5112 | |||
5075 | review_rule_name = Column('review_rule_name', String(255)) |
|
5113 | review_rule_name = Column('review_rule_name', String(255)) | |
5076 |
_branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default= |
|
5114 | _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default='*') # glob | |
5077 |
_target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default= |
|
5115 | _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default='*') # glob | |
5078 |
_file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default= |
|
5116 | _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default='*') # glob | |
5079 |
|
5117 | |||
5080 | use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) |
|
5118 | use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) | |
5081 |
|
5119 | |||
@@ -5242,9 +5280,8 b' class RepoReviewRule(Base, BaseModel):' | |||||
5242 | rules.append(user_group) |
|
5280 | rules.append(user_group) | |
5243 | return rules |
|
5281 | return rules | |
5244 |
|
5282 | |||
5245 |
def __ |
|
5283 | def __repr__(self): | |
5246 |
return '<RepoReviewerRule(id= |
|
5284 | return f'<RepoReviewerRule(id={self.repo_review_rule_id}, repo={self.repo!r})>' | |
5247 | self.repo_review_rule_id, self.repo) |
|
|||
5248 |
|
5285 | |||
5249 |
|
5286 | |||
5250 | class ScheduleEntry(Base, BaseModel): |
|
5287 | class ScheduleEntry(Base, BaseModel): | |
@@ -5308,7 +5345,7 b' class ScheduleEntry(Base, BaseModel):' | |||||
5308 | dot_notation = obj.task_dot_notation |
|
5345 | dot_notation = obj.task_dot_notation | |
5309 | val = '.'.join(map(safe_str, [ |
|
5346 | val = '.'.join(map(safe_str, [ | |
5310 | sorted(dot_notation), args, sorted(kwargs.items())])) |
|
5347 | sorted(dot_notation), args, sorted(kwargs.items())])) | |
5311 |
return |
|
5348 | return sha1(safe_bytes(val)) | |
5312 |
|
5349 | |||
5313 | @classmethod |
|
5350 | @classmethod | |
5314 | def get_by_schedule_name(cls, schedule_name): |
|
5351 | def get_by_schedule_name(cls, schedule_name): | |
@@ -5346,7 +5383,10 b' class ScheduleEntry(Base, BaseModel):' | |||||
5346 | if hasattr(val, 'de_coerce'): |
|
5383 | if hasattr(val, 'de_coerce'): | |
5347 | val = val.de_coerce() |
|
5384 | val = val.de_coerce() | |
5348 | if val: |
|
5385 | if val: | |
5349 | val = json.dumps(val, indent=indent, sort_keys=True) |
|
5386 | if indent: | |
|
5387 | ext_json.formatted_json(val) | |||
|
5388 | else: | |||
|
5389 | val = ext_json.json.dumps(val) | |||
5350 |
|
5390 | |||
5351 | return val |
|
5391 | return val | |
5352 |
|
5392 | |||
@@ -5360,9 +5400,8 b' class ScheduleEntry(Base, BaseModel):' | |||||
5360 | def kwargs_raw(self, indent=None): |
|
5400 | def kwargs_raw(self, indent=None): | |
5361 | return self._as_raw(self.task_kwargs, indent) |
|
5401 | return self._as_raw(self.task_kwargs, indent) | |
5362 |
|
5402 | |||
5363 |
def __ |
|
5403 | def __repr__(self): | |
5364 |
return '<DB:ScheduleEntry({}:{})>' |
|
5404 | return f'<DB:ScheduleEntry({self.schedule_entry_id}:{self.schedule_name})>' | |
5365 | self.schedule_entry_id, self.schedule_name) |
|
|||
5366 |
|
5405 | |||
5367 |
|
5406 | |||
5368 | @event.listens_for(ScheduleEntry, 'before_update') |
|
5407 | @event.listens_for(ScheduleEntry, 'before_update') | |
@@ -5424,19 +5463,19 b' class UserToRepoBranchPermission(Base, _' | |||||
5424 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) |
|
5463 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) | |
5425 |
|
5464 | |||
5426 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
5465 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
5427 |
repo = relationship('Repository', back |
|
5466 | repo = relationship('Repository', back_populates='user_branch_perms') | |
5428 |
|
5467 | |||
5429 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
5468 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
5430 | permission = relationship('Permission') |
|
5469 | permission = relationship('Permission') | |
5431 |
|
5470 | |||
5432 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) |
|
5471 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) | |
5433 | user_repo_to_perm = relationship('UserRepoToPerm') |
|
5472 | user_repo_to_perm = relationship('UserRepoToPerm', back_populates='branch_perm_entry') | |
5434 |
|
5473 | |||
5435 | rule_order = Column('rule_order', Integer(), nullable=False) |
|
5474 | rule_order = Column('rule_order', Integer(), nullable=False) | |
5436 |
_branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default= |
|
5475 | _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default='*') # glob | |
5437 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) |
|
5476 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) | |
5438 |
|
5477 | |||
5439 |
def __ |
|
5478 | def __repr__(self): | |
5440 | return f'<UserBranchPermission({self.user_repo_to_perm} => {self.branch_pattern!r})>' |
|
5479 | return f'<UserBranchPermission({self.user_repo_to_perm} => {self.branch_pattern!r})>' | |
5441 |
|
5480 | |||
5442 |
|
5481 | |||
@@ -5449,19 +5488,19 b' class UserGroupToRepoBranchPermission(Ba' | |||||
5449 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) |
|
5488 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) | |
5450 |
|
5489 | |||
5451 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
5490 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
5452 |
repo = relationship('Repository', back |
|
5491 | repo = relationship('Repository', back_populates='user_group_branch_perms') | |
5453 |
|
5492 | |||
5454 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
5493 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
5455 | permission = relationship('Permission') |
|
5494 | permission = relationship('Permission') | |
5456 |
|
5495 | |||
5457 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) |
|
5496 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) | |
5458 | user_group_repo_to_perm = relationship('UserGroupRepoToPerm') |
|
5497 | user_group_repo_to_perm = relationship('UserGroupRepoToPerm', back_populates='user_group_branch_perms') | |
5459 |
|
5498 | |||
5460 | rule_order = Column('rule_order', Integer(), nullable=False) |
|
5499 | rule_order = Column('rule_order', Integer(), nullable=False) | |
5461 |
_branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default= |
|
5500 | _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default='*') # glob | |
5462 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) |
|
5501 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) | |
5463 |
|
5502 | |||
5464 |
def __ |
|
5503 | def __repr__(self): | |
5465 | return f'<UserBranchPermission({self.user_group_repo_to_perm} => {self.branch_pattern!r})>' |
|
5504 | return f'<UserBranchPermission({self.user_group_repo_to_perm} => {self.branch_pattern!r})>' | |
5466 |
|
5505 | |||
5467 |
|
5506 | |||
@@ -5510,7 +5549,7 b' class UserBookmark(Base, BaseModel):' | |||||
5510 |
|
5549 | |||
5511 | return bookmarks.all() |
|
5550 | return bookmarks.all() | |
5512 |
|
5551 | |||
5513 |
def __ |
|
5552 | def __repr__(self): | |
5514 | return f'<UserBookmark({self.position} @ {self.redirect_url!r})>' |
|
5553 | return f'<UserBookmark({self.position} @ {self.redirect_url!r})>' | |
5515 |
|
5554 | |||
5516 |
|
5555 | |||
@@ -5543,7 +5582,7 b' class FileStore(Base, BaseModel):' | |||||
5543 | hidden = Column('hidden', Boolean(), nullable=False, default=False) |
|
5582 | hidden = Column('hidden', Boolean(), nullable=False, default=False) | |
5544 |
|
5583 | |||
5545 | user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) |
|
5584 | user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) | |
5546 | upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') |
|
5585 | upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id', back_populates='artifacts') | |
5547 |
|
5586 | |||
5548 | file_metadata = relationship('FileStoreMetadata', lazy='joined') |
|
5587 | file_metadata = relationship('FileStoreMetadata', lazy='joined') | |
5549 |
|
5588 | |||
@@ -5551,7 +5590,7 b' class FileStore(Base, BaseModel):' | |||||
5551 | scope_user_id = Column( |
|
5590 | scope_user_id = Column( | |
5552 | 'scope_user_id', Integer(), ForeignKey('users.user_id'), |
|
5591 | 'scope_user_id', Integer(), ForeignKey('users.user_id'), | |
5553 | nullable=True, unique=None, default=None) |
|
5592 | nullable=True, unique=None, default=None) | |
5554 | user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') |
|
5593 | user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id', back_populates='scope_artifacts') | |
5555 |
|
5594 | |||
5556 | # scope limited to user group, which requester have access to |
|
5595 | # scope limited to user group, which requester have access to | |
5557 | scope_user_group_id = Column( |
|
5596 | scope_user_group_id = Column( | |
@@ -5664,7 +5703,7 b' class FileStore(Base, BaseModel):' | |||||
5664 |
|
5703 | |||
5665 | return data |
|
5704 | return data | |
5666 |
|
5705 | |||
5667 |
def __ |
|
5706 | def __repr__(self): | |
5668 | return f'<FileStore({self.file_store_id})>' |
|
5707 | return f'<FileStore({self.file_store_id})>' | |
5669 |
|
5708 | |||
5670 |
|
5709 | |||
@@ -5709,7 +5748,7 b' class FileStoreMetadata(Base, BaseModel)' | |||||
5709 | 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), |
|
5748 | 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), | |
5710 | nullable=True, unique=None, default=None) |
|
5749 | nullable=True, unique=None, default=None) | |
5711 |
|
5750 | |||
5712 | file_store = relationship('FileStore', lazy='joined') |
|
5751 | file_store = relationship('FileStore', lazy='joined', viewonly=True) | |
5713 |
|
5752 | |||
5714 | @classmethod |
|
5753 | @classmethod | |
5715 | def valid_value_type(cls, value): |
|
5754 | def valid_value_type(cls, value): | |
@@ -5781,8 +5820,8 b' class FileStoreMetadata(Base, BaseModel)' | |||||
5781 |
|
5820 | |||
5782 | return data |
|
5821 | return data | |
5783 |
|
5822 | |||
5784 |
def __ |
|
5823 | def __repr__(self): | |
5785 |
return '<%s[%s]%s=>%s]>' % (self. |
|
5824 | return '<%s[%s]%s=>%s]>' % (self.cls_name, self.file_store_meta_section, | |
5786 | self.file_store_meta_key, self.file_store_meta_value) |
|
5825 | self.file_store_meta_key, self.file_store_meta_value) | |
5787 |
|
5826 | |||
5788 |
|
5827 | |||
@@ -5812,7 +5851,7 b' class DbSession(Base, BaseModel):' | |||||
5812 | base_table_args, |
|
5851 | base_table_args, | |
5813 | ) |
|
5852 | ) | |
5814 |
|
5853 | |||
5815 |
def __ |
|
5854 | def __repr__(self): | |
5816 | return f'<DB:DbSession({self.id})>' |
|
5855 | return f'<DB:DbSession({self.id})>' | |
5817 |
|
5856 | |||
5818 | id = Column('id', Integer()) |
|
5857 | id = Column('id', Integer()) |
General Comments 0
You need to be logged in to leave comments.
Login now