Show More
@@ -0,0 +1,31 b'' | |||
|
1 | <%inherit file="/base/base.html"/> | |
|
2 | ||
|
3 | <%def name="title()"> | |
|
4 | ${c.repo_name} ${_('All pull requests')} | |
|
5 | </%def> | |
|
6 | ||
|
7 | <%def name="breadcrumbs_links()"> | |
|
8 | ${h.link_to(u'Home',h.url('/'))} | |
|
9 | » | |
|
10 | ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))} | |
|
11 | » | |
|
12 | ${_('All pull requests')} | |
|
13 | </%def> | |
|
14 | ||
|
15 | <%def name="main()"> | |
|
16 | ||
|
17 | <div class="box"> | |
|
18 | <!-- box / title --> | |
|
19 | <div class="title"> | |
|
20 | ${self.breadcrumbs()} | |
|
21 | </div> | |
|
22 | ||
|
23 | %for pr in c.pull_requests: | |
|
24 | <a href="${h.url('pullrequest_show',repo_name=c.repo_name,pull_request_id=pr.pull_request_id)}">#${pr.pull_request_id}</a> | |
|
25 | %endfor | |
|
26 | ||
|
27 | </div> | |
|
28 | ||
|
29 | <script type="text/javascript"></script> | |
|
30 | ||
|
31 | </%def> |
@@ -451,6 +451,12 b' def make_map(config):' | |||
|
451 | 451 | action='show', conditions=dict(function=check_repo, |
|
452 | 452 | method=["GET"])) |
|
453 | 453 | |
|
454 | rmap.connect('pullrequest_show_all', | |
|
455 | '/{repo_name:.*}/pull-request', | |
|
456 | controller='pullrequests', | |
|
457 | action='show_all', conditions=dict(function=check_repo, | |
|
458 | method=["GET"])) | |
|
459 | ||
|
454 | 460 | rmap.connect('summary_home', '/{repo_name:.*}/summary', |
|
455 | 461 | controller='summary', conditions=dict(function=check_repo)) |
|
456 | 462 |
@@ -295,7 +295,7 b' class ChangesetController(BaseRepoContro' | |||
|
295 | 295 | ) |
|
296 | 296 | |
|
297 | 297 | # count inline comments |
|
298 | for _, lines in c.inline_comments: | |
|
298 | for __, lines in c.inline_comments: | |
|
299 | 299 | for comments in lines.values(): |
|
300 | 300 | c.inline_cnt += len(comments) |
|
301 | 301 |
@@ -24,6 +24,9 b'' | |||
|
24 | 24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
25 | 25 | import logging |
|
26 | 26 | import traceback |
|
27 | import binascii | |
|
28 | ||
|
29 | from webob.exc import HTTPNotFound | |
|
27 | 30 | |
|
28 | 31 | from pylons import request, response, session, tmpl_context as c, url |
|
29 | 32 | from pylons.controllers.util import abort, redirect |
@@ -32,9 +35,13 b' from pylons.i18n.translation import _' | |||
|
32 | 35 | from rhodecode.lib.base import BaseRepoController, render |
|
33 | 36 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
34 | 37 | from rhodecode.lib import helpers as h |
|
35 |
from rhodecode. |
|
|
38 | from rhodecode.lib import diffs | |
|
39 | from rhodecode.model.db import User, PullRequest, Repository, ChangesetStatus | |
|
36 | 40 | from rhodecode.model.pull_request import PullRequestModel |
|
37 | 41 | from rhodecode.model.meta import Session |
|
42 | from rhodecode.model.repo import RepoModel | |
|
43 | from rhodecode.model.comment import ChangesetCommentsModel | |
|
44 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
|
38 | 45 | |
|
39 | 46 | log = logging.getLogger(__name__) |
|
40 | 47 | |
@@ -50,12 +57,12 b' class PullrequestsController(BaseRepoCon' | |||
|
50 | 57 | def _get_repo_refs(self, repo): |
|
51 | 58 | hist_l = [] |
|
52 | 59 | |
|
53 |
branches_group = ([('branch:' |
|
|
54 | _("Branches")) | |
|
55 |
bookmarks_group = ([('book:' |
|
|
56 | _("Bookmarks")) | |
|
57 |
tags_group = ([('tag:' |
|
|
58 | _("Tags")) | |
|
60 | branches_group = ([('branch:%s:%s' % (k, v), k) for | |
|
61 | k, v in repo.branches.iteritems()], _("Branches")) | |
|
62 | bookmarks_group = ([('book:%s:%s' % (k, v), k) for | |
|
63 | k, v in repo.bookmarks.iteritems()], _("Bookmarks")) | |
|
64 | tags_group = ([('tag:%s:%s' % (k, v), k) for | |
|
65 | k, v in repo.tags.iteritems()], _("Tags")) | |
|
59 | 66 | |
|
60 | 67 | hist_l.append(bookmarks_group) |
|
61 | 68 | hist_l.append(branches_group) |
@@ -63,6 +70,11 b' class PullrequestsController(BaseRepoCon' | |||
|
63 | 70 | |
|
64 | 71 | return hist_l |
|
65 | 72 | |
|
73 | def show_all(self, repo_name): | |
|
74 | c.pull_requests = PullRequestModel().get_all(repo_name) | |
|
75 | c.repo_name = repo_name | |
|
76 | return render('/pullrequests/pullrequest_show_all.html') | |
|
77 | ||
|
66 | 78 | def index(self): |
|
67 | 79 | org_repo = c.rhodecode_db_repo |
|
68 | 80 | c.org_refs = self._get_repo_refs(c.rhodecode_repo) |
@@ -128,6 +140,118 b' class PullrequestsController(BaseRepoCon' | |||
|
128 | 140 | |
|
129 | 141 | return redirect(url('changelog_home', repo_name=repo_name)) |
|
130 | 142 | |
|
143 | def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp): | |
|
144 | changesets = [] | |
|
145 | #case two independent repos | |
|
146 | if org_repo != other_repo: | |
|
147 | common, incoming, rheads = tmp | |
|
148 | ||
|
149 | if not incoming: | |
|
150 | revs = [] | |
|
151 | else: | |
|
152 | revs = org_repo._repo.changelog.findmissing(common, rheads) | |
|
153 | ||
|
154 | for cs in reversed(map(binascii.hexlify, revs)): | |
|
155 | changesets.append(org_repo.get_changeset(cs)) | |
|
156 | else: | |
|
157 | revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1], | |
|
158 | other_ref[1])] | |
|
159 | from mercurial import scmutil | |
|
160 | out = scmutil.revrange(org_repo._repo, revs) | |
|
161 | for cs in reversed(out): | |
|
162 | changesets.append(org_repo.get_changeset(cs)) | |
|
163 | ||
|
164 | return changesets | |
|
165 | ||
|
166 | def _get_discovery(self, org_repo, org_ref, other_repo, other_ref): | |
|
167 | from mercurial import discovery | |
|
168 | other = org_repo._repo | |
|
169 | repo = other_repo._repo | |
|
170 | tip = other[org_ref[1]] | |
|
171 | log.debug('Doing discovery for %s@%s vs %s@%s' % ( | |
|
172 | org_repo, org_ref, other_repo, other_ref) | |
|
173 | ) | |
|
174 | log.debug('Filter heads are %s[%s]' % (tip, org_ref[1])) | |
|
175 | tmp = discovery.findcommonincoming( | |
|
176 | repo=repo, # other_repo we check for incoming | |
|
177 | remote=other, # org_repo source for incoming | |
|
178 | heads=[tip.node()], | |
|
179 | force=False | |
|
180 | ) | |
|
181 | return tmp | |
|
182 | ||
|
183 | def _compare(self, pull_request): | |
|
184 | ||
|
185 | org_repo = pull_request.org_repo | |
|
186 | org_ref_type, org_ref_, org_ref = pull_request.org_ref.split(':') | |
|
187 | other_repo = pull_request.other_repo | |
|
188 | other_ref_type, other_ref, other_ref_ = pull_request.other_ref.split(':') | |
|
189 | ||
|
190 | org_ref = (org_ref_type, org_ref) | |
|
191 | other_ref = (other_ref_type, other_ref) | |
|
192 | ||
|
193 | c.org_repo = org_repo | |
|
194 | c.other_repo = other_repo | |
|
195 | ||
|
196 | discovery_data = self._get_discovery(org_repo.scm_instance, | |
|
197 | org_ref, | |
|
198 | other_repo.scm_instance, | |
|
199 | other_ref) | |
|
200 | c.cs_ranges = self._get_changesets(org_repo.scm_instance, | |
|
201 | org_ref, | |
|
202 | other_repo.scm_instance, | |
|
203 | other_ref, | |
|
204 | discovery_data) | |
|
205 | ||
|
206 | c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in | |
|
207 | c.cs_ranges]) | |
|
208 | # defines that we need hidden inputs with changesets | |
|
209 | c.as_form = request.GET.get('as_form', False) | |
|
210 | if request.environ.get('HTTP_X_PARTIAL_XHR'): | |
|
211 | return render('compare/compare_cs.html') | |
|
212 | ||
|
213 | c.org_ref = org_ref[1] | |
|
214 | c.other_ref = other_ref[1] | |
|
215 | # diff needs to have swapped org with other to generate proper diff | |
|
216 | _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref, | |
|
217 | discovery_data) | |
|
218 | diff_processor = diffs.DiffProcessor(_diff, format='gitdiff') | |
|
219 | _parsed = diff_processor.prepare() | |
|
220 | ||
|
221 | c.files = [] | |
|
222 | c.changes = {} | |
|
223 | ||
|
224 | for f in _parsed: | |
|
225 | fid = h.FID('', f['filename']) | |
|
226 | c.files.append([fid, f['operation'], f['filename'], f['stats']]) | |
|
227 | diff = diff_processor.as_html(enable_comments=False, diff_lines=[f]) | |
|
228 | c.changes[fid] = [f['operation'], f['filename'], diff] | |
|
229 | ||
|
131 | 230 | def show(self, repo_name, pull_request_id): |
|
231 | repo_model = RepoModel() | |
|
232 | c.users_array = repo_model.get_users_js() | |
|
233 | c.users_groups_array = repo_model.get_users_groups_js() | |
|
132 | 234 | c.pull_request = PullRequest.get(pull_request_id) |
|
235 | ##TODO: need more generic solution | |
|
236 | self._compare(c.pull_request) | |
|
237 | ||
|
238 | # inline comments | |
|
239 | c.inline_cnt = 0 | |
|
240 | c.inline_comments = ChangesetCommentsModel()\ | |
|
241 | .get_inline_comments(c.rhodecode_db_repo.repo_id, | |
|
242 | pull_request=pull_request_id) | |
|
243 | # count inline comments | |
|
244 | for __, lines in c.inline_comments: | |
|
245 | for comments in lines.values(): | |
|
246 | c.inline_cnt += len(comments) | |
|
247 | # comments | |
|
248 | c.comments = ChangesetCommentsModel()\ | |
|
249 | .get_comments(c.rhodecode_db_repo.repo_id, | |
|
250 | pull_request=pull_request_id) | |
|
251 | ||
|
252 | # changeset(pull-request) statuse | |
|
253 | c.current_changeset_status = ChangesetStatusModel()\ | |
|
254 | .get_status(c.rhodecode_db_repo.repo_id, | |
|
255 | pull_request=pull_request_id) | |
|
256 | c.changeset_statuses = ChangesetStatus.STATUSES | |
|
133 | 257 | return render('/pullrequests/pullrequest_show.html') |
@@ -204,7 +204,7 b' class BaseRepoController(BaseController)' | |||
|
204 | 204 | super(BaseRepoController, self).__before__() |
|
205 | 205 | if c.repo_name: |
|
206 | 206 | |
|
207 | c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name) | |
|
207 | dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name) | |
|
208 | 208 | c.rhodecode_repo = c.rhodecode_db_repo.scm_instance |
|
209 | 209 | |
|
210 | 210 | if c.rhodecode_repo is None: |
@@ -213,5 +213,7 b' class BaseRepoController(BaseController)' | |||
|
213 | 213 | |
|
214 | 214 | redirect(url('home')) |
|
215 | 215 | |
|
216 | c.repository_followers = self.scm_model.get_followers(c.repo_name) | |
|
217 |
c.repository_for |
|
|
216 | # some globals counter for menu | |
|
217 | c.repository_followers = self.scm_model.get_followers(dbr) | |
|
218 | c.repository_forks = self.scm_model.get_forks(dbr) | |
|
219 | c.repository_pull_requests = self.scm_model.get_pull_requests(dbr) No newline at end of file |
@@ -26,7 +26,7 b'' | |||
|
26 | 26 | import logging |
|
27 | 27 | |
|
28 | 28 | from rhodecode.model import BaseModel |
|
29 | from rhodecode.model.db import ChangesetStatus | |
|
29 | from rhodecode.model.db import ChangesetStatus, PullRequest | |
|
30 | 30 | |
|
31 | 31 | log = logging.getLogger(__name__) |
|
32 | 32 | |
@@ -36,23 +36,37 b' class ChangesetStatusModel(BaseModel):' | |||
|
36 | 36 | def __get_changeset_status(self, changeset_status): |
|
37 | 37 | return self._get_instance(ChangesetStatus, changeset_status) |
|
38 | 38 | |
|
39 |
def |
|
|
39 | def __get_pull_request(self, pull_request): | |
|
40 | return self._get_instance(PullRequest, pull_request) | |
|
41 | ||
|
42 | def get_status(self, repo, revision=None, pull_request=None): | |
|
40 | 43 | """ |
|
41 |
Returns status of changeset for given revision |
|
|
42 | versioning makes a history of statuses, and version == 0 is always the | |
|
43 | current one | |
|
44 | Returns latest status of changeset for given revision or for given | |
|
45 | pull request. Statuses are versioned inside a table itself and | |
|
46 | version == 0 is always the current one | |
|
44 | 47 | |
|
45 | 48 | :param repo: |
|
46 | 49 | :type repo: |
|
47 | :param revision: 40char hash | |
|
50 | :param revision: 40char hash or None | |
|
48 | 51 | :type revision: str |
|
52 | :param pull_request: pull_request reference | |
|
53 | :type: | |
|
49 | 54 | """ |
|
50 | 55 | repo = self._get_repo(repo) |
|
51 | 56 | |
|
52 |
|
|
|
57 | q = ChangesetStatus.query()\ | |
|
53 | 58 | .filter(ChangesetStatus.repo == repo)\ |
|
54 |
.filter(ChangesetStatus.r |
|
|
55 | .filter(ChangesetStatus.version == 0).scalar() | |
|
59 | .filter(ChangesetStatus.version == 0) | |
|
60 | ||
|
61 | if revision: | |
|
62 | q = q.filter(ChangesetStatus.revision == revision) | |
|
63 | elif pull_request: | |
|
64 | pull_request = self.__get_pull_request(pull_request) | |
|
65 | q = q.filter(ChangesetStatus.pull_request == pull_request) | |
|
66 | else: | |
|
67 | raise Exception('Please specify revision or pull_request') | |
|
68 | ||
|
69 | status = q.scalar() | |
|
56 | 70 | status = status.status if status else status |
|
57 | 71 | st = status or ChangesetStatus.DEFAULT |
|
58 | 72 | return str(st) |
@@ -32,7 +32,8 b' from sqlalchemy.util.compat import defau' | |||
|
32 | 32 | from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode |
|
33 | 33 | from rhodecode.lib import helpers as h |
|
34 | 34 | from rhodecode.model import BaseModel |
|
35 |
from rhodecode.model.db import ChangesetComment, User, Repository, |
|
|
35 | from rhodecode.model.db import ChangesetComment, User, Repository, \ | |
|
36 | Notification, PullRequest | |
|
36 | 37 | from rhodecode.model.notification import NotificationModel |
|
37 | 38 | |
|
38 | 39 | log = logging.getLogger(__name__) |
@@ -43,6 +44,9 b' class ChangesetCommentsModel(BaseModel):' | |||
|
43 | 44 | def __get_changeset_comment(self, changeset_comment): |
|
44 | 45 | return self._get_instance(ChangesetComment, changeset_comment) |
|
45 | 46 | |
|
47 | def __get_pull_request(self, pull_request): | |
|
48 | return self._get_instance(PullRequest, pull_request) | |
|
49 | ||
|
46 | 50 | def _extract_mentions(self, s): |
|
47 | 51 | user_objects = [] |
|
48 | 52 | for username in extract_mentioned_users(s): |
@@ -135,7 +139,7 b' class ChangesetCommentsModel(BaseModel):' | |||
|
135 | 139 | |
|
136 | 140 | return comment |
|
137 | 141 | |
|
138 |
def get_comments(self, repo_id, revision=None, pull_request |
|
|
142 | def get_comments(self, repo_id, revision=None, pull_request=None): | |
|
139 | 143 | """ |
|
140 | 144 | Get's main comments based on revision or pull_request_id |
|
141 | 145 | |
@@ -143,22 +147,24 b' class ChangesetCommentsModel(BaseModel):' | |||
|
143 | 147 | :type repo_id: |
|
144 | 148 | :param revision: |
|
145 | 149 | :type revision: |
|
146 |
:param pull_request |
|
|
147 |
:type pull_request |
|
|
150 | :param pull_request: | |
|
151 | :type pull_request: | |
|
148 | 152 | """ |
|
153 | ||
|
149 | 154 | q = ChangesetComment.query()\ |
|
150 | 155 | .filter(ChangesetComment.repo_id == repo_id)\ |
|
151 | 156 | .filter(ChangesetComment.line_no == None)\ |
|
152 | 157 | .filter(ChangesetComment.f_path == None) |
|
153 | 158 | if revision: |
|
154 | 159 | q = q.filter(ChangesetComment.revision == revision) |
|
155 |
elif pull_request |
|
|
156 | q = q.filter(ChangesetComment.pull_request_id == pull_request_id) | |
|
160 | elif pull_request: | |
|
161 | pull_request = self.__get_pull_request(pull_request) | |
|
162 | q = q.filter(ChangesetComment.pull_request == pull_request) | |
|
157 | 163 | else: |
|
158 |
raise Exception('Please specify revision or pull_request |
|
|
164 | raise Exception('Please specify revision or pull_request') | |
|
159 | 165 | return q.all() |
|
160 | 166 | |
|
161 |
def get_inline_comments(self, repo_id, revision=None, pull_request |
|
|
167 | def get_inline_comments(self, repo_id, revision=None, pull_request=None): | |
|
162 | 168 | q = self.sa.query(ChangesetComment)\ |
|
163 | 169 | .filter(ChangesetComment.repo_id == repo_id)\ |
|
164 | 170 | .filter(ChangesetComment.line_no != None)\ |
@@ -167,8 +173,9 b' class ChangesetCommentsModel(BaseModel):' | |||
|
167 | 173 | |
|
168 | 174 | if revision: |
|
169 | 175 | q = q.filter(ChangesetComment.revision == revision) |
|
170 |
elif pull_request |
|
|
171 | q = q.filter(ChangesetComment.pull_request_id == pull_request_id) | |
|
176 | elif pull_request: | |
|
177 | pull_request = self.__get_pull_request(pull_request) | |
|
178 | q = q.filter(ChangesetComment.pull_request == pull_request) | |
|
172 | 179 | else: |
|
173 | 180 | raise Exception('Please specify revision or pull_request_id') |
|
174 | 181 |
@@ -1322,7 +1322,8 b' class ChangesetComment(Base, BaseModel):' | |||
|
1322 | 1322 | ) |
|
1323 | 1323 | comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) |
|
1324 | 1324 | repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) |
|
1325 |
revision = Column('revision', String(40), nullable= |
|
|
1325 | revision = Column('revision', String(40), nullable=True) | |
|
1326 | pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) | |
|
1326 | 1327 | line_no = Column('line_no', Unicode(10), nullable=True) |
|
1327 | 1328 | f_path = Column('f_path', Unicode(1000), nullable=True) |
|
1328 | 1329 | user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) |
@@ -1332,6 +1333,7 b' class ChangesetComment(Base, BaseModel):' | |||
|
1332 | 1333 | author = relationship('User', lazy='joined') |
|
1333 | 1334 | repo = relationship('Repository') |
|
1334 | 1335 | status_change = relationship('ChangesetStatus', uselist=False) |
|
1336 | pull_request = relationship('PullRequest', lazy='joined') | |
|
1335 | 1337 | |
|
1336 | 1338 | @classmethod |
|
1337 | 1339 | def get_users(cls, revision): |
@@ -1397,6 +1399,8 b' class PullRequest(Base, BaseModel):' | |||
|
1397 | 1399 | pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) |
|
1398 | 1400 | title = Column('title', Unicode(256), nullable=True) |
|
1399 | 1401 | description = Column('description', Unicode(10240), nullable=True) |
|
1402 | created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) | |
|
1403 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) | |
|
1400 | 1404 | _revisions = Column('revisions', UnicodeText(20500)) # 500 revisions max |
|
1401 | 1405 | org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) |
|
1402 | 1406 | org_ref = Column('org_ref', Unicode(256), nullable=False) |
@@ -1411,6 +1415,7 b' class PullRequest(Base, BaseModel):' | |||
|
1411 | 1415 | def revisions(self, val): |
|
1412 | 1416 | self._revisions = ':'.join(val) |
|
1413 | 1417 | |
|
1418 | author = relationship('User', lazy='joined') | |
|
1414 | 1419 | reviewers = relationship('PullRequestReviewers') |
|
1415 | 1420 | org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') |
|
1416 | 1421 | other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') |
@@ -37,8 +37,13 b' log = logging.getLogger(__name__)' | |||
|
37 | 37 | |
|
38 | 38 | class PullRequestModel(BaseModel): |
|
39 | 39 | |
|
40 | def get_all(self, repo): | |
|
41 | repo = self._get_repo(repo) | |
|
42 | return PullRequest.query().filter(PullRequest.other_repo == repo).all() | |
|
43 | ||
|
40 | 44 | def create(self, created_by, org_repo, org_ref, other_repo, |
|
41 | 45 | other_ref, revisions, reviewers, title, description=None): |
|
46 | created_by_user = self._get_user(created_by) | |
|
42 | 47 | |
|
43 | 48 | new = PullRequest() |
|
44 | 49 | new.org_repo = self._get_repo(org_repo) |
@@ -48,7 +53,7 b' class PullRequestModel(BaseModel):' | |||
|
48 | 53 | new.revisions = revisions |
|
49 | 54 | new.title = title |
|
50 | 55 | new.description = description |
|
51 | ||
|
56 | new.author = created_by_user | |
|
52 | 57 | self.sa.add(new) |
|
53 | 58 | |
|
54 | 59 | #members |
@@ -59,7 +64,7 b' class PullRequestModel(BaseModel):' | |||
|
59 | 64 | |
|
60 | 65 | #notification to reviewers |
|
61 | 66 | notif = NotificationModel() |
|
62 | created_by_user = self._get_user(created_by) | |
|
67 | ||
|
63 | 68 | subject = safe_unicode( |
|
64 | 69 | h.link_to( |
|
65 | 70 | _('%(user)s wants you to review pull request #%(pr_id)s') % \ |
@@ -43,7 +43,7 b' from rhodecode.lib.utils import get_repo' | |||
|
43 | 43 | action_logger, EmptyChangeset, REMOVED_REPO_PAT |
|
44 | 44 | from rhodecode.model import BaseModel |
|
45 | 45 | from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \ |
|
46 | UserFollowing, UserLog, User, RepoGroup | |
|
46 | UserFollowing, UserLog, User, RepoGroup, PullRequest | |
|
47 | 47 | |
|
48 | 48 | log = logging.getLogger(__name__) |
|
49 | 49 | |
@@ -320,19 +320,21 b' class ScmModel(BaseModel):' | |||
|
320 | 320 | |
|
321 | 321 | return f is not None |
|
322 | 322 | |
|
323 |
def get_followers(self, repo |
|
|
324 | if not isinstance(repo_id, int): | |
|
325 | repo_id = getattr(Repository.get_by_repo_name(repo_id), 'repo_id') | |
|
323 | def get_followers(self, repo): | |
|
324 | repo = self._get_repo(repo) | |
|
326 | 325 | |
|
327 | 326 | return self.sa.query(UserFollowing)\ |
|
328 |
.filter(UserFollowing.follows_repo |
|
|
327 | .filter(UserFollowing.follows_repository == repo).count() | |
|
329 | 328 | |
|
330 |
def get_forks(self, repo |
|
|
331 | if not isinstance(repo_id, int): | |
|
332 | repo_id = getattr(Repository.get_by_repo_name(repo_id), 'repo_id') | |
|
329 | def get_forks(self, repo): | |
|
330 | repo = self._get_repo(repo) | |
|
331 | return self.sa.query(Repository)\ | |
|
332 | .filter(Repository.fork == repo).count() | |
|
333 | 333 | |
|
334 | return self.sa.query(Repository)\ | |
|
335 | .filter(Repository.fork_id == repo_id).count() | |
|
334 | def get_pull_requests(self, repo): | |
|
335 | repo = self._get_repo(repo) | |
|
336 | return self.sa.query(PullRequest)\ | |
|
337 | .filter(PullRequest.other_repo == repo).count() | |
|
336 | 338 | |
|
337 | 339 | def mark_as_fork(self, repo, fork, user): |
|
338 | 340 | repo = self.__get_repo(repo) |
@@ -247,6 +247,14 b'' | |||
|
247 | 247 | <span class="short">${c.repository_forks}</span> |
|
248 | 248 | </a> |
|
249 | 249 | </li> |
|
250 | <li> | |
|
251 | <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}"> | |
|
252 | <span class="icon_short"> | |
|
253 | <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" /> | |
|
254 | </span> | |
|
255 | <span class="short">${c.repository_pull_requests}</span> | |
|
256 | </a> | |
|
257 | </li> | |
|
250 | 258 | ${usermenu()} |
|
251 | 259 | </ul> |
|
252 | 260 | <script type="text/javascript"> |
@@ -20,8 +20,59 b'' | |||
|
20 | 20 | ${self.breadcrumbs()} |
|
21 | 21 | </div> |
|
22 | 22 | |
|
23 | pull request ${c.pull_request} overview... | |
|
23 | <h3>${_('Title')}: ${c.pull_request.title}</h3> | |
|
24 | <div class="changeset-status-container" style="float:left;padding:0px 20px 20px 20px"> | |
|
25 | %if c.current_changeset_status: | |
|
26 | <div title="${_('Changeset status')}" class="changeset-status-lbl">[${h.changeset_status_lbl(c.current_changeset_status)}]</div> | |
|
27 | <div class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.current_changeset_status)}" /></div> | |
|
28 | %endif | |
|
29 | </div> | |
|
30 | <div style="padding:4px"> | |
|
31 | <div>${h.fmt_date(c.pull_request.created_on)}</div> | |
|
32 | </div> | |
|
33 | ||
|
34 | ##DIFF | |
|
35 | ||
|
36 | <div class="table"> | |
|
37 | <div id="body" class="diffblock"> | |
|
38 | <div style="white-space:pre-wrap;padding:5px">${h.literal(c.pull_request.description)}</div> | |
|
39 | </div> | |
|
40 | <div id="changeset_compare_view_content"> | |
|
41 | ##CS | |
|
42 | <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Incoming changesets')}</div> | |
|
43 | <%include file="/compare/compare_cs.html" /> | |
|
24 | 44 | |
|
45 | ## FILES | |
|
46 | <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Files affected')}</div> | |
|
47 | <div class="cs_files"> | |
|
48 | %for fid, change, f, stat in c.files: | |
|
49 | <div class="cs_${change}"> | |
|
50 | <div class="node">${h.link_to(h.safe_unicode(f),h.url.current(anchor=fid))}</div> | |
|
51 | <div class="changes">${h.fancy_file_stats(stat)}</div> | |
|
52 | </div> | |
|
53 | %endfor | |
|
54 | </div> | |
|
55 | </div> | |
|
56 | </div> | |
|
57 | <script> | |
|
58 | var _USERS_AC_DATA = ${c.users_array|n}; | |
|
59 | var _GROUPS_AC_DATA = ${c.users_groups_array|n}; | |
|
60 | </script> | |
|
61 | ||
|
62 | ## diff block | |
|
63 | <%namespace name="diff_block" file="/changeset/diff_block.html"/> | |
|
64 | %for fid, change, f, stat in c.files: | |
|
65 | ${diff_block.diff_block_simple([c.changes[fid]])} | |
|
66 | %endfor | |
|
67 | ||
|
68 | ## template for inline comment form | |
|
69 | <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> | |
|
70 | ##${comment.comment_inline_form(c.changeset)} | |
|
71 | ||
|
72 | ## render comments main comments form and it status | |
|
73 | ##${comment.comments(h.url('pull_request_comment', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id), | |
|
74 | ## c.current_changeset_status)} | |
|
75 | ||
|
25 | 76 | </div> |
|
26 | 77 | |
|
27 | 78 | <script type="text/javascript"> |
General Comments 0
You need to be logged in to leave comments.
Login now