##// END OF EJS Templates
Nicer email notifications about pull-request
marcink -
r2799:493646d3 beta
parent child Browse files
Show More
@@ -0,0 +1,20 b''
1 ## -*- coding: utf-8 -*-
2 <%inherit file="main.html"/>
3
4 User <b>${pr_user_created}</b> opened pull request for repository
5 ${pr_repo_url} and wants you to review changes.
6
7 <div>title: ${pr_title}</div>
8 <div>description:</div>
9 <p>
10 ${body}
11 </p>
12
13 <div>revisions for reviewing</div>
14 <ul>
15 %for r in pr_revisions:
16 <li>${r}</li>
17 %endfor
18 </ul>
19
20 View this pull request here: ${pr_url}
@@ -1,737 +1,739 b''
1 .. _changelog:
1 .. _changelog:
2
2
3 =========
3 =========
4 Changelog
4 Changelog
5 =========
5 =========
6
6
7
7
8 1.4.1 (**2012-09-04**)
8 1.4.1 (**2012-09-04**)
9 ----------------------
9 ----------------------
10
10
11 :status: in-progress
11 :status: in-progress
12 :branch: beta
12 :branch: beta
13
13
14 news
14 news
15 ++++
15 ++++
16
16
17 - always put a comment about code-review status change even if user send
17 - always put a comment about code-review status change even if user send
18 empty data
18 empty data
19 - modified_on column saves repository update and it's going to be used
19 - modified_on column saves repository update and it's going to be used
20 later for light version of main page ref #500
20 later for light version of main page ref #500
21 - pull request notifications send much nicer emails with details about pull
22 request
21
23
22 fixes
24 fixes
23 +++++
25 +++++
24
26
25 - fixed migrations of permissions that can lead to inconsistency.
27 - fixed migrations of permissions that can lead to inconsistency.
26 Some users sent feedback that after upgrading from older versions issues with updating
28 Some users sent feedback that after upgrading from older versions issues
27 default permissions occured. RhodeCode detects that now and resets default user
29 with updating default permissions occurred. RhodeCode detects that now and
28 permission to initial state if there is a need for that. Also forces users to set
30 resets default user permission to initial state if there is a need for that.
29 the default value for new forking permission.
31 Also forces users to set the default value for new forking permission.
30
32
31
33
32 1.4.0 (**2012-09-03**)
34 1.4.0 (**2012-09-03**)
33 ----------------------
35 ----------------------
34
36
35 news
37 news
36 ++++
38 ++++
37
39
38 - new codereview system
40 - new codereview system
39 - email map, allowing users to have multiple email addresses mapped into
41 - email map, allowing users to have multiple email addresses mapped into
40 their accounts
42 their accounts
41 - improved git-hook system. Now all actions for git are logged into journal
43 - improved git-hook system. Now all actions for git are logged into journal
42 including pushed revisions, user and IP address
44 including pushed revisions, user and IP address
43 - changed setup-app into setup-rhodecode and added default options to it.
45 - changed setup-app into setup-rhodecode and added default options to it.
44 - new git repos are created as bare now by default
46 - new git repos are created as bare now by default
45 - #464 added links to groups in permission box
47 - #464 added links to groups in permission box
46 - #465 mentions autocomplete inside comments boxes
48 - #465 mentions autocomplete inside comments boxes
47 - #469 added --update-only option to whoosh to re-index only given list
49 - #469 added --update-only option to whoosh to re-index only given list
48 of repos in index
50 of repos in index
49 - rhodecode-api CLI client
51 - rhodecode-api CLI client
50 - new git http protocol replaced buggy dulwich implementation.
52 - new git http protocol replaced buggy dulwich implementation.
51 Now based on pygrack & gitweb
53 Now based on pygrack & gitweb
52 - Improved RSS/ATOM feeds. Discoverable by browsers using proper headers, and
54 - Improved RSS/ATOM feeds. Discoverable by browsers using proper headers, and
53 reformated based on user suggestions. Additional rss/atom feeds for user
55 reformated based on user suggestions. Additional rss/atom feeds for user
54 journal
56 journal
55 - various i18n improvements
57 - various i18n improvements
56 - #478 permissions overview for admin in user edit view
58 - #478 permissions overview for admin in user edit view
57 - File view now displays small gravatars off all authors of given file
59 - File view now displays small gravatars off all authors of given file
58 - Implemented landing revisions. Each repository will get landing_rev attribute
60 - Implemented landing revisions. Each repository will get landing_rev attribute
59 that defines 'default' revision/branch for generating readme files
61 that defines 'default' revision/branch for generating readme files
60 - Implemented #509, RhodeCode enforces SSL for push/pulling if requested at
62 - Implemented #509, RhodeCode enforces SSL for push/pulling if requested at
61 earliest possible call.
63 earliest possible call.
62 - Import remote svn repositories to mercurial using hgsubversion.
64 - Import remote svn repositories to mercurial using hgsubversion.
63 - Fixed #508 RhodeCode now has a option to explicitly set forking permissions
65 - Fixed #508 RhodeCode now has a option to explicitly set forking permissions
64 - RhodeCode can use alternative server for generating avatar icons
66 - RhodeCode can use alternative server for generating avatar icons
65 - implemented repositories locking. Pull locks, push unlocks. Also can be done
67 - implemented repositories locking. Pull locks, push unlocks. Also can be done
66 via API calls
68 via API calls
67 - #538 form for permissions can handle multiple users at once
69 - #538 form for permissions can handle multiple users at once
68
70
69 fixes
71 fixes
70 +++++
72 +++++
71
73
72 - improved translations
74 - improved translations
73 - fixes issue #455 Creating an archive generates an exception on Windows
75 - fixes issue #455 Creating an archive generates an exception on Windows
74 - fixes #448 Download ZIP archive keeps file in /tmp open and results
76 - fixes #448 Download ZIP archive keeps file in /tmp open and results
75 in out of disk space
77 in out of disk space
76 - fixes issue #454 Search results under Windows include proceeding
78 - fixes issue #454 Search results under Windows include proceeding
77 backslash
79 backslash
78 - fixed issue #450. Rhodecode no longer will crash when bad revision is
80 - fixed issue #450. Rhodecode no longer will crash when bad revision is
79 present in journal data.
81 present in journal data.
80 - fix for issue #417, git execution was broken on windows for certain
82 - fix for issue #417, git execution was broken on windows for certain
81 commands.
83 commands.
82 - fixed #413. Don't disable .git directory for bare repos on deleting
84 - fixed #413. Don't disable .git directory for bare repos on deleting
83 - fixed issue #459. Changed the way of obtaining logger in reindex task.
85 - fixed issue #459. Changed the way of obtaining logger in reindex task.
84 - fixed #453 added ID field in whoosh SCHEMA that solves the issue of
86 - fixed #453 added ID field in whoosh SCHEMA that solves the issue of
85 reindexing modified files
87 reindexing modified files
86 - fixed #481 rhodecode emails are sent without Date header
88 - fixed #481 rhodecode emails are sent without Date header
87 - fixed #458 wrong count when no repos are present
89 - fixed #458 wrong count when no repos are present
88 - fixed issue #492 missing `\ No newline at end of file` test at the end of
90 - fixed issue #492 missing `\ No newline at end of file` test at the end of
89 new chunk in html diff
91 new chunk in html diff
90 - full text search now works also for commit messages
92 - full text search now works also for commit messages
91
93
92 1.3.6 (**2012-05-17**)
94 1.3.6 (**2012-05-17**)
93 ----------------------
95 ----------------------
94
96
95 news
97 news
96 ++++
98 ++++
97
99
98 - chinese traditional translation
100 - chinese traditional translation
99 - changed setup-app into setup-rhodecode and added arguments for auto-setup
101 - changed setup-app into setup-rhodecode and added arguments for auto-setup
100 mode that doesn't need user interaction
102 mode that doesn't need user interaction
101
103
102 fixes
104 fixes
103 +++++
105 +++++
104
106
105 - fixed no scm found warning
107 - fixed no scm found warning
106 - fixed __future__ import error on rcextensions
108 - fixed __future__ import error on rcextensions
107 - made simplejson required lib for speedup on JSON encoding
109 - made simplejson required lib for speedup on JSON encoding
108 - fixes #449 bad regex could get more than revisions from parsing history
110 - fixes #449 bad regex could get more than revisions from parsing history
109 - don't clear DB session when CELERY_EAGER is turned ON
111 - don't clear DB session when CELERY_EAGER is turned ON
110
112
111 1.3.5 (**2012-05-10**)
113 1.3.5 (**2012-05-10**)
112 ----------------------
114 ----------------------
113
115
114 news
116 news
115 ++++
117 ++++
116
118
117 - use ext_json for json module
119 - use ext_json for json module
118 - unified annotation view with file source view
120 - unified annotation view with file source view
119 - notification improvements, better inbox + css
121 - notification improvements, better inbox + css
120 - #419 don't strip passwords for login forms, make rhodecode
122 - #419 don't strip passwords for login forms, make rhodecode
121 more compatible with LDAP servers
123 more compatible with LDAP servers
122 - Added HTTP_X_FORWARDED_FOR as another method of extracting
124 - Added HTTP_X_FORWARDED_FOR as another method of extracting
123 IP for pull/push logs. - moved all to base controller
125 IP for pull/push logs. - moved all to base controller
124 - #415: Adding comment to changeset causes reload.
126 - #415: Adding comment to changeset causes reload.
125 Comments are now added via ajax and doesn't reload the page
127 Comments are now added via ajax and doesn't reload the page
126 - #374 LDAP config is discarded when LDAP can't be activated
128 - #374 LDAP config is discarded when LDAP can't be activated
127 - limited push/pull operations are now logged for git in the journal
129 - limited push/pull operations are now logged for git in the journal
128 - bumped mercurial to 2.2.X series
130 - bumped mercurial to 2.2.X series
129 - added support for displaying submodules in file-browser
131 - added support for displaying submodules in file-browser
130 - #421 added bookmarks in changelog view
132 - #421 added bookmarks in changelog view
131
133
132 fixes
134 fixes
133 +++++
135 +++++
134
136
135 - fixed dev-version marker for stable when served from source codes
137 - fixed dev-version marker for stable when served from source codes
136 - fixed missing permission checks on show forks page
138 - fixed missing permission checks on show forks page
137 - #418 cast to unicode fixes in notification objects
139 - #418 cast to unicode fixes in notification objects
138 - #426 fixed mention extracting regex
140 - #426 fixed mention extracting regex
139 - fixed remote-pulling for git remotes remopositories
141 - fixed remote-pulling for git remotes remopositories
140 - fixed #434: Error when accessing files or changesets of a git repository
142 - fixed #434: Error when accessing files or changesets of a git repository
141 with submodules
143 with submodules
142 - fixed issue with empty APIKEYS for users after registration ref. #438
144 - fixed issue with empty APIKEYS for users after registration ref. #438
143 - fixed issue with getting README files from git repositories
145 - fixed issue with getting README files from git repositories
144
146
145 1.3.4 (**2012-03-28**)
147 1.3.4 (**2012-03-28**)
146 ----------------------
148 ----------------------
147
149
148 news
150 news
149 ++++
151 ++++
150
152
151 - Whoosh logging is now controlled by the .ini files logging setup
153 - Whoosh logging is now controlled by the .ini files logging setup
152 - added clone-url into edit form on /settings page
154 - added clone-url into edit form on /settings page
153 - added help text into repo add/edit forms
155 - added help text into repo add/edit forms
154 - created rcextensions module with additional mappings (ref #322) and
156 - created rcextensions module with additional mappings (ref #322) and
155 post push/pull/create repo hooks callbacks
157 post push/pull/create repo hooks callbacks
156 - implemented #377 Users view for his own permissions on account page
158 - implemented #377 Users view for his own permissions on account page
157 - #399 added inheritance of permissions for users group on repos groups
159 - #399 added inheritance of permissions for users group on repos groups
158 - #401 repository group is automatically pre-selected when adding repos
160 - #401 repository group is automatically pre-selected when adding repos
159 inside a repository group
161 inside a repository group
160 - added alternative HTTP 403 response when client failed to authenticate. Helps
162 - added alternative HTTP 403 response when client failed to authenticate. Helps
161 solving issues with Mercurial and LDAP
163 solving issues with Mercurial and LDAP
162 - #402 removed group prefix from repository name when listing repositories
164 - #402 removed group prefix from repository name when listing repositories
163 inside a group
165 inside a group
164 - added gravatars into permission view and permissions autocomplete
166 - added gravatars into permission view and permissions autocomplete
165 - #347 when running multiple RhodeCode instances, properly invalidates cache
167 - #347 when running multiple RhodeCode instances, properly invalidates cache
166 for all registered servers
168 for all registered servers
167
169
168 fixes
170 fixes
169 +++++
171 +++++
170
172
171 - fixed #390 cache invalidation problems on repos inside group
173 - fixed #390 cache invalidation problems on repos inside group
172 - fixed #385 clone by ID url was loosing proxy prefix in URL
174 - fixed #385 clone by ID url was loosing proxy prefix in URL
173 - fixed some unicode problems with waitress
175 - fixed some unicode problems with waitress
174 - fixed issue with escaping < and > in changeset commits
176 - fixed issue with escaping < and > in changeset commits
175 - fixed error occurring during recursive group creation in API
177 - fixed error occurring during recursive group creation in API
176 create_repo function
178 create_repo function
177 - fixed #393 py2.5 fixes for routes url generator
179 - fixed #393 py2.5 fixes for routes url generator
178 - fixed #397 Private repository groups shows up before login
180 - fixed #397 Private repository groups shows up before login
179 - fixed #396 fixed problems with revoking users in nested groups
181 - fixed #396 fixed problems with revoking users in nested groups
180 - fixed mysql unicode issues + specified InnoDB as default engine with
182 - fixed mysql unicode issues + specified InnoDB as default engine with
181 utf8 charset
183 utf8 charset
182 - #406 trim long branch/tag names in changelog to not break UI
184 - #406 trim long branch/tag names in changelog to not break UI
183
185
184 1.3.3 (**2012-03-02**)
186 1.3.3 (**2012-03-02**)
185 ----------------------
187 ----------------------
186
188
187 news
189 news
188 ++++
190 ++++
189
191
190
192
191 fixes
193 fixes
192 +++++
194 +++++
193
195
194 - fixed some python2.5 compatibility issues
196 - fixed some python2.5 compatibility issues
195 - fixed issues with removed repos was accidentally added as groups, after
197 - fixed issues with removed repos was accidentally added as groups, after
196 full rescan of paths
198 full rescan of paths
197 - fixes #376 Cannot edit user (using container auth)
199 - fixes #376 Cannot edit user (using container auth)
198 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
200 - fixes #378 Invalid image urls on changeset screen with proxy-prefix
199 configuration
201 configuration
200 - fixed initial sorting of repos inside repo group
202 - fixed initial sorting of repos inside repo group
201 - fixes issue when user tried to resubmit same permission into user/user_groups
203 - fixes issue when user tried to resubmit same permission into user/user_groups
202 - bumped beaker version that fixes #375 leap error bug
204 - bumped beaker version that fixes #375 leap error bug
203 - fixed raw_changeset for git. It was generated with hg patch headers
205 - fixed raw_changeset for git. It was generated with hg patch headers
204 - fixed vcs issue with last_changeset for filenodes
206 - fixed vcs issue with last_changeset for filenodes
205 - fixed missing commit after hook delete
207 - fixed missing commit after hook delete
206 - fixed #372 issues with git operation detection that caused a security issue
208 - fixed #372 issues with git operation detection that caused a security issue
207 for git repos
209 for git repos
208
210
209 1.3.2 (**2012-02-28**)
211 1.3.2 (**2012-02-28**)
210 ----------------------
212 ----------------------
211
213
212 news
214 news
213 ++++
215 ++++
214
216
215
217
216 fixes
218 fixes
217 +++++
219 +++++
218
220
219 - fixed git protocol issues with repos-groups
221 - fixed git protocol issues with repos-groups
220 - fixed git remote repos validator that prevented from cloning remote git repos
222 - fixed git remote repos validator that prevented from cloning remote git repos
221 - fixes #370 ending slashes fixes for repo and groups
223 - fixes #370 ending slashes fixes for repo and groups
222 - fixes #368 improved git-protocol detection to handle other clients
224 - fixes #368 improved git-protocol detection to handle other clients
223 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
225 - fixes #366 When Setting Repository Group To Blank Repo Group Wont Be
224 Moved To Root
226 Moved To Root
225 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
227 - fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
226 - fixed #373 missing cascade drop on user_group_to_perm table
228 - fixed #373 missing cascade drop on user_group_to_perm table
227
229
228 1.3.1 (**2012-02-27**)
230 1.3.1 (**2012-02-27**)
229 ----------------------
231 ----------------------
230
232
231 news
233 news
232 ++++
234 ++++
233
235
234
236
235 fixes
237 fixes
236 +++++
238 +++++
237
239
238 - redirection loop occurs when remember-me wasn't checked during login
240 - redirection loop occurs when remember-me wasn't checked during login
239 - fixes issues with git blob history generation
241 - fixes issues with git blob history generation
240 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
242 - don't fetch branch for git in file history dropdown. Causes unneeded slowness
241
243
242 1.3.0 (**2012-02-26**)
244 1.3.0 (**2012-02-26**)
243 ----------------------
245 ----------------------
244
246
245 news
247 news
246 ++++
248 ++++
247
249
248 - code review, inspired by github code-comments
250 - code review, inspired by github code-comments
249 - #215 rst and markdown README files support
251 - #215 rst and markdown README files support
250 - #252 Container-based and proxy pass-through authentication support
252 - #252 Container-based and proxy pass-through authentication support
251 - #44 branch browser. Filtering of changelog by branches
253 - #44 branch browser. Filtering of changelog by branches
252 - mercurial bookmarks support
254 - mercurial bookmarks support
253 - new hover top menu, optimized to add maximum size for important views
255 - new hover top menu, optimized to add maximum size for important views
254 - configurable clone url template with possibility to specify protocol like
256 - configurable clone url template with possibility to specify protocol like
255 ssh:// or http:// and also manually alter other parts of clone_url.
257 ssh:// or http:// and also manually alter other parts of clone_url.
256 - enabled largefiles extension by default
258 - enabled largefiles extension by default
257 - optimized summary file pages and saved a lot of unused space in them
259 - optimized summary file pages and saved a lot of unused space in them
258 - #239 option to manually mark repository as fork
260 - #239 option to manually mark repository as fork
259 - #320 mapping of commit authors to RhodeCode users
261 - #320 mapping of commit authors to RhodeCode users
260 - #304 hashes are displayed using monospace font
262 - #304 hashes are displayed using monospace font
261 - diff configuration, toggle white lines and context lines
263 - diff configuration, toggle white lines and context lines
262 - #307 configurable diffs, whitespace toggle, increasing context lines
264 - #307 configurable diffs, whitespace toggle, increasing context lines
263 - sorting on branches, tags and bookmarks using YUI datatable
265 - sorting on branches, tags and bookmarks using YUI datatable
264 - improved file filter on files page
266 - improved file filter on files page
265 - implements #330 api method for listing nodes ar particular revision
267 - implements #330 api method for listing nodes ar particular revision
266 - #73 added linking issues in commit messages to chosen issue tracker url
268 - #73 added linking issues in commit messages to chosen issue tracker url
267 based on user defined regular expression
269 based on user defined regular expression
268 - added linking of changesets in commit messages
270 - added linking of changesets in commit messages
269 - new compact changelog with expandable commit messages
271 - new compact changelog with expandable commit messages
270 - firstname and lastname are optional in user creation
272 - firstname and lastname are optional in user creation
271 - #348 added post-create repository hook
273 - #348 added post-create repository hook
272 - #212 global encoding settings is now configurable from .ini files
274 - #212 global encoding settings is now configurable from .ini files
273 - #227 added repository groups permissions
275 - #227 added repository groups permissions
274 - markdown gets codehilite extensions
276 - markdown gets codehilite extensions
275 - new API methods, delete_repositories, grante/revoke permissions for groups
277 - new API methods, delete_repositories, grante/revoke permissions for groups
276 and repos
278 and repos
277
279
278
280
279 fixes
281 fixes
280 +++++
282 +++++
281
283
282 - rewrote dbsession management for atomic operations, and better error handling
284 - rewrote dbsession management for atomic operations, and better error handling
283 - fixed sorting of repo tables
285 - fixed sorting of repo tables
284 - #326 escape of special html entities in diffs
286 - #326 escape of special html entities in diffs
285 - normalized user_name => username in api attributes
287 - normalized user_name => username in api attributes
286 - fixes #298 ldap created users with mixed case emails created conflicts
288 - fixes #298 ldap created users with mixed case emails created conflicts
287 on saving a form
289 on saving a form
288 - fixes issue when owner of a repo couldn't revoke permissions for users
290 - fixes issue when owner of a repo couldn't revoke permissions for users
289 and groups
291 and groups
290 - fixes #271 rare JSON serialization problem with statistics
292 - fixes #271 rare JSON serialization problem with statistics
291 - fixes #337 missing validation check for conflicting names of a group with a
293 - fixes #337 missing validation check for conflicting names of a group with a
292 repositories group
294 repositories group
293 - #340 fixed session problem for mysql and celery tasks
295 - #340 fixed session problem for mysql and celery tasks
294 - fixed #331 RhodeCode mangles repository names if the a repository group
296 - fixed #331 RhodeCode mangles repository names if the a repository group
295 contains the "full path" to the repositories
297 contains the "full path" to the repositories
296 - #355 RhodeCode doesn't store encrypted LDAP passwords
298 - #355 RhodeCode doesn't store encrypted LDAP passwords
297
299
298 1.2.5 (**2012-01-28**)
300 1.2.5 (**2012-01-28**)
299 ----------------------
301 ----------------------
300
302
301 news
303 news
302 ++++
304 ++++
303
305
304 fixes
306 fixes
305 +++++
307 +++++
306
308
307 - #340 Celery complains about MySQL server gone away, added session cleanup
309 - #340 Celery complains about MySQL server gone away, added session cleanup
308 for celery tasks
310 for celery tasks
309 - #341 "scanning for repositories in None" log message during Rescan was missing
311 - #341 "scanning for repositories in None" log message during Rescan was missing
310 a parameter
312 a parameter
311 - fixed creating archives with subrepos. Some hooks were triggered during that
313 - fixed creating archives with subrepos. Some hooks were triggered during that
312 operation leading to crash.
314 operation leading to crash.
313 - fixed missing email in account page.
315 - fixed missing email in account page.
314 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
316 - Reverted Mercurial to 2.0.1 for windows due to bug in Mercurial that makes
315 forking on windows impossible
317 forking on windows impossible
316
318
317 1.2.4 (**2012-01-19**)
319 1.2.4 (**2012-01-19**)
318 ----------------------
320 ----------------------
319
321
320 news
322 news
321 ++++
323 ++++
322
324
323 - RhodeCode is bundled with mercurial series 2.0.X by default, with
325 - RhodeCode is bundled with mercurial series 2.0.X by default, with
324 full support to largefiles extension. Enabled by default in new installations
326 full support to largefiles extension. Enabled by default in new installations
325 - #329 Ability to Add/Remove Groups to/from a Repository via AP
327 - #329 Ability to Add/Remove Groups to/from a Repository via AP
326 - added requires.txt file with requirements
328 - added requires.txt file with requirements
327
329
328 fixes
330 fixes
329 +++++
331 +++++
330
332
331 - fixes db session issues with celery when emailing admins
333 - fixes db session issues with celery when emailing admins
332 - #331 RhodeCode mangles repository names if the a repository group
334 - #331 RhodeCode mangles repository names if the a repository group
333 contains the "full path" to the repositories
335 contains the "full path" to the repositories
334 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
336 - #298 Conflicting e-mail addresses for LDAP and RhodeCode users
335 - DB session cleanup after hg protocol operations, fixes issues with
337 - DB session cleanup after hg protocol operations, fixes issues with
336 `mysql has gone away` errors
338 `mysql has gone away` errors
337 - #333 doc fixes for get_repo api function
339 - #333 doc fixes for get_repo api function
338 - #271 rare JSON serialization problem with statistics enabled
340 - #271 rare JSON serialization problem with statistics enabled
339 - #337 Fixes issues with validation of repository name conflicting with
341 - #337 Fixes issues with validation of repository name conflicting with
340 a group name. A proper message is now displayed.
342 a group name. A proper message is now displayed.
341 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
343 - #292 made ldap_dn in user edit readonly, to get rid of confusion that field
342 doesn't work
344 doesn't work
343 - #316 fixes issues with web description in hgrc files
345 - #316 fixes issues with web description in hgrc files
344
346
345 1.2.3 (**2011-11-02**)
347 1.2.3 (**2011-11-02**)
346 ----------------------
348 ----------------------
347
349
348 news
350 news
349 ++++
351 ++++
350
352
351 - added option to manage repos group for non admin users
353 - added option to manage repos group for non admin users
352 - added following API methods for get_users, create_user, get_users_groups,
354 - added following API methods for get_users, create_user, get_users_groups,
353 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
355 get_users_group, create_users_group, add_user_to_users_groups, get_repos,
354 get_repo, create_repo, add_user_to_repo
356 get_repo, create_repo, add_user_to_repo
355 - implements #237 added password confirmation for my account
357 - implements #237 added password confirmation for my account
356 and admin edit user.
358 and admin edit user.
357 - implements #291 email notification for global events are now sent to all
359 - implements #291 email notification for global events are now sent to all
358 administrator users, and global config email.
360 administrator users, and global config email.
359
361
360 fixes
362 fixes
361 +++++
363 +++++
362
364
363 - added option for passing auth method for smtp mailer
365 - added option for passing auth method for smtp mailer
364 - #276 issue with adding a single user with id>10 to usergroups
366 - #276 issue with adding a single user with id>10 to usergroups
365 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
367 - #277 fixes windows LDAP settings in which missing values breaks the ldap auth
366 - #288 fixes managing of repos in a group for non admin user
368 - #288 fixes managing of repos in a group for non admin user
367
369
368 1.2.2 (**2011-10-17**)
370 1.2.2 (**2011-10-17**)
369 ----------------------
371 ----------------------
370
372
371 news
373 news
372 ++++
374 ++++
373
375
374 - #226 repo groups are available by path instead of numerical id
376 - #226 repo groups are available by path instead of numerical id
375
377
376 fixes
378 fixes
377 +++++
379 +++++
378
380
379 - #259 Groups with the same name but with different parent group
381 - #259 Groups with the same name but with different parent group
380 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
382 - #260 Put repo in group, then move group to another group -> repo becomes unavailable
381 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
383 - #258 RhodeCode 1.2 assumes egg folder is writable (lockfiles problems)
382 - #265 ldap save fails sometimes on converting attributes to booleans,
384 - #265 ldap save fails sometimes on converting attributes to booleans,
383 added getter and setter into model that will prevent from this on db model level
385 added getter and setter into model that will prevent from this on db model level
384 - fixed problems with timestamps issues #251 and #213
386 - fixed problems with timestamps issues #251 and #213
385 - fixes #266 RhodeCode allows to create repo with the same name and in
387 - fixes #266 RhodeCode allows to create repo with the same name and in
386 the same parent as group
388 the same parent as group
387 - fixes #245 Rescan of the repositories on Windows
389 - fixes #245 Rescan of the repositories on Windows
388 - fixes #248 cannot edit repos inside a group on windows
390 - fixes #248 cannot edit repos inside a group on windows
389 - fixes #219 forking problems on windows
391 - fixes #219 forking problems on windows
390
392
391 1.2.1 (**2011-10-08**)
393 1.2.1 (**2011-10-08**)
392 ----------------------
394 ----------------------
393
395
394 news
396 news
395 ++++
397 ++++
396
398
397
399
398 fixes
400 fixes
399 +++++
401 +++++
400
402
401 - fixed problems with basic auth and push problems
403 - fixed problems with basic auth and push problems
402 - gui fixes
404 - gui fixes
403 - fixed logger
405 - fixed logger
404
406
405 1.2.0 (**2011-10-07**)
407 1.2.0 (**2011-10-07**)
406 ----------------------
408 ----------------------
407
409
408 news
410 news
409 ++++
411 ++++
410
412
411 - implemented #47 repository groups
413 - implemented #47 repository groups
412 - implemented #89 Can setup google analytics code from settings menu
414 - implemented #89 Can setup google analytics code from settings menu
413 - implemented #91 added nicer looking archive urls with more download options
415 - implemented #91 added nicer looking archive urls with more download options
414 like tags, branches
416 like tags, branches
415 - implemented #44 into file browsing, and added follow branch option
417 - implemented #44 into file browsing, and added follow branch option
416 - implemented #84 downloads can be enabled/disabled for each repository
418 - implemented #84 downloads can be enabled/disabled for each repository
417 - anonymous repository can be cloned without having to pass default:default
419 - anonymous repository can be cloned without having to pass default:default
418 into clone url
420 into clone url
419 - fixed #90 whoosh indexer can index chooses repositories passed in command
421 - fixed #90 whoosh indexer can index chooses repositories passed in command
420 line
422 line
421 - extended journal with day aggregates and paging
423 - extended journal with day aggregates and paging
422 - implemented #107 source code lines highlight ranges
424 - implemented #107 source code lines highlight ranges
423 - implemented #93 customizable changelog on combined revision ranges -
425 - implemented #93 customizable changelog on combined revision ranges -
424 equivalent of githubs compare view
426 equivalent of githubs compare view
425 - implemented #108 extended and more powerful LDAP configuration
427 - implemented #108 extended and more powerful LDAP configuration
426 - implemented #56 users groups
428 - implemented #56 users groups
427 - major code rewrites optimized codes for speed and memory usage
429 - major code rewrites optimized codes for speed and memory usage
428 - raw and diff downloads are now in git format
430 - raw and diff downloads are now in git format
429 - setup command checks for write access to given path
431 - setup command checks for write access to given path
430 - fixed many issues with international characters and unicode. It uses utf8
432 - fixed many issues with international characters and unicode. It uses utf8
431 decode with replace to provide less errors even with non utf8 encoded strings
433 decode with replace to provide less errors even with non utf8 encoded strings
432 - #125 added API KEY access to feeds
434 - #125 added API KEY access to feeds
433 - #109 Repository can be created from external Mercurial link (aka. remote
435 - #109 Repository can be created from external Mercurial link (aka. remote
434 repository, and manually updated (via pull) from admin panel
436 repository, and manually updated (via pull) from admin panel
435 - beta git support - push/pull server + basic view for git repos
437 - beta git support - push/pull server + basic view for git repos
436 - added followers page and forks page
438 - added followers page and forks page
437 - server side file creation (with binary file upload interface)
439 - server side file creation (with binary file upload interface)
438 and edition with commits powered by codemirror
440 and edition with commits powered by codemirror
439 - #111 file browser file finder, quick lookup files on whole file tree
441 - #111 file browser file finder, quick lookup files on whole file tree
440 - added quick login sliding menu into main page
442 - added quick login sliding menu into main page
441 - changelog uses lazy loading of affected files details, in some scenarios
443 - changelog uses lazy loading of affected files details, in some scenarios
442 this can improve speed of changelog page dramatically especially for
444 this can improve speed of changelog page dramatically especially for
443 larger repositories.
445 larger repositories.
444 - implements #214 added support for downloading subrepos in download menu.
446 - implements #214 added support for downloading subrepos in download menu.
445 - Added basic API for direct operations on rhodecode via JSON
447 - Added basic API for direct operations on rhodecode via JSON
446 - Implemented advanced hook management
448 - Implemented advanced hook management
447
449
448 fixes
450 fixes
449 +++++
451 +++++
450
452
451 - fixed file browser bug, when switching into given form revision the url was
453 - fixed file browser bug, when switching into given form revision the url was
452 not changing
454 not changing
453 - fixed propagation to error controller on simplehg and simplegit middlewares
455 - fixed propagation to error controller on simplehg and simplegit middlewares
454 - fixed error when trying to make a download on empty repository
456 - fixed error when trying to make a download on empty repository
455 - fixed problem with '[' chars in commit messages in journal
457 - fixed problem with '[' chars in commit messages in journal
456 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
458 - fixed #99 Unicode errors, on file node paths with non utf-8 characters
457 - journal fork fixes
459 - journal fork fixes
458 - removed issue with space inside renamed repository after deletion
460 - removed issue with space inside renamed repository after deletion
459 - fixed strange issue on formencode imports
461 - fixed strange issue on formencode imports
460 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
462 - fixed #126 Deleting repository on Windows, rename used incompatible chars.
461 - #150 fixes for errors on repositories mapped in db but corrupted in
463 - #150 fixes for errors on repositories mapped in db but corrupted in
462 filesystem
464 filesystem
463 - fixed problem with ascendant characters in realm #181
465 - fixed problem with ascendant characters in realm #181
464 - fixed problem with sqlite file based database connection pool
466 - fixed problem with sqlite file based database connection pool
465 - whoosh indexer and code stats share the same dynamic extensions map
467 - whoosh indexer and code stats share the same dynamic extensions map
466 - fixes #188 - relationship delete of repo_to_perm entry on user removal
468 - fixes #188 - relationship delete of repo_to_perm entry on user removal
467 - fixes issue #189 Trending source files shows "show more" when no more exist
469 - fixes issue #189 Trending source files shows "show more" when no more exist
468 - fixes issue #197 Relative paths for pidlocks
470 - fixes issue #197 Relative paths for pidlocks
469 - fixes issue #198 password will require only 3 chars now for login form
471 - fixes issue #198 password will require only 3 chars now for login form
470 - fixes issue #199 wrong redirection for non admin users after creating a repository
472 - fixes issue #199 wrong redirection for non admin users after creating a repository
471 - fixes issues #202, bad db constraint made impossible to attach same group
473 - fixes issues #202, bad db constraint made impossible to attach same group
472 more than one time. Affects only mysql/postgres
474 more than one time. Affects only mysql/postgres
473 - fixes #218 os.kill patch for windows was missing sig param
475 - fixes #218 os.kill patch for windows was missing sig param
474 - improved rendering of dag (they are not trimmed anymore when number of
476 - improved rendering of dag (they are not trimmed anymore when number of
475 heads exceeds 5)
477 heads exceeds 5)
476
478
477 1.1.8 (**2011-04-12**)
479 1.1.8 (**2011-04-12**)
478 ----------------------
480 ----------------------
479
481
480 news
482 news
481 ++++
483 ++++
482
484
483 - improved windows support
485 - improved windows support
484
486
485 fixes
487 fixes
486 +++++
488 +++++
487
489
488 - fixed #140 freeze of python dateutil library, since new version is python2.x
490 - fixed #140 freeze of python dateutil library, since new version is python2.x
489 incompatible
491 incompatible
490 - setup-app will check for write permission in given path
492 - setup-app will check for write permission in given path
491 - cleaned up license info issue #149
493 - cleaned up license info issue #149
492 - fixes for issues #137,#116 and problems with unicode and accented characters.
494 - fixes for issues #137,#116 and problems with unicode and accented characters.
493 - fixes crashes on gravatar, when passed in email as unicode
495 - fixes crashes on gravatar, when passed in email as unicode
494 - fixed tooltip flickering problems
496 - fixed tooltip flickering problems
495 - fixed came_from redirection on windows
497 - fixed came_from redirection on windows
496 - fixed logging modules, and sql formatters
498 - fixed logging modules, and sql formatters
497 - windows fixes for os.kill issue #133
499 - windows fixes for os.kill issue #133
498 - fixes path splitting for windows issues #148
500 - fixes path splitting for windows issues #148
499 - fixed issue #143 wrong import on migration to 1.1.X
501 - fixed issue #143 wrong import on migration to 1.1.X
500 - fixed problems with displaying binary files, thanks to Thomas Waldmann
502 - fixed problems with displaying binary files, thanks to Thomas Waldmann
501 - removed name from archive files since it's breaking ui for long repo names
503 - removed name from archive files since it's breaking ui for long repo names
502 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
504 - fixed issue with archive headers sent to browser, thanks to Thomas Waldmann
503 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
505 - fixed compatibility for 1024px displays, and larger dpi settings, thanks to
504 Thomas Waldmann
506 Thomas Waldmann
505 - fixed issue #166 summary pager was skipping 10 revisions on second page
507 - fixed issue #166 summary pager was skipping 10 revisions on second page
506
508
507
509
508 1.1.7 (**2011-03-23**)
510 1.1.7 (**2011-03-23**)
509 ----------------------
511 ----------------------
510
512
511 news
513 news
512 ++++
514 ++++
513
515
514 fixes
516 fixes
515 +++++
517 +++++
516
518
517 - fixed (again) #136 installation support for FreeBSD
519 - fixed (again) #136 installation support for FreeBSD
518
520
519
521
520 1.1.6 (**2011-03-21**)
522 1.1.6 (**2011-03-21**)
521 ----------------------
523 ----------------------
522
524
523 news
525 news
524 ++++
526 ++++
525
527
526 fixes
528 fixes
527 +++++
529 +++++
528
530
529 - fixed #136 installation support for FreeBSD
531 - fixed #136 installation support for FreeBSD
530 - RhodeCode will check for python version during installation
532 - RhodeCode will check for python version during installation
531
533
532 1.1.5 (**2011-03-17**)
534 1.1.5 (**2011-03-17**)
533 ----------------------
535 ----------------------
534
536
535 news
537 news
536 ++++
538 ++++
537
539
538 - basic windows support, by exchanging pybcrypt into sha256 for windows only
540 - basic windows support, by exchanging pybcrypt into sha256 for windows only
539 highly inspired by idea of mantis406
541 highly inspired by idea of mantis406
540
542
541 fixes
543 fixes
542 +++++
544 +++++
543
545
544 - fixed sorting by author in main page
546 - fixed sorting by author in main page
545 - fixed crashes with diffs on binary files
547 - fixed crashes with diffs on binary files
546 - fixed #131 problem with boolean values for LDAP
548 - fixed #131 problem with boolean values for LDAP
547 - fixed #122 mysql problems thanks to striker69
549 - fixed #122 mysql problems thanks to striker69
548 - fixed problem with errors on calling raw/raw_files/annotate functions
550 - fixed problem with errors on calling raw/raw_files/annotate functions
549 with unknown revisions
551 with unknown revisions
550 - fixed returned rawfiles attachment names with international character
552 - fixed returned rawfiles attachment names with international character
551 - cleaned out docs, big thanks to Jason Harris
553 - cleaned out docs, big thanks to Jason Harris
552
554
553 1.1.4 (**2011-02-19**)
555 1.1.4 (**2011-02-19**)
554 ----------------------
556 ----------------------
555
557
556 news
558 news
557 ++++
559 ++++
558
560
559 fixes
561 fixes
560 +++++
562 +++++
561
563
562 - fixed formencode import problem on settings page, that caused server crash
564 - fixed formencode import problem on settings page, that caused server crash
563 when that page was accessed as first after server start
565 when that page was accessed as first after server start
564 - journal fixes
566 - journal fixes
565 - fixed option to access repository just by entering http://server/<repo_name>
567 - fixed option to access repository just by entering http://server/<repo_name>
566
568
567 1.1.3 (**2011-02-16**)
569 1.1.3 (**2011-02-16**)
568 ----------------------
570 ----------------------
569
571
570 news
572 news
571 ++++
573 ++++
572
574
573 - implemented #102 allowing the '.' character in username
575 - implemented #102 allowing the '.' character in username
574 - added option to access repository just by entering http://server/<repo_name>
576 - added option to access repository just by entering http://server/<repo_name>
575 - celery task ignores result for better performance
577 - celery task ignores result for better performance
576
578
577 fixes
579 fixes
578 +++++
580 +++++
579
581
580 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
582 - fixed ehlo command and non auth mail servers on smtp_lib. Thanks to
581 apollo13 and Johan Walles
583 apollo13 and Johan Walles
582 - small fixes in journal
584 - small fixes in journal
583 - fixed problems with getting setting for celery from .ini files
585 - fixed problems with getting setting for celery from .ini files
584 - registration, password reset and login boxes share the same title as main
586 - registration, password reset and login boxes share the same title as main
585 application now
587 application now
586 - fixed #113: to high permissions to fork repository
588 - fixed #113: to high permissions to fork repository
587 - fixed problem with '[' chars in commit messages in journal
589 - fixed problem with '[' chars in commit messages in journal
588 - removed issue with space inside renamed repository after deletion
590 - removed issue with space inside renamed repository after deletion
589 - db transaction fixes when filesystem repository creation failed
591 - db transaction fixes when filesystem repository creation failed
590 - fixed #106 relation issues on databases different than sqlite
592 - fixed #106 relation issues on databases different than sqlite
591 - fixed static files paths links to use of url() method
593 - fixed static files paths links to use of url() method
592
594
593 1.1.2 (**2011-01-12**)
595 1.1.2 (**2011-01-12**)
594 ----------------------
596 ----------------------
595
597
596 news
598 news
597 ++++
599 ++++
598
600
599
601
600 fixes
602 fixes
601 +++++
603 +++++
602
604
603 - fixes #98 protection against float division of percentage stats
605 - fixes #98 protection against float division of percentage stats
604 - fixed graph bug
606 - fixed graph bug
605 - forced webhelpers version since it was making troubles during installation
607 - forced webhelpers version since it was making troubles during installation
606
608
607 1.1.1 (**2011-01-06**)
609 1.1.1 (**2011-01-06**)
608 ----------------------
610 ----------------------
609
611
610 news
612 news
611 ++++
613 ++++
612
614
613 - added force https option into ini files for easier https usage (no need to
615 - added force https option into ini files for easier https usage (no need to
614 set server headers with this options)
616 set server headers with this options)
615 - small css updates
617 - small css updates
616
618
617 fixes
619 fixes
618 +++++
620 +++++
619
621
620 - fixed #96 redirect loop on files view on repositories without changesets
622 - fixed #96 redirect loop on files view on repositories without changesets
621 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
623 - fixed #97 unicode string passed into server header in special cases (mod_wsgi)
622 and server crashed with errors
624 and server crashed with errors
623 - fixed large tooltips problems on main page
625 - fixed large tooltips problems on main page
624 - fixed #92 whoosh indexer is more error proof
626 - fixed #92 whoosh indexer is more error proof
625
627
626 1.1.0 (**2010-12-18**)
628 1.1.0 (**2010-12-18**)
627 ----------------------
629 ----------------------
628
630
629 news
631 news
630 ++++
632 ++++
631
633
632 - rewrite of internals for vcs >=0.1.10
634 - rewrite of internals for vcs >=0.1.10
633 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
635 - uses mercurial 1.7 with dotencode disabled for maintaining compatibility
634 with older clients
636 with older clients
635 - anonymous access, authentication via ldap
637 - anonymous access, authentication via ldap
636 - performance upgrade for cached repos list - each repository has its own
638 - performance upgrade for cached repos list - each repository has its own
637 cache that's invalidated when needed.
639 cache that's invalidated when needed.
638 - performance upgrades on repositories with large amount of commits (20K+)
640 - performance upgrades on repositories with large amount of commits (20K+)
639 - main page quick filter for filtering repositories
641 - main page quick filter for filtering repositories
640 - user dashboards with ability to follow chosen repositories actions
642 - user dashboards with ability to follow chosen repositories actions
641 - sends email to admin on new user registration
643 - sends email to admin on new user registration
642 - added cache/statistics reset options into repository settings
644 - added cache/statistics reset options into repository settings
643 - more detailed action logger (based on hooks) with pushed changesets lists
645 - more detailed action logger (based on hooks) with pushed changesets lists
644 and options to disable those hooks from admin panel
646 and options to disable those hooks from admin panel
645 - introduced new enhanced changelog for merges that shows more accurate results
647 - introduced new enhanced changelog for merges that shows more accurate results
646 - new improved and faster code stats (based on pygments lexers mapping tables,
648 - new improved and faster code stats (based on pygments lexers mapping tables,
647 showing up to 10 trending sources for each repository. Additionally stats
649 showing up to 10 trending sources for each repository. Additionally stats
648 can be disabled in repository settings.
650 can be disabled in repository settings.
649 - gui optimizations, fixed application width to 1024px
651 - gui optimizations, fixed application width to 1024px
650 - added cut off (for large files/changesets) limit into config files
652 - added cut off (for large files/changesets) limit into config files
651 - whoosh, celeryd, upgrade moved to paster command
653 - whoosh, celeryd, upgrade moved to paster command
652 - other than sqlite database backends can be used
654 - other than sqlite database backends can be used
653
655
654 fixes
656 fixes
655 +++++
657 +++++
656
658
657 - fixes #61 forked repo was showing only after cache expired
659 - fixes #61 forked repo was showing only after cache expired
658 - fixes #76 no confirmation on user deletes
660 - fixes #76 no confirmation on user deletes
659 - fixes #66 Name field misspelled
661 - fixes #66 Name field misspelled
660 - fixes #72 block user removal when he owns repositories
662 - fixes #72 block user removal when he owns repositories
661 - fixes #69 added password confirmation fields
663 - fixes #69 added password confirmation fields
662 - fixes #87 RhodeCode crashes occasionally on updating repository owner
664 - fixes #87 RhodeCode crashes occasionally on updating repository owner
663 - fixes #82 broken annotations on files with more than 1 blank line at the end
665 - fixes #82 broken annotations on files with more than 1 blank line at the end
664 - a lot of fixes and tweaks for file browser
666 - a lot of fixes and tweaks for file browser
665 - fixed detached session issues
667 - fixed detached session issues
666 - fixed when user had no repos he would see all repos listed in my account
668 - fixed when user had no repos he would see all repos listed in my account
667 - fixed ui() instance bug when global hgrc settings was loaded for server
669 - fixed ui() instance bug when global hgrc settings was loaded for server
668 instance and all hgrc options were merged with our db ui() object
670 instance and all hgrc options were merged with our db ui() object
669 - numerous small bugfixes
671 - numerous small bugfixes
670
672
671 (special thanks for TkSoh for detailed feedback)
673 (special thanks for TkSoh for detailed feedback)
672
674
673
675
674 1.0.2 (**2010-11-12**)
676 1.0.2 (**2010-11-12**)
675 ----------------------
677 ----------------------
676
678
677 news
679 news
678 ++++
680 ++++
679
681
680 - tested under python2.7
682 - tested under python2.7
681 - bumped sqlalchemy and celery versions
683 - bumped sqlalchemy and celery versions
682
684
683 fixes
685 fixes
684 +++++
686 +++++
685
687
686 - fixed #59 missing graph.js
688 - fixed #59 missing graph.js
687 - fixed repo_size crash when repository had broken symlinks
689 - fixed repo_size crash when repository had broken symlinks
688 - fixed python2.5 crashes.
690 - fixed python2.5 crashes.
689
691
690
692
691 1.0.1 (**2010-11-10**)
693 1.0.1 (**2010-11-10**)
692 ----------------------
694 ----------------------
693
695
694 news
696 news
695 ++++
697 ++++
696
698
697 - small css updated
699 - small css updated
698
700
699 fixes
701 fixes
700 +++++
702 +++++
701
703
702 - fixed #53 python2.5 incompatible enumerate calls
704 - fixed #53 python2.5 incompatible enumerate calls
703 - fixed #52 disable mercurial extension for web
705 - fixed #52 disable mercurial extension for web
704 - fixed #51 deleting repositories don't delete it's dependent objects
706 - fixed #51 deleting repositories don't delete it's dependent objects
705
707
706
708
707 1.0.0 (**2010-11-02**)
709 1.0.0 (**2010-11-02**)
708 ----------------------
710 ----------------------
709
711
710 - security bugfix simplehg wasn't checking for permissions on commands
712 - security bugfix simplehg wasn't checking for permissions on commands
711 other than pull or push.
713 other than pull or push.
712 - fixed doubled messages after push or pull in admin journal
714 - fixed doubled messages after push or pull in admin journal
713 - templating and css corrections, fixed repo switcher on chrome, updated titles
715 - templating and css corrections, fixed repo switcher on chrome, updated titles
714 - admin menu accessible from options menu on repository view
716 - admin menu accessible from options menu on repository view
715 - permissions cached queries
717 - permissions cached queries
716
718
717 1.0.0rc4 (**2010-10-12**)
719 1.0.0rc4 (**2010-10-12**)
718 --------------------------
720 --------------------------
719
721
720 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
722 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
721 - removed cache_manager settings from sqlalchemy meta
723 - removed cache_manager settings from sqlalchemy meta
722 - added sqlalchemy cache settings to ini files
724 - added sqlalchemy cache settings to ini files
723 - validated password length and added second try of failure on paster setup-app
725 - validated password length and added second try of failure on paster setup-app
724 - fixed setup database destroy prompt even when there was no db
726 - fixed setup database destroy prompt even when there was no db
725
727
726
728
727 1.0.0rc3 (**2010-10-11**)
729 1.0.0rc3 (**2010-10-11**)
728 -------------------------
730 -------------------------
729
731
730 - fixed i18n during installation.
732 - fixed i18n during installation.
731
733
732 1.0.0rc2 (**2010-10-11**)
734 1.0.0rc2 (**2010-10-11**)
733 -------------------------
735 -------------------------
734
736
735 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
737 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
736 occure. After vcs is fixed it'll be put back again.
738 occure. After vcs is fixed it'll be put back again.
737 - templating/css rewrites, optimized css. No newline at end of file
739 - templating/css rewrites, optimized css.
@@ -1,274 +1,275 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.notification
3 rhodecode.model.notification
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Model for notifications
6 Model for notifications
7
7
8
8
9 :created_on: Nov 20, 2011
9 :created_on: Nov 20, 2011
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
26
27 import os
27 import os
28 import logging
28 import logging
29 import traceback
29 import traceback
30
30
31 from pylons.i18n.translation import _
31 from pylons.i18n.translation import _
32
32
33 import rhodecode
33 import rhodecode
34 from rhodecode.lib import helpers as h
34 from rhodecode.lib import helpers as h
35 from rhodecode.model import BaseModel
35 from rhodecode.model import BaseModel
36 from rhodecode.model.db import Notification, User, UserNotification
36 from rhodecode.model.db import Notification, User, UserNotification
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 class NotificationModel(BaseModel):
41 class NotificationModel(BaseModel):
42
42
43 cls = Notification
43 cls = Notification
44
44
45 def __get_notification(self, notification):
45 def __get_notification(self, notification):
46 if isinstance(notification, Notification):
46 if isinstance(notification, Notification):
47 return notification
47 return notification
48 elif isinstance(notification, (int, long)):
48 elif isinstance(notification, (int, long)):
49 return Notification.get(notification)
49 return Notification.get(notification)
50 else:
50 else:
51 if notification:
51 if notification:
52 raise Exception('notification must be int, long or Instance'
52 raise Exception('notification must be int, long or Instance'
53 ' of Notification got %s' % type(notification))
53 ' of Notification got %s' % type(notification))
54
54
55 def create(self, created_by, subject, body, recipients=None,
55 def create(self, created_by, subject, body, recipients=None,
56 type_=Notification.TYPE_MESSAGE, with_email=True,
56 type_=Notification.TYPE_MESSAGE, with_email=True,
57 email_kwargs={}):
57 email_kwargs={}):
58 """
58 """
59
59
60 Creates notification of given type
60 Creates notification of given type
61
61
62 :param created_by: int, str or User instance. User who created this
62 :param created_by: int, str or User instance. User who created this
63 notification
63 notification
64 :param subject:
64 :param subject:
65 :param body:
65 :param body:
66 :param recipients: list of int, str or User objects, when None
66 :param recipients: list of int, str or User objects, when None
67 is given send to all admins
67 is given send to all admins
68 :param type_: type of notification
68 :param type_: type of notification
69 :param with_email: send email with this notification
69 :param with_email: send email with this notification
70 :param email_kwargs: additional dict to pass as args to email template
70 :param email_kwargs: additional dict to pass as args to email template
71 """
71 """
72 from rhodecode.lib.celerylib import tasks, run_task
72 from rhodecode.lib.celerylib import tasks, run_task
73
73
74 if recipients and not getattr(recipients, '__iter__', False):
74 if recipients and not getattr(recipients, '__iter__', False):
75 raise Exception('recipients must be a list of iterable')
75 raise Exception('recipients must be a list of iterable')
76
76
77 created_by_obj = self._get_user(created_by)
77 created_by_obj = self._get_user(created_by)
78
78
79 if recipients:
79 if recipients:
80 recipients_objs = []
80 recipients_objs = []
81 for u in recipients:
81 for u in recipients:
82 obj = self._get_user(u)
82 obj = self._get_user(u)
83 if obj:
83 if obj:
84 recipients_objs.append(obj)
84 recipients_objs.append(obj)
85 recipients_objs = set(recipients_objs)
85 recipients_objs = set(recipients_objs)
86 log.debug('sending notifications %s to %s' % (
86 log.debug('sending notifications %s to %s' % (
87 type_, recipients_objs)
87 type_, recipients_objs)
88 )
88 )
89 else:
89 else:
90 # empty recipients means to all admins
90 # empty recipients means to all admins
91 recipients_objs = User.query().filter(User.admin == True).all()
91 recipients_objs = User.query().filter(User.admin == True).all()
92 log.debug('sending notifications %s to admins: %s' % (
92 log.debug('sending notifications %s to admins: %s' % (
93 type_, recipients_objs)
93 type_, recipients_objs)
94 )
94 )
95 notif = Notification.create(
95 notif = Notification.create(
96 created_by=created_by_obj, subject=subject,
96 created_by=created_by_obj, subject=subject,
97 body=body, recipients=recipients_objs, type_=type_
97 body=body, recipients=recipients_objs, type_=type_
98 )
98 )
99
99
100 if with_email is False:
100 if with_email is False:
101 return notif
101 return notif
102
102
103 #don't send email to person who created this comment
103 #don't send email to person who created this comment
104 rec_objs = set(recipients_objs).difference(set([created_by_obj]))
104 rec_objs = set(recipients_objs).difference(set([created_by_obj]))
105
105
106 # send email with notification to all other participants
106 # send email with notification to all other participants
107 for rec in rec_objs:
107 for rec in rec_objs:
108 email_subject = NotificationModel().make_description(notif, False)
108 email_subject = NotificationModel().make_description(notif, False)
109 type_ = type_
109 type_ = type_
110 email_body = body
110 email_body = body
111 ## this is passed into template
111 ## this is passed into template
112 kwargs = {'subject': subject, 'body': h.rst_w_mentions(body)}
112 kwargs = {'subject': subject, 'body': h.rst_w_mentions(body)}
113 kwargs.update(email_kwargs)
113 kwargs.update(email_kwargs)
114 email_body_html = EmailNotificationModel()\
114 email_body_html = EmailNotificationModel()\
115 .get_email_tmpl(type_, **kwargs)
115 .get_email_tmpl(type_, **kwargs)
116
116
117 run_task(tasks.send_email, rec.email, email_subject, email_body,
117 run_task(tasks.send_email, rec.email, email_subject, email_body,
118 email_body_html)
118 email_body_html)
119
119
120 return notif
120 return notif
121
121
122 def delete(self, user, notification):
122 def delete(self, user, notification):
123 # we don't want to remove actual notification just the assignment
123 # we don't want to remove actual notification just the assignment
124 try:
124 try:
125 notification = self.__get_notification(notification)
125 notification = self.__get_notification(notification)
126 user = self._get_user(user)
126 user = self._get_user(user)
127 if notification and user:
127 if notification and user:
128 obj = UserNotification.query()\
128 obj = UserNotification.query()\
129 .filter(UserNotification.user == user)\
129 .filter(UserNotification.user == user)\
130 .filter(UserNotification.notification
130 .filter(UserNotification.notification
131 == notification)\
131 == notification)\
132 .one()
132 .one()
133 self.sa.delete(obj)
133 self.sa.delete(obj)
134 return True
134 return True
135 except Exception:
135 except Exception:
136 log.error(traceback.format_exc())
136 log.error(traceback.format_exc())
137 raise
137 raise
138
138
139 def get_for_user(self, user, filter_=None):
139 def get_for_user(self, user, filter_=None):
140 """
140 """
141 Get mentions for given user, filter them if filter dict is given
141 Get mentions for given user, filter them if filter dict is given
142
142
143 :param user:
143 :param user:
144 :type user:
144 :type user:
145 :param filter:
145 :param filter:
146 """
146 """
147 user = self._get_user(user)
147 user = self._get_user(user)
148
148
149 q = UserNotification.query()\
149 q = UserNotification.query()\
150 .filter(UserNotification.user == user)\
150 .filter(UserNotification.user == user)\
151 .join((Notification, UserNotification.notification_id ==
151 .join((Notification, UserNotification.notification_id ==
152 Notification.notification_id))
152 Notification.notification_id))
153
153
154 if filter_:
154 if filter_:
155 q = q.filter(Notification.type_.in_(filter_))
155 q = q.filter(Notification.type_.in_(filter_))
156
156
157 return q.all()
157 return q.all()
158
158
159 def mark_read(self, user, notification):
159 def mark_read(self, user, notification):
160 try:
160 try:
161 notification = self.__get_notification(notification)
161 notification = self.__get_notification(notification)
162 user = self._get_user(user)
162 user = self._get_user(user)
163 if notification and user:
163 if notification and user:
164 obj = UserNotification.query()\
164 obj = UserNotification.query()\
165 .filter(UserNotification.user == user)\
165 .filter(UserNotification.user == user)\
166 .filter(UserNotification.notification
166 .filter(UserNotification.notification
167 == notification)\
167 == notification)\
168 .one()
168 .one()
169 obj.read = True
169 obj.read = True
170 self.sa.add(obj)
170 self.sa.add(obj)
171 return True
171 return True
172 except Exception:
172 except Exception:
173 log.error(traceback.format_exc())
173 log.error(traceback.format_exc())
174 raise
174 raise
175
175
176 def mark_all_read_for_user(self, user, filter_=None):
176 def mark_all_read_for_user(self, user, filter_=None):
177 user = self._get_user(user)
177 user = self._get_user(user)
178 q = UserNotification.query()\
178 q = UserNotification.query()\
179 .filter(UserNotification.user == user)\
179 .filter(UserNotification.user == user)\
180 .filter(UserNotification.read == False)\
180 .filter(UserNotification.read == False)\
181 .join((Notification, UserNotification.notification_id ==
181 .join((Notification, UserNotification.notification_id ==
182 Notification.notification_id))
182 Notification.notification_id))
183 if filter_:
183 if filter_:
184 q = q.filter(Notification.type_.in_(filter_))
184 q = q.filter(Notification.type_.in_(filter_))
185
185
186 # this is a little inefficient but sqlalchemy doesn't support
186 # this is a little inefficient but sqlalchemy doesn't support
187 # update on joined tables :(
187 # update on joined tables :(
188 for obj in q.all():
188 for obj in q.all():
189 obj.read = True
189 obj.read = True
190 self.sa.add(obj)
190 self.sa.add(obj)
191
191
192 def get_unread_cnt_for_user(self, user):
192 def get_unread_cnt_for_user(self, user):
193 user = self._get_user(user)
193 user = self._get_user(user)
194 return UserNotification.query()\
194 return UserNotification.query()\
195 .filter(UserNotification.read == False)\
195 .filter(UserNotification.read == False)\
196 .filter(UserNotification.user == user).count()
196 .filter(UserNotification.user == user).count()
197
197
198 def get_unread_for_user(self, user):
198 def get_unread_for_user(self, user):
199 user = self._get_user(user)
199 user = self._get_user(user)
200 return [x.notification for x in UserNotification.query()\
200 return [x.notification for x in UserNotification.query()\
201 .filter(UserNotification.read == False)\
201 .filter(UserNotification.read == False)\
202 .filter(UserNotification.user == user).all()]
202 .filter(UserNotification.user == user).all()]
203
203
204 def get_user_notification(self, user, notification):
204 def get_user_notification(self, user, notification):
205 user = self._get_user(user)
205 user = self._get_user(user)
206 notification = self.__get_notification(notification)
206 notification = self.__get_notification(notification)
207
207
208 return UserNotification.query()\
208 return UserNotification.query()\
209 .filter(UserNotification.notification == notification)\
209 .filter(UserNotification.notification == notification)\
210 .filter(UserNotification.user == user).scalar()
210 .filter(UserNotification.user == user).scalar()
211
211
212 def make_description(self, notification, show_age=True):
212 def make_description(self, notification, show_age=True):
213 """
213 """
214 Creates a human readable description based on properties
214 Creates a human readable description based on properties
215 of notification object
215 of notification object
216 """
216 """
217 #alias
217 #alias
218 _n = notification
218 _n = notification
219 _map = {
219 _map = {
220 _n.TYPE_CHANGESET_COMMENT: _('commented on commit'),
220 _n.TYPE_CHANGESET_COMMENT: _('commented on commit'),
221 _n.TYPE_MESSAGE: _('sent message'),
221 _n.TYPE_MESSAGE: _('sent message'),
222 _n.TYPE_MENTION: _('mentioned you'),
222 _n.TYPE_MENTION: _('mentioned you'),
223 _n.TYPE_REGISTRATION: _('registered in RhodeCode'),
223 _n.TYPE_REGISTRATION: _('registered in RhodeCode'),
224 _n.TYPE_PULL_REQUEST: _('opened new pull request'),
224 _n.TYPE_PULL_REQUEST: _('opened new pull request'),
225 _n.TYPE_PULL_REQUEST_COMMENT: _('commented on pull request')
225 _n.TYPE_PULL_REQUEST_COMMENT: _('commented on pull request')
226 }
226 }
227
227
228 # action == _map string
228 # action == _map string
229 tmpl = "%(user)s %(action)s at %(when)s"
229 tmpl = "%(user)s %(action)s at %(when)s"
230 if show_age:
230 if show_age:
231 when = h.age(notification.created_on)
231 when = h.age(notification.created_on)
232 else:
232 else:
233 when = h.fmt_date(notification.created_on)
233 when = h.fmt_date(notification.created_on)
234
234
235 data = dict(
235 data = dict(
236 user=notification.created_by_user.username,
236 user=notification.created_by_user.username,
237 action=_map[notification.type_], when=when,
237 action=_map[notification.type_], when=when,
238 )
238 )
239 return tmpl % data
239 return tmpl % data
240
240
241
241
242 class EmailNotificationModel(BaseModel):
242 class EmailNotificationModel(BaseModel):
243
243
244 TYPE_CHANGESET_COMMENT = Notification.TYPE_CHANGESET_COMMENT
244 TYPE_CHANGESET_COMMENT = Notification.TYPE_CHANGESET_COMMENT
245 TYPE_PASSWORD_RESET = 'passoword_link'
245 TYPE_PASSWORD_RESET = 'passoword_link'
246 TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
246 TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
247 TYPE_PULL_REQUEST = Notification.TYPE_PULL_REQUEST
247 TYPE_PULL_REQUEST = Notification.TYPE_PULL_REQUEST
248 TYPE_DEFAULT = 'default'
248 TYPE_DEFAULT = 'default'
249
249
250 def __init__(self):
250 def __init__(self):
251 self._template_root = rhodecode.CONFIG['pylons.paths']['templates'][0]
251 self._template_root = rhodecode.CONFIG['pylons.paths']['templates'][0]
252 self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
252 self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
253
253
254 self.email_types = {
254 self.email_types = {
255 self.TYPE_CHANGESET_COMMENT: 'email_templates/changeset_comment.html',
255 self.TYPE_CHANGESET_COMMENT: 'email_templates/changeset_comment.html',
256 self.TYPE_PASSWORD_RESET: 'email_templates/password_reset.html',
256 self.TYPE_PASSWORD_RESET: 'email_templates/password_reset.html',
257 self.TYPE_REGISTRATION: 'email_templates/registration.html',
257 self.TYPE_REGISTRATION: 'email_templates/registration.html',
258 self.TYPE_DEFAULT: 'email_templates/default.html'
258 self.TYPE_DEFAULT: 'email_templates/default.html',
259 self.TYPE_PULL_REQUEST: 'email_templates/pull_request.html',
259 }
260 }
260
261
261 def get_email_tmpl(self, type_, **kwargs):
262 def get_email_tmpl(self, type_, **kwargs):
262 """
263 """
263 return generated template for email based on given type
264 return generated template for email based on given type
264
265
265 :param type_:
266 :param type_:
266 """
267 """
267
268
268 base = self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT])
269 base = self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT])
269 email_template = self._tmpl_lookup.get_template(base)
270 email_template = self._tmpl_lookup.get_template(base)
270 # translator inject
271 # translator inject
271 _kwargs = {'_': _}
272 _kwargs = {'_': _}
272 _kwargs.update(kwargs)
273 _kwargs.update(kwargs)
273 log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs))
274 log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs))
274 return email_template.render(**_kwargs)
275 return email_template.render(**_kwargs)
@@ -1,249 +1,257 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.pull_request
3 rhodecode.model.pull_request
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 pull request model for RhodeCode
6 pull request model for RhodeCode
7
7
8 :created_on: Jun 6, 2012
8 :created_on: Jun 6, 2012
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2012-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2012-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 logging
26 import logging
27 import binascii
27 import binascii
28 import datetime
28 import datetime
29
29
30 from pylons.i18n.translation import _
30 from pylons.i18n.translation import _
31
31
32 from rhodecode.model.meta import Session
32 from rhodecode.model.meta import Session
33 from rhodecode.lib import helpers as h
33 from rhodecode.lib import helpers as h
34 from rhodecode.model import BaseModel
34 from rhodecode.model import BaseModel
35 from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification
35 from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification
36 from rhodecode.model.notification import NotificationModel
36 from rhodecode.model.notification import NotificationModel
37 from rhodecode.lib.utils2 import safe_unicode
37 from rhodecode.lib.utils2 import safe_unicode
38
38
39 from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil
39 from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil
40
40
41 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
42
42
43
43
44 class PullRequestModel(BaseModel):
44 class PullRequestModel(BaseModel):
45
45
46 cls = PullRequest
46 cls = PullRequest
47
47
48 def __get_pull_request(self, pull_request):
48 def __get_pull_request(self, pull_request):
49 return self._get_instance(PullRequest, pull_request)
49 return self._get_instance(PullRequest, pull_request)
50
50
51 def get_all(self, repo):
51 def get_all(self, repo):
52 repo = self._get_repo(repo)
52 repo = self._get_repo(repo)
53 return PullRequest.query().filter(PullRequest.other_repo == repo).all()
53 return PullRequest.query().filter(PullRequest.other_repo == repo).all()
54
54
55 def create(self, created_by, org_repo, org_ref, other_repo,
55 def create(self, created_by, org_repo, org_ref, other_repo,
56 other_ref, revisions, reviewers, title, description=None):
56 other_ref, revisions, reviewers, title, description=None):
57
57
58 created_by_user = self._get_user(created_by)
58 created_by_user = self._get_user(created_by)
59 org_repo = self._get_repo(org_repo)
59 org_repo = self._get_repo(org_repo)
60 other_repo = self._get_repo(other_repo)
60 other_repo = self._get_repo(other_repo)
61
61
62 new = PullRequest()
62 new = PullRequest()
63 new.org_repo = org_repo
63 new.org_repo = org_repo
64 new.org_ref = org_ref
64 new.org_ref = org_ref
65 new.other_repo = other_repo
65 new.other_repo = other_repo
66 new.other_ref = other_ref
66 new.other_ref = other_ref
67 new.revisions = revisions
67 new.revisions = revisions
68 new.title = title
68 new.title = title
69 new.description = description
69 new.description = description
70 new.author = created_by_user
70 new.author = created_by_user
71 self.sa.add(new)
71 self.sa.add(new)
72 Session().flush()
72 Session().flush()
73 #members
73 #members
74 for member in reviewers:
74 for member in reviewers:
75 _usr = self._get_user(member)
75 _usr = self._get_user(member)
76 reviewer = PullRequestReviewers(_usr, new)
76 reviewer = PullRequestReviewers(_usr, new)
77 self.sa.add(reviewer)
77 self.sa.add(reviewer)
78
78
79 #notification to reviewers
79 #notification to reviewers
80 notif = NotificationModel()
80 notif = NotificationModel()
81
81
82 pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name,
83 pull_request_id=new.pull_request_id,
84 qualified=True,
85 )
82 subject = safe_unicode(
86 subject = safe_unicode(
83 h.link_to(
87 h.link_to(
84 _('%(user)s wants you to review pull request #%(pr_id)s') % \
88 _('%(user)s wants you to review pull request #%(pr_id)s') % \
85 {'user': created_by_user.username,
89 {'user': created_by_user.username,
86 'pr_id': new.pull_request_id},
90 'pr_id': new.pull_request_id},
87 h.url('pullrequest_show', repo_name=other_repo.repo_name,
91 pr_url
88 pull_request_id=new.pull_request_id,
89 qualified=True,
90 )
91 )
92 )
92 )
93 )
93 body = description
94 body = description
95 kwargs = {
96 'pr_title': title,
97 'pr_user_created': h.person(created_by_user.email),
98 'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name,
99 qualified=True,),
100 'pr_url': pr_url,
101 'pr_revisions': revisions
102 }
94 notif.create(created_by=created_by_user, subject=subject, body=body,
103 notif.create(created_by=created_by_user, subject=subject, body=body,
95 recipients=reviewers,
104 recipients=reviewers,
96 type_=Notification.TYPE_PULL_REQUEST,)
105 type_=Notification.TYPE_PULL_REQUEST, email_kwargs=kwargs)
97
98 return new
106 return new
99
107
100 def update_reviewers(self, pull_request, reviewers_ids):
108 def update_reviewers(self, pull_request, reviewers_ids):
101 reviewers_ids = set(reviewers_ids)
109 reviewers_ids = set(reviewers_ids)
102 pull_request = self.__get_pull_request(pull_request)
110 pull_request = self.__get_pull_request(pull_request)
103 current_reviewers = PullRequestReviewers.query()\
111 current_reviewers = PullRequestReviewers.query()\
104 .filter(PullRequestReviewers.pull_request==
112 .filter(PullRequestReviewers.pull_request==
105 pull_request)\
113 pull_request)\
106 .all()
114 .all()
107 current_reviewers_ids = set([x.user.user_id for x in current_reviewers])
115 current_reviewers_ids = set([x.user.user_id for x in current_reviewers])
108
116
109 to_add = reviewers_ids.difference(current_reviewers_ids)
117 to_add = reviewers_ids.difference(current_reviewers_ids)
110 to_remove = current_reviewers_ids.difference(reviewers_ids)
118 to_remove = current_reviewers_ids.difference(reviewers_ids)
111
119
112 log.debug("Adding %s reviewers" % to_add)
120 log.debug("Adding %s reviewers" % to_add)
113 log.debug("Removing %s reviewers" % to_remove)
121 log.debug("Removing %s reviewers" % to_remove)
114
122
115 for uid in to_add:
123 for uid in to_add:
116 _usr = self._get_user(uid)
124 _usr = self._get_user(uid)
117 reviewer = PullRequestReviewers(_usr, pull_request)
125 reviewer = PullRequestReviewers(_usr, pull_request)
118 self.sa.add(reviewer)
126 self.sa.add(reviewer)
119
127
120 for uid in to_remove:
128 for uid in to_remove:
121 reviewer = PullRequestReviewers.query()\
129 reviewer = PullRequestReviewers.query()\
122 .filter(PullRequestReviewers.user_id==uid,
130 .filter(PullRequestReviewers.user_id==uid,
123 PullRequestReviewers.pull_request==pull_request)\
131 PullRequestReviewers.pull_request==pull_request)\
124 .scalar()
132 .scalar()
125 if reviewer:
133 if reviewer:
126 self.sa.delete(reviewer)
134 self.sa.delete(reviewer)
127
135
128 def delete(self, pull_request):
136 def delete(self, pull_request):
129 pull_request = self.__get_pull_request(pull_request)
137 pull_request = self.__get_pull_request(pull_request)
130 Session().delete(pull_request)
138 Session().delete(pull_request)
131
139
132 def close_pull_request(self, pull_request):
140 def close_pull_request(self, pull_request):
133 pull_request = self.__get_pull_request(pull_request)
141 pull_request = self.__get_pull_request(pull_request)
134 pull_request.status = PullRequest.STATUS_CLOSED
142 pull_request.status = PullRequest.STATUS_CLOSED
135 pull_request.updated_on = datetime.datetime.now()
143 pull_request.updated_on = datetime.datetime.now()
136 self.sa.add(pull_request)
144 self.sa.add(pull_request)
137
145
138 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref,
146 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref,
139 discovery_data):
147 discovery_data):
140 """
148 """
141 Returns a list of changesets that are incoming from org_repo@org_ref
149 Returns a list of changesets that are incoming from org_repo@org_ref
142 to other_repo@other_ref
150 to other_repo@other_ref
143
151
144 :param org_repo:
152 :param org_repo:
145 :type org_repo:
153 :type org_repo:
146 :param org_ref:
154 :param org_ref:
147 :type org_ref:
155 :type org_ref:
148 :param other_repo:
156 :param other_repo:
149 :type other_repo:
157 :type other_repo:
150 :param other_ref:
158 :param other_ref:
151 :type other_ref:
159 :type other_ref:
152 :param tmp:
160 :param tmp:
153 :type tmp:
161 :type tmp:
154 """
162 """
155 changesets = []
163 changesets = []
156 #case two independent repos
164 #case two independent repos
157 common, incoming, rheads = discovery_data
165 common, incoming, rheads = discovery_data
158 if org_repo != other_repo and incoming:
166 if org_repo != other_repo and incoming:
159 revs = org_repo._repo.changelog.findmissing(common, rheads)
167 revs = org_repo._repo.changelog.findmissing(common, rheads)
160
168
161 for cs in reversed(map(binascii.hexlify, revs)):
169 for cs in reversed(map(binascii.hexlify, revs)):
162 changesets.append(org_repo.get_changeset(cs))
170 changesets.append(org_repo.get_changeset(cs))
163 else:
171 else:
164 _revset_predicates = {
172 _revset_predicates = {
165 'branch': 'branch',
173 'branch': 'branch',
166 'book': 'bookmark',
174 'book': 'bookmark',
167 'tag': 'tag',
175 'tag': 'tag',
168 'rev': 'id',
176 'rev': 'id',
169 }
177 }
170
178
171 revs = [
179 revs = [
172 "ancestors(%s('%s')) and not ancestors(%s('%s'))" % (
180 "ancestors(%s('%s')) and not ancestors(%s('%s'))" % (
173 _revset_predicates[org_ref[0]], org_ref[1],
181 _revset_predicates[org_ref[0]], org_ref[1],
174 _revset_predicates[other_ref[0]], other_ref[1]
182 _revset_predicates[other_ref[0]], other_ref[1]
175 )
183 )
176 ]
184 ]
177
185
178 out = scmutil.revrange(org_repo._repo, revs)
186 out = scmutil.revrange(org_repo._repo, revs)
179 for cs in reversed(out):
187 for cs in reversed(out):
180 changesets.append(org_repo.get_changeset(cs))
188 changesets.append(org_repo.get_changeset(cs))
181
189
182 return changesets
190 return changesets
183
191
184 def _get_discovery(self, org_repo, org_ref, other_repo, other_ref):
192 def _get_discovery(self, org_repo, org_ref, other_repo, other_ref):
185 """
193 """
186 Get's mercurial discovery data used to calculate difference between
194 Get's mercurial discovery data used to calculate difference between
187 repos and refs
195 repos and refs
188
196
189 :param org_repo:
197 :param org_repo:
190 :type org_repo:
198 :type org_repo:
191 :param org_ref:
199 :param org_ref:
192 :type org_ref:
200 :type org_ref:
193 :param other_repo:
201 :param other_repo:
194 :type other_repo:
202 :type other_repo:
195 :param other_ref:
203 :param other_ref:
196 :type other_ref:
204 :type other_ref:
197 """
205 """
198
206
199 _org_repo = org_repo._repo
207 _org_repo = org_repo._repo
200 org_rev_type, org_rev = org_ref
208 org_rev_type, org_rev = org_ref
201
209
202 _other_repo = other_repo._repo
210 _other_repo = other_repo._repo
203 other_rev_type, other_rev = other_ref
211 other_rev_type, other_rev = other_ref
204
212
205 log.debug('Doing discovery for %s@%s vs %s@%s' % (
213 log.debug('Doing discovery for %s@%s vs %s@%s' % (
206 org_repo, org_ref, other_repo, other_ref)
214 org_repo, org_ref, other_repo, other_ref)
207 )
215 )
208 #log.debug('Filter heads are %s[%s]' % ('', org_ref[1]))
216 #log.debug('Filter heads are %s[%s]' % ('', org_ref[1]))
209 org_peer = localrepo.locallegacypeer(_org_repo.local())
217 org_peer = localrepo.locallegacypeer(_org_repo.local())
210 tmp = discovery.findcommonincoming(
218 tmp = discovery.findcommonincoming(
211 repo=_other_repo, # other_repo we check for incoming
219 repo=_other_repo, # other_repo we check for incoming
212 remote=org_peer, # org_repo source for incoming
220 remote=org_peer, # org_repo source for incoming
213 heads=[_other_repo[other_rev].node(),
221 heads=[_other_repo[other_rev].node(),
214 _org_repo[org_rev].node()],
222 _org_repo[org_rev].node()],
215 force=False
223 force=False
216 )
224 )
217 return tmp
225 return tmp
218
226
219 def get_compare_data(self, org_repo, org_ref, other_repo, other_ref):
227 def get_compare_data(self, org_repo, org_ref, other_repo, other_ref):
220 """
228 """
221 Returns a tuple of incomming changesets, and discoverydata cache
229 Returns a tuple of incomming changesets, and discoverydata cache
222
230
223 :param org_repo:
231 :param org_repo:
224 :type org_repo:
232 :type org_repo:
225 :param org_ref:
233 :param org_ref:
226 :type org_ref:
234 :type org_ref:
227 :param other_repo:
235 :param other_repo:
228 :type other_repo:
236 :type other_repo:
229 :param other_ref:
237 :param other_ref:
230 :type other_ref:
238 :type other_ref:
231 """
239 """
232
240
233 if len(org_ref) != 2 or not isinstance(org_ref, (list, tuple)):
241 if len(org_ref) != 2 or not isinstance(org_ref, (list, tuple)):
234 raise Exception('org_ref must be a two element list/tuple')
242 raise Exception('org_ref must be a two element list/tuple')
235
243
236 if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)):
244 if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)):
237 raise Exception('other_ref must be a two element list/tuple')
245 raise Exception('other_ref must be a two element list/tuple')
238
246
239 discovery_data = self._get_discovery(org_repo.scm_instance,
247 discovery_data = self._get_discovery(org_repo.scm_instance,
240 org_ref,
248 org_ref,
241 other_repo.scm_instance,
249 other_repo.scm_instance,
242 other_ref)
250 other_ref)
243 cs_ranges = self._get_changesets(org_repo.scm_instance,
251 cs_ranges = self._get_changesets(org_repo.scm_instance,
244 org_ref,
252 org_ref,
245 other_repo.scm_instance,
253 other_repo.scm_instance,
246 other_ref,
254 other_ref,
247 discovery_data)
255 discovery_data)
248
256
249 return cs_ranges, discovery_data
257 return cs_ranges, discovery_data
General Comments 0
You need to be logged in to leave comments. Login now