Changeset - ba7e24cd4786
[Not reviewed]
default
0 10 0
Marcin Kuzminski - 15 years ago 2010-10-09 16:05:14
marcin@python-works.com
refactor codes and setup for python 2.5
readme update
10 files changed with 65 insertions and 63 deletions:
0 comments (0 inline, 0 general)
README.rst
Show inline comments
 
--------------------------------------------------------------
 
Pylons based repository management for mercurial (and soon git)
 
--------------------------------------------------------------
 

	
 
Fully customizable, with authentication, permissions. Based on vcs library.
 
------------------------------------------------
 
Pylons based repository management for mercurial
 
------------------------------------------------
 

	
 
**Overview**
 

	
 
- has it's own middleware to handle mercurial protocol request each request can 
 
  be logged and authenticated + threaded performance unlikely to hgweb
 
- full permissions per project read/write/admin access even on mercurial request
 
- mako templates let's you customize look and feel of application.
 
- diffs annotations and source code all colored by pygments.
 
- mercurial branch graph and yui-flot powered graphs with zooming and statistics
 
- admin interface for performing user/permission managements as well as repository
 
  management.
 
- server side forks, it's possible to fork a project and hack it free without
 
- Has it's own middleware to handle mercurial protocol request. Each request can 
 
  be logged and authenticated. Runs on threads unlikely to hgweb You can make
 
  multiple pulls/pushes simultaneous
 
- Full permissions and authentication per project private/read/write/admin. 
 
  One account for web interface and mercurial push/pull/clone.
 
- Mako templates let's you customize look and feel of application.
 
- Beautiful diffs, annotations and source codes all colored by pygments.
 
- Mercurial branch graph and yui-flot powered graphs with zooming and statistics
 
- Admin interface with user/permission management. User activity journal logs
 
  pulls, pushes, forks,registrations. Possible to disable built in hooks
 
- Server side forks, it's possible to fork a project and hack it free without
 
  breaking the main.   
 
- full text search of source codes with indexing daemons using whoosh
 
- Full text search on source codes, search on file names. All powered by whoosh
 
  and build in indexing daemons
 
  (no external search servers required all in one application)
 
- async tasks for speed and performance using celery (works without them too)  
 
- Additional settings for mercurial web, (hooks editable from admin
 
  panel !) also manage paths, archive, remote messages  
 
- backup scripts can do backup of whole app and send it over scp to desired location
 
- setup project descriptions and info inside built in db for easy, non 
 
- Rss / atom feeds, gravatar support, download sources as zip/tarballs  
 
- Async tasks for speed and performance using celery (works without them too)  
 
- Backup scripts can do backup of whole app and send it over scp to desired 
 
  location
 
- Setup project descriptions and info inside built in db for easy, non 
 
  file-system operations
 
- added cache with invalidation on push/repo management for high performance and
 
- Added cache with invalidation on push/repo management for high performance and
 
  always up to date data. 
 
- rss / atom feeds, gravatar support
 
- based on pylons 1.0 / sqlalchemy 0.6
 
- Based on pylons 1.0 / sqlalchemy 0.6 / sqlite
 

	
 
**Incoming**
 

	
 
- code review based on hg-review (when it's stable)
 
- git support (when vcs can handle it - almost there !)
 
- commit based wikis
 
- clonning from remote repositories into rhodecode (git/mercurial)
 
- other cools stuff that i can figure out (or You can help me figure out)
 

	
 
.. note::
 
   This software is still in beta mode. 
 
   I don't guarantee that it'll work correctly.
 
   
 
------------
 
Installation
 
------------
 

	
 
-------------
 
Installation
 
-------------
 

	
 
quick setup
 
**quick setup**
 
 
 
- pip install -E rhodecode-venv http://bitbucket.org/marcinkuzminski/rhodecode/get/tip.zip
 
- pip install -E rhodecode-venv rhodecode
 
- activate virtualenv
 
- run `paster make-config RhodeCode production.ini`
 
- run `paster setup-app production.ini`
 
- run `paster runserver production.ini`
 

	
 
You're ready to go.
 

	
 

	
 
MORE DETAILED INSTRUCTIONS
 
**MORE DETAILED INSTRUCTIONS**
 

	
 
- I highly recommend to install new virtualenv for rhodecode see 
 
  http://pypi.python.org/pypi/virtualenv for more details.
 
- Create new virtualenv using `virtualenv --no-site-packages /var/www/rhodecode-venv`
 
  this will install new virtual env into /var/www/rhodecode-venv. 
 
  Activate the virtualenv by running 
 
  `source activate /var/www/rhodecode-venv/bin/activate`   
 
- Make a folder for rhodecode somewhere on the filesystem for example /var/www/rhodecode  
 
- Run easy_install http://bitbucket.org/marcinkuzminski/rhodecode/get/tip.zip.
 
- Run easy_install rhodecode
 
- Run `paster make-config RhodeCode production.inii` in order to install 
 
  the application config. You can play with the app settings later 
 
- Run `paster setup-app production.ini` it should create all needed tables 
 
  and an admin account make sure You specify correct path to repositories. 
 
- Remember that the given path for mercurial repositories must be write 
 
  accessible for the application
 
@@ -80,15 +74,14 @@ MORE DETAILED INSTRUCTIONS
 
  to update these.
 
- In order to use full power of async tasks, You must install message broker
 
  preferably rabbitmq and start celeryd daemon together with rhodecode. 
 
  The app should gain a lot of speed and become much more responsible. 
 
  For installation instructions You can visit: 
 
  http://ask.github.com/celery/getting-started/index.html. 
 
- All needed configs are inside rhodecode ie. celeryconfig.py , production.ini
 
  You can configure the email, ports, loggers, workers from there.
 
- All needed configs are inside rhodecode sources ie. celeryconfig.py, 
 
  development.ini, production.ini You can configure the email, ports, loggers, 
 
  workers from there.
 
- For full text search You can either put crontab entry for 
 
  `python /var/www/rhodecode/rhodecode/lib/indexers/daemon.py incremental <path_to_repos>`
 
  or run indexer from admin panel. This will scann the repos given in the 
 
  application setup or given path for daemon.py and each scann in incremental 
 
  mode will scann only changed files, 
 
  Hg Update hook must be activated to index the content it's enabled by default
 
  after setup
 
\ No newline at end of file
 
  mode will scann only changed files.
 
\ No newline at end of file
rhodecode/controllers/admin/permissions.py
Show inline comments
 
@@ -99,13 +99,13 @@ class PermissionsController(BaseControll
 
            form_result = _form.to_python(dict(request.POST))
 
            form_result.update({'perm_user_name':id})
 
            permission_model.update(form_result)
 
            h.flash(_('Default permissions updated succesfully'),
 
                    category='success')
 
                           
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.perms_choices = self.perms_choices
 
            c.register_choices = self.register_choices
 
            c.create_choices = self.create_choices
 
                    
 
            return htmlfill.render(
 
                render('admin/permissions/permissions.html'),
rhodecode/controllers/admin/repos.py
Show inline comments
 
@@ -76,19 +76,19 @@ class ReposController(BaseController):
 
            repo_model.create(form_result, c.rhodecode_user)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('created repository %s') % form_result['repo_name'],
 
                    category='success')
 

	
 
            if request.POST.get('user_created'):
 
                action_logger(self.rhodecode_user, 'user_created_repo', 
 
                action_logger(self.rhodecode_user, 'user_created_repo',
 
                              form_result['repo_name'], '', self.sa)
 
            else:
 
                action_logger(self.rhodecode_user, 'admin_created_repo', 
 
                action_logger(self.rhodecode_user, 'admin_created_repo',
 
                              form_result['repo_name'], '', self.sa)                
 
                                                                             
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.new_repo = errors.value['repo_name']
 
            
 
            if request.POST.get('user_created'):
 
                r = render('admin/repos/repo_add_create_repository.html')
 
            else:              
 
                r = render('admin/repos/repo_add.html')
 
@@ -134,13 +134,13 @@ class ReposController(BaseController):
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('Repository %s updated succesfully' % repo_name),
 
                    category='success')
 
            changed_name = form_result['repo_name']
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.repo_info = repo_model.get(repo_name)
 
            c.users_array = repo_model.get_users_js()
 
            errors.value.update({'user':c.repo_info.user.username})
 
            return htmlfill.render(
 
                render('admin/repos/repo_edit.html'),
 
                defaults=errors.value,
 
@@ -173,13 +173,13 @@ class ReposController(BaseController):
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % repo_name,
 
                      category='error')
 
        
 
            return redirect(url('repos'))
 
        try:
 
            action_logger(self.rhodecode_user, 'admin_deleted_repo', 
 
            action_logger(self.rhodecode_user, 'admin_deleted_repo',
 
                              repo_name, '', self.sa)
 
            repo_model.delete(repo)            
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 
           
 
        except Exception, e:
 
@@ -196,13 +196,13 @@ class ReposController(BaseController):
 
        @param repo_name:
 
        """
 
        
 
        try:
 
            repo_model = RepoModel()
 
            repo_model.delete_perm_user(request.POST, repo_name)            
 
        except Exception as e:
 
        except Exception, e:
 
            h.flash(_('An error occured during deletion of repository user'),
 
                    category='error')
 
            raise HTTPInternalServerError()
 
    
 
    @HasPermissionAllDecorator('hg.admin')    
 
    def show(self, repo_name, format='html'):
rhodecode/controllers/admin/settings.py
Show inline comments
 
@@ -137,13 +137,13 @@ class SettingsController(BaseController)
 
                    h.flash(_('error occurred during updating application settings'),
 
                            category='error')
 
                                
 
                    self.sa.rollback()
 
                    
 

	
 
            except formencode.Invalid as errors:
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                     render('admin/settings/settings.html'),
 
                     defaults=errors.value,
 
                     errors=errors.error_dict or {},
 
                     prefix_error=False,
 
                     encoding="UTF-8") 
 
@@ -190,13 +190,13 @@ class SettingsController(BaseController)
 
                    h.flash(_('error occurred during updating application settings'),
 
                            category='error')
 
                                
 
                    self.sa.rollback()
 
                    
 

	
 
            except formencode.Invalid as errors:
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                     render('admin/settings/settings.html'),
 
                     defaults=errors.value,
 
                     errors=errors.error_dict or {},
 
                     prefix_error=False,
 
                     encoding="UTF-8") 
 
@@ -266,13 +266,13 @@ class SettingsController(BaseController)
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            user_model.update_my_account(uid, form_result)
 
            h.flash(_('Your account was updated succesfully'),
 
                    category='success')
 
                           
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.user = self.sa.query(User).get(c.rhodecode_user.user_id)
 
            c.user_repos = []
 
            for repo in c.cached_repo_list.values():
 
                if repo.dbrepo.user.username == c.user.username:
 
                    c.user_repos.append(repo)            
 
            return htmlfill.render(
rhodecode/controllers/admin/users.py
Show inline comments
 
@@ -70,13 +70,13 @@ class UsersController(BaseController):
 
        try:
 
            form_result = login_form.to_python(dict(request.POST))
 
            user_model.create(form_result)
 
            h.flash(_('created user %s') % form_result['username'],
 
                    category='success')
 
            #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            return htmlfill.render(
 
                render('admin/users/user_add.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8") 
 
@@ -107,13 +107,13 @@ class UsersController(BaseController):
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            user_model.update(id, form_result)
 
            h.flash(_('User updated succesfully'), category='success')
 
                           
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            return htmlfill.render(
 
                render('admin/users/user_edit.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8") 
 
@@ -133,13 +133,13 @@ class UsersController(BaseController):
 
        #           method='delete')
 
        # url('user', id=ID)
 
        user_model = UserModel()
 
        try:
 
            user_model.delete(id)
 
            h.flash(_('sucessfully deleted user'), category='success')
 
        except DefaultUserException as e:
 
        except DefaultUserException, e:
 
            h.flash(str(e), category='warning')
 
        except Exception:
 
            h.flash(_('An error occured during deletion of user'),
 
                    category='error')            
 
        return redirect(url('users'))
 
        
rhodecode/controllers/login.py
Show inline comments
 
@@ -71,13 +71,13 @@ class LoginController(BaseController):
 
                                        
 
                if c.came_from:
 
                    return redirect(c.came_from)
 
                else:
 
                    return redirect(url('hg_home'))
 
                               
 
            except formencode.Invalid as errors:
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('/login.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
@@ -102,13 +102,13 @@ class LoginController(BaseController):
 
                form_result['active'] = c.auto_active
 
                user_model.create_registration(form_result)
 
                h.flash(_('You have successfully registered into rhodecode'),
 
                            category='success')                
 
                return redirect(url('login_home'))
 
                               
 
            except formencode.Invalid as errors:
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('/register.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
@@ -124,13 +124,13 @@ class LoginController(BaseController):
 
                form_result = password_reset_form.to_python(dict(request.POST))
 
                user_model.reset_password(form_result)
 
                h.flash(_('Your new password was sent'),
 
                            category='success')                 
 
                return redirect(url('login_home'))
 
                               
 
            except formencode.Invalid as errors:
 
            except formencode.Invalid, errors:
 
                return htmlfill.render(
 
                    render('/password_reset.html'),
 
                    defaults=errors.value,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
rhodecode/controllers/settings.py
Show inline comments
 
@@ -79,13 +79,13 @@ class SettingsController(BaseController)
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('Repository %s updated successfully' % repo_name),
 
                    category='success')
 
            changed_name = form_result['repo_name']               
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.repo_info = repo_model.get(repo_name)
 
            c.users_array = repo_model.get_users_js()
 
            errors.value.update({'user':c.repo_info.user.username})
 
            return htmlfill.render(
 
                render('settings/repo_settings.html'),
 
                defaults=errors.value,
 
@@ -118,13 +118,13 @@ class SettingsController(BaseController)
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % repo_name,
 
                      category='error')
 
        
 
            return redirect(url('hg_home'))
 
        try:
 
            action_logger(self.rhodecode_user, 'user_deleted_repo', 
 
            action_logger(self.rhodecode_user, 'user_deleted_repo',
 
                              repo_name, '', self.sa)            
 
            repo_model.delete(repo)            
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 
        except Exception:
 
            h.flash(_('An error occurred during deletion of %s') % repo_name,
 
@@ -159,13 +159,13 @@ class SettingsController(BaseController)
 
            repo_model.create_fork(form_result, c.rhodecode_user)
 
            h.flash(_('fork %s repository as %s task added') \
 
                      % (repo_name, form_result['fork_name']),
 
                    category='success')
 
            action_logger(self.rhodecode_user, 'user_forked_repo',
 
                            repo_name, '', self.sa)                                                 
 
        except formencode.Invalid as errors:
 
        except formencode.Invalid, errors:
 
            c.new_repo = errors.value['fork_name']
 
            r = render('settings/repo_fork.html')
 
            
 
            return htmlfill.render(
 
                r,
 
                defaults=errors.value,
rhodecode/lib/auth.py
Show inline comments
 
@@ -82,13 +82,13 @@ def get_user_cached(username):
 
        meta.Session.remove()
 
    return user
 

	
 
def authfunc(environ, username, password):
 
    try:
 
        user = get_user_cached(username)
 
    except (NoResultFound, MultipleResultsFound, OperationalError) as e:
 
    except (NoResultFound, MultipleResultsFound, OperationalError), e:
 
        log.error(e)
 
        user = None
 
        
 
    if user:
 
        if user.active:
 
            if user.username == username and check_password(password, user.password):
rhodecode/lib/celerylib/tasks.py
Show inline comments
 
@@ -5,16 +5,21 @@ from pylons.i18n.translation import _
 
from rhodecode.lib.celerylib import run_task, locked_task
 
from rhodecode.lib.helpers import person
 
from rhodecode.lib.smtp_mailer import SmtpMailer
 
from rhodecode.lib.utils import OrderedDict
 
from time import mktime
 
from vcs.backends.hg import MercurialRepository
 
import json
 
import traceback
 

	
 
try:
 
    import json
 
except ImportError:
 
    #python 2.5 compatibility
 
    import simplejson as json
 

	
 
try:
 
    from celeryconfig import PYLONS_CONFIG as config
 
    celery_on = True
 
except ImportError:
 
    #if celeryconfig is not present let's just load our pylons
 
    #config instead
 
    from pylons import config
setup.py
Show inline comments
 
from rhodecode import get_version
 
import sys
 
py_version = sys.version_info
 

	
 
requirements = [
 
        "Pylons>=1.0.0",
 
        "SQLAlchemy>=0.6",
 
        "babel",
 
        "Mako>=0.3.2",
 
        "vcs>=0.1.7",
 
        "pygments>=1.3.0",
 
        "mercurial>=1.6",
 
        "pysqlite",
 
        "whoosh==1.0.0",
 
        "py-bcrypt",
 
        "celery",
 
    ]
 

	
 
if sys.version_info < (2, 6):
 
    requirements.append("simplejson")
 
    requirements.append("pysqlite")
 

	
 
#additional files from project that goes somewhere in the filesystem
 
#relative to sys.prefix
 
data_files = []
 

	
 
#additional files that goes into package itself
 
package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
0 comments (0 inline, 0 general)