diff --git a/rhodecode/controllers/home.py b/rhodecode/controllers/home.py --- a/rhodecode/controllers/home.py +++ b/rhodecode/controllers/home.py @@ -76,6 +76,13 @@ class HomeController(BaseController): .render(repo_name, _=_, h=h, c=c)) atom_lnk = lambda repo_name: (template.get_def("atom") .render(repo_name, _=_, h=h, c=c)) + tip = lambda repo_name, cs_cache: (template.get_def("revision") + .render(repo_name, + cs_cache.get('revision'), + cs_cache.get('raw_id'), + cs_cache.get('author'), + cs_cache.get('message'), _=_, h=h, + c=c)) def desc(desc): if c.visual.stylify_metatags: @@ -90,6 +97,7 @@ class HomeController(BaseController): "name": repo_lnk(repo.repo_name, repo.repo_type, repo.private, repo.fork), "last_change": last_change(repo.last_db_change), + "tip": tip(repo.repo_name, repo.changeset_cache), "desc": desc(repo.description), "owner": h.person(repo.user.username), "rss": rss_lnk(repo.repo_name), diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -319,7 +319,7 @@ class BaseRepoController(BaseController) dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name) c.rhodecode_repo = c.rhodecode_db_repo.scm_instance # update last change according to VCS data - dbr.update_last_change(c.rhodecode_repo.last_change) + dbr.update_changeset_cache(dbr.get_changeset()) if c.rhodecode_repo is None: log.error('%s this repository is present in database but it ' 'cannot be created as an scm instance', c.repo_name) diff --git a/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py b/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py --- a/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py +++ b/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py @@ -28,6 +28,23 @@ def upgrade(migrate_engine): tbl = UserIpMap.__table__ tbl.create() + #========================================================================== + # REPOSITORIES + #========================================================================== + from rhodecode.lib.dbmigrate.schema.db_1_5_0 import Repository + tbl = Repository.__table__ + changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) + # create username column + changeset_cache.create(table=tbl) + + #fix cache data + _Session = Session() + ## after adding that column fix all usernames + repositories = _Session.query(Repository).all() + for entry in repositories: + entry.update_changeset_cache() + _Session.commit() + def downgrade(migrate_engine): meta = MetaData() diff --git a/rhodecode/lib/update_repoinfo.py b/rhodecode/lib/update_repoinfo.py --- a/rhodecode/lib/update_repoinfo.py +++ b/rhodecode/lib/update_repoinfo.py @@ -34,6 +34,7 @@ from os.path import dirname as dn, join from rhodecode.model import init_model from rhodecode.lib.utils2 import engine_from_config, safe_str from rhodecode.model.db import RhodeCodeUi, Repository +from rhodecode.lib.vcs.backends.base import EmptyChangeset #to get the rhodecode import @@ -73,9 +74,9 @@ class UpdateCommand(BasePasterCommand): else: repo_list = Repository.getAll() for repo in repo_list: - last_change = (repo.scm_instance.last_change if repo.scm_instance - else datetime.datetime.utcfromtimestamp(0)) - repo.update_last_change(last_change) + last_cs = (repo.scm_instance.get_changeset() if repo.scm_instance + else EmptyChangeset()) + repo.update_changeset_cache(last_cs) def update_parser(self): self.parser.add_option('--update-only', diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -455,6 +455,7 @@ def repo2db_mapper(initial_repo_list, re # installed if new_repo.repo_type == 'git': ScmModel().install_git_hook(new_repo.scm_instance) + new_repo.update_changeset_cache() elif install_git_hook: if db_repo.repo_type == 'git': ScmModel().install_git_hook(db_repo.scm_instance) diff --git a/rhodecode/lib/vcs/backends/base.py b/rhodecode/lib/vcs/backends/base.py --- a/rhodecode/lib/vcs/backends/base.py +++ b/rhodecode/lib/vcs/backends/base.py @@ -376,6 +376,7 @@ class BaseChangeset(object): return dict( short_id=self.short_id, raw_id=self.raw_id, + revision=self.revision, message=self.message, date=self.date, author=self.author, diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -671,7 +671,7 @@ class Repository(Base, BaseModel): landing_rev = Column("landing_revision", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None) - #changeset_cache = Column("changeset_cache", LargeBinary(), nullable=False) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) @@ -717,6 +717,24 @@ class Repository(Base, BaseModel): else: self._locked = None + @hybrid_property + def changeset_cache(self): + from rhodecode.lib.vcs.backends.base import EmptyChangeset + dummy = EmptyChangeset().__json__() + if not self._changeset_cache: + return dummy + try: + return json.loads(self._changeset_cache) + except TypeError: + return dummy + + @changeset_cache.setter + def changeset_cache(self, val): + try: + self._changeset_cache = json.dumps(val) + except: + log.error(traceback.format_exc()) + @classmethod def url_sep(cls): return URL_SEP @@ -914,12 +932,30 @@ class Repository(Base, BaseModel): cs = self.get_changeset(self.landing_rev) or self.get_changeset() return cs - def update_last_change(self, last_change=None): - if last_change is None: - last_change = datetime.datetime.now() - if self.updated_on is None or self.updated_on != last_change: - log.debug('updated repo %s with new date %s' % (self, last_change)) + def update_changeset_cache(self, cs_cache=None): + """ + Update cache of last changeset for repository, keys should be:: + + short_id + raw_id + revision + message + date + author + + :param cs_cache: + """ + from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: + cs_cache = self.get_changeset() + if isinstance(cs_cache, BaseChangeset): + cs_cache = cs_cache.__json__() + + if cs_cache != self.changeset_cache: + last_change = cs_cache.get('date') or self.last_change + log.debug('updated repo %s with new cs cache %s' % (self, cs_cache)) self.updated_on = last_change + self.changeset_cache = cs_cache Session().add(self) Session().commit() diff --git a/rhodecode/templates/index_base.html b/rhodecode/templates/index_base.html --- a/rhodecode/templates/index_base.html +++ b/rhodecode/templates/index_base.html @@ -233,6 +233,7 @@ {key:"name"}, {key:"desc"}, {key:"last_change"}, + {key: "tip"}, {key:"owner"}, {key:"rss"}, {key:"atom"}, @@ -266,6 +267,8 @@ {key:"desc",label:"${_('Description')}",sortable:true}, {key:"last_change",label:"${_('Last Change')}",sortable:true, sortOptions: { sortFunction: ageSort }}, + {key:"tip",label:"${_('Tip')}",sortable:true, + sortOptions: { sortFunction: revisionSort }}, {key:"owner",label:"${_('Owner')}",sortable:true}, {key:"rss",label:"",sortable:false}, {key:"atom",label:"",sortable:false}, diff --git a/setup.cfg b/setup.cfg --- a/setup.cfg +++ b/setup.cfg @@ -11,8 +11,8 @@ verbosity=2 with-pylons=test.ini detailed-errors=1 nologcapture=1 -#pdb=1 -#pdb-failures=1 +pdb=1 +pdb-failures=1 # Babel configuration [compile_catalog]