| | 79 | Index: trac/versioncontrol/web_ui/changeset.py |
|---|
| | 80 | =================================================================== |
|---|
| | 81 | --- trac/versioncontrol/web_ui/changeset.py (revision 5807) |
|---|
| | 82 | +++ trac/versioncontrol/web_ui/changeset.py (working copy) |
|---|
| | 83 | @@ -590,6 +590,8 @@ |
|---|
| | 84 | info = None |
|---|
| | 85 | changes.append(info) # the sequence should be immutable |
|---|
| | 86 | |
|---|
| | 87 | + data['backrefs'] = self._get_backrefs(context, rev) |
|---|
| | 88 | + |
|---|
| | 89 | data.update({'has_diffs': has_diffs, 'changes': changes, 'xhr': xhr, |
|---|
| | 90 | 'filestats': filestats, |
|---|
| | 91 | 'files': files, 'location': self._get_location(files), |
|---|
| | 92 | @@ -903,6 +905,44 @@ |
|---|
| | 93 | old=data['old_rev']) + query |
|---|
| | 94 | return tag.a(label, class_="changeset", title=title, href=href) |
|---|
| | 95 | |
|---|
| | 96 | + def _get_backrefs(self, context, rev): |
|---|
| | 97 | + cursor = context.db.cursor() |
|---|
| | 98 | + refs = [] |
|---|
| | 99 | + |
|---|
| | 100 | + cursor.execute("SELECT 'ticket', id, description " |
|---|
| | 101 | + "FROM ticket WHERE description LIKE '%%[%s]%%' " |
|---|
| | 102 | + " OR description LIKE '%%r%s%%' " |
|---|
| | 103 | + " OR description LIKE '%%changeset:%s%%' " |
|---|
| | 104 | + "UNION " |
|---|
| | 105 | + "SELECT 'ticket', t.id, newvalue " |
|---|
| | 106 | + "FROM ticket_change c JOIN ticket t on c.ticket = t.id " |
|---|
| | 107 | + "WHERE newvalue LIKE '%%[%s%%' " |
|---|
| | 108 | + " OR newvalue LIKE '%%r:%s%%' " |
|---|
| | 109 | + " OR newvalue LIKE '%%changeset:%s%%' " |
|---|
| | 110 | + "UNION " |
|---|
| | 111 | + "SELECT 'changeset', rev, message " |
|---|
| | 112 | + "FROM revision WHERE message LIKE '%%[%s]%%' " |
|---|
| | 113 | + " OR message LIKE '%%r:%s%%' " |
|---|
| | 114 | + " OR message LIKE '%%changeset:%s%%' " |
|---|
| | 115 | + "UNION " |
|---|
| | 116 | + "SELECT 'wiki', name, text " |
|---|
| | 117 | + "FROM wiki WHERE (text LIKE '%%[%s]%%' " |
|---|
| | 118 | + " OR text LIKE '%%r:%s%%' " |
|---|
| | 119 | + " OR text LIKE '%%changeset:%s%%' ) " |
|---|
| | 120 | + " AND version = (SELECT max(version) FROM wiki w " |
|---|
| | 121 | + " WHERE w.name = wiki.name) " |
|---|
| | 122 | + "ORDER BY 1 desc, 2" |
|---|
| | 123 | + % ((rev,) * 12)) |
|---|
| | 124 | + |
|---|
| | 125 | + self.env.log.info(rev) |
|---|
| | 126 | + for idx, row in enumerate(cursor): |
|---|
| | 127 | + rtyp, rid, text = row |
|---|
| | 128 | + self.env.log.info(row) |
|---|
| | 129 | + # check whether the link is an single word |
|---|
| | 130 | + if re.search(r"(\W|^)(\[|r:|changeset:)%s\]?(\W|$)" % id, text) or 1: |
|---|
| | 131 | + refs.append(context(rtyp, rid)) |
|---|
| | 132 | + return refs |
|---|
| | 133 | + |
|---|
| | 134 | # ISearchSource methods |
|---|
| | 135 | |
|---|
| | 136 | def get_search_filters(self, req): |
|---|
| | 137 | Index: trac/versioncontrol/templates/changeset.html |
|---|
| | 138 | =================================================================== |
|---|
| | 139 | --- trac/versioncontrol/templates/changeset.html (revision 5807) |
|---|
| | 140 | +++ trac/versioncontrol/templates/changeset.html (working copy) |
|---|
| | 141 | @@ -130,6 +130,18 @@ |
|---|
| | 142 | </py:when> |
|---|
| | 143 | <py:otherwise><pre>${changeset.message}</pre></py:otherwise> |
|---|
| | 144 | </dd> |
|---|
| | 145 | + |
|---|
| | 146 | + <py:if test="backrefs"> |
|---|
| | 147 | + <dt class="property message">Referenced by:</dt> |
|---|
| | 148 | + <dd class="message searchable"> |
|---|
| | 149 | + <py:for each="ref in backrefs"> |
|---|
| | 150 | + <a class="new ticket" |
|---|
| | 151 | + href="${ref.resource_href()+'?q=%%5B%i%%5D+r%i+changeset%%3A%i' % (context.id, context.id, context.id)}" |
|---|
| | 152 | + title="${[ref.summary(),''][ref.summary()==ref.shortname()]}">${ref.shortname()}</a> |
|---|
| | 153 | + </py:for> |
|---|
| | 154 | + </dd> |
|---|
| | 155 | + </py:if> |
|---|
| | 156 | + |
|---|
| | 157 | </py:if> |
|---|
| | 158 | <py:if test="location and len(files) > 1"> |
|---|
| | 159 | <dt class="property location">Location:</dt> |
|---|
| | 160 | Index: trac/wiki/web_ui.py |
|---|
| | 161 | =================================================================== |
|---|
| | 162 | --- trac/wiki/web_ui.py (revision 5807) |
|---|
| | 163 | +++ trac/wiki/web_ui.py (working copy) |
|---|
| | 164 | @@ -512,6 +512,8 @@ |
|---|
| | 165 | WikiSystem(self.env).get_pages(prefix) if 'WIKI_VIEW' |
|---|
| | 166 | in req.perm(context(id=t))] |
|---|
| | 167 | |
|---|
| | 168 | + data['backrefs'] = self._get_backrefs(context, page) |
|---|
| | 169 | + |
|---|
| | 170 | # -- prev/up/next links |
|---|
| | 171 | if prev_version: |
|---|
| | 172 | add_link(req, 'prev', req.href.wiki(page.name, |
|---|
| | 173 | @@ -533,6 +535,35 @@ |
|---|
| | 174 | }) |
|---|
| | 175 | return 'wiki_view.html', data, None |
|---|
| | 176 | |
|---|
| | 177 | + def _get_backrefs(self, context, page): |
|---|
| | 178 | + id = page.id |
|---|
| | 179 | + cursor = context.db.cursor() |
|---|
| | 180 | + refs = [] |
|---|
| | 181 | + |
|---|
| | 182 | + cursor.execute("SELECT 'ticket', id, description " |
|---|
| | 183 | + "FROM ticket WHERE description LIKE '%%%s%%' " |
|---|
| | 184 | + "UNION " |
|---|
| | 185 | + "SELECT 'ticket', t.id, newvalue " |
|---|
| | 186 | + "FROM ticket_change c JOIN ticket t on c.ticket = t.id " |
|---|
| | 187 | + "WHERE newvalue LIKE '%%%s%%' " |
|---|
| | 188 | + "UNION " |
|---|
| | 189 | + "SELECT 'changeset', rev, message " |
|---|
| | 190 | + "FROM revision WHERE message LIKE '%%%s%%' " |
|---|
| | 191 | + "UNION " |
|---|
| | 192 | + "SELECT 'wiki', name, text " |
|---|
| | 193 | + "FROM wiki WHERE text LIKE '%%%s%%' " |
|---|
| | 194 | + "AND version = (SELECT max(version) FROM wiki w " |
|---|
| | 195 | + " WHERE w.name = wiki.name) " |
|---|
| | 196 | + "ORDER BY 1 desc, 2" |
|---|
| | 197 | + % ((id,) * 4)) |
|---|
| | 198 | + |
|---|
| | 199 | + for idx, row in enumerate(cursor): |
|---|
| | 200 | + rtyp, rid, text = row |
|---|
| | 201 | + # check whether the link is an single word |
|---|
| | 202 | + if re.search(r"(\W|^)(wiki:)?%s(\W|$)" % id, text): |
|---|
| | 203 | + refs.append(context(rtyp, rid)) |
|---|
| | 204 | + return refs |
|---|
| | 205 | + |
|---|
| | 206 | # ITimelineEventProvider methods |
|---|
| | 207 | |
|---|
| | 208 | def get_timeline_filters(self, req): |
|---|
| | 209 | Index: trac/wiki/templates/wiki_view.html |
|---|
| | 210 | =================================================================== |
|---|
| | 211 | --- trac/wiki/templates/wiki_view.html (revision 5807) |
|---|
| | 212 | +++ trac/wiki/templates/wiki_view.html (working copy) |
|---|
| | 213 | @@ -104,6 +104,16 @@ |
|---|
| | 214 | <input type="submit" value="${_('Delete page')}" /> |
|---|
| | 215 | </div> |
|---|
| | 216 | </form> |
|---|
| | 217 | + |
|---|
| | 218 | + <py:if test="backrefs"> |
|---|
| | 219 | + <p>Referenced by: |
|---|
| | 220 | + <py:for each="ref in backrefs"> |
|---|
| | 221 | + <a class="new ticket" |
|---|
| | 222 | + href="${ref.resource_href()+'?q=%s' % context.id}" |
|---|
| | 223 | + title="${[ref.summary(),''][ref.summary()==ref.shortname()]}">${ref.shortname()}</a> |
|---|
| | 224 | + </py:for></p> |
|---|
| | 225 | + </py:if> |
|---|
| | 226 | + |
|---|
| | 227 | </py:if> |
|---|
| | 228 | </div> |
|---|
| | 229 | </py:if> |
|---|