##// END OF EJS Templates
merge with beta
marcink -
r2300:edfff9f3 merge rhodecode-0.0.1.3.6 default
parent child Browse files
Show More
@@ -1,651 +1,652 b''
1 .. _changelog:
1 .. _changelog:
2
2
3 =========
3 =========
4 Changelog
4 Changelog
5 =========
5 =========
6
6
7 1.3.6 (**2012-05-17**)
7 1.3.6 (**2012-05-17**)
8 ----------------------
8 ----------------------
9
9
10 news
10 news
11 ++++
11 ++++
12
12
13 - chinese traditional translation
13 - chinese traditional translation
14 - changed setup-app into setup-rhodecode and added arguments for auto-setup
14 - changed setup-app into setup-rhodecode and added arguments for auto-setup
15 mode that doesn't need user interaction
15 mode that doesn't need user interaction
16
16
17 fixes
17 fixes
18 +++++
18 +++++
19
19
20 - fixed no scm found warning
20 - fixed no scm found warning
21 - fixed __future__ import error on rcextensions
21 - fixed __future__ import error on rcextensions
22 - made simplejson required lib for speedup on JSON encoding
22 - made simplejson required lib for speedup on JSON encoding
23 - fixes #449 bad regex could get more than revisions from parsing history
23 - fixes #449 bad regex could get more than revisions from parsing history
24 - don't clear DB session when CELERY_EAGER is turned ON
24
25
25 1.3.5 (**2012-05-10**)
26 1.3.5 (**2012-05-10**)
26 ----------------------
27 ----------------------
27
28
28 news
29 news
29 ++++
30 ++++
30
31
31 - use ext_json for json module
32 - use ext_json for json module
32 - unified annotation view with file source view
33 - unified annotation view with file source view
33 - notification improvements, better inbox + css
34 - notification improvements, better inbox + css
34 - #419 don't strip passwords for login forms, make rhodecode
35 - #419 don't strip passwords for login forms, make rhodecode
35 more compatible with LDAP servers
36 more compatible with LDAP servers
36 - Added HTTP_X_FORWARDED_FOR as another method of extracting
37 - Added HTTP_X_FORWARDED_FOR as another method of extracting
37 IP for pull/push logs. - moved all to base controller
38 IP for pull/push logs. - moved all to base controller
38 - #415: Adding comment to changeset causes reload.
39 - #415: Adding comment to changeset causes reload.
39 Comments are now added via ajax and doesn't reload the page
40 Comments are now added via ajax and doesn't reload the page
40 - #374 LDAP config is discarded when LDAP can't be activated
41 - #374 LDAP config is discarded when LDAP can't be activated
41 - limited push/pull operations are now logged for git in the journal
42 - limited push/pull operations are now logged for git in the journal
42 - bumped mercurial to 2.2.X series
43 - bumped mercurial to 2.2.X series
43 - added support for displaying submodules in file-browser
44 - added support for displaying submodules in file-browser
44 - #421 added bookmarks in changelog view
45 - #421 added bookmarks in changelog view
45
46
46 fixes
47 fixes
47 +++++
48 +++++
48
49
49 - fixed dev-version marker for stable when served from source codes
50 - fixed dev-version marker for stable when served from source codes
50 - fixed missing permission checks on show forks page
51 - fixed missing permission checks on show forks page
51 - #418 cast to unicode fixes in notification objects
52 - #418 cast to unicode fixes in notification objects
52 - #426 fixed mention extracting regex
53 - #426 fixed mention extracting regex
53 - fixed remote-pulling for git remotes remopositories
54 - fixed remote-pulling for git remotes remopositories
54 - fixed #434: Error when accessing files or changesets of a git repository
55 - fixed #434: Error when accessing files or changesets of a git repository
55 with submodules
56 with submodules
56 - fixed issue with empty APIKEYS for users after registration ref. #438
57 - fixed issue with empty APIKEYS for users after registration ref. #438
57 - fixed issue with getting README files from git repositories
58 - fixed issue with getting README files from git repositories
58
59
59 1.3.4 (**2012-03-28**)
60 1.3.4 (**2012-03-28**)
60 ----------------------
61 ----------------------
61
62
62 news
63 news
63 ++++
64 ++++
64
65
65 - Whoosh logging is now controlled by the .ini files logging setup
66 - Whoosh logging is now controlled by the .ini files logging setup
66 - added clone-url into edit form on /settings page
67 - added clone-url into edit form on /settings page
67 - added help text into repo add/edit forms
68 - added help text into repo add/edit forms
68 - created rcextensions module with additional mappings (ref #322) and
69 - created rcextensions module with additional mappings (ref #322) and
69 post push/pull/create repo hooks callbacks
70 post push/pull/create repo hooks callbacks
70 - implemented #377 Users view for his own permissions on account page
71 - implemented #377 Users view for his own permissions on account page
71 - #399 added inheritance of permissions for users group on repos groups
72 - #399 added inheritance of permissions for users group on repos groups
72 - #401 repository group is automatically pre-selected when adding repos
73 - #401 repository group is automatically pre-selected when adding repos
73 inside a repository group
74 inside a repository group
74 - added alternative HTTP 403 response when client failed to authenticate. Helps
75 - added alternative HTTP 403 response when client failed to authenticate. Helps
75 solving issues with Mercurial and LDAP
76 solving issues with Mercurial and LDAP
76 - #402 removed group prefix from repository name when listing repositories
77 - #402 removed group prefix from repository name when listing repositories
77 inside a group
78 inside a group
78 - added gravatars into permission view and permissions autocomplete
79 - added gravatars into permission view and permissions autocomplete
79 - #347 when running multiple RhodeCode instances, properly invalidates cache
80 - #347 when running multiple RhodeCode instances, properly invalidates cache
80 for all registered servers
81 for all registered servers
81
82
82 fixes
83 fixes
83 +++++
84 +++++
84
85
85 - fixed #390 cache invalidation problems on repos inside group
86 - fixed #390 cache invalidation problems on repos inside group
86 - fixed #385 clone by ID url was loosing proxy prefix in URL
87 - fixed #385 clone by ID url was loosing proxy prefix in URL
87 - fixed some unicode problems with waitress
88 - fixed some unicode problems with waitress
88 - fixed issue with escaping < and > in changeset commits
89 - fixed issue with escaping < and > in changeset commits
89 - fixed error occurring during recursive group creation in API
90 - fixed error occurring during recursive group creation in API
90 create_repo function
91 create_repo function
91 - fixed #393 py2.5 fixes for routes url generator
92 - fixed #393 py2.5 fixes for routes url generator
92 - fixed #397 Private repository groups shows up before login
93 - fixed #397 Private repository groups shows up before login
93 - fixed #396 fixed problems with revoking users in nested groups
94 - fixed #396 fixed problems with revoking users in nested groups
94 - fixed mysql unicode issues + specified InnoDB as default engine with
95 - fixed mysql unicode issues + specified InnoDB as default engine with
95 utf8 charset
96 utf8 charset
96 - #406 trim long branch/tag names in changelog to not break UI
97 - #406 trim long branch/tag names in changelog to not break UI
97
98
98 1.3.3 (**2012-03-02**)
99 1.3.3 (**2012-03-02**)
99 ----------------------
100 ----------------------
100
101
101 news
102 news
102 ++++
103 ++++
103
104
104
105
105 fixes
106 fixes
106 +++++
107 +++++
107
108
108 - fixed some python2.5 compatibility issues
109 - fixed some python2.5 compatibility issues
109 - fixed issues with removed repos was accidentally added as groups, after
110 - fixed issues with removed repos was accidentally added as groups, after
110 full rescan of paths
111 full rescan of paths
111 - fixes #376 Cannot edit user (using container auth)
112 - fixes #376 Cannot edit user (using container auth)
112 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
113 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
113 configuration
114 configuration
114 - fixed initial sorting of repos inside repo group
115 - fixed initial sorting of repos inside repo group
115 - fixes issue when user tried to resubmit same permission into user/user_groups
116 - fixes issue when user tried to resubmit same permission into user/user_groups
116 - bumped beaker version that fixes #375 leap error bug
117 - bumped beaker version that fixes #375 leap error bug
117 - fixed raw_changeset for git. It was generated with hg patch headers
118 - fixed raw_changeset for git. It was generated with hg patch headers
118 - fixed vcs issue with last_changeset for filenodes
119 - fixed vcs issue with last_changeset for filenodes
119 - fixed missing commit after hook delete
120 - fixed missing commit after hook delete
120 - fixed #372 issues with git operation detection that caused a security issue
121 - fixed #372 issues with git operation detection that caused a security issue
121 for git repos
122 for git repos
122
123
123 1.3.2 (**2012-02-28**)
124 1.3.2 (**2012-02-28**)
124 ----------------------
125 ----------------------
125
126
126 news
127 news
127 ++++
128 ++++
128
129
129
130
130 fixes
131 fixes
131 +++++
132 +++++
132
133
133 - fixed git protocol issues with repos-groups
134 - fixed git protocol issues with repos-groups
134 - fixed git remote repos validator that prevented from cloning remote git repos
135 - fixed git remote repos validator that prevented from cloning remote git repos
135 - fixes #370 ending slashes fixes for repo and groups
136 - fixes #370 ending slashes fixes for repo and groups
136 - fixes #368 improved git-protocol detection to handle other clients
137 - fixes #368 improved git-protocol detection to handle other clients
137 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
138 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
138 Moved To Root
139 Moved To Root
139 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
140 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
140 - fixed #373 missing cascade drop on user_group_to_perm table
141 - fixed #373 missing cascade drop on user_group_to_perm table
141
142
142 1.3.1 (**2012-02-27**)
143 1.3.1 (**2012-02-27**)
143 ----------------------
144 ----------------------
144
145
145 news
146 news
146 ++++
147 ++++
147
148
148
149
149 fixes
150 fixes
150 +++++
151 +++++
151
152
152 - redirection loop occurs when remember-me wasn't checked during login
153 - redirection loop occurs when remember-me wasn't checked during login
153 - fixes issues with git blob history generation
154 - fixes issues with git blob history generation
154 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
155 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
155
156
156 1.3.0 (**2012-02-26**)
157 1.3.0 (**2012-02-26**)
157 ----------------------
158 ----------------------
158
159
159 news
160 news
160 ++++
161 ++++
161
162
162 - code review, inspired by github code-comments
163 - code review, inspired by github code-comments
163 - #215 rst and markdown README files support
164 - #215 rst and markdown README files support
164 - #252 Container-based and proxy pass-through authentication support
165 - #252 Container-based and proxy pass-through authentication support
165 - #44 branch browser. Filtering of changelog by branches
166 - #44 branch browser. Filtering of changelog by branches
166 - mercurial bookmarks support
167 - mercurial bookmarks support
167 - new hover top menu, optimized to add maximum size for important views
168 - new hover top menu, optimized to add maximum size for important views
168 - configurable clone url template with possibility to specify protocol like
169 - configurable clone url template with possibility to specify protocol like
169 ssh:// or http:// and also manually alter other parts of clone_url.
170 ssh:// or http:// and also manually alter other parts of clone_url.
170 - enabled largefiles extension by default
171 - enabled largefiles extension by default
171 - optimized summary file pages and saved a lot of unused space in them
172 - optimized summary file pages and saved a lot of unused space in them
172 - #239 option to manually mark repository as fork
173 - #239 option to manually mark repository as fork
173 - #320 mapping of commit authors to RhodeCode users
174 - #320 mapping of commit authors to RhodeCode users
174 - #304 hashes are displayed using monospace font
175 - #304 hashes are displayed using monospace font
175 - diff configuration, toggle white lines and context lines
176 - diff configuration, toggle white lines and context lines
176 - #307 configurable diffs, whitespace toggle, increasing context lines
177 - #307 configurable diffs, whitespace toggle, increasing context lines
177 - sorting on branches, tags and bookmarks using YUI datatable
178 - sorting on branches, tags and bookmarks using YUI datatable
178 - improved file filter on files page
179 - improved file filter on files page
179 - implements #330 api method for listing nodes ar particular revision
180 - implements #330 api method for listing nodes ar particular revision
180 - #73 added linking issues in commit messages to chosen issue tracker url
181 - #73 added linking issues in commit messages to chosen issue tracker url
181 based on user defined regular expression
182 based on user defined regular expression
182 - added linking of changesets in commit messages
183 - added linking of changesets in commit messages
183 - new compact changelog with expandable commit messages
184 - new compact changelog with expandable commit messages
184 - firstname and lastname are optional in user creation
185 - firstname and lastname are optional in user creation
185 - #348 added post-create repository hook
186 - #348 added post-create repository hook
186 - #212 global encoding settings is now configurable from .ini files
187 - #212 global encoding settings is now configurable from .ini files
187 - #227 added repository groups permissions
188 - #227 added repository groups permissions
188 - markdown gets codehilite extensions
189 - markdown gets codehilite extensions
189 - new API methods, delete_repositories, grante/revoke permissions for groups
190 - new API methods, delete_repositories, grante/revoke permissions for groups
190 and repos
191 and repos
191
192
192
193
193 fixes
194 fixes
194 +++++
195 +++++
195
196
196 - rewrote dbsession management for atomic operations, and better error handling
197 - rewrote dbsession management for atomic operations, and better error handling
197 - fixed sorting of repo tables
198 - fixed sorting of repo tables
198 - #326 escape of special html entities in diffs
199 - #326 escape of special html entities in diffs
199 - normalized user_name => username in api attributes
200 - normalized user_name => username in api attributes
200 - fixes #298 ldap created users with mixed case emails created conflicts
201 - fixes #298 ldap created users with mixed case emails created conflicts
201 on saving a form
202 on saving a form
202 - fixes issue when owner of a repo couldn't revoke permissions for users
203 - fixes issue when owner of a repo couldn't revoke permissions for users
203 and groups
204 and groups
204 - fixes #271 rare JSON serialization problem with statistics
205 - fixes #271 rare JSON serialization problem with statistics
205 - fixes #337 missing validation check for conflicting names of a group with a
206 - fixes #337 missing validation check for conflicting names of a group with a
206 repositories group
207 repositories group
207 - #340 fixed session problem for mysql and celery tasks
208 - #340 fixed session problem for mysql and celery tasks
208 - fixed #331 RhodeCode mangles repository names if the a repository group
209 - fixed #331 RhodeCode mangles repository names if the a repository group
209 contains the "full path" to the repositories
210 contains the "full path" to the repositories
210 - #355 RhodeCode doesn't store encrypted LDAP passwords
211 - #355 RhodeCode doesn't store encrypted LDAP passwords
211
212
212 1.2.5 (**2012-01-28**)
213 1.2.5 (**2012-01-28**)
213 ----------------------
214 ----------------------
214
215
215 news
216 news
216 ++++
217 ++++
217
218
218 fixes
219 fixes
219 +++++
220 +++++
220
221
221 - #340 Celery complains about MySQL server gone away, added session cleanup
222 - #340 Celery complains about MySQL server gone away, added session cleanup
222 for celery tasks
223 for celery tasks
223 - #341 "scanning for repositories in None" log message during Rescan was missing
224 - #341 "scanning for repositories in None" log message during Rescan was missing
224 a parameter
225 a parameter
225 - fixed creating archives with subrepos. Some hooks were triggered during that
226 - fixed creating archives with subrepos. Some hooks were triggered during that
226 operation leading to crash.
227 operation leading to crash.
227 - fixed missing email in account page.
228 - fixed missing email in account page.
228 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
229 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
229 forking on windows impossible
230 forking on windows impossible
230
231
231 1.2.4 (**2012-01-19**)
232 1.2.4 (**2012-01-19**)
232 ----------------------
233 ----------------------
233
234
234 news
235 news
235 ++++
236 ++++
236
237
237 - RhodeCode is bundled with mercurial series 2.0.X by default, with
238 - RhodeCode is bundled with mercurial series 2.0.X by default, with
238 full support to largefiles extension. Enabled by default in new installations
239 full support to largefiles extension. Enabled by default in new installations
239 - #329 Ability to Add/Remove Groups to/from a Repository via AP
240 - #329 Ability to Add/Remove Groups to/from a Repository via AP
240 - added requires.txt file with requirements
241 - added requires.txt file with requirements
241
242
242 fixes
243 fixes
243 +++++
244 +++++
244
245
245 - fixes db session issues with celery when emailing admins
246 - fixes db session issues with celery when emailing admins
246 - #331 RhodeCode mangles repository names if the a repository group
247 - #331 RhodeCode mangles repository names if the a repository group
247 contains the "full path" to the repositories
248 contains the "full path" to the repositories
248 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
249 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
249 - DB session cleanup after hg protocol operations, fixes issues with
250 - DB session cleanup after hg protocol operations, fixes issues with
250 `mysql has gone away` errors
251 `mysql has gone away` errors
251 - #333 doc fixes for get_repo api function
252 - #333 doc fixes for get_repo api function
252 - #271 rare JSON serialization problem with statistics enabled
253 - #271 rare JSON serialization problem with statistics enabled
253 - #337 Fixes issues with validation of repository name conflicting with
254 - #337 Fixes issues with validation of repository name conflicting with
254 a group name. A proper message is now displayed.
255 a group name. A proper message is now displayed.
255 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
256 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
256 doesn't work
257 doesn't work
257 - #316 fixes issues with web description in hgrc files
258 - #316 fixes issues with web description in hgrc files
258
259
259 1.2.3 (**2011-11-02**)
260 1.2.3 (**2011-11-02**)
260 ----------------------
261 ----------------------
261
262
262 news
263 news
263 ++++
264 ++++
264
265
265 - added option to manage repos group for non admin users
266 - added option to manage repos group for non admin users
266 - added following API methods for get_users, create_user, get_users_groups,
267 - added following API methods for get_users, create_user, get_users_groups,
267 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
268 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
268 get_repo, create_repo, add_user_to_repo
269 get_repo, create_repo, add_user_to_repo
269 - implements #237 added password confirmation for my account
270 - implements #237 added password confirmation for my account
270 and admin edit user.
271 and admin edit user.
271 - implements #291 email notification for global events are now sent to all
272 - implements #291 email notification for global events are now sent to all
272 administrator users, and global config email.
273 administrator users, and global config email.
273
274
274 fixes
275 fixes
275 +++++
276 +++++
276
277
277 - added option for passing auth method for smtp mailer
278 - added option for passing auth method for smtp mailer
278 - #276 issue with adding a single user with id>10 to usergroups
279 - #276 issue with adding a single user with id>10 to usergroups
279 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
280 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
280 - #288 fixes managing of repos in a group for non admin user
281 - #288 fixes managing of repos in a group for non admin user
281
282
282 1.2.2 (**2011-10-17**)
283 1.2.2 (**2011-10-17**)
283 ----------------------
284 ----------------------
284
285
285 news
286 news
286 ++++
287 ++++
287
288
288 - #226 repo groups are available by path instead of numerical id
289 - #226 repo groups are available by path instead of numerical id
289
290
290 fixes
291 fixes
291 +++++
292 +++++
292
293
293 - #259 Groups with the same name but with different parent group
294 - #259 Groups with the same name but with different parent group
294 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
295 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
295 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
296 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
296 - #265 ldap save fails sometimes on converting attributes to booleans,
297 - #265 ldap save fails sometimes on converting attributes to booleans,
297 added getter and setter into model that will prevent from this on db model level
298 added getter and setter into model that will prevent from this on db model level
298 - fixed problems with timestamps issues #251 and #213
299 - fixed problems with timestamps issues #251 and #213
299 - fixes #266 RhodeCode allows to create repo with the same name and in
300 - fixes #266 RhodeCode allows to create repo with the same name and in
300 the same parent as group
301 the same parent as group
301 - fixes #245 Rescan of the repositories on Windows
302 - fixes #245 Rescan of the repositories on Windows
302 - fixes #248 cannot edit repos inside a group on windows
303 - fixes #248 cannot edit repos inside a group on windows
303 - fixes #219 forking problems on windows
304 - fixes #219 forking problems on windows
304
305
305 1.2.1 (**2011-10-08**)
306 1.2.1 (**2011-10-08**)
306 ----------------------
307 ----------------------
307
308
308 news
309 news
309 ++++
310 ++++
310
311
311
312
312 fixes
313 fixes
313 +++++
314 +++++
314
315
315 - fixed problems with basic auth and push problems
316 - fixed problems with basic auth and push problems
316 - gui fixes
317 - gui fixes
317 - fixed logger
318 - fixed logger
318
319
319 1.2.0 (**2011-10-07**)
320 1.2.0 (**2011-10-07**)
320 ----------------------
321 ----------------------
321
322
322 news
323 news
323 ++++
324 ++++
324
325
325 - implemented #47 repository groups
326 - implemented #47 repository groups
326 - implemented #89 Can setup google analytics code from settings menu
327 - implemented #89 Can setup google analytics code from settings menu
327 - implemented #91 added nicer looking archive urls with more download options
328 - implemented #91 added nicer looking archive urls with more download options
328 like tags, branches
329 like tags, branches
329 - implemented #44 into file browsing, and added follow branch option
330 - implemented #44 into file browsing, and added follow branch option
330 - implemented #84 downloads can be enabled/disabled for each repository
331 - implemented #84 downloads can be enabled/disabled for each repository
331 - anonymous repository can be cloned without having to pass default:default
332 - anonymous repository can be cloned without having to pass default:default
332 into clone url
333 into clone url
333 - fixed #90 whoosh indexer can index chooses repositories passed in command
334 - fixed #90 whoosh indexer can index chooses repositories passed in command
334 line
335 line
335 - extended journal with day aggregates and paging
336 - extended journal with day aggregates and paging
336 - implemented #107 source code lines highlight ranges
337 - implemented #107 source code lines highlight ranges
337 - implemented #93 customizable changelog on combined revision ranges -
338 - implemented #93 customizable changelog on combined revision ranges -
338 equivalent of githubs compare view
339 equivalent of githubs compare view
339 - implemented #108 extended and more powerful LDAP configuration
340 - implemented #108 extended and more powerful LDAP configuration
340 - implemented #56 users groups
341 - implemented #56 users groups
341 - major code rewrites optimized codes for speed and memory usage
342 - major code rewrites optimized codes for speed and memory usage
342 - raw and diff downloads are now in git format
343 - raw and diff downloads are now in git format
343 - setup command checks for write access to given path
344 - setup command checks for write access to given path
344 - fixed many issues with international characters and unicode. It uses utf8
345 - fixed many issues with international characters and unicode. It uses utf8
345 decode with replace to provide less errors even with non utf8 encoded strings
346 decode with replace to provide less errors even with non utf8 encoded strings
346 - #125 added API KEY access to feeds
347 - #125 added API KEY access to feeds
347 - #109 Repository can be created from external Mercurial link (aka. remote
348 - #109 Repository can be created from external Mercurial link (aka. remote
348 repository, and manually updated (via pull) from admin panel
349 repository, and manually updated (via pull) from admin panel
349 - beta git support - push/pull server + basic view for git repos
350 - beta git support - push/pull server + basic view for git repos
350 - added followers page and forks page
351 - added followers page and forks page
351 - server side file creation (with binary file upload interface)
352 - server side file creation (with binary file upload interface)
352 and edition with commits powered by codemirror
353 and edition with commits powered by codemirror
353 - #111 file browser file finder, quick lookup files on whole file tree
354 - #111 file browser file finder, quick lookup files on whole file tree
354 - added quick login sliding menu into main page
355 - added quick login sliding menu into main page
355 - changelog uses lazy loading of affected files details, in some scenarios
356 - changelog uses lazy loading of affected files details, in some scenarios
356 this can improve speed of changelog page dramatically especially for
357 this can improve speed of changelog page dramatically especially for
357 larger repositories.
358 larger repositories.
358 - implements #214 added support for downloading subrepos in download menu.
359 - implements #214 added support for downloading subrepos in download menu.
359 - Added basic API for direct operations on rhodecode via JSON
360 - Added basic API for direct operations on rhodecode via JSON
360 - Implemented advanced hook management
361 - Implemented advanced hook management
361
362
362 fixes
363 fixes
363 +++++
364 +++++
364
365
365 - fixed file browser bug, when switching into given form revision the url was
366 - fixed file browser bug, when switching into given form revision the url was
366 not changing
367 not changing
367 - fixed propagation to error controller on simplehg and simplegit middlewares
368 - fixed propagation to error controller on simplehg and simplegit middlewares
368 - fixed error when trying to make a download on empty repository
369 - fixed error when trying to make a download on empty repository
369 - fixed problem with '[' chars in commit messages in journal
370 - fixed problem with '[' chars in commit messages in journal
370 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
371 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
371 - journal fork fixes
372 - journal fork fixes
372 - removed issue with space inside renamed repository after deletion
373 - removed issue with space inside renamed repository after deletion
373 - fixed strange issue on formencode imports
374 - fixed strange issue on formencode imports
374 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
375 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
375 - #150 fixes for errors on repositories mapped in db but corrupted in
376 - #150 fixes for errors on repositories mapped in db but corrupted in
376 filesystem
377 filesystem
377 - fixed problem with ascendant characters in realm #181
378 - fixed problem with ascendant characters in realm #181
378 - fixed problem with sqlite file based database connection pool
379 - fixed problem with sqlite file based database connection pool
379 - whoosh indexer and code stats share the same dynamic extensions map
380 - whoosh indexer and code stats share the same dynamic extensions map
380 - fixes #188 - relationship delete of repo_to_perm entry on user removal
381 - fixes #188 - relationship delete of repo_to_perm entry on user removal
381 - fixes issue #189 Trending source files shows "show more" when no more exist
382 - fixes issue #189 Trending source files shows "show more" when no more exist
382 - fixes issue #197 Relative paths for pidlocks
383 - fixes issue #197 Relative paths for pidlocks
383 - fixes issue #198 password will require only 3 chars now for login form
384 - fixes issue #198 password will require only 3 chars now for login form
384 - fixes issue #199 wrong redirection for non admin users after creating a repository
385 - fixes issue #199 wrong redirection for non admin users after creating a repository
385 - fixes issues #202, bad db constraint made impossible to attach same group
386 - fixes issues #202, bad db constraint made impossible to attach same group
386 more than one time. Affects only mysql/postgres
387 more than one time. Affects only mysql/postgres
387 - fixes #218 os.kill patch for windows was missing sig param
388 - fixes #218 os.kill patch for windows was missing sig param
388 - improved rendering of dag (they are not trimmed anymore when number of
389 - improved rendering of dag (they are not trimmed anymore when number of
389 heads exceeds 5)
390 heads exceeds 5)
390
391
391 1.1.8 (**2011-04-12**)
392 1.1.8 (**2011-04-12**)
392 ----------------------
393 ----------------------
393
394
394 news
395 news
395 ++++
396 ++++
396
397
397 - improved windows support
398 - improved windows support
398
399
399 fixes
400 fixes
400 +++++
401 +++++
401
402
402 - fixed #140 freeze of python dateutil library, since new version is python2.x
403 - fixed #140 freeze of python dateutil library, since new version is python2.x
403 incompatible
404 incompatible
404 - setup-app will check for write permission in given path
405 - setup-app will check for write permission in given path
405 - cleaned up license info issue #149
406 - cleaned up license info issue #149
406 - fixes for issues #137,#116 and problems with unicode and accented characters.
407 - fixes for issues #137,#116 and problems with unicode and accented characters.
407 - fixes crashes on gravatar, when passed in email as unicode
408 - fixes crashes on gravatar, when passed in email as unicode
408 - fixed tooltip flickering problems
409 - fixed tooltip flickering problems
409 - fixed came_from redirection on windows
410 - fixed came_from redirection on windows
410 - fixed logging modules, and sql formatters
411 - fixed logging modules, and sql formatters
411 - windows fixes for os.kill issue #133
412 - windows fixes for os.kill issue #133
412 - fixes path splitting for windows issues #148
413 - fixes path splitting for windows issues #148
413 - fixed issue #143 wrong import on migration to 1.1.X
414 - fixed issue #143 wrong import on migration to 1.1.X
414 - fixed problems with displaying binary files, thanks to Thomas Waldmann
415 - fixed problems with displaying binary files, thanks to Thomas Waldmann
415 - removed name from archive files since it's breaking ui for long repo names
416 - removed name from archive files since it's breaking ui for long repo names
416 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
417 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
417 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
418 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
418 Thomas Waldmann
419 Thomas Waldmann
419 - fixed issue #166 summary pager was skipping 10 revisions on second page
420 - fixed issue #166 summary pager was skipping 10 revisions on second page
420
421
421
422
422 1.1.7 (**2011-03-23**)
423 1.1.7 (**2011-03-23**)
423 ----------------------
424 ----------------------
424
425
425 news
426 news
426 ++++
427 ++++
427
428
428 fixes
429 fixes
429 +++++
430 +++++
430
431
431 - fixed (again) #136 installation support for FreeBSD
432 - fixed (again) #136 installation support for FreeBSD
432
433
433
434
434 1.1.6 (**2011-03-21**)
435 1.1.6 (**2011-03-21**)
435 ----------------------
436 ----------------------
436
437
437 news
438 news
438 ++++
439 ++++
439
440
440 fixes
441 fixes
441 +++++
442 +++++
442
443
443 - fixed #136 installation support for FreeBSD
444 - fixed #136 installation support for FreeBSD
444 - RhodeCode will check for python version during installation
445 - RhodeCode will check for python version during installation
445
446
446 1.1.5 (**2011-03-17**)
447 1.1.5 (**2011-03-17**)
447 ----------------------
448 ----------------------
448
449
449 news
450 news
450 ++++
451 ++++
451
452
452 - basic windows support, by exchanging pybcrypt into sha256 for windows only
453 - basic windows support, by exchanging pybcrypt into sha256 for windows only
453 highly inspired by idea of mantis406
454 highly inspired by idea of mantis406
454
455
455 fixes
456 fixes
456 +++++
457 +++++
457
458
458 - fixed sorting by author in main page
459 - fixed sorting by author in main page
459 - fixed crashes with diffs on binary files
460 - fixed crashes with diffs on binary files
460 - fixed #131 problem with boolean values for LDAP
461 - fixed #131 problem with boolean values for LDAP
461 - fixed #122 mysql problems thanks to striker69
462 - fixed #122 mysql problems thanks to striker69
462 - fixed problem with errors on calling raw/raw_files/annotate functions
463 - fixed problem with errors on calling raw/raw_files/annotate functions
463 with unknown revisions
464 with unknown revisions
464 - fixed returned rawfiles attachment names with international character
465 - fixed returned rawfiles attachment names with international character
465 - cleaned out docs, big thanks to Jason Harris
466 - cleaned out docs, big thanks to Jason Harris
466
467
467 1.1.4 (**2011-02-19**)
468 1.1.4 (**2011-02-19**)
468 ----------------------
469 ----------------------
469
470
470 news
471 news
471 ++++
472 ++++
472
473
473 fixes
474 fixes
474 +++++
475 +++++
475
476
476 - fixed formencode import problem on settings page, that caused server crash
477 - fixed formencode import problem on settings page, that caused server crash
477 when that page was accessed as first after server start
478 when that page was accessed as first after server start
478 - journal fixes
479 - journal fixes
479 - fixed option to access repository just by entering http://server/<repo_name>
480 - fixed option to access repository just by entering http://server/<repo_name>
480
481
481 1.1.3 (**2011-02-16**)
482 1.1.3 (**2011-02-16**)
482 ----------------------
483 ----------------------
483
484
484 news
485 news
485 ++++
486 ++++
486
487
487 - implemented #102 allowing the '.' character in username
488 - implemented #102 allowing the '.' character in username
488 - added option to access repository just by entering http://server/<repo_name>
489 - added option to access repository just by entering http://server/<repo_name>
489 - celery task ignores result for better performance
490 - celery task ignores result for better performance
490
491
491 fixes
492 fixes
492 +++++
493 +++++
493
494
494 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
495 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
495 apollo13 and Johan Walles
496 apollo13 and Johan Walles
496 - small fixes in journal
497 - small fixes in journal
497 - fixed problems with getting setting for celery from .ini files
498 - fixed problems with getting setting for celery from .ini files
498 - registration, password reset and login boxes share the same title as main
499 - registration, password reset and login boxes share the same title as main
499 application now
500 application now
500 - fixed #113: to high permissions to fork repository
501 - fixed #113: to high permissions to fork repository
501 - fixed problem with '[' chars in commit messages in journal
502 - fixed problem with '[' chars in commit messages in journal
502 - removed issue with space inside renamed repository after deletion
503 - removed issue with space inside renamed repository after deletion
503 - db transaction fixes when filesystem repository creation failed
504 - db transaction fixes when filesystem repository creation failed
504 - fixed #106 relation issues on databases different than sqlite
505 - fixed #106 relation issues on databases different than sqlite
505 - fixed static files paths links to use of url() method
506 - fixed static files paths links to use of url() method
506
507
507 1.1.2 (**2011-01-12**)
508 1.1.2 (**2011-01-12**)
508 ----------------------
509 ----------------------
509
510
510 news
511 news
511 ++++
512 ++++
512
513
513
514
514 fixes
515 fixes
515 +++++
516 +++++
516
517
517 - fixes #98 protection against float division of percentage stats
518 - fixes #98 protection against float division of percentage stats
518 - fixed graph bug
519 - fixed graph bug
519 - forced webhelpers version since it was making troubles during installation
520 - forced webhelpers version since it was making troubles during installation
520
521
521 1.1.1 (**2011-01-06**)
522 1.1.1 (**2011-01-06**)
522 ----------------------
523 ----------------------
523
524
524 news
525 news
525 ++++
526 ++++
526
527
527 - added force https option into ini files for easier https usage (no need to
528 - added force https option into ini files for easier https usage (no need to
528 set server headers with this options)
529 set server headers with this options)
529 - small css updates
530 - small css updates
530
531
531 fixes
532 fixes
532 +++++
533 +++++
533
534
534 - fixed #96 redirect loop on files view on repositories without changesets
535 - fixed #96 redirect loop on files view on repositories without changesets
535 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
536 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
536 and server crashed with errors
537 and server crashed with errors
537 - fixed large tooltips problems on main page
538 - fixed large tooltips problems on main page
538 - fixed #92 whoosh indexer is more error proof
539 - fixed #92 whoosh indexer is more error proof
539
540
540 1.1.0 (**2010-12-18**)
541 1.1.0 (**2010-12-18**)
541 ----------------------
542 ----------------------
542
543
543 news
544 news
544 ++++
545 ++++
545
546
546 - rewrite of internals for vcs >=0.1.10
547 - rewrite of internals for vcs >=0.1.10
547 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
548 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
548 with older clients
549 with older clients
549 - anonymous access, authentication via ldap
550 - anonymous access, authentication via ldap
550 - performance upgrade for cached repos list - each repository has its own
551 - performance upgrade for cached repos list - each repository has its own
551 cache that's invalidated when needed.
552 cache that's invalidated when needed.
552 - performance upgrades on repositories with large amount of commits (20K+)
553 - performance upgrades on repositories with large amount of commits (20K+)
553 - main page quick filter for filtering repositories
554 - main page quick filter for filtering repositories
554 - user dashboards with ability to follow chosen repositories actions
555 - user dashboards with ability to follow chosen repositories actions
555 - sends email to admin on new user registration
556 - sends email to admin on new user registration
556 - added cache/statistics reset options into repository settings
557 - added cache/statistics reset options into repository settings
557 - more detailed action logger (based on hooks) with pushed changesets lists
558 - more detailed action logger (based on hooks) with pushed changesets lists
558 and options to disable those hooks from admin panel
559 and options to disable those hooks from admin panel
559 - introduced new enhanced changelog for merges that shows more accurate results
560 - introduced new enhanced changelog for merges that shows more accurate results
560 - new improved and faster code stats (based on pygments lexers mapping tables,
561 - new improved and faster code stats (based on pygments lexers mapping tables,
561 showing up to 10 trending sources for each repository. Additionally stats
562 showing up to 10 trending sources for each repository. Additionally stats
562 can be disabled in repository settings.
563 can be disabled in repository settings.
563 - gui optimizations, fixed application width to 1024px
564 - gui optimizations, fixed application width to 1024px
564 - added cut off (for large files/changesets) limit into config files
565 - added cut off (for large files/changesets) limit into config files
565 - whoosh, celeryd, upgrade moved to paster command
566 - whoosh, celeryd, upgrade moved to paster command
566 - other than sqlite database backends can be used
567 - other than sqlite database backends can be used
567
568
568 fixes
569 fixes
569 +++++
570 +++++
570
571
571 - fixes #61 forked repo was showing only after cache expired
572 - fixes #61 forked repo was showing only after cache expired
572 - fixes #76 no confirmation on user deletes
573 - fixes #76 no confirmation on user deletes
573 - fixes #66 Name field misspelled
574 - fixes #66 Name field misspelled
574 - fixes #72 block user removal when he owns repositories
575 - fixes #72 block user removal when he owns repositories
575 - fixes #69 added password confirmation fields
576 - fixes #69 added password confirmation fields
576 - fixes #87 RhodeCode crashes occasionally on updating repository owner
577 - fixes #87 RhodeCode crashes occasionally on updating repository owner
577 - fixes #82 broken annotations on files with more than 1 blank line at the end
578 - fixes #82 broken annotations on files with more than 1 blank line at the end
578 - a lot of fixes and tweaks for file browser
579 - a lot of fixes and tweaks for file browser
579 - fixed detached session issues
580 - fixed detached session issues
580 - fixed when user had no repos he would see all repos listed in my account
581 - fixed when user had no repos he would see all repos listed in my account
581 - fixed ui() instance bug when global hgrc settings was loaded for server
582 - fixed ui() instance bug when global hgrc settings was loaded for server
582 instance and all hgrc options were merged with our db ui() object
583 instance and all hgrc options were merged with our db ui() object
583 - numerous small bugfixes
584 - numerous small bugfixes
584
585
585 (special thanks for TkSoh for detailed feedback)
586 (special thanks for TkSoh for detailed feedback)
586
587
587
588
588 1.0.2 (**2010-11-12**)
589 1.0.2 (**2010-11-12**)
589 ----------------------
590 ----------------------
590
591
591 news
592 news
592 ++++
593 ++++
593
594
594 - tested under python2.7
595 - tested under python2.7
595 - bumped sqlalchemy and celery versions
596 - bumped sqlalchemy and celery versions
596
597
597 fixes
598 fixes
598 +++++
599 +++++
599
600
600 - fixed #59 missing graph.js
601 - fixed #59 missing graph.js
601 - fixed repo_size crash when repository had broken symlinks
602 - fixed repo_size crash when repository had broken symlinks
602 - fixed python2.5 crashes.
603 - fixed python2.5 crashes.
603
604
604
605
605 1.0.1 (**2010-11-10**)
606 1.0.1 (**2010-11-10**)
606 ----------------------
607 ----------------------
607
608
608 news
609 news
609 ++++
610 ++++
610
611
611 - small css updated
612 - small css updated
612
613
613 fixes
614 fixes
614 +++++
615 +++++
615
616
616 - fixed #53 python2.5 incompatible enumerate calls
617 - fixed #53 python2.5 incompatible enumerate calls
617 - fixed #52 disable mercurial extension for web
618 - fixed #52 disable mercurial extension for web
618 - fixed #51 deleting repositories don't delete it's dependent objects
619 - fixed #51 deleting repositories don't delete it's dependent objects
619
620
620
621
621 1.0.0 (**2010-11-02**)
622 1.0.0 (**2010-11-02**)
622 ----------------------
623 ----------------------
623
624
624 - security bugfix simplehg wasn't checking for permissions on commands
625 - security bugfix simplehg wasn't checking for permissions on commands
625 other than pull or push.
626 other than pull or push.
626 - fixed doubled messages after push or pull in admin journal
627 - fixed doubled messages after push or pull in admin journal
627 - templating and css corrections, fixed repo switcher on chrome, updated titles
628 - templating and css corrections, fixed repo switcher on chrome, updated titles
628 - admin menu accessible from options menu on repository view
629 - admin menu accessible from options menu on repository view
629 - permissions cached queries
630 - permissions cached queries
630
631
631 1.0.0rc4 (**2010-10-12**)
632 1.0.0rc4 (**2010-10-12**)
632 --------------------------
633 --------------------------
633
634
634 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
635 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
635 - removed cache_manager settings from sqlalchemy meta
636 - removed cache_manager settings from sqlalchemy meta
636 - added sqlalchemy cache settings to ini files
637 - added sqlalchemy cache settings to ini files
637 - validated password length and added second try of failure on paster setup-app
638 - validated password length and added second try of failure on paster setup-app
638 - fixed setup database destroy prompt even when there was no db
639 - fixed setup database destroy prompt even when there was no db
639
640
640
641
641 1.0.0rc3 (**2010-10-11**)
642 1.0.0rc3 (**2010-10-11**)
642 -------------------------
643 -------------------------
643
644
644 - fixed i18n during installation.
645 - fixed i18n during installation.
645
646
646 1.0.0rc2 (**2010-10-11**)
647 1.0.0rc2 (**2010-10-11**)
647 -------------------------
648 -------------------------
648
649
649 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
650 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
650 occure. After vcs is fixed it'll be put back again.
651 occure. After vcs is fixed it'll be put back again.
651 - templating/css rewrites, optimized css. No newline at end of file
652 - templating/css rewrites, optimized css.
@@ -1,97 +1,98 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.__init__
3 rhodecode.__init__
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 RhodeCode, a web based repository management based on pylons
6 RhodeCode, a web based repository management based on pylons
7 versioning implementation: http://www.python.org/dev/peps/pep-0386/
7 versioning implementation: http://www.python.org/dev/peps/pep-0386/
8
8
9 :created_on: Apr 9, 2010
9 :created_on: Apr 9, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import sys
26 import sys
27 import platform
27 import platform
28
28
29 VERSION = (1, 3, 6)
29 VERSION = (1, 3, 6)
30
30
31 try:
31 try:
32 from rhodecode.lib import get_current_revision
32 from rhodecode.lib import get_current_revision
33 _rev = get_current_revision(quiet=True)
33 _rev = get_current_revision(quiet=True)
34 if _rev and len(VERSION) > 3:
34 if _rev and len(VERSION) > 3:
35 VERSION += ('dev%s' % _rev[0],)
35 VERSION += ('dev%s' % _rev[0],)
36 except ImportError:
36 except ImportError:
37 pass
37 pass
38
38
39 __version__ = ('.'.join((str(each) for each in VERSION[:3])) +
39 __version__ = ('.'.join((str(each) for each in VERSION[:3])) +
40 '.'.join(VERSION[3:]))
40 '.'.join(VERSION[3:]))
41 __dbversion__ = 5 # defines current db version for migrations
41 __dbversion__ = 5 # defines current db version for migrations
42 __platform__ = platform.system()
42 __platform__ = platform.system()
43 __license__ = 'GPLv3'
43 __license__ = 'GPLv3'
44 __py_version__ = sys.version_info
44 __py_version__ = sys.version_info
45
45
46 PLATFORM_WIN = ('Windows')
46 PLATFORM_WIN = ('Windows')
47 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
47 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
48
48
49 is_windows = __platform__ in PLATFORM_WIN
49 is_windows = __platform__ in PLATFORM_WIN
50 is_unix = __platform__ in PLATFORM_OTHERS
50 is_unix = __platform__ in PLATFORM_OTHERS
51
51
52 requirements = [
52 requirements = [
53 "Pylons==1.0.0",
53 "Pylons==1.0.0",
54 "Beaker==1.6.3",
54 "Beaker==1.6.3",
55 "WebHelpers==1.3",
55 "WebHelpers==1.3",
56 "formencode==1.2.4",
56 "formencode==1.2.4",
57 "SQLAlchemy==0.7.6",
57 "SQLAlchemy==0.7.6",
58 "Mako==0.7.0",
58 "Mako==0.7.0",
59 "pygments>=1.4",
59 "pygments>=1.4",
60 "whoosh>=2.4.0,<2.5",
60 "whoosh>=2.4.0,<2.5",
61 "celery>=2.2.5,<2.3",
61 "celery>=2.2.5,<2.3",
62 "babel",
62 "babel",
63 "python-dateutil>=1.5.0,<2.0.0",
63 "python-dateutil>=1.5.0,<2.0.0",
64 "dulwich>=0.8.5,<0.9.0",
64 "dulwich>=0.8.5,<0.9.0",
65 "webob==1.0.8",
65 "webob==1.0.8",
66 "markdown==2.1.1",
66 "markdown==2.1.1",
67 "docutils==0.8.1",
67 "docutils==0.8.1",
68 "simplejson==2.5.2",
68 "simplejson==2.5.2",
69 ]
69 ]
70
70
71 if __py_version__ < (2, 6):
71 if __py_version__ < (2, 6):
72 requirements.append("pysqlite")
72 requirements.append("pysqlite")
73
73
74 if is_windows:
74 if is_windows:
75 requirements.append("mercurial>=2.2.1,<2.3")
75 requirements.append("mercurial>=2.2.1,<2.3")
76 else:
76 else:
77 requirements.append("py-bcrypt")
77 requirements.append("py-bcrypt")
78 requirements.append("mercurial>=2.2.1,<2.3")
78 requirements.append("mercurial>=2.2.1,<2.3")
79
79
80
80
81 def get_version():
81 def get_version():
82 """Returns shorter version (digit parts only) as string."""
82 """Returns shorter version (digit parts only) as string."""
83
83
84 return '.'.join((str(each) for each in VERSION[:3]))
84 return '.'.join((str(each) for each in VERSION[:3]))
85
85
86 BACKENDS = {
86 BACKENDS = {
87 'hg': 'Mercurial repository',
87 'hg': 'Mercurial repository',
88 'git': 'Git repository',
88 'git': 'Git repository',
89 }
89 }
90
90
91 CELERY_ON = False
91 CELERY_ON = False
92 CELERY_EAGER = False
92
93
93 # link to config for pylons
94 # link to config for pylons
94 CONFIG = {}
95 CONFIG = {}
95
96
96 # Linked module for extensions
97 # Linked module for extensions
97 EXTENSIONS = {}
98 EXTENSIONS = {}
@@ -1,96 +1,97 b''
1 """Pylons environment configuration"""
1 """Pylons environment configuration"""
2
2
3 import os
3 import os
4 import logging
4 import logging
5 import rhodecode
5 import rhodecode
6
6
7 from mako.lookup import TemplateLookup
7 from mako.lookup import TemplateLookup
8 from pylons.configuration import PylonsConfig
8 from pylons.configuration import PylonsConfig
9 from pylons.error import handle_mako_error
9 from pylons.error import handle_mako_error
10
10
11 # don't remove this import it does magic for celery
11 # don't remove this import it does magic for celery
12 from rhodecode.lib import celerypylons
12 from rhodecode.lib import celerypylons
13
13
14 import rhodecode.lib.app_globals as app_globals
14 import rhodecode.lib.app_globals as app_globals
15
15
16 from rhodecode.config.routing import make_map
16 from rhodecode.config.routing import make_map
17
17
18 from rhodecode.lib import helpers
18 from rhodecode.lib import helpers
19 from rhodecode.lib.auth import set_available_permissions
19 from rhodecode.lib.auth import set_available_permissions
20 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config,\
20 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config,\
21 load_rcextensions
21 load_rcextensions
22 from rhodecode.lib.utils2 import engine_from_config, str2bool
22 from rhodecode.lib.utils2 import engine_from_config, str2bool
23 from rhodecode.model import init_model
23 from rhodecode.model import init_model
24 from rhodecode.model.scm import ScmModel
24 from rhodecode.model.scm import ScmModel
25
25
26 log = logging.getLogger(__name__)
26 log = logging.getLogger(__name__)
27
27
28
28
29 def load_environment(global_conf, app_conf, initial=False):
29 def load_environment(global_conf, app_conf, initial=False):
30 """
30 """
31 Configure the Pylons environment via the ``pylons.config``
31 Configure the Pylons environment via the ``pylons.config``
32 object
32 object
33 """
33 """
34 config = PylonsConfig()
34 config = PylonsConfig()
35
35
36 # Pylons paths
36 # Pylons paths
37 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
37 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
38 paths = dict(
38 paths = dict(
39 root=root,
39 root=root,
40 controllers=os.path.join(root, 'controllers'),
40 controllers=os.path.join(root, 'controllers'),
41 static_files=os.path.join(root, 'public'),
41 static_files=os.path.join(root, 'public'),
42 templates=[os.path.join(root, 'templates')]
42 templates=[os.path.join(root, 'templates')]
43 )
43 )
44
44
45 # Initialize config with the basic options
45 # Initialize config with the basic options
46 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
46 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
47
47
48 # store some globals into rhodecode
48 # store some globals into rhodecode
49 rhodecode.CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
49 rhodecode.CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
50 rhodecode.CELERY_EAGER = str2bool(config['app_conf'].get('celery.always.eager'))
50
51
51 config['routes.map'] = make_map(config)
52 config['routes.map'] = make_map(config)
52 config['pylons.app_globals'] = app_globals.Globals(config)
53 config['pylons.app_globals'] = app_globals.Globals(config)
53 config['pylons.h'] = helpers
54 config['pylons.h'] = helpers
54 rhodecode.CONFIG = config
55 rhodecode.CONFIG = config
55
56
56 load_rcextensions(root_path=config['here'])
57 load_rcextensions(root_path=config['here'])
57
58
58 # Setup cache object as early as possible
59 # Setup cache object as early as possible
59 import pylons
60 import pylons
60 pylons.cache._push_object(config['pylons.app_globals'].cache)
61 pylons.cache._push_object(config['pylons.app_globals'].cache)
61
62
62 # Create the Mako TemplateLookup, with the default auto-escaping
63 # Create the Mako TemplateLookup, with the default auto-escaping
63 config['pylons.app_globals'].mako_lookup = TemplateLookup(
64 config['pylons.app_globals'].mako_lookup = TemplateLookup(
64 directories=paths['templates'],
65 directories=paths['templates'],
65 error_handler=handle_mako_error,
66 error_handler=handle_mako_error,
66 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
67 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
67 input_encoding='utf-8', default_filters=['escape'],
68 input_encoding='utf-8', default_filters=['escape'],
68 imports=['from webhelpers.html import escape'])
69 imports=['from webhelpers.html import escape'])
69
70
70 # sets the c attribute access when don't existing attribute are accessed
71 # sets the c attribute access when don't existing attribute are accessed
71 config['pylons.strict_tmpl_context'] = True
72 config['pylons.strict_tmpl_context'] = True
72 test = os.path.split(config['__file__'])[-1] == 'test.ini'
73 test = os.path.split(config['__file__'])[-1] == 'test.ini'
73 if test:
74 if test:
74 from rhodecode.lib.utils import create_test_env, create_test_index
75 from rhodecode.lib.utils import create_test_env, create_test_index
75 from rhodecode.tests import TESTS_TMP_PATH
76 from rhodecode.tests import TESTS_TMP_PATH
76 create_test_env(TESTS_TMP_PATH, config)
77 create_test_env(TESTS_TMP_PATH, config)
77 create_test_index(TESTS_TMP_PATH, config, True)
78 create_test_index(TESTS_TMP_PATH, config, True)
78
79
79 # MULTIPLE DB configs
80 # MULTIPLE DB configs
80 # Setup the SQLAlchemy database engine
81 # Setup the SQLAlchemy database engine
81 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
82 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
82
83
83 init_model(sa_engine_db1)
84 init_model(sa_engine_db1)
84
85
85 repos_path = make_ui('db').configitems('paths')[0][1]
86 repos_path = make_ui('db').configitems('paths')[0][1]
86 repo2db_mapper(ScmModel().repo_scan(repos_path))
87 repo2db_mapper(ScmModel().repo_scan(repos_path))
87 set_available_permissions(config)
88 set_available_permissions(config)
88 config['base_path'] = repos_path
89 config['base_path'] = repos_path
89 set_rhodecode_config(config)
90 set_rhodecode_config(config)
90 # CONFIGURATION OPTIONS HERE (note: all config options will override
91 # CONFIGURATION OPTIONS HERE (note: all config options will override
91 # any Pylons config options)
92 # any Pylons config options)
92
93
93 # store config reference into our module to skip import magic of
94 # store config reference into our module to skip import magic of
94 # pylons
95 # pylons
95 rhodecode.CONFIG.update(config)
96 rhodecode.CONFIG.update(config)
96 return config
97 return config
@@ -1,128 +1,128 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.celerylib.__init__
3 rhodecode.lib.celerylib.__init__
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 celery libs for RhodeCode
6 celery libs for RhodeCode
7
7
8 :created_on: Nov 27, 2010
8 :created_on: Nov 27, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import sys
27 import sys
28 import socket
28 import socket
29 import traceback
29 import traceback
30 import logging
30 import logging
31 from os.path import dirname as dn, join as jn
31 from os.path import dirname as dn, join as jn
32 from pylons import config
32 from pylons import config
33
33
34 from hashlib import md5
34 from hashlib import md5
35 from decorator import decorator
35 from decorator import decorator
36
36
37 from rhodecode.lib.vcs.utils.lazy import LazyProperty
37 from rhodecode.lib.vcs.utils.lazy import LazyProperty
38 from rhodecode import CELERY_ON
38 from rhodecode import CELERY_ON, CELERY_EAGER
39 from rhodecode.lib.utils2 import str2bool, safe_str
39 from rhodecode.lib.utils2 import str2bool, safe_str
40 from rhodecode.lib.pidlock import DaemonLock, LockHeld
40 from rhodecode.lib.pidlock import DaemonLock, LockHeld
41 from rhodecode.model import init_model
41 from rhodecode.model import init_model
42 from rhodecode.model import meta
42 from rhodecode.model import meta
43 from rhodecode.model.db import Statistics, Repository, User
43 from rhodecode.model.db import Statistics, Repository, User
44
44
45 from sqlalchemy import engine_from_config
45 from sqlalchemy import engine_from_config
46
46
47 from celery.messaging import establish_connection
47 from celery.messaging import establish_connection
48
48
49 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
50
50
51
51
52 class ResultWrapper(object):
52 class ResultWrapper(object):
53 def __init__(self, task):
53 def __init__(self, task):
54 self.task = task
54 self.task = task
55
55
56 @LazyProperty
56 @LazyProperty
57 def result(self):
57 def result(self):
58 return self.task
58 return self.task
59
59
60
60
61 def run_task(task, *args, **kwargs):
61 def run_task(task, *args, **kwargs):
62 if CELERY_ON:
62 if CELERY_ON:
63 try:
63 try:
64 t = task.apply_async(args=args, kwargs=kwargs)
64 t = task.apply_async(args=args, kwargs=kwargs)
65 log.info('running task %s:%s' % (t.task_id, task))
65 log.info('running task %s:%s' % (t.task_id, task))
66 return t
66 return t
67
67
68 except socket.error, e:
68 except socket.error, e:
69 if isinstance(e, IOError) and e.errno == 111:
69 if isinstance(e, IOError) and e.errno == 111:
70 log.debug('Unable to connect to celeryd. Sync execution')
70 log.debug('Unable to connect to celeryd. Sync execution')
71 else:
71 else:
72 log.error(traceback.format_exc())
72 log.error(traceback.format_exc())
73 except KeyError, e:
73 except KeyError, e:
74 log.debug('Unable to connect to celeryd. Sync execution')
74 log.debug('Unable to connect to celeryd. Sync execution')
75 except Exception, e:
75 except Exception, e:
76 log.error(traceback.format_exc())
76 log.error(traceback.format_exc())
77
77
78 log.debug('executing task %s in sync mode' % task)
78 log.debug('executing task %s in sync mode' % task)
79 return ResultWrapper(task(*args, **kwargs))
79 return ResultWrapper(task(*args, **kwargs))
80
80
81
81
82 def __get_lockkey(func, *fargs, **fkwargs):
82 def __get_lockkey(func, *fargs, **fkwargs):
83 params = list(fargs)
83 params = list(fargs)
84 params.extend(['%s-%s' % ar for ar in fkwargs.items()])
84 params.extend(['%s-%s' % ar for ar in fkwargs.items()])
85
85
86 func_name = str(func.__name__) if hasattr(func, '__name__') else str(func)
86 func_name = str(func.__name__) if hasattr(func, '__name__') else str(func)
87
87
88 lockkey = 'task_%s.lock' % \
88 lockkey = 'task_%s.lock' % \
89 md5(func_name + '-' + '-'.join(map(safe_str, params))).hexdigest()
89 md5(func_name + '-' + '-'.join(map(safe_str, params))).hexdigest()
90 return lockkey
90 return lockkey
91
91
92
92
93 def locked_task(func):
93 def locked_task(func):
94 def __wrapper(func, *fargs, **fkwargs):
94 def __wrapper(func, *fargs, **fkwargs):
95 lockkey = __get_lockkey(func, *fargs, **fkwargs)
95 lockkey = __get_lockkey(func, *fargs, **fkwargs)
96 lockkey_path = config['here']
96 lockkey_path = config['here']
97
97
98 log.info('running task with lockkey %s' % lockkey)
98 log.info('running task with lockkey %s' % lockkey)
99 try:
99 try:
100 l = DaemonLock(file_=jn(lockkey_path, lockkey))
100 l = DaemonLock(file_=jn(lockkey_path, lockkey))
101 ret = func(*fargs, **fkwargs)
101 ret = func(*fargs, **fkwargs)
102 l.release()
102 l.release()
103 return ret
103 return ret
104 except LockHeld:
104 except LockHeld:
105 log.info('LockHeld')
105 log.info('LockHeld')
106 return 'Task with key %s already running' % lockkey
106 return 'Task with key %s already running' % lockkey
107
107
108 return decorator(__wrapper, func)
108 return decorator(__wrapper, func)
109
109
110
110
111 def get_session():
111 def get_session():
112 if CELERY_ON:
112 if CELERY_ON:
113 engine = engine_from_config(config, 'sqlalchemy.db1.')
113 engine = engine_from_config(config, 'sqlalchemy.db1.')
114 init_model(engine)
114 init_model(engine)
115 sa = meta.Session
115 sa = meta.Session
116 return sa
116 return sa
117
117
118
118
119 def dbsession(func):
119 def dbsession(func):
120 def __wrapper(func, *fargs, **fkwargs):
120 def __wrapper(func, *fargs, **fkwargs):
121 try:
121 try:
122 ret = func(*fargs, **fkwargs)
122 ret = func(*fargs, **fkwargs)
123 return ret
123 return ret
124 finally:
124 finally:
125 if CELERY_ON:
125 if CELERY_ON and CELERY_EAGER is False:
126 meta.Session.remove()
126 meta.Session.remove()
127
127
128 return decorator(__wrapper, func)
128 return decorator(__wrapper, func)
@@ -1,421 +1,421 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.celerylib.tasks
3 rhodecode.lib.celerylib.tasks
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 RhodeCode task modules, containing all task that suppose to be run
6 RhodeCode task modules, containing all task that suppose to be run
7 by celery daemon
7 by celery daemon
8
8
9 :created_on: Oct 6, 2010
9 :created_on: Oct 6, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 from celery.decorators import task
26 from celery.decorators import task
27
27
28 import os
28 import os
29 import traceback
29 import traceback
30 import logging
30 import logging
31 from os.path import join as jn
31 from os.path import join as jn
32
32
33 from time import mktime
33 from time import mktime
34 from operator import itemgetter
34 from operator import itemgetter
35 from string import lower
35 from string import lower
36
36
37 from pylons import config, url
37 from pylons import config, url
38 from pylons.i18n.translation import _
38 from pylons.i18n.translation import _
39
39
40 from rhodecode.lib.vcs import get_backend
40 from rhodecode.lib.vcs import get_backend
41
41
42 from rhodecode import CELERY_ON
42 from rhodecode import CELERY_ON, CELERY_EAGER
43 from rhodecode.lib.utils2 import safe_str
43 from rhodecode.lib.utils2 import safe_str
44 from rhodecode.lib.celerylib import run_task, locked_task, dbsession, \
44 from rhodecode.lib.celerylib import run_task, locked_task, dbsession, \
45 str2bool, __get_lockkey, LockHeld, DaemonLock, get_session
45 str2bool, __get_lockkey, LockHeld, DaemonLock, get_session
46 from rhodecode.lib.helpers import person
46 from rhodecode.lib.helpers import person
47 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
47 from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
48 from rhodecode.lib.utils import add_cache, action_logger
48 from rhodecode.lib.utils import add_cache, action_logger
49 from rhodecode.lib.compat import json, OrderedDict
49 from rhodecode.lib.compat import json, OrderedDict
50 from rhodecode.lib.hooks import log_create_repository
50 from rhodecode.lib.hooks import log_create_repository
51
51
52 from rhodecode.model.db import Statistics, Repository, User
52 from rhodecode.model.db import Statistics, Repository, User
53
53
54
54
55 add_cache(config)
55 add_cache(config)
56
56
57 __all__ = ['whoosh_index', 'get_commits_stats',
57 __all__ = ['whoosh_index', 'get_commits_stats',
58 'reset_user_password', 'send_email']
58 'reset_user_password', 'send_email']
59
59
60
60
61 def get_logger(cls):
61 def get_logger(cls):
62 if CELERY_ON:
62 if CELERY_ON:
63 try:
63 try:
64 log = cls.get_logger()
64 log = cls.get_logger()
65 except:
65 except:
66 log = logging.getLogger(__name__)
66 log = logging.getLogger(__name__)
67 else:
67 else:
68 log = logging.getLogger(__name__)
68 log = logging.getLogger(__name__)
69
69
70 return log
70 return log
71
71
72
72
73 @task(ignore_result=True)
73 @task(ignore_result=True)
74 @locked_task
74 @locked_task
75 @dbsession
75 @dbsession
76 def whoosh_index(repo_location, full_index):
76 def whoosh_index(repo_location, full_index):
77 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
77 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
78 log = whoosh_index.get_logger(whoosh_index)
78 log = whoosh_index.get_logger(whoosh_index)
79 DBS = get_session()
79 DBS = get_session()
80
80
81 index_location = config['index_dir']
81 index_location = config['index_dir']
82 WhooshIndexingDaemon(index_location=index_location,
82 WhooshIndexingDaemon(index_location=index_location,
83 repo_location=repo_location, sa=DBS)\
83 repo_location=repo_location, sa=DBS)\
84 .run(full_index=full_index)
84 .run(full_index=full_index)
85
85
86
86
87 @task(ignore_result=True)
87 @task(ignore_result=True)
88 @dbsession
88 @dbsession
89 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
89 def get_commits_stats(repo_name, ts_min_y, ts_max_y):
90 log = get_logger(get_commits_stats)
90 log = get_logger(get_commits_stats)
91 DBS = get_session()
91 DBS = get_session()
92 lockkey = __get_lockkey('get_commits_stats', repo_name, ts_min_y,
92 lockkey = __get_lockkey('get_commits_stats', repo_name, ts_min_y,
93 ts_max_y)
93 ts_max_y)
94 lockkey_path = config['here']
94 lockkey_path = config['here']
95
95
96 log.info('running task with lockkey %s' % lockkey)
96 log.info('running task with lockkey %s' % lockkey)
97
97
98 try:
98 try:
99 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
99 lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
100
100
101 # for js data compatibility cleans the key for person from '
101 # for js data compatibility cleans the key for person from '
102 akc = lambda k: person(k).replace('"', "")
102 akc = lambda k: person(k).replace('"', "")
103
103
104 co_day_auth_aggr = {}
104 co_day_auth_aggr = {}
105 commits_by_day_aggregate = {}
105 commits_by_day_aggregate = {}
106 repo = Repository.get_by_repo_name(repo_name)
106 repo = Repository.get_by_repo_name(repo_name)
107 if repo is None:
107 if repo is None:
108 return True
108 return True
109
109
110 repo = repo.scm_instance
110 repo = repo.scm_instance
111 repo_size = repo.count()
111 repo_size = repo.count()
112 # return if repo have no revisions
112 # return if repo have no revisions
113 if repo_size < 1:
113 if repo_size < 1:
114 lock.release()
114 lock.release()
115 return True
115 return True
116
116
117 skip_date_limit = True
117 skip_date_limit = True
118 parse_limit = int(config['app_conf'].get('commit_parse_limit'))
118 parse_limit = int(config['app_conf'].get('commit_parse_limit'))
119 last_rev = None
119 last_rev = None
120 last_cs = None
120 last_cs = None
121 timegetter = itemgetter('time')
121 timegetter = itemgetter('time')
122
122
123 dbrepo = DBS.query(Repository)\
123 dbrepo = DBS.query(Repository)\
124 .filter(Repository.repo_name == repo_name).scalar()
124 .filter(Repository.repo_name == repo_name).scalar()
125 cur_stats = DBS.query(Statistics)\
125 cur_stats = DBS.query(Statistics)\
126 .filter(Statistics.repository == dbrepo).scalar()
126 .filter(Statistics.repository == dbrepo).scalar()
127
127
128 if cur_stats is not None:
128 if cur_stats is not None:
129 last_rev = cur_stats.stat_on_revision
129 last_rev = cur_stats.stat_on_revision
130
130
131 if last_rev == repo.get_changeset().revision and repo_size > 1:
131 if last_rev == repo.get_changeset().revision and repo_size > 1:
132 # pass silently without any work if we're not on first revision or
132 # pass silently without any work if we're not on first revision or
133 # current state of parsing revision(from db marker) is the
133 # current state of parsing revision(from db marker) is the
134 # last revision
134 # last revision
135 lock.release()
135 lock.release()
136 return True
136 return True
137
137
138 if cur_stats:
138 if cur_stats:
139 commits_by_day_aggregate = OrderedDict(json.loads(
139 commits_by_day_aggregate = OrderedDict(json.loads(
140 cur_stats.commit_activity_combined))
140 cur_stats.commit_activity_combined))
141 co_day_auth_aggr = json.loads(cur_stats.commit_activity)
141 co_day_auth_aggr = json.loads(cur_stats.commit_activity)
142
142
143 log.debug('starting parsing %s' % parse_limit)
143 log.debug('starting parsing %s' % parse_limit)
144 lmktime = mktime
144 lmktime = mktime
145
145
146 last_rev = last_rev + 1 if last_rev >= 0 else 0
146 last_rev = last_rev + 1 if last_rev >= 0 else 0
147 log.debug('Getting revisions from %s to %s' % (
147 log.debug('Getting revisions from %s to %s' % (
148 last_rev, last_rev + parse_limit)
148 last_rev, last_rev + parse_limit)
149 )
149 )
150 for cs in repo[last_rev:last_rev + parse_limit]:
150 for cs in repo[last_rev:last_rev + parse_limit]:
151 log.debug('parsing %s' % cs)
151 log.debug('parsing %s' % cs)
152 last_cs = cs # remember last parsed changeset
152 last_cs = cs # remember last parsed changeset
153 k = lmktime([cs.date.timetuple()[0], cs.date.timetuple()[1],
153 k = lmktime([cs.date.timetuple()[0], cs.date.timetuple()[1],
154 cs.date.timetuple()[2], 0, 0, 0, 0, 0, 0])
154 cs.date.timetuple()[2], 0, 0, 0, 0, 0, 0])
155
155
156 if akc(cs.author) in co_day_auth_aggr:
156 if akc(cs.author) in co_day_auth_aggr:
157 try:
157 try:
158 l = [timegetter(x) for x in
158 l = [timegetter(x) for x in
159 co_day_auth_aggr[akc(cs.author)]['data']]
159 co_day_auth_aggr[akc(cs.author)]['data']]
160 time_pos = l.index(k)
160 time_pos = l.index(k)
161 except ValueError:
161 except ValueError:
162 time_pos = False
162 time_pos = False
163
163
164 if time_pos >= 0 and time_pos is not False:
164 if time_pos >= 0 and time_pos is not False:
165
165
166 datadict = \
166 datadict = \
167 co_day_auth_aggr[akc(cs.author)]['data'][time_pos]
167 co_day_auth_aggr[akc(cs.author)]['data'][time_pos]
168
168
169 datadict["commits"] += 1
169 datadict["commits"] += 1
170 datadict["added"] += len(cs.added)
170 datadict["added"] += len(cs.added)
171 datadict["changed"] += len(cs.changed)
171 datadict["changed"] += len(cs.changed)
172 datadict["removed"] += len(cs.removed)
172 datadict["removed"] += len(cs.removed)
173
173
174 else:
174 else:
175 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
175 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
176
176
177 datadict = {"time": k,
177 datadict = {"time": k,
178 "commits": 1,
178 "commits": 1,
179 "added": len(cs.added),
179 "added": len(cs.added),
180 "changed": len(cs.changed),
180 "changed": len(cs.changed),
181 "removed": len(cs.removed),
181 "removed": len(cs.removed),
182 }
182 }
183 co_day_auth_aggr[akc(cs.author)]['data']\
183 co_day_auth_aggr[akc(cs.author)]['data']\
184 .append(datadict)
184 .append(datadict)
185
185
186 else:
186 else:
187 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
187 if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
188 co_day_auth_aggr[akc(cs.author)] = {
188 co_day_auth_aggr[akc(cs.author)] = {
189 "label": akc(cs.author),
189 "label": akc(cs.author),
190 "data": [{"time":k,
190 "data": [{"time":k,
191 "commits":1,
191 "commits":1,
192 "added":len(cs.added),
192 "added":len(cs.added),
193 "changed":len(cs.changed),
193 "changed":len(cs.changed),
194 "removed":len(cs.removed),
194 "removed":len(cs.removed),
195 }],
195 }],
196 "schema": ["commits"],
196 "schema": ["commits"],
197 }
197 }
198
198
199 #gather all data by day
199 #gather all data by day
200 if k in commits_by_day_aggregate:
200 if k in commits_by_day_aggregate:
201 commits_by_day_aggregate[k] += 1
201 commits_by_day_aggregate[k] += 1
202 else:
202 else:
203 commits_by_day_aggregate[k] = 1
203 commits_by_day_aggregate[k] = 1
204
204
205 overview_data = sorted(commits_by_day_aggregate.items(),
205 overview_data = sorted(commits_by_day_aggregate.items(),
206 key=itemgetter(0))
206 key=itemgetter(0))
207
207
208 if not co_day_auth_aggr:
208 if not co_day_auth_aggr:
209 co_day_auth_aggr[akc(repo.contact)] = {
209 co_day_auth_aggr[akc(repo.contact)] = {
210 "label": akc(repo.contact),
210 "label": akc(repo.contact),
211 "data": [0, 1],
211 "data": [0, 1],
212 "schema": ["commits"],
212 "schema": ["commits"],
213 }
213 }
214
214
215 stats = cur_stats if cur_stats else Statistics()
215 stats = cur_stats if cur_stats else Statistics()
216 stats.commit_activity = json.dumps(co_day_auth_aggr)
216 stats.commit_activity = json.dumps(co_day_auth_aggr)
217 stats.commit_activity_combined = json.dumps(overview_data)
217 stats.commit_activity_combined = json.dumps(overview_data)
218
218
219 log.debug('last revison %s' % last_rev)
219 log.debug('last revison %s' % last_rev)
220 leftovers = len(repo.revisions[last_rev:])
220 leftovers = len(repo.revisions[last_rev:])
221 log.debug('revisions to parse %s' % leftovers)
221 log.debug('revisions to parse %s' % leftovers)
222
222
223 if last_rev == 0 or leftovers < parse_limit:
223 if last_rev == 0 or leftovers < parse_limit:
224 log.debug('getting code trending stats')
224 log.debug('getting code trending stats')
225 stats.languages = json.dumps(__get_codes_stats(repo_name))
225 stats.languages = json.dumps(__get_codes_stats(repo_name))
226
226
227 try:
227 try:
228 stats.repository = dbrepo
228 stats.repository = dbrepo
229 stats.stat_on_revision = last_cs.revision if last_cs else 0
229 stats.stat_on_revision = last_cs.revision if last_cs else 0
230 DBS.add(stats)
230 DBS.add(stats)
231 DBS.commit()
231 DBS.commit()
232 except:
232 except:
233 log.error(traceback.format_exc())
233 log.error(traceback.format_exc())
234 DBS.rollback()
234 DBS.rollback()
235 lock.release()
235 lock.release()
236 return False
236 return False
237
237
238 # final release
238 # final release
239 lock.release()
239 lock.release()
240
240
241 # execute another task if celery is enabled
241 # execute another task if celery is enabled
242 if len(repo.revisions) > 1 and CELERY_ON:
242 if len(repo.revisions) > 1 and CELERY_ON:
243 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
243 run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
244 return True
244 return True
245 except LockHeld:
245 except LockHeld:
246 log.info('LockHeld')
246 log.info('LockHeld')
247 return 'Task with key %s already running' % lockkey
247 return 'Task with key %s already running' % lockkey
248
248
249 @task(ignore_result=True)
249 @task(ignore_result=True)
250 @dbsession
250 @dbsession
251 def send_password_link(user_email):
251 def send_password_link(user_email):
252 from rhodecode.model.notification import EmailNotificationModel
252 from rhodecode.model.notification import EmailNotificationModel
253
253
254 log = get_logger(send_password_link)
254 log = get_logger(send_password_link)
255 DBS = get_session()
255 DBS = get_session()
256
256
257 try:
257 try:
258 user = User.get_by_email(user_email)
258 user = User.get_by_email(user_email)
259 if user:
259 if user:
260 log.debug('password reset user found %s' % user)
260 log.debug('password reset user found %s' % user)
261 link = url('reset_password_confirmation', key=user.api_key,
261 link = url('reset_password_confirmation', key=user.api_key,
262 qualified=True)
262 qualified=True)
263 reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
263 reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
264 body = EmailNotificationModel().get_email_tmpl(reg_type,
264 body = EmailNotificationModel().get_email_tmpl(reg_type,
265 **{'user':user.short_contact,
265 **{'user':user.short_contact,
266 'reset_url':link})
266 'reset_url':link})
267 log.debug('sending email')
267 log.debug('sending email')
268 run_task(send_email, user_email,
268 run_task(send_email, user_email,
269 _("password reset link"), body)
269 _("password reset link"), body)
270 log.info('send new password mail to %s' % user_email)
270 log.info('send new password mail to %s' % user_email)
271 else:
271 else:
272 log.debug("password reset email %s not found" % user_email)
272 log.debug("password reset email %s not found" % user_email)
273 except:
273 except:
274 log.error(traceback.format_exc())
274 log.error(traceback.format_exc())
275 return False
275 return False
276
276
277 return True
277 return True
278
278
279 @task(ignore_result=True)
279 @task(ignore_result=True)
280 @dbsession
280 @dbsession
281 def reset_user_password(user_email):
281 def reset_user_password(user_email):
282 from rhodecode.lib import auth
282 from rhodecode.lib import auth
283
283
284 log = get_logger(reset_user_password)
284 log = get_logger(reset_user_password)
285 DBS = get_session()
285 DBS = get_session()
286
286
287 try:
287 try:
288 try:
288 try:
289 user = User.get_by_email(user_email)
289 user = User.get_by_email(user_email)
290 new_passwd = auth.PasswordGenerator().gen_password(8,
290 new_passwd = auth.PasswordGenerator().gen_password(8,
291 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
291 auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
292 if user:
292 if user:
293 user.password = auth.get_crypt_password(new_passwd)
293 user.password = auth.get_crypt_password(new_passwd)
294 user.api_key = auth.generate_api_key(user.username)
294 user.api_key = auth.generate_api_key(user.username)
295 DBS.add(user)
295 DBS.add(user)
296 DBS.commit()
296 DBS.commit()
297 log.info('change password for %s' % user_email)
297 log.info('change password for %s' % user_email)
298 if new_passwd is None:
298 if new_passwd is None:
299 raise Exception('unable to generate new password')
299 raise Exception('unable to generate new password')
300 except:
300 except:
301 log.error(traceback.format_exc())
301 log.error(traceback.format_exc())
302 DBS.rollback()
302 DBS.rollback()
303
303
304 run_task(send_email, user_email,
304 run_task(send_email, user_email,
305 'Your new password',
305 'Your new password',
306 'Your new RhodeCode password:%s' % (new_passwd))
306 'Your new RhodeCode password:%s' % (new_passwd))
307 log.info('send new password mail to %s' % user_email)
307 log.info('send new password mail to %s' % user_email)
308
308
309 except:
309 except:
310 log.error('Failed to update user password')
310 log.error('Failed to update user password')
311 log.error(traceback.format_exc())
311 log.error(traceback.format_exc())
312
312
313 return True
313 return True
314
314
315
315
316 @task(ignore_result=True)
316 @task(ignore_result=True)
317 @dbsession
317 @dbsession
318 def send_email(recipients, subject, body, html_body=''):
318 def send_email(recipients, subject, body, html_body=''):
319 """
319 """
320 Sends an email with defined parameters from the .ini files.
320 Sends an email with defined parameters from the .ini files.
321
321
322 :param recipients: list of recipients, it this is empty the defined email
322 :param recipients: list of recipients, it this is empty the defined email
323 address from field 'email_to' is used instead
323 address from field 'email_to' is used instead
324 :param subject: subject of the mail
324 :param subject: subject of the mail
325 :param body: body of the mail
325 :param body: body of the mail
326 :param html_body: html version of body
326 :param html_body: html version of body
327 """
327 """
328 log = get_logger(send_email)
328 log = get_logger(send_email)
329 DBS = get_session()
329 DBS = get_session()
330
330
331 email_config = config
331 email_config = config
332 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
332 subject = "%s %s" % (email_config.get('email_prefix', ''), subject)
333 if not recipients:
333 if not recipients:
334 # if recipients are not defined we send to email_config + all admins
334 # if recipients are not defined we send to email_config + all admins
335 admins = [u.email for u in User.query()
335 admins = [u.email for u in User.query()
336 .filter(User.admin == True).all()]
336 .filter(User.admin == True).all()]
337 recipients = [email_config.get('email_to')] + admins
337 recipients = [email_config.get('email_to')] + admins
338
338
339 mail_from = email_config.get('app_email_from', 'RhodeCode')
339 mail_from = email_config.get('app_email_from', 'RhodeCode')
340 user = email_config.get('smtp_username')
340 user = email_config.get('smtp_username')
341 passwd = email_config.get('smtp_password')
341 passwd = email_config.get('smtp_password')
342 mail_server = email_config.get('smtp_server')
342 mail_server = email_config.get('smtp_server')
343 mail_port = email_config.get('smtp_port')
343 mail_port = email_config.get('smtp_port')
344 tls = str2bool(email_config.get('smtp_use_tls'))
344 tls = str2bool(email_config.get('smtp_use_tls'))
345 ssl = str2bool(email_config.get('smtp_use_ssl'))
345 ssl = str2bool(email_config.get('smtp_use_ssl'))
346 debug = str2bool(config.get('debug'))
346 debug = str2bool(config.get('debug'))
347 smtp_auth = email_config.get('smtp_auth')
347 smtp_auth = email_config.get('smtp_auth')
348
348
349 try:
349 try:
350 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
350 m = SmtpMailer(mail_from, user, passwd, mail_server, smtp_auth,
351 mail_port, ssl, tls, debug=debug)
351 mail_port, ssl, tls, debug=debug)
352 m.send(recipients, subject, body, html_body)
352 m.send(recipients, subject, body, html_body)
353 except:
353 except:
354 log.error('Mail sending failed')
354 log.error('Mail sending failed')
355 log.error(traceback.format_exc())
355 log.error(traceback.format_exc())
356 return False
356 return False
357 return True
357 return True
358
358
359
359
360 @task(ignore_result=True)
360 @task(ignore_result=True)
361 @dbsession
361 @dbsession
362 def create_repo_fork(form_data, cur_user):
362 def create_repo_fork(form_data, cur_user):
363 """
363 """
364 Creates a fork of repository using interval VCS methods
364 Creates a fork of repository using interval VCS methods
365
365
366 :param form_data:
366 :param form_data:
367 :param cur_user:
367 :param cur_user:
368 """
368 """
369 from rhodecode.model.repo import RepoModel
369 from rhodecode.model.repo import RepoModel
370
370
371 log = get_logger(create_repo_fork)
371 log = get_logger(create_repo_fork)
372 DBS = get_session()
372 DBS = get_session()
373
373
374 base_path = Repository.base_path()
374 base_path = Repository.base_path()
375
375
376 fork_repo = RepoModel(DBS).create(form_data, cur_user,
376 fork_repo = RepoModel(DBS).create(form_data, cur_user,
377 just_db=True, fork=True)
377 just_db=True, fork=True)
378
378
379 alias = form_data['repo_type']
379 alias = form_data['repo_type']
380 org_repo_name = form_data['org_path']
380 org_repo_name = form_data['org_path']
381 fork_name = form_data['repo_name_full']
381 fork_name = form_data['repo_name_full']
382 update_after_clone = form_data['update_after_clone']
382 update_after_clone = form_data['update_after_clone']
383 source_repo_path = os.path.join(base_path, org_repo_name)
383 source_repo_path = os.path.join(base_path, org_repo_name)
384 destination_fork_path = os.path.join(base_path, fork_name)
384 destination_fork_path = os.path.join(base_path, fork_name)
385
385
386 log.info('creating fork of %s as %s', source_repo_path,
386 log.info('creating fork of %s as %s', source_repo_path,
387 destination_fork_path)
387 destination_fork_path)
388 backend = get_backend(alias)
388 backend = get_backend(alias)
389 backend(safe_str(destination_fork_path), create=True,
389 backend(safe_str(destination_fork_path), create=True,
390 src_url=safe_str(source_repo_path),
390 src_url=safe_str(source_repo_path),
391 update_after_clone=update_after_clone)
391 update_after_clone=update_after_clone)
392 log_create_repository(fork_repo.get_dict(), created_by=cur_user.username)
392 log_create_repository(fork_repo.get_dict(), created_by=cur_user.username)
393
393
394 action_logger(cur_user, 'user_forked_repo:%s' % fork_name,
394 action_logger(cur_user, 'user_forked_repo:%s' % fork_name,
395 org_repo_name, '', DBS)
395 org_repo_name, '', DBS)
396
396
397 action_logger(cur_user, 'user_created_fork:%s' % fork_name,
397 action_logger(cur_user, 'user_created_fork:%s' % fork_name,
398 fork_name, '', DBS)
398 fork_name, '', DBS)
399 # finally commit at latest possible stage
399 # finally commit at latest possible stage
400 DBS.commit()
400 DBS.commit()
401
401
402
402
403 def __get_codes_stats(repo_name):
403 def __get_codes_stats(repo_name):
404 from rhodecode.config.conf import LANGUAGES_EXTENSIONS_MAP
404 from rhodecode.config.conf import LANGUAGES_EXTENSIONS_MAP
405 repo = Repository.get_by_repo_name(repo_name).scm_instance
405 repo = Repository.get_by_repo_name(repo_name).scm_instance
406
406
407 tip = repo.get_changeset()
407 tip = repo.get_changeset()
408 code_stats = {}
408 code_stats = {}
409
409
410 def aggregate(cs):
410 def aggregate(cs):
411 for f in cs[2]:
411 for f in cs[2]:
412 ext = lower(f.extension)
412 ext = lower(f.extension)
413 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
413 if ext in LANGUAGES_EXTENSIONS_MAP.keys() and not f.is_binary:
414 if ext in code_stats:
414 if ext in code_stats:
415 code_stats[ext] += 1
415 code_stats[ext] += 1
416 else:
416 else:
417 code_stats[ext] = 1
417 code_stats[ext] = 1
418
418
419 map(aggregate, tip.walk('/'))
419 map(aggregate, tip.walk('/'))
420
420
421 return code_stats or {}
421 return code_stats or {}
General Comments 0
You need to be logged in to leave comments. Login now