Show More
@@ -1,33 +1,33 b'' | |||
|
1 |
------------------------------------------------ |
|
|
2 |
Pylons based repository management for mercurial |
|
|
3 |
------------------------------------------------ |
|
|
4 | ||
|
5 | Fully customizable, with authentication, permissions. Based on vcs library. | |
|
1 | ------------------------------------------------ | |
|
2 | Pylons based repository management for mercurial | |
|
3 | ------------------------------------------------ | |
|
6 | 4 | |
|
7 | 5 | **Overview** |
|
8 | 6 | |
|
9 |
- |
|
|
10 |
be logged and authenticated |
|
|
11 | - full permissions per project read/write/admin access even on mercurial request | |
|
12 | - mako templates let's you customize look and feel of application. | |
|
13 | - diffs annotations and source code all colored by pygments. | |
|
14 | - mercurial branch graph and yui-flot powered graphs with zooming and statistics | |
|
15 | - admin interface for performing user/permission managements as well as repository | |
|
16 | management. | |
|
17 | - server side forks, it's possible to fork a project and hack it free without | |
|
7 | - Has it's own middleware to handle mercurial protocol request. Each request can | |
|
8 | be logged and authenticated. Runs on threads unlikely to hgweb You can make | |
|
9 | multiple pulls/pushes simultaneous | |
|
10 | - Full permissions and authentication per project private/read/write/admin. | |
|
11 | One account for web interface and mercurial push/pull/clone. | |
|
12 | - Mako templates let's you customize look and feel of application. | |
|
13 | - Beautiful diffs, annotations and source codes all colored by pygments. | |
|
14 | - Mercurial branch graph and yui-flot powered graphs with zooming and statistics | |
|
15 | - Admin interface with user/permission management. User activity journal logs | |
|
16 | pulls, pushes, forks,registrations. Possible to disable built in hooks | |
|
17 | - Server side forks, it's possible to fork a project and hack it free without | |
|
18 | 18 | breaking the main. |
|
19 |
- |
|
|
19 | - Full text search on source codes, search on file names. All powered by whoosh | |
|
20 | and build in indexing daemons | |
|
20 | 21 | (no external search servers required all in one application) |
|
21 | - async tasks for speed and performance using celery (works without them too) | |
|
22 | - Additional settings for mercurial web, (hooks editable from admin | |
|
23 | panel !) also manage paths, archive, remote messages | |
|
24 | - backup scripts can do backup of whole app and send it over scp to desired location | |
|
25 |
- |
|
|
22 | - Rss / atom feeds, gravatar support, download sources as zip/tarballs | |
|
23 | - Async tasks for speed and performance using celery (works without them too) | |
|
24 | - Backup scripts can do backup of whole app and send it over scp to desired | |
|
25 | location | |
|
26 | - Setup project descriptions and info inside built in db for easy, non | |
|
26 | 27 | file-system operations |
|
27 |
- |
|
|
28 | - Added cache with invalidation on push/repo management for high performance and | |
|
28 | 29 | always up to date data. |
|
29 | - rss / atom feeds, gravatar support | |
|
30 | - based on pylons 1.0 / sqlalchemy 0.6 | |
|
30 | - Based on pylons 1.0 / sqlalchemy 0.6 / sqlite | |
|
31 | 31 | |
|
32 | 32 | **Incoming** |
|
33 | 33 | |
@@ -36,19 +36,14 b' Fully customizable, with authentication,' | |||
|
36 | 36 | - commit based wikis |
|
37 | 37 | - clonning from remote repositories into rhodecode (git/mercurial) |
|
38 | 38 | - other cools stuff that i can figure out (or You can help me figure out) |
|
39 | ||
|
40 | .. note:: | |
|
41 | This software is still in beta mode. | |
|
42 | I don't guarantee that it'll work correctly. | |
|
43 | 39 | |
|
40 | ------------ | |
|
41 | Installation | |
|
42 | ------------ | |
|
44 | 43 | |
|
45 | ------------- | |
|
46 | Installation | |
|
47 | ------------- | |
|
48 | ||
|
49 | quick setup | |
|
44 | **quick setup** | |
|
50 | 45 | |
|
51 |
- pip install -E rhodecode-venv |
|
|
46 | - pip install -E rhodecode-venv rhodecode | |
|
52 | 47 | - activate virtualenv |
|
53 | 48 | - run `paster make-config RhodeCode production.ini` |
|
54 | 49 | - run `paster setup-app production.ini` |
@@ -56,8 +51,7 b' quick setup' | |||
|
56 | 51 | |
|
57 | 52 | You're ready to go. |
|
58 | 53 | |
|
59 | ||
|
60 | MORE DETAILED INSTRUCTIONS | |
|
54 | **MORE DETAILED INSTRUCTIONS** | |
|
61 | 55 | |
|
62 | 56 | - I highly recommend to install new virtualenv for rhodecode see |
|
63 | 57 | http://pypi.python.org/pypi/virtualenv for more details. |
@@ -66,7 +60,7 b' MORE DETAILED INSTRUCTIONS' | |||
|
66 | 60 | Activate the virtualenv by running |
|
67 | 61 | `source activate /var/www/rhodecode-venv/bin/activate` |
|
68 | 62 | - Make a folder for rhodecode somewhere on the filesystem for example /var/www/rhodecode |
|
69 | - Run easy_install http://bitbucket.org/marcinkuzminski/rhodecode/get/tip.zip. | |
|
63 | - Run easy_install rhodecode | |
|
70 | 64 | - Run `paster make-config RhodeCode production.inii` in order to install |
|
71 | 65 | the application config. You can play with the app settings later |
|
72 | 66 | - Run `paster setup-app production.ini` it should create all needed tables |
@@ -83,12 +77,11 b' MORE DETAILED INSTRUCTIONS' | |||
|
83 | 77 | The app should gain a lot of speed and become much more responsible. |
|
84 | 78 | For installation instructions You can visit: |
|
85 | 79 | http://ask.github.com/celery/getting-started/index.html. |
|
86 |
- All needed configs are inside rhodecode ie. celeryconfig.py |
|
|
87 |
You can configure the email, ports, loggers, |
|
|
80 | - All needed configs are inside rhodecode sources ie. celeryconfig.py, | |
|
81 | development.ini, production.ini You can configure the email, ports, loggers, | |
|
82 | workers from there. | |
|
88 | 83 | - For full text search You can either put crontab entry for |
|
89 | 84 | `python /var/www/rhodecode/rhodecode/lib/indexers/daemon.py incremental <path_to_repos>` |
|
90 | 85 | or run indexer from admin panel. This will scann the repos given in the |
|
91 | 86 | application setup or given path for daemon.py and each scann in incremental |
|
92 |
mode will scann only changed files |
|
|
93 | Hg Update hook must be activated to index the content it's enabled by default | |
|
94 | after setup No newline at end of file | |
|
87 | mode will scann only changed files. No newline at end of file |
@@ -102,7 +102,7 b' class PermissionsController(BaseControll' | |||
|
102 | 102 | h.flash(_('Default permissions updated succesfully'), |
|
103 | 103 | category='success') |
|
104 | 104 | |
|
105 |
except formencode.Invalid |
|
|
105 | except formencode.Invalid, errors: | |
|
106 | 106 | c.perms_choices = self.perms_choices |
|
107 | 107 | c.register_choices = self.register_choices |
|
108 | 108 | c.create_choices = self.create_choices |
@@ -79,13 +79,13 b' class ReposController(BaseController):' | |||
|
79 | 79 | category='success') |
|
80 | 80 | |
|
81 | 81 | if request.POST.get('user_created'): |
|
82 |
action_logger(self.rhodecode_user, 'user_created_repo', |
|
|
82 | action_logger(self.rhodecode_user, 'user_created_repo', | |
|
83 | 83 | form_result['repo_name'], '', self.sa) |
|
84 | 84 | else: |
|
85 |
action_logger(self.rhodecode_user, 'admin_created_repo', |
|
|
85 | action_logger(self.rhodecode_user, 'admin_created_repo', | |
|
86 | 86 | form_result['repo_name'], '', self.sa) |
|
87 | 87 | |
|
88 |
except formencode.Invalid |
|
|
88 | except formencode.Invalid, errors: | |
|
89 | 89 | c.new_repo = errors.value['repo_name'] |
|
90 | 90 | |
|
91 | 91 | if request.POST.get('user_created'): |
@@ -137,7 +137,7 b' class ReposController(BaseController):' | |||
|
137 | 137 | h.flash(_('Repository %s updated succesfully' % repo_name), |
|
138 | 138 | category='success') |
|
139 | 139 | changed_name = form_result['repo_name'] |
|
140 |
except formencode.Invalid |
|
|
140 | except formencode.Invalid, errors: | |
|
141 | 141 | c.repo_info = repo_model.get(repo_name) |
|
142 | 142 | c.users_array = repo_model.get_users_js() |
|
143 | 143 | errors.value.update({'user':c.repo_info.user.username}) |
@@ -176,7 +176,7 b' class ReposController(BaseController):' | |||
|
176 | 176 | |
|
177 | 177 | return redirect(url('repos')) |
|
178 | 178 | try: |
|
179 |
action_logger(self.rhodecode_user, 'admin_deleted_repo', |
|
|
179 | action_logger(self.rhodecode_user, 'admin_deleted_repo', | |
|
180 | 180 | repo_name, '', self.sa) |
|
181 | 181 | repo_model.delete(repo) |
|
182 | 182 | invalidate_cache('cached_repo_list') |
@@ -199,7 +199,7 b' class ReposController(BaseController):' | |||
|
199 | 199 | try: |
|
200 | 200 | repo_model = RepoModel() |
|
201 | 201 | repo_model.delete_perm_user(request.POST, repo_name) |
|
202 |
except Exception |
|
|
202 | except Exception, e: | |
|
203 | 203 | h.flash(_('An error occured during deletion of repository user'), |
|
204 | 204 | category='error') |
|
205 | 205 | raise HTTPInternalServerError() |
@@ -140,7 +140,7 b' class SettingsController(BaseController)' | |||
|
140 | 140 | self.sa.rollback() |
|
141 | 141 | |
|
142 | 142 | |
|
143 |
except formencode.Invalid |
|
|
143 | except formencode.Invalid, errors: | |
|
144 | 144 | return htmlfill.render( |
|
145 | 145 | render('admin/settings/settings.html'), |
|
146 | 146 | defaults=errors.value, |
@@ -193,7 +193,7 b' class SettingsController(BaseController)' | |||
|
193 | 193 | self.sa.rollback() |
|
194 | 194 | |
|
195 | 195 | |
|
196 |
except formencode.Invalid |
|
|
196 | except formencode.Invalid, errors: | |
|
197 | 197 | return htmlfill.render( |
|
198 | 198 | render('admin/settings/settings.html'), |
|
199 | 199 | defaults=errors.value, |
@@ -269,7 +269,7 b' class SettingsController(BaseController)' | |||
|
269 | 269 | h.flash(_('Your account was updated succesfully'), |
|
270 | 270 | category='success') |
|
271 | 271 | |
|
272 |
except formencode.Invalid |
|
|
272 | except formencode.Invalid, errors: | |
|
273 | 273 | c.user = self.sa.query(User).get(c.rhodecode_user.user_id) |
|
274 | 274 | c.user_repos = [] |
|
275 | 275 | for repo in c.cached_repo_list.values(): |
@@ -73,7 +73,7 b' class UsersController(BaseController):' | |||
|
73 | 73 | h.flash(_('created user %s') % form_result['username'], |
|
74 | 74 | category='success') |
|
75 | 75 | #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa) |
|
76 |
except formencode.Invalid |
|
|
76 | except formencode.Invalid, errors: | |
|
77 | 77 | return htmlfill.render( |
|
78 | 78 | render('admin/users/user_add.html'), |
|
79 | 79 | defaults=errors.value, |
@@ -110,7 +110,7 b' class UsersController(BaseController):' | |||
|
110 | 110 | user_model.update(id, form_result) |
|
111 | 111 | h.flash(_('User updated succesfully'), category='success') |
|
112 | 112 | |
|
113 |
except formencode.Invalid |
|
|
113 | except formencode.Invalid, errors: | |
|
114 | 114 | return htmlfill.render( |
|
115 | 115 | render('admin/users/user_edit.html'), |
|
116 | 116 | defaults=errors.value, |
@@ -136,7 +136,7 b' class UsersController(BaseController):' | |||
|
136 | 136 | try: |
|
137 | 137 | user_model.delete(id) |
|
138 | 138 | h.flash(_('sucessfully deleted user'), category='success') |
|
139 |
except DefaultUserException |
|
|
139 | except DefaultUserException, e: | |
|
140 | 140 | h.flash(str(e), category='warning') |
|
141 | 141 | except Exception: |
|
142 | 142 | h.flash(_('An error occured during deletion of user'), |
@@ -74,7 +74,7 b' class LoginController(BaseController):' | |||
|
74 | 74 | else: |
|
75 | 75 | return redirect(url('hg_home')) |
|
76 | 76 | |
|
77 |
except formencode.Invalid |
|
|
77 | except formencode.Invalid, errors: | |
|
78 | 78 | return htmlfill.render( |
|
79 | 79 | render('/login.html'), |
|
80 | 80 | defaults=errors.value, |
@@ -105,7 +105,7 b' class LoginController(BaseController):' | |||
|
105 | 105 | category='success') |
|
106 | 106 | return redirect(url('login_home')) |
|
107 | 107 | |
|
108 |
except formencode.Invalid |
|
|
108 | except formencode.Invalid, errors: | |
|
109 | 109 | return htmlfill.render( |
|
110 | 110 | render('/register.html'), |
|
111 | 111 | defaults=errors.value, |
@@ -127,7 +127,7 b' class LoginController(BaseController):' | |||
|
127 | 127 | category='success') |
|
128 | 128 | return redirect(url('login_home')) |
|
129 | 129 | |
|
130 |
except formencode.Invalid |
|
|
130 | except formencode.Invalid, errors: | |
|
131 | 131 | return htmlfill.render( |
|
132 | 132 | render('/password_reset.html'), |
|
133 | 133 | defaults=errors.value, |
@@ -82,7 +82,7 b' class SettingsController(BaseController)' | |||
|
82 | 82 | h.flash(_('Repository %s updated successfully' % repo_name), |
|
83 | 83 | category='success') |
|
84 | 84 | changed_name = form_result['repo_name'] |
|
85 |
except formencode.Invalid |
|
|
85 | except formencode.Invalid, errors: | |
|
86 | 86 | c.repo_info = repo_model.get(repo_name) |
|
87 | 87 | c.users_array = repo_model.get_users_js() |
|
88 | 88 | errors.value.update({'user':c.repo_info.user.username}) |
@@ -121,7 +121,7 b' class SettingsController(BaseController)' | |||
|
121 | 121 | |
|
122 | 122 | return redirect(url('hg_home')) |
|
123 | 123 | try: |
|
124 |
action_logger(self.rhodecode_user, 'user_deleted_repo', |
|
|
124 | action_logger(self.rhodecode_user, 'user_deleted_repo', | |
|
125 | 125 | repo_name, '', self.sa) |
|
126 | 126 | repo_model.delete(repo) |
|
127 | 127 | invalidate_cache('cached_repo_list') |
@@ -162,7 +162,7 b' class SettingsController(BaseController)' | |||
|
162 | 162 | category='success') |
|
163 | 163 | action_logger(self.rhodecode_user, 'user_forked_repo', |
|
164 | 164 | repo_name, '', self.sa) |
|
165 |
except formencode.Invalid |
|
|
165 | except formencode.Invalid, errors: | |
|
166 | 166 | c.new_repo = errors.value['fork_name'] |
|
167 | 167 | r = render('settings/repo_fork.html') |
|
168 | 168 |
@@ -85,7 +85,7 b' def get_user_cached(username):' | |||
|
85 | 85 | def authfunc(environ, username, password): |
|
86 | 86 | try: |
|
87 | 87 | user = get_user_cached(username) |
|
88 |
except (NoResultFound, MultipleResultsFound, OperationalError) |
|
|
88 | except (NoResultFound, MultipleResultsFound, OperationalError), e: | |
|
89 | 89 | log.error(e) |
|
90 | 90 | user = None |
|
91 | 91 |
@@ -8,10 +8,15 b' from rhodecode.lib.smtp_mailer import Sm' | |||
|
8 | 8 | from rhodecode.lib.utils import OrderedDict |
|
9 | 9 | from time import mktime |
|
10 | 10 | from vcs.backends.hg import MercurialRepository |
|
11 | import json | |
|
12 | 11 | import traceback |
|
13 | 12 | |
|
14 | 13 | try: |
|
14 | import json | |
|
15 | except ImportError: | |
|
16 | #python 2.5 compatibility | |
|
17 | import simplejson as json | |
|
18 | ||
|
19 | try: | |
|
15 | 20 | from celeryconfig import PYLONS_CONFIG as config |
|
16 | 21 | celery_on = True |
|
17 | 22 | except ImportError: |
@@ -1,5 +1,6 b'' | |||
|
1 | 1 | from rhodecode import get_version |
|
2 | 2 | import sys |
|
3 | py_version = sys.version_info | |
|
3 | 4 | |
|
4 | 5 | requirements = [ |
|
5 | 6 | "Pylons>=1.0.0", |
@@ -9,12 +10,15 b' requirements = [' | |||
|
9 | 10 | "vcs>=0.1.7", |
|
10 | 11 | "pygments>=1.3.0", |
|
11 | 12 | "mercurial>=1.6", |
|
12 | "pysqlite", | |
|
13 | 13 | "whoosh==1.0.0", |
|
14 | 14 | "py-bcrypt", |
|
15 | 15 | "celery", |
|
16 | 16 | ] |
|
17 | 17 | |
|
18 | if sys.version_info < (2, 6): | |
|
19 | requirements.append("simplejson") | |
|
20 | requirements.append("pysqlite") | |
|
21 | ||
|
18 | 22 | #additional files from project that goes somewhere in the filesystem |
|
19 | 23 | #relative to sys.prefix |
|
20 | 24 | data_files = [] |
General Comments 0
You need to be logged in to leave comments.
Login now