##// END OF EJS Templates
feat: changed last change of repo group to be commit of a latest repository.
marcink -
r3689:2d150bfd new-ui
parent child Browse files
Show More
@@ -0,0 +1,37 b''
1 # -*- coding: utf-8 -*-
2
3 import logging
4
5 from alembic.migration import MigrationContext
6 from alembic.operations import Operations
7 from sqlalchemy import Column, LargeBinary
8
9 from rhodecode.lib.dbmigrate.versions import _reset_base
10 from rhodecode.model import init_model_encryption
11
12
13 log = logging.getLogger(__name__)
14
15
16 def upgrade(migrate_engine):
17 """
18 Upgrade operations go here.
19 Don't create your own engine; bind migrate_engine to your metadata
20 """
21 _reset_base(migrate_engine)
22 from rhodecode.lib.dbmigrate.schema import db_4_16_0_2
23
24 init_model_encryption(db_4_16_0_2)
25
26 context = MigrationContext.configure(migrate_engine.connect())
27 op = Operations(context)
28
29 repo_group = db_4_16_0_2.RepoGroup.__table__
30
31 with op.batch_alter_table(repo_group.name) as batch_op:
32 batch_op.add_column(
33 Column("changeset_cache", LargeBinary(1024), nullable=True))
34
35
36 def downgrade(migrate_engine):
37 pass
@@ -45,7 +45,7 b' PYRAMID_SETTINGS = {}'
45 EXTENSIONS = {}
45 EXTENSIONS = {}
46
46
47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
47 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
48 __dbversion__ = 97 # defines current db version for migrations
48 __dbversion__ = 98 # defines current db version for migrations
49 __platform__ = platform.system()
49 __platform__ = platform.system()
50 __license__ = 'AGPLv3, and Commercial License'
50 __license__ = 'AGPLv3, and Commercial License'
51 __author__ = 'RhodeCode GmbH'
51 __author__ = 'RhodeCode GmbH'
@@ -703,8 +703,9 b' class HomeView(BaseAppView):'
703 def repo_group_main_page(self):
703 def repo_group_main_page(self):
704 c = self.load_default_context()
704 c = self.load_default_context()
705 c.repo_group = self.request.db_repo_group
705 c.repo_group = self.request.db_repo_group
706 repo_data, repo_group_data = self._get_groups_and_repos(
706 repo_data, repo_group_data = self._get_groups_and_repos(c.repo_group.group_id)
707 c.repo_group.group_id)
707
708 c.repo_group.update_commit_cache()
708
709
709 # json used to render the grids
710 # json used to render the grids
710 c.repos_data = json.dumps(repo_data)
711 c.repos_data = json.dumps(repo_data)
@@ -485,9 +485,6 b' class DbManage(object):'
485 self.populate_default_permissions()
485 self.populate_default_permissions()
486 return fixed
486 return fixed
487
487
488 def update_repo_info(self):
489 RepoModel.update_repoinfo()
490
491 def config_prompt(self, test_repo_path='', retries=3):
488 def config_prompt(self, test_repo_path='', retries=3):
492 defaults = self.cli_args
489 defaults = self.cli_args
493 _path = defaults.get('repos_location')
490 _path = defaults.get('repos_location')
@@ -614,7 +614,7 b' class Repository(Base, BaseModel):'
614 if (cs_cache != self.changeset_cache or not self.changeset_cache):
614 if (cs_cache != self.changeset_cache or not self.changeset_cache):
615 _default = datetime.datetime.fromtimestamp(0)
615 _default = datetime.datetime.fromtimestamp(0)
616 last_change = cs_cache.get('date') or _default
616 last_change = cs_cache.get('date') or _default
617 log.debug('updated repo %s with new cs cache %s', self.repo_name, cs_cache)
617 log.debug('updated repo %s with new commit cache %s', self.repo_name, cs_cache)
618 self.updated_on = last_change
618 self.updated_on = last_change
619 self.changeset_cache = cs_cache
619 self.changeset_cache = cs_cache
620 Session().add(self)
620 Session().add(self)
@@ -2164,7 +2164,7 b' class Repository(Base, BaseModel):'
2164 if is_outdated(cs_cache) or not self.changeset_cache:
2164 if is_outdated(cs_cache) or not self.changeset_cache:
2165 _default = datetime.datetime.fromtimestamp(0)
2165 _default = datetime.datetime.fromtimestamp(0)
2166 last_change = cs_cache.get('date') or _default
2166 last_change = cs_cache.get('date') or _default
2167 log.debug('updated repo %s with new cs cache %s',
2167 log.debug('updated repo %s with new commit cache %s',
2168 self.repo_name, cs_cache)
2168 self.repo_name, cs_cache)
2169 self.updated_on = last_change
2169 self.updated_on = last_change
2170 self.changeset_cache = cs_cache
2170 self.changeset_cache = cs_cache
@@ -2230,7 +2230,7 b' class Repository(Base, BaseModel):'
2230 if is_outdated(cs_cache) or not self.changeset_cache:
2230 if is_outdated(cs_cache) or not self.changeset_cache:
2231 _default = datetime.datetime.fromtimestamp(0)
2231 _default = datetime.datetime.fromtimestamp(0)
2232 last_change = cs_cache.get('date') or _default
2232 last_change = cs_cache.get('date') or _default
2233 log.debug('updated repo %s with new cs cache %s',
2233 log.debug('updated repo %s with new commit cache %s',
2234 self.repo_name, cs_cache)
2234 self.repo_name, cs_cache)
2235 self.updated_on = last_change
2235 self.updated_on = last_change
2236 self.changeset_cache = cs_cache
2236 self.changeset_cache = cs_cache
@@ -2278,7 +2278,7 b' class Repository(Base, BaseModel):'
2278 # if yes, we use the current timestamp instead. Imagine you get
2278 # if yes, we use the current timestamp instead. Imagine you get
2279 # old commit pushed 1y ago, we'd set last update 1y to ago.
2279 # old commit pushed 1y ago, we'd set last update 1y to ago.
2280 last_change = _default
2280 last_change = _default
2281 log.debug('updated repo %s with new cs cache %s',
2281 log.debug('updated repo %s with new commit cache %s',
2282 self.repo_name, cs_cache)
2282 self.repo_name, cs_cache)
2283 self.updated_on = last_change
2283 self.updated_on = last_change
2284 self.changeset_cache = cs_cache
2284 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 # if yes, we use the current timestamp instead. Imagine you get
2301 # if yes, we use the current timestamp instead. Imagine you get
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 last_change = _default
2303 last_change = _default
2304 log.debug('updated repo %s with new cs cache %s',
2304 log.debug('updated repo %s with new commit cache %s',
2305 self.repo_name, cs_cache)
2305 self.repo_name, cs_cache)
2306 self.updated_on = last_change
2306 self.updated_on = last_change
2307 self.changeset_cache = cs_cache
2307 self.changeset_cache = cs_cache
@@ -2301,7 +2301,7 b' class Repository(Base, BaseModel):'
2301 # if yes, we use the current timestamp instead. Imagine you get
2301 # if yes, we use the current timestamp instead. Imagine you get
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2302 # old commit pushed 1y ago, we'd set last update 1y to ago.
2303 last_change = _default
2303 last_change = _default
2304 log.debug('updated repo %s with new cs cache %s',
2304 log.debug('updated repo %s with new commit cache %s',
2305 self.repo_name, cs_cache)
2305 self.repo_name, cs_cache)
2306 self.updated_on = last_change
2306 self.updated_on = last_change
2307 self.changeset_cache = cs_cache
2307 self.changeset_cache = cs_cache
@@ -1865,7 +1865,7 b' class Repository(Base, BaseModel):'
1865 if is_outdated(cs_cache) or not self.changeset_cache:
1865 if is_outdated(cs_cache) or not self.changeset_cache:
1866 _default = datetime.datetime.fromtimestamp(0)
1866 _default = datetime.datetime.fromtimestamp(0)
1867 last_change = cs_cache.get('date') or _default
1867 last_change = cs_cache.get('date') or _default
1868 log.debug('updated repo %s with new cs cache %s',
1868 log.debug('updated repo %s with new commit cache %s',
1869 self.repo_name, cs_cache)
1869 self.repo_name, cs_cache)
1870 self.updated_on = last_change
1870 self.updated_on = last_change
1871 self.changeset_cache = cs_cache
1871 self.changeset_cache = cs_cache
@@ -1868,7 +1868,7 b' class Repository(Base, BaseModel):'
1868 if is_outdated(cs_cache) or not self.changeset_cache:
1868 if is_outdated(cs_cache) or not self.changeset_cache:
1869 _default = datetime.datetime.fromtimestamp(0)
1869 _default = datetime.datetime.fromtimestamp(0)
1870 last_change = cs_cache.get('date') or _default
1870 last_change = cs_cache.get('date') or _default
1871 log.debug('updated repo %s with new cs cache %s',
1871 log.debug('updated repo %s with new commit cache %s',
1872 self.repo_name, cs_cache)
1872 self.repo_name, cs_cache)
1873 self.updated_on = last_change
1873 self.updated_on = last_change
1874 self.changeset_cache = cs_cache
1874 self.changeset_cache = cs_cache
@@ -1867,7 +1867,7 b' class Repository(Base, BaseModel):'
1867 if is_outdated(cs_cache) or not self.changeset_cache:
1867 if is_outdated(cs_cache) or not self.changeset_cache:
1868 _default = datetime.datetime.fromtimestamp(0)
1868 _default = datetime.datetime.fromtimestamp(0)
1869 last_change = cs_cache.get('date') or _default
1869 last_change = cs_cache.get('date') or _default
1870 log.debug('updated repo %s with new cs cache %s',
1870 log.debug('updated repo %s with new commit cache %s',
1871 self.repo_name, cs_cache)
1871 self.repo_name, cs_cache)
1872 self.updated_on = last_change
1872 self.updated_on = last_change
1873 self.changeset_cache = cs_cache
1873 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 _default = datetime.datetime.fromtimestamp(0)
1870 _default = datetime.datetime.fromtimestamp(0)
1871 last_change = cs_cache.get('date') or _default
1871 last_change = cs_cache.get('date') or _default
1872 log.debug('updated repo %s with new cs cache %s',
1872 log.debug('updated repo %s with new commit cache %s',
1873 self.repo_name, cs_cache)
1873 self.repo_name, cs_cache)
1874 self.updated_on = last_change
1874 self.updated_on = last_change
1875 self.changeset_cache = cs_cache
1875 self.changeset_cache = cs_cache
@@ -1869,7 +1869,7 b' class Repository(Base, BaseModel):'
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1869 if is_outdated(cs_cache) or not self.changeset_cache:
1870 _default = datetime.datetime.fromtimestamp(0)
1870 _default = datetime.datetime.fromtimestamp(0)
1871 last_change = cs_cache.get('date') or _default
1871 last_change = cs_cache.get('date') or _default
1872 log.debug('updated repo %s with new cs cache %s',
1872 log.debug('updated repo %s with new commit cache %s',
1873 self.repo_name, cs_cache)
1873 self.repo_name, cs_cache)
1874 self.updated_on = last_change
1874 self.updated_on = last_change
1875 self.changeset_cache = cs_cache
1875 self.changeset_cache = cs_cache
@@ -1912,7 +1912,7 b' class Repository(Base, BaseModel):'
1912 if is_outdated(cs_cache) or not self.changeset_cache:
1912 if is_outdated(cs_cache) or not self.changeset_cache:
1913 _default = datetime.datetime.fromtimestamp(0)
1913 _default = datetime.datetime.fromtimestamp(0)
1914 last_change = cs_cache.get('date') or _default
1914 last_change = cs_cache.get('date') or _default
1915 log.debug('updated repo %s with new cs cache %s',
1915 log.debug('updated repo %s with new commit cache %s',
1916 self.repo_name, cs_cache)
1916 self.repo_name, cs_cache)
1917 self.updated_on = last_change
1917 self.updated_on = last_change
1918 self.changeset_cache = cs_cache
1918 self.changeset_cache = cs_cache
@@ -1913,7 +1913,7 b' class Repository(Base, BaseModel):'
1913 if is_outdated(cs_cache) or not self.changeset_cache:
1913 if is_outdated(cs_cache) or not self.changeset_cache:
1914 _default = datetime.datetime.fromtimestamp(0)
1914 _default = datetime.datetime.fromtimestamp(0)
1915 last_change = cs_cache.get('date') or _default
1915 last_change = cs_cache.get('date') or _default
1916 log.debug('updated repo %s with new cs cache %s',
1916 log.debug('updated repo %s with new commit cache %s',
1917 self.repo_name, cs_cache)
1917 self.repo_name, cs_cache)
1918 self.updated_on = last_change
1918 self.updated_on = last_change
1919 self.changeset_cache = cs_cache
1919 self.changeset_cache = cs_cache
@@ -2100,7 +2100,7 b' class Repository(Base, BaseModel):'
2100 if is_outdated(cs_cache) or not self.changeset_cache:
2100 if is_outdated(cs_cache) or not self.changeset_cache:
2101 _default = datetime.datetime.fromtimestamp(0)
2101 _default = datetime.datetime.fromtimestamp(0)
2102 last_change = cs_cache.get('date') or _default
2102 last_change = cs_cache.get('date') or _default
2103 log.debug('updated repo %s with new cs cache %s',
2103 log.debug('updated repo %s with new commit cache %s',
2104 self.repo_name, cs_cache)
2104 self.repo_name, cs_cache)
2105 self.updated_on = last_change
2105 self.updated_on = last_change
2106 self.changeset_cache = cs_cache
2106 self.changeset_cache = cs_cache
@@ -30,7 +30,7 b' def upgrade(migrate_engine):'
30 op = Operations(context)
30 op = Operations(context)
31
31
32 repo_group = db_4_16_0_2.RepoGroup.__table__
32 repo_group = db_4_16_0_2.RepoGroup.__table__
33
33
34 with op.batch_alter_table(repo_group.name) as batch_op:
34 with op.batch_alter_table(repo_group.name) as batch_op:
35 batch_op.add_column(
35 batch_op.add_column(
36 Column("repo_group_name_hash", String(1024), nullable=True, unique=False))
36 Column("repo_group_name_hash", String(1024), nullable=True, unique=False))
@@ -26,7 +26,7 b' def upgrade(migrate_engine):'
26 op = Operations(context)
26 op = Operations(context)
27
27
28 repo_group = db_4_16_0_2.RepoGroup.__table__
28 repo_group = db_4_16_0_2.RepoGroup.__table__
29
29
30 with op.batch_alter_table(repo_group.name) as batch_op:
30 with op.batch_alter_table(repo_group.name) as batch_op:
31 batch_op.alter_column("repo_group_name_hash", nullable=False)
31 batch_op.alter_column("repo_group_name_hash", nullable=False)
32
32
@@ -1489,10 +1489,12 b' def breadcrumb_repo_link(repo):'
1489 """
1489 """
1490
1490
1491 path = [
1491 path = [
1492 link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name))
1492 link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name),
1493 title='last change:{}'.format(format_date(group.last_commit_change)))
1493 for group in repo.groups_with_parents
1494 for group in repo.groups_with_parents
1494 ] + [
1495 ] + [
1495 link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name))
1496 link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name),
1497 title='last change:{}'.format(format_date(repo.last_commit_change)))
1496 ]
1498 ]
1497
1499
1498 return literal(' » '.join(path))
1500 return literal(' » '.join(path))
@@ -1510,11 +1512,13 b' def breadcrumb_repo_group_link(repo_grou'
1510
1512
1511 path = [
1513 path = [
1512 link_to(group.name,
1514 link_to(group.name,
1513 route_path('repo_group_home', repo_group_name=group.group_name))
1515 route_path('repo_group_home', repo_group_name=group.group_name),
1516 title='last change:{}'.format(format_date(group.last_commit_change)))
1514 for group in repo_group.parents
1517 for group in repo_group.parents
1515 ] + [
1518 ] + [
1516 link_to(repo_group.name,
1519 link_to(repo_group.name,
1517 route_path('repo_group_home', repo_group_name=repo_group.group_name))
1520 route_path('repo_group_home', repo_group_name=repo_group.group_name),
1521 title='last change:{}'.format(format_date(repo_group.last_commit_change)))
1518 ]
1522 ]
1519
1523
1520 return literal(' » '.join(path))
1524 return literal(' » '.join(path))
@@ -101,23 +101,34 b' def parse_datetime(text):'
101 :param text: string of desired date/datetime or something more verbose,
101 :param text: string of desired date/datetime or something more verbose,
102 like *yesterday*, *2weeks 3days*, etc.
102 like *yesterday*, *2weeks 3days*, etc.
103 """
103 """
104 if not text:
105 raise ValueError('Wrong date: "%s"' % text)
106
107 if isinstance(text, datetime.datetime):
108 return text
104
109
105 text = text.strip().lower()
110 text = text.strip().lower()
106
111
107 INPUT_FORMATS = (
112 input_formats = (
108 '%Y-%m-%d %H:%M:%S',
113 '%Y-%m-%d %H:%M:%S',
114 '%Y-%m-%dT%H:%M:%S',
109 '%Y-%m-%d %H:%M',
115 '%Y-%m-%d %H:%M',
116 '%Y-%m-%dT%H:%M',
110 '%Y-%m-%d',
117 '%Y-%m-%d',
111 '%m/%d/%Y %H:%M:%S',
118 '%m/%d/%Y %H:%M:%S',
119 '%m/%d/%YT%H:%M:%S',
112 '%m/%d/%Y %H:%M',
120 '%m/%d/%Y %H:%M',
121 '%m/%d/%YT%H:%M',
113 '%m/%d/%Y',
122 '%m/%d/%Y',
114 '%m/%d/%y %H:%M:%S',
123 '%m/%d/%y %H:%M:%S',
124 '%m/%d/%yT%H:%M:%S',
115 '%m/%d/%y %H:%M',
125 '%m/%d/%y %H:%M',
126 '%m/%d/%yT%H:%M',
116 '%m/%d/%y',
127 '%m/%d/%y',
117 )
128 )
118 for format in INPUT_FORMATS:
129 for format_def in input_formats:
119 try:
130 try:
120 return datetime.datetime(*time.strptime(text, format)[:6])
131 return datetime.datetime(*time.strptime(text, format_def)[:6])
121 except ValueError:
132 except ValueError:
122 pass
133 pass
123
134
@@ -59,7 +59,7 b' from rhodecode.lib.vcs.backends.base imp'
59 from rhodecode.lib.utils2 import (
59 from rhodecode.lib.utils2 import (
60 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
60 str2bool, safe_str, get_commit_safe, safe_unicode, sha1_safe,
61 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
61 time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict,
62 glob2re, StrictAttributeDict, cleaned_uri)
62 glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time, OrderedDefaultDict)
63 from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \
63 from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \
64 JsonRaw
64 JsonRaw
65 from rhodecode.lib.ext_json import json
65 from rhodecode.lib.ext_json import json
@@ -1730,7 +1730,9 b' class Repository(Base, BaseModel):'
1730 from rhodecode.lib.vcs.backends.base import EmptyCommit
1730 from rhodecode.lib.vcs.backends.base import EmptyCommit
1731 dummy = EmptyCommit().__json__()
1731 dummy = EmptyCommit().__json__()
1732 if not self._changeset_cache:
1732 if not self._changeset_cache:
1733 return dummy
1733 dummy['source_repo_id'] = self.repo_id
1734 return json.loads(json.dumps(dummy))
1735
1734 try:
1736 try:
1735 return json.loads(self._changeset_cache)
1737 return json.loads(self._changeset_cache)
1736 except TypeError:
1738 except TypeError:
@@ -2183,6 +2185,16 b' class Repository(Base, BaseModel):'
2183 return make_lock, currently_locked, lock_info
2185 return make_lock, currently_locked, lock_info
2184
2186
2185 @property
2187 @property
2188 def last_commit_change(self):
2189 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2190 empty_date = datetime.datetime.fromtimestamp(0)
2191 date_latest = self.changeset_cache.get('date', empty_date)
2192 try:
2193 return parse_datetime(date_latest)
2194 except Exception:
2195 return empty_date
2196
2197 @property
2186 def last_db_change(self):
2198 def last_db_change(self):
2187 return self.updated_on
2199 return self.updated_on
2188
2200
@@ -2275,6 +2287,7 b' class Repository(Base, BaseModel):'
2275 """
2287 """
2276 Update cache of last changeset for repository, keys should be::
2288 Update cache of last changeset for repository, keys should be::
2277
2289
2290 source_repo_id
2278 short_id
2291 short_id
2279 raw_id
2292 raw_id
2280 revision
2293 revision
@@ -2283,7 +2296,6 b' class Repository(Base, BaseModel):'
2283 date
2296 date
2284 author
2297 author
2285
2298
2286 :param cs_cache:
2287 """
2299 """
2288 from rhodecode.lib.vcs.backends.base import BaseChangeset
2300 from rhodecode.lib.vcs.backends.base import BaseChangeset
2289 if cs_cache is None:
2301 if cs_cache is None:
@@ -2310,17 +2322,20 b' class Repository(Base, BaseModel):'
2310 if is_outdated(cs_cache) or not self.changeset_cache:
2322 if is_outdated(cs_cache) or not self.changeset_cache:
2311 _default = datetime.datetime.utcnow()
2323 _default = datetime.datetime.utcnow()
2312 last_change = cs_cache.get('date') or _default
2324 last_change = cs_cache.get('date') or _default
2313 if self.updated_on and self.updated_on > last_change:
2325 # we check if last update is newer than the new value
2314 # we check if last update is newer than the new value
2326 # if yes, we use the current timestamp instead. Imagine you get
2315 # if yes, we use the current timestamp instead. Imagine you get
2327 # old commit pushed 1y ago, we'd set last update 1y to ago.
2316 # old commit pushed 1y ago, we'd set last update 1y to ago.
2328 last_change_timestamp = datetime_to_time(last_change)
2317 last_change = _default
2329 current_timestamp = datetime_to_time(last_change)
2318 log.debug('updated repo %s with new cs cache %s',
2330 if last_change_timestamp > current_timestamp:
2319 self.repo_name, cs_cache)
2331 cs_cache['date'] = _default
2320 self.updated_on = last_change
2332
2321 self.changeset_cache = cs_cache
2333 self.changeset_cache = cs_cache
2322 Session().add(self)
2334 Session().add(self)
2323 Session().commit()
2335 Session().commit()
2336
2337 log.debug('updated repo %s with new commit cache %s',
2338 self.repo_name, cs_cache)
2324 else:
2339 else:
2325 log.debug('Skipping update_commit_cache for repo:`%s` '
2340 log.debug('Skipping update_commit_cache for repo:`%s` '
2326 'commit already with latest changes', self.repo_name)
2341 'commit already with latest changes', self.repo_name)
@@ -2489,6 +2504,8 b' class RepoGroup(Base, BaseModel):'
2489 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
2504 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
2490 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
2505 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
2491 personal = Column('personal', Boolean(), nullable=True, unique=None, default=None)
2506 personal = Column('personal', Boolean(), nullable=True, unique=None, default=None)
2507 _changeset_cache = Column(
2508 "changeset_cache", LargeBinary(), nullable=True) # JSON data
2492
2509
2493 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
2510 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
2494 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
2511 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
@@ -2513,6 +2530,29 b' class RepoGroup(Base, BaseModel):'
2513 self._group_name = value
2530 self._group_name = value
2514 self.group_name_hash = self.hash_repo_group_name(value)
2531 self.group_name_hash = self.hash_repo_group_name(value)
2515
2532
2533 @hybrid_property
2534 def changeset_cache(self):
2535 from rhodecode.lib.vcs.backends.base import EmptyCommit
2536 dummy = EmptyCommit().__json__()
2537 if not self._changeset_cache:
2538 dummy['source_repo_id'] = ''
2539 return json.loads(json.dumps(dummy))
2540
2541 try:
2542 return json.loads(self._changeset_cache)
2543 except TypeError:
2544 return dummy
2545 except Exception:
2546 log.error(traceback.format_exc())
2547 return dummy
2548
2549 @changeset_cache.setter
2550 def changeset_cache(self, val):
2551 try:
2552 self._changeset_cache = json.dumps(val)
2553 except Exception:
2554 log.error(traceback.format_exc())
2555
2516 @validates('group_parent_id')
2556 @validates('group_parent_id')
2517 def validate_group_parent_id(self, key, val):
2557 def validate_group_parent_id(self, key, val):
2518 """
2558 """
@@ -2608,8 +2648,7 b' class RepoGroup(Base, BaseModel):'
2608 return q.all()
2648 return q.all()
2609
2649
2610 @property
2650 @property
2611 def parents(self):
2651 def parents(self, parents_recursion_limit = 10):
2612 parents_recursion_limit = 10
2613 groups = []
2652 groups = []
2614 if self.parent_group is None:
2653 if self.parent_group is None:
2615 return groups
2654 return groups
@@ -2632,6 +2671,16 b' class RepoGroup(Base, BaseModel):'
2632 return groups
2671 return groups
2633
2672
2634 @property
2673 @property
2674 def last_commit_change(self):
2675 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2676 empty_date = datetime.datetime.fromtimestamp(0)
2677 date_latest = self.changeset_cache.get('date', empty_date)
2678 try:
2679 return parse_datetime(date_latest)
2680 except Exception:
2681 return empty_date
2682
2683 @property
2635 def last_db_change(self):
2684 def last_db_change(self):
2636 return self.updated_on
2685 return self.updated_on
2637
2686
@@ -2670,7 +2719,7 b' class RepoGroup(Base, BaseModel):'
2670
2719
2671 return cnt + children_count(self)
2720 return cnt + children_count(self)
2672
2721
2673 def _recursive_objects(self, include_repos=True):
2722 def _recursive_objects(self, include_repos=True, include_groups=True):
2674 all_ = []
2723 all_ = []
2675
2724
2676 def _get_members(root_gr):
2725 def _get_members(root_gr):
@@ -2680,11 +2729,16 b' class RepoGroup(Base, BaseModel):'
2680 childs = root_gr.children.all()
2729 childs = root_gr.children.all()
2681 if childs:
2730 if childs:
2682 for gr in childs:
2731 for gr in childs:
2683 all_.append(gr)
2732 if include_groups:
2733 all_.append(gr)
2684 _get_members(gr)
2734 _get_members(gr)
2685
2735
2736 root_group = []
2737 if include_groups:
2738 root_group = [self]
2739
2686 _get_members(self)
2740 _get_members(self)
2687 return [self] + all_
2741 return root_group + all_
2688
2742
2689 def recursive_groups_and_repos(self):
2743 def recursive_groups_and_repos(self):
2690 """
2744 """
@@ -2698,6 +2752,12 b' class RepoGroup(Base, BaseModel):'
2698 """
2752 """
2699 return self._recursive_objects(include_repos=False)
2753 return self._recursive_objects(include_repos=False)
2700
2754
2755 def recursive_repos(self):
2756 """
2757 Returns all children repositories for this group
2758 """
2759 return self._recursive_objects(include_groups=False)
2760
2701 def get_new_name(self, group_name):
2761 def get_new_name(self, group_name):
2702 """
2762 """
2703 returns new full group name based on parent and new name
2763 returns new full group name based on parent and new name
@@ -2708,6 +2768,62 b' class RepoGroup(Base, BaseModel):'
2708 self.parent_group else [])
2768 self.parent_group else [])
2709 return RepoGroup.url_sep().join(path_prefix + [group_name])
2769 return RepoGroup.url_sep().join(path_prefix + [group_name])
2710
2770
2771 def update_commit_cache(self, config=None):
2772 """
2773 Update cache of last changeset for newest repository inside this group, keys should be::
2774
2775 source_repo_id
2776 short_id
2777 raw_id
2778 revision
2779 parents
2780 message
2781 date
2782 author
2783
2784 """
2785 from rhodecode.lib.vcs.utils.helpers import parse_datetime
2786
2787 def repo_groups_and_repos():
2788 all_entries = OrderedDefaultDict(list)
2789
2790 def _get_members(root_gr, pos=0):
2791
2792 for repo in root_gr.repositories:
2793 all_entries[root_gr].append(repo)
2794
2795 # fill in all parent positions
2796 for parent_group in root_gr.parents:
2797 all_entries[parent_group].extend(all_entries[root_gr])
2798
2799 children_groups = root_gr.children.all()
2800 if children_groups:
2801 for cnt, gr in enumerate(children_groups, 1):
2802 _get_members(gr, pos=pos+cnt)
2803
2804 _get_members(root_gr=self)
2805 return all_entries
2806
2807 empty_date = datetime.datetime.fromtimestamp(0)
2808 for repo_group, repos in repo_groups_and_repos().items():
2809
2810 latest_repo_cs_cache = {}
2811 for repo in repos:
2812 repo_cs_cache = repo.changeset_cache
2813 date_latest = latest_repo_cs_cache.get('date', empty_date)
2814 date_current = repo_cs_cache.get('date', empty_date)
2815 current_timestamp = datetime_to_time(parse_datetime(date_latest))
2816 if current_timestamp < datetime_to_time(parse_datetime(date_current)):
2817 latest_repo_cs_cache = repo_cs_cache
2818 latest_repo_cs_cache['source_repo_id'] = repo.repo_id
2819
2820 repo_group.changeset_cache = latest_repo_cs_cache
2821 Session().add(repo_group)
2822 Session().commit()
2823
2824 log.debug('updated repo group %s with new commit cache %s',
2825 repo_group.group_name, latest_repo_cs_cache)
2826
2711 def permissions(self, with_admins=True, with_owner=True,
2827 def permissions(self, with_admins=True, with_owner=True,
2712 expand_from_user_groups=False):
2828 expand_from_user_groups=False):
2713 """
2829 """
@@ -192,7 +192,7 b' class RepoModel(BaseModel):'
192 return repo_log
192 return repo_log
193
193
194 @classmethod
194 @classmethod
195 def update_repoinfo(cls, repositories=None):
195 def update_commit_cache(cls, repositories=None):
196 if not repositories:
196 if not repositories:
197 repositories = Repository.getAll()
197 repositories = Repository.getAll()
198 for repo in repositories:
198 for repo in repositories:
@@ -309,6 +309,10 b' class RepoGroupModel(BaseModel):'
309 # trigger the post hook
309 # trigger the post hook
310 from rhodecode.lib.hooks_base import log_create_repository_group
310 from rhodecode.lib.hooks_base import log_create_repository_group
311 repo_group = RepoGroup.get_by_group_name(group_name)
311 repo_group = RepoGroup.get_by_group_name(group_name)
312
313 # update repo group commit caches initially
314 repo_group.update_commit_cache()
315
312 log_create_repository_group(
316 log_create_repository_group(
313 created_by=user.username, **repo_group.get_dict())
317 created_by=user.username, **repo_group.get_dict())
314
318
@@ -686,6 +690,13 b' class RepoGroupModel(BaseModel):'
686 'revoked permission from usergroup: {} on repogroup: {}'.format(
690 'revoked permission from usergroup: {} on repogroup: {}'.format(
687 group_name, repo_group), namespace='security.repogroup')
691 group_name, repo_group), namespace='security.repogroup')
688
692
693 @classmethod
694 def update_commit_cache(cls, repo_groups=None):
695 if not repo_groups:
696 repo_groups = RepoGroup.getAll()
697 for repo_group in repo_groups:
698 repo_group.update_commit_cache()
699
689 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
700 def get_repo_groups_as_dict(self, repo_group_list=None, admin=False,
690 super_user_actions=False):
701 super_user_actions=False):
691
702
@@ -707,6 +718,11 b' class RepoGroupModel(BaseModel):'
707 (datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
718 (datetime.datetime.now() - datetime.datetime.utcnow()).seconds)
708 return _render("last_change", last_change)
719 return _render("last_change", last_change)
709
720
721 def last_rev(repo_name, cs_cache):
722 return _render('revision', repo_name, cs_cache.get('revision'),
723 cs_cache.get('raw_id'), cs_cache.get('author'),
724 cs_cache.get('message'), cs_cache.get('date'))
725
710 def desc(desc, personal):
726 def desc(desc, personal):
711 return _render(
727 return _render(
712 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
728 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
@@ -723,13 +739,15 b' class RepoGroupModel(BaseModel):'
723
739
724 repo_group_data = []
740 repo_group_data = []
725 for group in repo_group_list:
741 for group in repo_group_list:
742 cs_cache = group.changeset_cache
743 last_repo_name = cs_cache.get('source_repo_name')
726
744
727 row = {
745 row = {
728 "menu": quick_menu(group.group_name),
746 "menu": quick_menu(group.group_name),
729 "name": repo_group_lnk(group.group_name),
747 "name": repo_group_lnk(group.group_name),
730 "name_raw": group.group_name,
748 "name_raw": group.group_name,
731 "last_change": last_change(group.last_db_change),
749 "last_change": last_change(group.last_commit_change),
732 "last_change_raw": datetime_to_time(group.last_db_change),
750 "last_change_raw": datetime_to_time(group.last_commit_change),
733
751
734 "last_changeset": "",
752 "last_changeset": "",
735 "last_changeset_raw": "",
753 "last_changeset_raw": "",
@@ -292,7 +292,7 b''
292 position: absolute;
292 position: absolute;
293 top: 100%;
293 top: 100%;
294 left: 0;
294 left: 0;
295 min-width: 150px;
295 min-width: 180px;
296 margin: 2px 0 0;
296 margin: 2px 0 0;
297 padding: 0;
297 padding: 0;
298 text-align: left;
298 text-align: left;
@@ -1,10 +1,16 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <%
3 <%
4 source_repo_id = c.repo_group.changeset_cache.get('source_repo_id')
5
4 elems = [
6 elems = [
5 (_('Repository Group ID'), c.repo_group.group_id, '', ''),
7 (_('Repository Group ID'), c.repo_group.group_id, '', ''),
6 (_('Owner'), lambda:base.gravatar_with_user(c.repo_group.user.email), '', ''),
8 (_('Owner'), lambda:base.gravatar_with_user(c.repo_group.user.email), '', ''),
7 (_('Created on'), h.format_date(c.repo_group.created_on), '', ''),
9 (_('Created on'), h.format_date(c.repo_group.created_on), '', ''),
10 (_('Updated on'), h.format_date(c.repo_group.updated_on), '', ''),
11 (_('Cached Commit date'), (c.repo_group.changeset_cache.get('date')), '', ''),
12 (_('Cached Commit repo_id'), (h.link_to_if(source_repo_id, source_repo_id, h.route_path('repo_summary', repo_name='_{}'.format(source_repo_id)))), '', ''),
13
8 (_('Is Personal Group'), c.repo_group.personal or False, '', ''),
14 (_('Is Personal Group'), c.repo_group.personal or False, '', ''),
9
15
10 (_('Total repositories'), c.repo_group.repositories_recursive_count, '', ''),
16 (_('Total repositories'), c.repo_group.repositories_recursive_count, '', ''),
@@ -7,6 +7,7 b''
7 (_('Created on'), h.format_date(c.rhodecode_db_repo.created_on), '', ''),
7 (_('Created on'), h.format_date(c.rhodecode_db_repo.created_on), '', ''),
8 (_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''),
8 (_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''),
9 (_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''),
9 (_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''),
10 (_('Cached Commit date'), c.rhodecode_db_repo.changeset_cache.get('date'), '', ''),
10 (_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]),
11 (_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]),
11 (_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]),
12 (_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]),
12 (_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]),
13 (_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]),
General Comments 0
You need to be logged in to leave comments. Login now