##// END OF EJS Templates
- pull request generates overview based on it's params...
marcink -
r2440:1bc579bc codereview
parent child Browse files
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 &raquo;
10 ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))}
11 &raquo;
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 action='show', conditions=dict(function=check_repo,
451 action='show', conditions=dict(function=check_repo,
452 method=["GET"]))
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 rmap.connect('summary_home', '/{repo_name:.*}/summary',
460 rmap.connect('summary_home', '/{repo_name:.*}/summary',
455 controller='summary', conditions=dict(function=check_repo))
461 controller='summary', conditions=dict(function=check_repo))
456
462
@@ -295,7 +295,7 b' class ChangesetController(BaseRepoContro'
295 )
295 )
296
296
297 # count inline comments
297 # count inline comments
298 for _, lines in c.inline_comments:
298 for __, lines in c.inline_comments:
299 for comments in lines.values():
299 for comments in lines.values():
300 c.inline_cnt += len(comments)
300 c.inline_cnt += len(comments)
301
301
@@ -24,6 +24,9 b''
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 import logging
25 import logging
26 import traceback
26 import traceback
27 import binascii
28
29 from webob.exc import HTTPNotFound
27
30
28 from pylons import request, response, session, tmpl_context as c, url
31 from pylons import request, response, session, tmpl_context as c, url
29 from pylons.controllers.util import abort, redirect
32 from pylons.controllers.util import abort, redirect
@@ -32,9 +35,13 b' from pylons.i18n.translation import _'
32 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
35 from rhodecode.model.db import User, PullRequest
38 from rhodecode.lib import diffs
39 from rhodecode.model.db import User, PullRequest, Repository, ChangesetStatus
36 from rhodecode.model.pull_request import PullRequestModel
40 from rhodecode.model.pull_request import PullRequestModel
37 from rhodecode.model.meta import Session
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 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
40
47
@@ -50,12 +57,12 b' class PullrequestsController(BaseRepoCon'
50 def _get_repo_refs(self, repo):
57 def _get_repo_refs(self, repo):
51 hist_l = []
58 hist_l = []
52
59
53 branches_group = ([('branch:' + k, k) for k in repo.branches.keys()],
60 branches_group = ([('branch:%s:%s' % (k, v), k) for
54 _("Branches"))
61 k, v in repo.branches.iteritems()], _("Branches"))
55 bookmarks_group = ([('book:' + k, k) for k in repo.bookmarks.keys()],
62 bookmarks_group = ([('book:%s:%s' % (k, v), k) for
56 _("Bookmarks"))
63 k, v in repo.bookmarks.iteritems()], _("Bookmarks"))
57 tags_group = ([('tag:' + k, k) for k in repo.tags.keys()],
64 tags_group = ([('tag:%s:%s' % (k, v), k) for
58 _("Tags"))
65 k, v in repo.tags.iteritems()], _("Tags"))
59
66
60 hist_l.append(bookmarks_group)
67 hist_l.append(bookmarks_group)
61 hist_l.append(branches_group)
68 hist_l.append(branches_group)
@@ -63,6 +70,11 b' class PullrequestsController(BaseRepoCon'
63
70
64 return hist_l
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 def index(self):
78 def index(self):
67 org_repo = c.rhodecode_db_repo
79 org_repo = c.rhodecode_db_repo
68 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
80 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
@@ -128,6 +140,118 b' class PullrequestsController(BaseRepoCon'
128
140
129 return redirect(url('changelog_home', repo_name=repo_name))
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 def show(self, repo_name, pull_request_id):
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 c.pull_request = PullRequest.get(pull_request_id)
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 return render('/pullrequests/pullrequest_show.html')
257 return render('/pullrequests/pullrequest_show.html')
@@ -204,7 +204,7 b' class BaseRepoController(BaseController)'
204 super(BaseRepoController, self).__before__()
204 super(BaseRepoController, self).__before__()
205 if c.repo_name:
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 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
208 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
209
209
210 if c.rhodecode_repo is None:
210 if c.rhodecode_repo is None:
@@ -213,5 +213,7 b' class BaseRepoController(BaseController)'
213
213
214 redirect(url('home'))
214 redirect(url('home'))
215
215
216 c.repository_followers = self.scm_model.get_followers(c.repo_name)
216 # some globals counter for menu
217 c.repository_forks = self.scm_model.get_forks(c.repo_name)
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 import logging
26 import logging
27
27
28 from rhodecode.model import BaseModel
28 from rhodecode.model import BaseModel
29 from rhodecode.model.db import ChangesetStatus
29 from rhodecode.model.db import ChangesetStatus, PullRequest
30
30
31 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
32
32
@@ -36,23 +36,37 b' class ChangesetStatusModel(BaseModel):'
36 def __get_changeset_status(self, changeset_status):
36 def __get_changeset_status(self, changeset_status):
37 return self._get_instance(ChangesetStatus, changeset_status)
37 return self._get_instance(ChangesetStatus, changeset_status)
38
38
39 def get_status(self, repo, revision):
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 and version 0
44 Returns latest status of changeset for given revision or for given
42 versioning makes a history of statuses, and version == 0 is always the
45 pull request. Statuses are versioned inside a table itself and
43 current one
46 version == 0 is always the current one
44
47
45 :param repo:
48 :param repo:
46 :type repo:
49 :type repo:
47 :param revision: 40char hash
50 :param revision: 40char hash or None
48 :type revision: str
51 :type revision: str
52 :param pull_request: pull_request reference
53 :type:
49 """
54 """
50 repo = self._get_repo(repo)
55 repo = self._get_repo(repo)
51
56
52 status = ChangesetStatus.query()\
57 q = ChangesetStatus.query()\
53 .filter(ChangesetStatus.repo == repo)\
58 .filter(ChangesetStatus.repo == repo)\
54 .filter(ChangesetStatus.revision == revision)\
59 .filter(ChangesetStatus.version == 0)
55 .filter(ChangesetStatus.version == 0).scalar()
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 status = status.status if status else status
70 status = status.status if status else status
57 st = status or ChangesetStatus.DEFAULT
71 st = status or ChangesetStatus.DEFAULT
58 return str(st)
72 return str(st)
@@ -32,7 +32,8 b' from sqlalchemy.util.compat import defau'
32 from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode
32 from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode
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 ChangesetComment, User, Repository, Notification
35 from rhodecode.model.db import ChangesetComment, User, Repository, \
36 Notification, PullRequest
36 from rhodecode.model.notification import NotificationModel
37 from rhodecode.model.notification import NotificationModel
37
38
38 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
@@ -43,6 +44,9 b' class ChangesetCommentsModel(BaseModel):'
43 def __get_changeset_comment(self, changeset_comment):
44 def __get_changeset_comment(self, changeset_comment):
44 return self._get_instance(ChangesetComment, changeset_comment)
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 def _extract_mentions(self, s):
50 def _extract_mentions(self, s):
47 user_objects = []
51 user_objects = []
48 for username in extract_mentioned_users(s):
52 for username in extract_mentioned_users(s):
@@ -135,7 +139,7 b' class ChangesetCommentsModel(BaseModel):'
135
139
136 return comment
140 return comment
137
141
138 def get_comments(self, repo_id, revision=None, pull_request_id=None):
142 def get_comments(self, repo_id, revision=None, pull_request=None):
139 """
143 """
140 Get's main comments based on revision or pull_request_id
144 Get's main comments based on revision or pull_request_id
141
145
@@ -143,22 +147,24 b' class ChangesetCommentsModel(BaseModel):'
143 :type repo_id:
147 :type repo_id:
144 :param revision:
148 :param revision:
145 :type revision:
149 :type revision:
146 :param pull_request_id:
150 :param pull_request:
147 :type pull_request_id:
151 :type pull_request:
148 """
152 """
153
149 q = ChangesetComment.query()\
154 q = ChangesetComment.query()\
150 .filter(ChangesetComment.repo_id == repo_id)\
155 .filter(ChangesetComment.repo_id == repo_id)\
151 .filter(ChangesetComment.line_no == None)\
156 .filter(ChangesetComment.line_no == None)\
152 .filter(ChangesetComment.f_path == None)
157 .filter(ChangesetComment.f_path == None)
153 if revision:
158 if revision:
154 q = q.filter(ChangesetComment.revision == revision)
159 q = q.filter(ChangesetComment.revision == revision)
155 elif pull_request_id:
160 elif pull_request:
156 q = q.filter(ChangesetComment.pull_request_id == pull_request_id)
161 pull_request = self.__get_pull_request(pull_request)
162 q = q.filter(ChangesetComment.pull_request == pull_request)
157 else:
163 else:
158 raise Exception('Please specify revision or pull_request_id')
164 raise Exception('Please specify revision or pull_request')
159 return q.all()
165 return q.all()
160
166
161 def get_inline_comments(self, repo_id, revision=None, pull_request_id=None):
167 def get_inline_comments(self, repo_id, revision=None, pull_request=None):
162 q = self.sa.query(ChangesetComment)\
168 q = self.sa.query(ChangesetComment)\
163 .filter(ChangesetComment.repo_id == repo_id)\
169 .filter(ChangesetComment.repo_id == repo_id)\
164 .filter(ChangesetComment.line_no != None)\
170 .filter(ChangesetComment.line_no != None)\
@@ -167,8 +173,9 b' class ChangesetCommentsModel(BaseModel):'
167
173
168 if revision:
174 if revision:
169 q = q.filter(ChangesetComment.revision == revision)
175 q = q.filter(ChangesetComment.revision == revision)
170 elif pull_request_id:
176 elif pull_request:
171 q = q.filter(ChangesetComment.pull_request_id == pull_request_id)
177 pull_request = self.__get_pull_request(pull_request)
178 q = q.filter(ChangesetComment.pull_request == pull_request)
172 else:
179 else:
173 raise Exception('Please specify revision or pull_request_id')
180 raise Exception('Please specify revision or pull_request_id')
174
181
@@ -1322,7 +1322,8 b' class ChangesetComment(Base, BaseModel):'
1322 )
1322 )
1323 comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
1323 comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
1324 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1324 repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1325 revision = Column('revision', String(40), nullable=False)
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 line_no = Column('line_no', Unicode(10), nullable=True)
1327 line_no = Column('line_no', Unicode(10), nullable=True)
1327 f_path = Column('f_path', Unicode(1000), nullable=True)
1328 f_path = Column('f_path', Unicode(1000), nullable=True)
1328 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
1329 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
@@ -1332,6 +1333,7 b' class ChangesetComment(Base, BaseModel):'
1332 author = relationship('User', lazy='joined')
1333 author = relationship('User', lazy='joined')
1333 repo = relationship('Repository')
1334 repo = relationship('Repository')
1334 status_change = relationship('ChangesetStatus', uselist=False)
1335 status_change = relationship('ChangesetStatus', uselist=False)
1336 pull_request = relationship('PullRequest', lazy='joined')
1335
1337
1336 @classmethod
1338 @classmethod
1337 def get_users(cls, revision):
1339 def get_users(cls, revision):
@@ -1397,6 +1399,8 b' class PullRequest(Base, BaseModel):'
1397 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
1399 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
1398 title = Column('title', Unicode(256), nullable=True)
1400 title = Column('title', Unicode(256), nullable=True)
1399 description = Column('description', Unicode(10240), nullable=True)
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 _revisions = Column('revisions', UnicodeText(20500)) # 500 revisions max
1404 _revisions = Column('revisions', UnicodeText(20500)) # 500 revisions max
1401 org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1405 org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
1402 org_ref = Column('org_ref', Unicode(256), nullable=False)
1406 org_ref = Column('org_ref', Unicode(256), nullable=False)
@@ -1411,6 +1415,7 b' class PullRequest(Base, BaseModel):'
1411 def revisions(self, val):
1415 def revisions(self, val):
1412 self._revisions = ':'.join(val)
1416 self._revisions = ':'.join(val)
1413
1417
1418 author = relationship('User', lazy='joined')
1414 reviewers = relationship('PullRequestReviewers')
1419 reviewers = relationship('PullRequestReviewers')
1415 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1420 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
1416 other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
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 class PullRequestModel(BaseModel):
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 def create(self, created_by, org_repo, org_ref, other_repo,
44 def create(self, created_by, org_repo, org_ref, other_repo,
41 other_ref, revisions, reviewers, title, description=None):
45 other_ref, revisions, reviewers, title, description=None):
46 created_by_user = self._get_user(created_by)
42
47
43 new = PullRequest()
48 new = PullRequest()
44 new.org_repo = self._get_repo(org_repo)
49 new.org_repo = self._get_repo(org_repo)
@@ -48,7 +53,7 b' class PullRequestModel(BaseModel):'
48 new.revisions = revisions
53 new.revisions = revisions
49 new.title = title
54 new.title = title
50 new.description = description
55 new.description = description
51
56 new.author = created_by_user
52 self.sa.add(new)
57 self.sa.add(new)
53
58
54 #members
59 #members
@@ -59,7 +64,7 b' class PullRequestModel(BaseModel):'
59
64
60 #notification to reviewers
65 #notification to reviewers
61 notif = NotificationModel()
66 notif = NotificationModel()
62 created_by_user = self._get_user(created_by)
67
63 subject = safe_unicode(
68 subject = safe_unicode(
64 h.link_to(
69 h.link_to(
65 _('%(user)s wants you to review pull request #%(pr_id)s') % \
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 action_logger, EmptyChangeset, REMOVED_REPO_PAT
43 action_logger, EmptyChangeset, REMOVED_REPO_PAT
44 from rhodecode.model import BaseModel
44 from rhodecode.model import BaseModel
45 from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \
45 from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \
46 UserFollowing, UserLog, User, RepoGroup
46 UserFollowing, UserLog, User, RepoGroup, PullRequest
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
@@ -320,19 +320,21 b' class ScmModel(BaseModel):'
320
320
321 return f is not None
321 return f is not None
322
322
323 def get_followers(self, repo_id):
323 def get_followers(self, repo):
324 if not isinstance(repo_id, int):
324 repo = self._get_repo(repo)
325 repo_id = getattr(Repository.get_by_repo_name(repo_id), 'repo_id')
326
325
327 return self.sa.query(UserFollowing)\
326 return self.sa.query(UserFollowing)\
328 .filter(UserFollowing.follows_repo_id == repo_id).count()
327 .filter(UserFollowing.follows_repository == repo).count()
329
328
330 def get_forks(self, repo_id):
329 def get_forks(self, repo):
331 if not isinstance(repo_id, int):
330 repo = self._get_repo(repo)
332 repo_id = getattr(Repository.get_by_repo_name(repo_id), 'repo_id')
331 return self.sa.query(Repository)\
332 .filter(Repository.fork == repo).count()
333
333
334 return self.sa.query(Repository)\
334 def get_pull_requests(self, repo):
335 .filter(Repository.fork_id == repo_id).count()
335 repo = self._get_repo(repo)
336 return self.sa.query(PullRequest)\
337 .filter(PullRequest.other_repo == repo).count()
336
338
337 def mark_as_fork(self, repo, fork, user):
339 def mark_as_fork(self, repo, fork, user):
338 repo = self.__get_repo(repo)
340 repo = self.__get_repo(repo)
@@ -247,6 +247,14 b''
247 <span class="short">${c.repository_forks}</span>
247 <span class="short">${c.repository_forks}</span>
248 </a>
248 </a>
249 </li>
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 ${usermenu()}
258 ${usermenu()}
251 </ul>
259 </ul>
252 <script type="text/javascript">
260 <script type="text/javascript">
@@ -20,8 +20,59 b''
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 </div>
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 </div>
76 </div>
26
77
27 <script type="text/javascript">
78 <script type="text/javascript">
General Comments 0
You need to be logged in to leave comments. Login now