Changeset - bb35ad076e2f
[Not reviewed]
beta
0 8 5
Marcin Kuzminski - 15 years ago 2010-12-05 17:22:57
marcin@python-works.com
docs updates
13 files changed with 182 insertions and 40 deletions:
0 comments (0 inline, 0 general)
docs/api/index.rst
Show inline comments
 
new file 100644
 
.. _api:
 

	
 
API Reference
 
=============
 

	
 
.. toctree::
 
   :maxdepth: 3
 

	
 
   models
 
    
 
\ No newline at end of file
docs/api/models.rst
Show inline comments
 
new file 100644
 
.. _models::
 

	
 
The :mod:`models` Module
 
========================
 

	
 
.. automodule:: rhodecode.model
 
   :members:
 
   
 
.. automodule:: rhodecode.model.permission
 
   :members:
 
  
 
.. automodule:: rhodecode.model.repo
 
   :members:   
 

	
 
.. automodule:: rhodecode.model.scm
 
   :members:
 

	
 
.. automodule:: rhodecode.model.user
 
   :members:      
 
\ No newline at end of file
docs/changelog.rst
Show inline comments
 
@@ -15,12 +15,13 @@ news
 
- rewrite of internals for vcs >=0.1.10
 
- uses mercurial 1.7 with dotencode disabled for maintaining compatibility 
 
  with older clients
 
- anonymous access, authentication via ldap
 
- performance upgrade for cached repos list - each repository has it's own 
 
  cache that's invalidated when needed.
 
- performance upgrades on repositories with large amount of commits (20K+)
 
- main page quick filter for filtering repositories
 
- user dashboards with ability to follow chosen repositories actions
 
- sends email to admin on new user registration
 
- added cache/statistics reset options into repository settings
 
- more detailed action logger (based on hooks) with pushed changesets lists
 
  and options to disable those hooks from admin panel
docs/contributing.rst
Show inline comments
 
new file 100644
 
.. _contributing:
 

	
 
Contributing in RhodeCode
 
=========================
 

	
 
If You would like to contribute to RhodeCode, please contact me, any help is
 
greatly appreciated.
 

	
 
Thank You.
docs/enable_git.rst
Show inline comments
 
new file 100644
 
.. _enable_git:
 

	
 
Enabling GIT support (beta)
 
===========================
 

	
 

	
 
Git support in RhodeCode 1.1 was disabled due to some instability issues, but
 
If You would like to test it fell free to re-enable it. To enable GIT just
 
uncomment git line in rhodecode/__init__.py file
 

	
 
.. code-block:: python
 
 
 
   BACKENDS = {
 
       'hg': 'Mercurial repository',
 
       #'git': 'Git repository',
 
   }
 

	
 
.. note::
 
   Please note that it's not fully stable and it might crash (that's why it 
 
   was disabled), so be carefull about enabling git support. Don't use it in 
 
   production !
 
\ No newline at end of file
docs/images/screenshot1_main_page.png
Show inline comments
 
binary diff not shown
Show images
docs/index.rst
Show inline comments
 
@@ -10,14 +10,37 @@ Documentation
 
.. toctree::
 
   :maxdepth: 1
 

	
 
   installation
 
   setup
 
   upgrade
 
   
 
**Usage**
 

	
 
.. toctree::
 
   :maxdepth: 1
 

	
 
   enable_git
 
   statistics
 
   
 
**Develop**
 

	
 
.. toctree::
 
   :maxdepth: 1
 
   
 
   contributing
 
   changelog
 

	
 
**API**
 

	
 
.. toctree::
 
   :maxdepth: 2
 

	
 
   api/index
 
   
 

	
 
Other topics
 
------------
 

	
 
* :ref:`genindex`
 
* :ref:`search`
 

	
docs/statistics.rst
Show inline comments
 
new file 100644
 
.. _statistics:
 

	
 

	
 
Statistics
 
==========
 

	
 
RhodeCode statistics system is heavy on resources, so in order to keep a 
 
balance between the usability and performance statistics are cached inside db
 
and are gathered incrementally, this is how RhodeCode does this:
 

	
 
With Celery disabled
 
++++++++++++++++++++
 

	
 
- on each first visit on summary page a set of 250 commits are parsed and
 
  updates statistics cache
 
- this happens on each single visit of statistics page until all commits are
 
  fetched. Statistics are kept cached until some more commits are added to
 
  repository, in such case RhodeCode will fetch only the ones added and will
 
  update it's cache.
 

	
 

	
 
With Celery enabled
 
+++++++++++++++++++
 

	
 
- on first visit on summary page RhodeCode will create task that will execute
 
  on celery workers, that will gather all stats until all commits are parsed,
 
  each task will parse 250 commits, and run next task to parse next 250 
 
  commits, until all are parsed.
 

	
 
.. note::
 
   In any time You can disable statistics on each repository in repository edit
 
   form in admin panel, just uncheck the statistics checkbox.
 
\ No newline at end of file
rhodecode/model/__init__.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    package.rhodecode.model.__init__
 
    ~~~~~~~~~~~~~~
 
    rhodecode.model.__init__
 
    ~~~~~~~~~~~~~~~~~~~~~~~~
 
    
 
    The application's model objects
 
    
 
    :created_on: Nov 25, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :license: GPLv3, see COPYING for more details.
 
    
 
    
 
    :example:
 
        from paste.deploy import appconfig
 
        from pylons import config
 
        from sqlalchemy import engine_from_config
 
        from rhodecode.config.environment import load_environment
 
        
 
        conf = appconfig('config:development.ini', relative_to = './../../')
 
        load_environment(conf.global_conf, conf.local_conf)
 
        
 
        engine = engine_from_config(config, 'sqlalchemy.')
 
        init_model(engine)
 
        #RUN YOUR CODE HERE    
 
    
 
        .. code-block:: python
 
    
 
           from paste.deploy import appconfig
 
           from pylons import config
 
           from sqlalchemy import engine_from_config
 
           from rhodecode.config.environment import load_environment
 
           
 
           conf = appconfig('config:development.ini', relative_to = './../../')
 
           load_environment(conf.global_conf, conf.local_conf)
 
           
 
           engine = engine_from_config(config, 'sqlalchemy.')
 
           init_model(engine)
 
           # RUN YOUR CODE HERE
 
    
 
"""
 
# This program is free software; you can redistribute it and/or
 
# modify it under the terms of the GNU General Public License
 
# as published by the Free Software Foundation; version 2
 
# of the License or (at your opinion) any later version of the license.
 
@@ -41,17 +45,27 @@
 

	
 
import logging
 
from rhodecode.model import meta
 
log = logging.getLogger(__name__)
 

	
 
def init_model(engine):
 
    """Call me before using any of the tables or classes in the model"""
 
    """Initializes db session, bind the engine with the metadata,
 
    Call this before using any of the tables or classes in the model, preferably
 
    once in application start
 
    
 
    :param engine: engine to bind to
 
    """
 
    log.info("initializing db models for %s", engine)
 
    meta.Base.metadata.bind = engine
 

	
 
class BaseModel(object):
 
    """Base Model for all RhodeCode models, it adds sql alchemy session
 
    into instance of model
 
    
 
    :param sa: If passed it reuses this session instead of creating a new one
 
    """
 

	
 
    def __init__(self, sa=None):
 
        if sa is not None:
 
            self.sa = sa
 
        else:
 
            self.sa = meta.Session()
rhodecode/model/permission.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    package.rhodecode.model.permission
 
    ~~~~~~~~~~~~~~
 
    rhodecode.model.permission
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    permissions model for RhodeCode
 
    
 
    :created_on: Aug 20, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software; you can redistribute it and/or
 
@@ -34,21 +35,33 @@ from rhodecode.model.db import User, Per
 
from rhodecode.model.caching_query import FromCache
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PermissionModel(BaseModel):
 
    """Permissions model for RhodeCode
 
    """
 

	
 
    def get_permission(self, permission_id, cache=False):
 
        """Get's permissions by id
 
        
 
        :param permission_id: id of permission to get from database
 
        :param cache: use Cache for this query
 
        """
 
        perm = self.sa.query(Permission)
 
        if cache:
 
            perm = perm.options(FromCache("sql_cache_short",
 
                                          "get_permission_%s" % permission_id))
 
        return perm.get(permission_id)
 

	
 
    def get_permission_by_name(self, name, cache=False):
 
        """Get's permissions by given name
 
        
 
        :param name: name to fetch
 
        :param cache: Use cache for this query
 
        """
 
        perm = self.sa.query(Permission)\
 
            .filter(Permission.permission_name == name)
 
        if cache:
 
            perm = perm.options(FromCache("sql_cache_short",
 
                                          "get_permission_%s" % name))
 
        return perm.scalar()
rhodecode/model/repo.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    package.rhodecode.model.repo
 
    ~~~~~~~~~~~~~~
 
    rhodecode.model.repo
 
    ~~~~~~~~~~~~~~~~~~~~
 

	
 
    Repository model for rhodecode
 
    
 
    :created_on: Jun 5, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
rhodecode/model/scm.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    package.rhodecode.model.scm
 
    ~~~~~~~~~~~~~~
 
    rhodecode.model.scm
 
    ~~~~~~~~~~~~~~~~~~~
 

	
 
    scm model for RhodeCode 
 
    Scm model for RhodeCode
 

	
 
    :created_on: Apr 9, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software; you can redistribute it and/or
 
@@ -20,13 +21,12 @@
 
# GNU General Public License for more details.
 
# 
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import os
 
import time
 
import traceback
 
import logging
 

	
 
from vcs import get_backend
 
@@ -61,33 +61,32 @@ class UserTemp(object):
 
        self.user_id = user_id
 
class RepoTemp(object):
 
    def __init__(self, repo_id):
 
        self.repo_id = repo_id
 

	
 
class ScmModel(BaseModel):
 
    """
 
    Mercurial Model
 
    """Generic Scm Model
 
    """
 

	
 
    @LazyProperty
 
    def repos_path(self):
 
        """Get's the repositories root path from database
 
        """
 
        Get's the repositories root path from database
 
        """
 

	
 
        q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
 

	
 
        return q.ui_value
 

	
 
    def repo_scan(self, repos_path, baseui):
 
        """
 
        Listing of repositories in given path. This path should not be a 
 
        """Listing of repositories in given path. This path should not be a 
 
        repository itself. Return a dictionary of repository objects
 
        
 
        :param repos_path: path to directory containing repositories
 
        :param baseui
 
        """
 

	
 
        log.info('scanning for repositories in %s', repos_path)
 

	
 
        if not isinstance(baseui, ui.ui):
 
            baseui = make_ui('db')
 
        repos_list = {}
 

	
 
@@ -108,18 +107,18 @@ class ScmModel(BaseModel):
 
            except OSError:
 
                continue
 

	
 
        return repos_list
 

	
 
    def get_repos(self, all_repos=None):
 
        """
 
        Get all repos from db and for each repo create it's backend instance.
 
        """Get all repos from db and for each repo create it's backend instance.
 
        and fill that backed with information from database
 
        
 
        :param all_repos: give specific repositories list, good for filtering
 
        """
 

	
 
        if all_repos is None:
 
            all_repos = self.sa.query(Repository)\
 
                .order_by(Repository.repo_name).all()
 

	
 
        #get the repositories that should be invalidated
 
        invalidation_list = [str(x.cache_key) for x in \
 
@@ -153,14 +152,13 @@ class ScmModel(BaseModel):
 
                yield tmp_d
 

	
 
    def get_repo(self, repo_name):
 
        return self.get(repo_name)
 

	
 
    def get(self, repo_name, invalidation_list=None):
 
        """
 
        Get's repository from given name, creates BackendInstance and
 
        """Get's repository from given name, creates BackendInstance and
 
        propagates it's data from database with all additional information
 
        
 
        :param repo_name:
 
        :param invalidation_list: if a invalidation list is given the get
 
            method should not manually check if this repository needs 
 
            invalidation and just invalidate the repositories in list
 
@@ -225,18 +223,18 @@ class ScmModel(BaseModel):
 

	
 
        return _get_repo(repo_name)
 

	
 

	
 

	
 
    def mark_for_invalidation(self, repo_name):
 
        """
 
        Puts cache invalidation task into db for 
 
        """Puts cache invalidation task into db for 
 
        further global cache invalidation
 
        
 
        :param repo_name: this repo that should invalidation take place
 
        """
 

	
 
        log.debug('marking %s for invalidation', repo_name)
 
        cache = self.sa.query(CacheInvalidation)\
 
            .filter(CacheInvalidation.cache_key == repo_name).scalar()
 

	
 
        if cache:
 
            #mark this cache as inactive
 
@@ -344,14 +342,14 @@ class ScmModel(BaseModel):
 

	
 
    def get_unread_journal(self):
 
        return self.sa.query(UserLog).count()
 

	
 

	
 
    def _should_invalidate(self, repo_name):
 
        """
 
        Looks up database for invalidation signals for this repo_name
 
        """Looks up database for invalidation signals for this repo_name
 
        
 
        :param repo_name:
 
        """
 

	
 
        ret = self.sa.query(CacheInvalidation)\
 
            .options(FromCache('sql_cache_short',
 
                           'get_invalidation_%s' % repo_name))\
 
@@ -359,16 +357,17 @@ class ScmModel(BaseModel):
 
            .filter(CacheInvalidation.cache_active == False)\
 
            .scalar()
 

	
 
        return ret
 

	
 
    def _mark_invalidated(self, cache_key):
 
        """ Marks all occurences of cache to invaldation as already invalidated
 
        
 
        :param cache_key:
 
        """
 
        Marks all occurences of cache to invaldation as already invalidated
 
        :param repo_name:
 
        """
 

	
 
        if cache_key:
 
            log.debug('marking %s as already invalidated', cache_key)
 
        try:
 
            cache_key.cache_active = True
 
            self.sa.add(cache_key)
 
            self.sa.commit()
rhodecode/model/user.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    package.rhodecode.model.user
 
    ~~~~~~~~~~~~~~
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    users model for RhodeCode
 
    
 
    :created_on: Apr 9, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software; you can redistribute it and/or
0 comments (0 inline, 0 general)