Commit 500a12404773523d3837ad883504b4e3a2ea4fa0

Authored by Sergio Oliveira
2 parents 75292867 a3acbdfd

Merge pull request #18 from colab-community/update_trac_puppet

Remove trac dependency
src/colab/custom_settings.py
... ... @@ -255,15 +255,6 @@ MESSAGE_TAGS = {
255 255 messages.ERROR: 'alert-danger',
256 256 }
257 257  
258   -
259   -### Trac
260   -TRAC_ENABLED = False
261   -
262   -if TRAC_ENABLED:
263   - from trac_settings import *
264   - DATABASES['trac'] = TRAC_DATABASE
265   -
266   -
267 258 ### Feedzilla (planet)
268 259 from feedzilla.settings import *
269 260 FEEDZILLA_PAGE_SIZE = 5
... ... @@ -318,7 +309,16 @@ DPASTE_EXPIRE_DEFAULT = DPASTE_EXPIRE_CHOICES[4][0]
318 309 DPASTE_DEFAULT_GIST_DESCRIPTION = 'Gist created on Colab Interlegis'
319 310 DPASTE_DEFAULT_GIST_NAME = 'colab_paste'
320 311  
  312 +
  313 +### Trac
  314 +TRAC_ENABLED = False
  315 +
321 316 try:
322 317 from local_settings import *
323 318 except ImportError:
324 319 pass
  320 +
  321 +if TRAC_ENABLED:
  322 + INSTALLED_APPS = INSTALLED_APPS + (
  323 + 'proxy.trac',
  324 + )
325 325 \ No newline at end of file
... ...
src/colab/local_settings-dev.py
... ... @@ -27,16 +27,23 @@ CONVERSEJS_BOSH_SERVICE_URL = 'http://localhost:5280/http-bind'
27 27  
28 28 DATABASES['default']['PASSWORD'] = 'colab'
29 29 DATABASES['default']['HOST'] = 'localhost'
  30 +
  31 +TRAC_ENABLED = False
  32 +
30 33 if TRAC_ENABLED:
  34 + from trac_settings import *
  35 + DATABASES['trac'] = TRAC_DATABASE
31 36 DATABASES['trac']['PASSWORD'] = 'colab'
32 37 DATABASES['trac']['HOST'] = 'localhost'
33 38  
34 39 HAYSTACK_CONNECTIONS['default']['URL'] = 'http://localhost:8983/solr/'
35 40  
  41 +COLAB_TRAC_URL = 'http://localhost:5000/trac/'
36 42 COLAB_CI_URL = 'http://localhost:8080/ci/'
37 43 COLAB_GITLAB_URL = 'http://localhost:8090/gitlab/'
38 44 COLAB_REDMINE_URL = 'http://localhost:9080/redmine/'
39 45  
  46 +
40 47 CONVERSEJS_ENABLED = False
41 48  
42 49 DIAZO_THEME = SITE_URL
... ...
src/home/views.py
... ... @@ -23,18 +23,24 @@ def index(request):
23 23 count_types = cache.get('home_chart')
24 24 if count_types is None:
25 25 count_types = OrderedDict()
26   - for type in ['thread', 'changeset', 'attachment']:
27   - count_types[type] = SearchQuerySet().filter(
28   - type=type,
29   - ).count()
30   -
31   - count_types['ticket'] = sum([
32   - ticket.count for ticket in TicketCollabCount.objects.all()
33   - ])
34   -
35   - count_types['wiki'] = sum([
36   - wiki.count for wiki in WikiCollabCount.objects.all()
37   - ])
  26 + count_types['thread'] = SearchQuerySet().filter(
  27 + type='thread',
  28 + ).count()
  29 + # TODO: this section should be inside trac app and only use it here
  30 + if settings.TRAC_ENABLED:
  31 + for type in ['changeset', 'attachment']:
  32 + count_types[type] = SearchQuerySet().filter(
  33 + type=type,
  34 + ).count()
  35 +
  36 + count_types['ticket'] = sum([
  37 + ticket.count for ticket in TicketCollabCount.objects.all()
  38 + ])
  39 +
  40 + count_types['wiki'] = sum([
  41 + wiki.count for wiki in WikiCollabCount.objects.all()
  42 + ])
  43 +
38 44 cache.set('home_chart', count_types)
39 45  
40 46 for key in count_types.keys():
... ...
src/proxy/migrations/0001_initial.py
... ... @@ -1,248 +0,0 @@
1   -# -*- coding: utf-8 -*-
2   -import datetime
3   -from django.db import connections
4   -from south.db import db
5   -from south.v2 import SchemaMigration
6   -from django.db import models
7   -
8   -
9   -class Migration(SchemaMigration):
10   -
11   - def forwards(self, orm):
12   - connection = connections['trac']
13   -
14   - cursor = connection.cursor()
15   - cursor.execute('''
16   - CREATE OR REPLACE VIEW wiki_view AS SELECT
17   - wiki.name AS name,
18   - (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
19   - AND wiki2.version = MAX(wiki.version)) AS wiki_text,
20   - (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
21   - AND wiki3.version = 1) AS author,
22   - string_agg(DISTINCT wiki.author, ', ') AS collaborators,
23   - TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS created,
24   - TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS modified
25   - FROM wiki
26   - GROUP BY wiki.name;
27   -
28   - CREATE OR REPLACE VIEW ticket_view AS SELECT
29   - ticket.id AS id,
30   - ticket.summary as summary,
31   - ticket.description as description,
32   - ticket.milestone as milestone,
33   - ticket.priority as priority,
34   - ticket.component as component,
35   - ticket.version as version,
36   - ticket.severity as severity,
37   - ticket.reporter as reporter,
38   - ticket.reporter as author,
39   - ticket.status as status,
40   - ticket.keywords as keywords,
41   - (SELECT
42   - string_agg(DISTINCT ticket_change.author, ', ')
43   - FROM ticket_change WHERE ticket_change.ticket = ticket.id
44   - GROUP BY ticket_change.ticket) as collaborators,
45   - TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created,
46   - TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified
47   - FROM ticket;
48   -
49   - CREATE OR REPLACE VIEW revision_view AS SELECT
50   - revision.rev,
51   - revision.author,
52   - revision.message,
53   - repository.value AS repository_name,
54   - TIMESTAMP WITH TIME ZONE 'epoch' + (revision.time/1000000) * INTERVAL '1s' AS created
55   - FROM revision
56   - INNER JOIN repository ON(
57   - repository.id = revision.repos
58   - AND repository.name = 'name'
59   - AND repository.value != ''
60   - );
61   - ''')
62   - cursor.execute('''
63   -CREATE OR REPLACE VIEW revision_view AS SELECT
64   -revision.rev,
65   -revision.author,
66   -revision.message,
67   -repository.value AS repository_name,
68   -TIMESTAMP WITH TIME ZONE 'epoch' + (revision.time/1000000) * INTERVAL '1s' AS created,
69   -CONCAT(revision.repos, '-', revision.rev) AS key
70   -FROM revision
71   -INNER JOIN repository ON(
72   -repository.id = revision.repos
73   -AND repository.name = 'name'
74   -AND repository.value != ''
75   -);
76   -''')
77   - cursor.execute('''
78   -CREATE OR REPLACE VIEW attachment_view AS SELECT
79   -CONCAT(attachment.type, '/' , attachment.id, '/', attachment.filename) AS url,
80   -attachment.type AS used_by,
81   -attachment.filename AS filename,
82   -attachment.id as attach_id,
83   -(SELECT LOWER(SUBSTRING(attachment.filename FROM '\.(\w+)$'))) AS mimetype,
84   -attachment.author AS author,
85   -attachment.description AS description,
86   -attachment.size AS size,
87   -TIMESTAMP WITH TIME ZONE 'epoch' + (attachment.time/1000000)* INTERVAL '1s' AS created
88   -FROM attachment;
89   -''')
90   - cursor.execute('''
91   -CREATE OR REPLACE VIEW wiki_view AS SELECT
92   -wiki.name AS name,
93   -(SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
94   -AND wiki2.version = MAX(wiki.version)) AS wiki_text,
95   -(SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
96   -AND wiki3.version = 1) AS author,
97   -string_agg(DISTINCT wiki.author, ', ') AS collaborators,
98   -TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created,
99   -TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified
100   -FROM wiki
101   -GROUP BY wiki.name;
102   -''')
103   - cursor.execute('''
104   -CREATE OR REPLACE VIEW wiki_view AS SELECT
105   -wiki.name AS name,
106   -(SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
107   -AND wiki2.version = MAX(wiki.version)) AS wiki_text,
108   -(SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
109   -AND wiki3.version = 1) AS author,
110   -string_agg(DISTINCT wiki.author, ', ') AS collaborators,
111   -TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created,
112   -TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified,
113   -(SELECT wiki4.author FROM wiki AS wiki4 WHERE wiki4.name = wiki.name
114   -AND wiki4.version = MAX(wiki.version)) AS modified_by
115   -FROM wiki
116   -GROUP BY wiki.name;
117   -
118   -CREATE OR REPLACE VIEW ticket_view AS SELECT
119   -ticket.id AS id,
120   -ticket.summary as summary,
121   -ticket.description as description,
122   -ticket.milestone as milestone,
123   -ticket.priority as priority,
124   -ticket.component as component,
125   -ticket.version as version,
126   -ticket.severity as severity,
127   -ticket.reporter as reporter,
128   -ticket.reporter as author,
129   -ticket.status as status,
130   -ticket.keywords as keywords,
131   -(SELECT
132   -string_agg(DISTINCT ticket_change.author, ', ')
133   -FROM ticket_change WHERE ticket_change.ticket = ticket.id
134   -GROUP BY ticket_change.ticket) as collaborators,
135   -TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created,
136   -TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified,
137   -(SELECT
138   -ticket_change.author
139   -FROM ticket_change
140   -WHERE ticket_change.ticket = ticket.id
141   -AND ticket_change.time = ticket.changetime
142   -LIMIT 1
143   -) AS modified_by
144   -FROM ticket;
145   -''')
146   - cursor.execute('''
147   -CREATE OR REPLACE VIEW ticket_collab_count_view AS
148   -SELECT
149   -COALESCE (t1.author, t2.author) as author,
150   -(COALESCE(t1.count, 0) + COALESCE(t2.count, 0)) as count
151   -FROM
152   -(SELECT author, count(*) as count
153   -FROM ticket_change
154   -GROUP BY author
155   -ORDER BY author
156   -) AS t1
157   -FULL OUTER JOIN
158   -(SELECT reporter as author, count(*) as count
159   -FROM ticket
160   -GROUP BY reporter
161   -ORDER BY reporter
162   -) AS t2
163   -ON t1.author = t2.author;
164   -
165   -CREATE OR REPLACE VIEW wiki_collab_count_view AS
166   -SELECT author, count(*) from wiki GROUP BY author;
167   -''')
168   -
169   - pass
170   -
171   - def backwards(self, orm):
172   - connection = connections['trac']
173   -
174   - cursor = connection.cursor()
175   - cursor.execute('''
176   -DROP VIEW IF EXISTS revision_view;
177   -DROP VIEW IF EXISTS ticket_view;
178   -DROP VIEW IF EXISTS wiki_view;
179   -''')
180   - cursor.execute('DROP VIEW IF EXISTS attachment_view;')
181   -
182   - pass
183   -
184   - models = {
185   - u'proxy.attachment': {
186   - 'Meta': {'object_name': 'Attachment', 'db_table': "'attachment_view'", 'managed': 'False'},
187   - 'attach_id': ('django.db.models.fields.TextField', [], {}),
188   - 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
189   - 'created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True'}),
190   - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
191   - 'filename': ('django.db.models.fields.TextField', [], {}),
192   - 'mimetype': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
193   - 'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
194   - 'url': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
195   - 'used_by': ('django.db.models.fields.TextField', [], {})
196   - },
197   - u'proxy.revision': {
198   - 'Meta': {'object_name': 'Revision', 'db_table': "'revision_view'", 'managed': 'False'},
199   - 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
200   - 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
201   - 'key': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
202   - 'message': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
203   - 'repository_name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
204   - 'rev': ('django.db.models.fields.TextField', [], {'blank': 'True'})
205   - },
206   - u'proxy.ticket': {
207   - 'Meta': {'object_name': 'Ticket', 'db_table': "'ticket_view'", 'managed': 'False'},
208   - 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
209   - 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
210   - 'component': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
211   - 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
212   - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
213   - 'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
214   - 'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
215   - 'milestone': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
216   - 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
217   - 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
218   - 'priority': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
219   - 'reporter': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
220   - 'severity': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
221   - 'status': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
222   - 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
223   - 'version': ('django.db.models.fields.TextField', [], {'blank': 'True'})
224   - },
225   - u'proxy.ticketcollabcount': {
226   - 'Meta': {'object_name': 'TicketCollabCount', 'db_table': "'ticket_collab_count_view'", 'managed': 'False'},
227   - 'author': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
228   - 'count': ('django.db.models.fields.IntegerField', [], {})
229   - },
230   - u'proxy.wiki': {
231   - 'Meta': {'object_name': 'Wiki', 'db_table': "'wiki_view'", 'managed': 'False'},
232   - 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
233   - 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
234   - 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
235   - 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
236   - 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
237   - 'name': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
238   - 'wiki_text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
239   - },
240   - u'proxy.wikicollabcount': {
241   - 'Meta': {'object_name': 'WikiCollabCount', 'db_table': "'wiki_collab_count_view'", 'managed': 'False'},
242   - 'author': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
243   - 'count': ('django.db.models.fields.IntegerField', [], {})
244   - }
245   - }
246   -
247   - complete_apps = ['proxy']
248   - symmetrical = True
src/proxy/migrations/__init__.py
src/proxy/models.py
1 1 # -*- coding: utf-8 -*-
2   -
  2 +from django.db import models
  3 +from django.conf import settings
3 4 import os
4 5 import urllib2
5 6  
... ... @@ -11,7 +12,6 @@ from django.dispatch import receiver
11 12 from accounts.models import User
12 13 from hitcounter.models import HitCounterModelMixin
13 14  
14   -
15 15 class Attachment(models.Model, HitCounterModelMixin):
16 16 url = models.TextField(primary_key=True)
17 17 attach_id = models.TextField()
... ... @@ -104,7 +104,6 @@ class Ticket(models.Model, HitCounterModelMixin):
104 104 except User.DoesNotExist:
105 105 return None
106 106  
107   -
108 107 class Wiki(models.Model, HitCounterModelMixin):
109 108 name = models.TextField(primary_key=True)
110 109 wiki_text = models.TextField(blank=True)
... ...
src/proxy/templatetags/__init__.py 0 → 100644
src/proxy/templatetags/proxy.py 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +from django import template
  2 +
  3 +from super_archives.utils import url
  4 +from django.conf import settings
  5 +
  6 +
  7 +register = template.Library()
  8 +TEMPLATE_PATH = 'proxy/tags/'
  9 +
  10 +@register.assignment_tag
  11 +def is_trac_enable():
  12 + return settings.TRAC_ENABLED
0 13 \ No newline at end of file
... ...
src/proxy/trac/__init__.py 0 → 100644
src/proxy/trac/admin.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.contrib import admin
  2 +
  3 +# Register your models here.
... ...
src/proxy/trac/migrations/0001_initial.py 0 → 100644
... ... @@ -0,0 +1,250 @@
  1 +# -*- coding: utf-8 -*-
  2 +import datetime
  3 +from django.db import connections
  4 +from south.db import db
  5 +from south.v2 import SchemaMigration
  6 +from django.db import models
  7 +
  8 +
  9 +class Migration(SchemaMigration):
  10 +
  11 + def forwards(self, orm):
  12 + connection = connections['trac']
  13 +
  14 + cursor = connection.cursor()
  15 + cursor.execute('''
  16 + CREATE OR REPLACE VIEW wiki_view AS SELECT
  17 + wiki.name AS name,
  18 + (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
  19 + AND wiki2.version = MAX(wiki.version)) AS wiki_text,
  20 + (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
  21 + AND wiki3.version = 1) AS author,
  22 + string_agg(DISTINCT wiki.author, ', ') AS collaborators,
  23 + TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS created,
  24 + TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS modified
  25 + FROM wiki
  26 + GROUP BY wiki.name;
  27 +
  28 + CREATE OR REPLACE VIEW ticket_view AS SELECT
  29 + ticket.id AS id,
  30 + ticket.summary as summary,
  31 + ticket.description as description,
  32 + ticket.milestone as milestone,
  33 + ticket.priority as priority,
  34 + ticket.component as component,
  35 + ticket.version as version,
  36 + ticket.severity as severity,
  37 + ticket.reporter as reporter,
  38 + ticket.reporter as author,
  39 + ticket.status as status,
  40 + ticket.keywords as keywords,
  41 + (SELECT
  42 + string_agg(DISTINCT ticket_change.author, ', ')
  43 + FROM ticket_change WHERE ticket_change.ticket = ticket.id
  44 + GROUP BY ticket_change.ticket) as collaborators,
  45 + TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created,
  46 + TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified
  47 + FROM ticket;
  48 +
  49 + CREATE OR REPLACE VIEW revision_view AS SELECT
  50 + revision.rev,
  51 + revision.author,
  52 + revision.message,
  53 + repository.value AS repository_name,
  54 + TIMESTAMP WITH TIME ZONE 'epoch' + (revision.time/1000000) * INTERVAL '1s' AS created
  55 + FROM revision
  56 + INNER JOIN repository ON(
  57 + repository.id = revision.repos
  58 + AND repository.name = 'name'
  59 + AND repository.value != ''
  60 + );
  61 + ''')
  62 + cursor.execute('''
  63 + CREATE OR REPLACE VIEW revision_view AS SELECT
  64 + revision.rev,
  65 + revision.author,
  66 + revision.message,
  67 + repository.value AS repository_name,
  68 + TIMESTAMP WITH TIME ZONE 'epoch' + (revision.time/1000000) * INTERVAL '1s' AS created,
  69 + CONCAT(revision.repos, '-', revision.rev) AS key
  70 + FROM revision
  71 + INNER JOIN repository ON(
  72 + repository.id = revision.repos
  73 + AND repository.name = 'name'
  74 + AND repository.value != ''
  75 + );
  76 + ''')
  77 + cursor.execute('''
  78 + CREATE OR REPLACE VIEW attachment_view AS SELECT
  79 + CONCAT(attachment.type, '/' , attachment.id, '/', attachment.filename) AS url,
  80 + attachment.type AS used_by,
  81 + attachment.filename AS filename,
  82 + attachment.id as attach_id,
  83 + (SELECT LOWER(SUBSTRING(attachment.filename FROM '\.(\w+)$'))) AS mimetype,
  84 + attachment.author AS author,
  85 + attachment.description AS description,
  86 + attachment.size AS size,
  87 + TIMESTAMP WITH TIME ZONE 'epoch' + (attachment.time/1000000)* INTERVAL '1s' AS created
  88 + FROM attachment;
  89 + ''')
  90 + cursor.execute('''
  91 + CREATE OR REPLACE VIEW wiki_view AS SELECT
  92 + wiki.name AS name,
  93 + (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
  94 + AND wiki2.version = MAX(wiki.version)) AS wiki_text,
  95 + (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
  96 + AND wiki3.version = 1) AS author,
  97 + string_agg(DISTINCT wiki.author, ', ') AS collaborators,
  98 + TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created,
  99 + TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified
  100 + FROM wiki
  101 + GROUP BY wiki.name;
  102 + ''')
  103 + cursor.execute('''
  104 + CREATE OR REPLACE VIEW wiki_view AS SELECT
  105 + wiki.name AS name,
  106 + (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name
  107 + AND wiki2.version = MAX(wiki.version)) AS wiki_text,
  108 + (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name
  109 + AND wiki3.version = 1) AS author,
  110 + string_agg(DISTINCT wiki.author, ', ') AS collaborators,
  111 + TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created,
  112 + TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified,
  113 + (SELECT wiki4.author FROM wiki AS wiki4 WHERE wiki4.name = wiki.name
  114 + AND wiki4.version = MAX(wiki.version)) AS modified_by
  115 + FROM wiki
  116 + GROUP BY wiki.name;
  117 +
  118 + CREATE OR REPLACE VIEW ticket_view AS SELECT
  119 + ticket.id AS id,
  120 + ticket.summary as summary,
  121 + ticket.description as description,
  122 + ticket.milestone as milestone,
  123 + ticket.priority as priority,
  124 + ticket.component as component,
  125 + ticket.version as version,
  126 + ticket.severity as severity,
  127 + ticket.reporter as reporter,
  128 + ticket.reporter as author,
  129 + ticket.status as status,
  130 + ticket.keywords as keywords,
  131 + (SELECT
  132 + string_agg(DISTINCT ticket_change.author, ', ')
  133 + FROM ticket_change WHERE ticket_change.ticket = ticket.id
  134 + GROUP BY ticket_change.ticket) as collaborators,
  135 + TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created,
  136 + TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified,
  137 + (SELECT
  138 + ticket_change.author
  139 + FROM ticket_change
  140 + WHERE ticket_change.ticket = ticket.id
  141 + AND ticket_change.time = ticket.changetime
  142 + LIMIT 1
  143 + ) AS modified_by
  144 + FROM ticket;
  145 + ''')
  146 + cursor.execute('''
  147 + CREATE OR REPLACE VIEW ticket_collab_count_view AS
  148 + SELECT
  149 + COALESCE (t1.author, t2.author) as author,
  150 + (COALESCE(t1.count, 0) + COALESCE(t2.count, 0)) as count
  151 + FROM
  152 + (SELECT author, count(*) as count
  153 + FROM ticket_change
  154 + GROUP BY author
  155 + ORDER BY author
  156 + ) AS t1
  157 + FULL OUTER JOIN
  158 + (SELECT reporter as author, count(*) as count
  159 + FROM ticket
  160 + GROUP BY reporter
  161 + ORDER BY reporter
  162 + ) AS t2
  163 + ON t1.author = t2.author;
  164 +
  165 + CREATE OR REPLACE VIEW wiki_collab_count_view AS
  166 + SELECT author, count(*) from wiki GROUP BY author;
  167 + ''')
  168 +
  169 + pass
  170 +
  171 + def backwards(self, orm):
  172 + connection = connections['trac']
  173 +
  174 + cursor = connection.cursor()
  175 + cursor.execute('''
  176 + DROP VIEW IF EXISTS revision_view;
  177 + DROP VIEW IF EXISTS ticket_view;
  178 + DROP VIEW IF EXISTS wiki_view;
  179 + DROP VIEW IF EXISTS ticket_collab_count_view;
  180 + DROP VIEW IF EXISTS wiki_collab_count_view;
  181 + DROP VIEW IF EXISTS attachment_view;
  182 + ''')
  183 +
  184 + pass
  185 +
  186 + models = {
  187 + u'proxy.attachment': {
  188 + 'Meta': {'object_name': 'Attachment', 'db_table': "'attachment_view'", 'managed': 'False'},
  189 + 'attach_id': ('django.db.models.fields.TextField', [], {}),
  190 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  191 + 'created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True'}),
  192 + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  193 + 'filename': ('django.db.models.fields.TextField', [], {}),
  194 + 'mimetype': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  195 + 'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
  196 + 'url': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  197 + 'used_by': ('django.db.models.fields.TextField', [], {})
  198 + },
  199 + u'proxy.revision': {
  200 + 'Meta': {'object_name': 'Revision', 'db_table': "'revision_view'", 'managed': 'False'},
  201 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  202 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  203 + 'key': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  204 + 'message': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  205 + 'repository_name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  206 + 'rev': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  207 + },
  208 + u'proxy.ticket': {
  209 + 'Meta': {'object_name': 'Ticket', 'db_table': "'ticket_view'", 'managed': 'False'},
  210 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  211 + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  212 + 'component': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  213 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  214 + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  215 + 'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
  216 + 'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  217 + 'milestone': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  218 + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  219 + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  220 + 'priority': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  221 + 'reporter': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  222 + 'severity': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  223 + 'status': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  224 + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  225 + 'version': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  226 + },
  227 + u'proxy.ticketcollabcount': {
  228 + 'Meta': {'object_name': 'TicketCollabCount', 'db_table': "'ticket_collab_count_view'", 'managed': 'False'},
  229 + 'author': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  230 + 'count': ('django.db.models.fields.IntegerField', [], {})
  231 + },
  232 + u'proxy.wiki': {
  233 + 'Meta': {'object_name': 'Wiki', 'db_table': "'wiki_view'", 'managed': 'False'},
  234 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  235 + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  236 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  237 + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  238 + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  239 + 'name': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  240 + 'wiki_text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  241 + },
  242 + u'proxy.wikicollabcount': {
  243 + 'Meta': {'object_name': 'WikiCollabCount', 'db_table': "'wiki_collab_count_view'", 'managed': 'False'},
  244 + 'author': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  245 + 'count': ('django.db.models.fields.IntegerField', [], {})
  246 + }
  247 + }
  248 +
  249 + complete_apps = ['proxy']
  250 + symmetrical = True
0 251 \ No newline at end of file
... ...
src/proxy/trac/migrations/__init__.py 0 → 100644
src/proxy/trac/models.py 0 → 100644
src/proxy/trac/tests.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
... ...
src/proxy/trac/views.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +from django.shortcuts import render
  2 +
  3 +# Create your views here.
... ...
src/search/templates/search/includes/search_filters.html
1   -{% load i18n superarchives %}
  1 +{% load i18n superarchives proxy %}
2 2  
3 3 {% if filters %}
4 4 <ul class="unstyled-list">
... ... @@ -111,30 +111,34 @@
111 111 <h4>{% trans "Types" %}</h4>
112 112  
113 113 <ul class="unstyled-list">
114   - <li>
115   - <span class="glyphicon glyphicon-book"></span>
116   - <a href="{% append_to_get type='wiki' %}">{% trans "Wiki" %}</a>
117   - </li>
  114 + {% is_trac_enable as is_trac %}
  115 +
  116 + {% if is_trac %}
  117 + <li>
  118 + <span class="glyphicon glyphicon-book"></span>
  119 + <a href="{% append_to_get type='wiki' %}">{% trans "Wiki" %}</a>
  120 + </li>
  121 + <li>
  122 + <span class="glyphicon glyphicon-tag"></span>
  123 + <a href="{% append_to_get type='ticket' %}">{% trans "Ticket" %}</a>
  124 + </li>
  125 + <li>
  126 + <span class="glyphicon glyphicon-align-right"></span>
  127 + <a href="{% append_to_get type='changeset' %}">{% trans "Changeset" %}</a>
  128 + </li>
  129 + <li>
  130 + <span class="glyphicon glyphicon-user"></span>
  131 + <a href="{% append_to_get type='user' %}">{% trans "User" %}</a>
  132 + </li>
  133 + <li>
  134 + <span class="glyphicon glyphicon-file"></span>
  135 + <a href="{% append_to_get type='attachment' %}">{% trans "Attachment" %}</a>
  136 + </li>
  137 + {% endif %}
118 138 <li>
119 139 <span class="glyphicon glyphicon-envelope"></span>
120 140 <a href="{% append_to_get type='thread' %}">{% trans "Discussion" %}</a>
121 141 </li>
122   - <li>
123   - <span class="glyphicon glyphicon-tag"></span>
124   - <a href="{% append_to_get type='ticket' %}">{% trans "Ticket" %}</a>
125   - </li>
126   - <li>
127   - <span class="glyphicon glyphicon-align-right"></span>
128   - <a href="{% append_to_get type='changeset' %}">{% trans "Changeset" %}</a>
129   - </li>
130   - <li>
131   - <span class="glyphicon glyphicon-user"></span>
132   - <a href="{% append_to_get type='user' %}">{% trans "User" %}</a>
133   - </li>
134   - <li>
135   - <span class="glyphicon glyphicon-file"></span>
136   - <a href="{% append_to_get type='attachment' %}">{% trans "Attachment" %}</a>
137   - </li>
138 142 </ul>
139 143 {% endif %}
140 144 <hr />
... ...
src/search/views.py
... ... @@ -16,17 +16,6 @@ class ColabSearchView(SearchView):
16 16 )
17 17  
18 18 types = {
19   - 'wiki': {
20   - 'name': _(u'Wiki'),
21   - 'fields': (
22   - ('author', _(u'Author'), self.request.GET.get('author')),
23   - (
24   - 'collaborators',
25   - _(u'Collaborators'),
26   - self.request.GET.get('collaborators'),
27   - ),
28   - ),
29   - },
30 19 'thread': {
31 20 'name': _(u'Discussion'),
32 21 'fields': (
... ... @@ -38,7 +27,22 @@ class ColabSearchView(SearchView):
38 27 ),
39 28 ),
40 29 },
41   - 'ticket': {
  30 + }
  31 + # TODO: Replace for a more generic plugin architecture
  32 + if settings.TRAC_ENABLED:
  33 + types['wiki'] = {
  34 + 'name': _(u'Wiki'),
  35 + 'fields': (
  36 + ('author', _(u'Author'), self.request.GET.get('author')),
  37 + (
  38 + 'collaborators',
  39 + _(u'Collaborators'),
  40 + self.request.GET.get('collaborators'),
  41 + ),
  42 + ),
  43 + }
  44 +
  45 + types['ticket'] = {
42 46 'name': _(u'Ticket'),
43 47 'fields': (
44 48 (
... ... @@ -79,8 +83,9 @@ class ColabSearchView(SearchView):
79 83 self.request.GET.get('collaborators')
80 84 ),
81 85 ),
82   - },
83   - 'changeset': {
  86 + }
  87 +
  88 + types['changeset'] = {
84 89 'name': _(u'Changeset'),
85 90 'fields': (
86 91 ('author', _(u'Author'), self.request.GET.get('author')),
... ... @@ -90,8 +95,9 @@ class ColabSearchView(SearchView):
90 95 self.request.GET.get('repository_name'),
91 96 ),
92 97 )
93   - },
94   - 'user': {
  98 + }
  99 +
  100 + types['user'] = {
95 101 'name': _(u'User'),
96 102 'fields': (
97 103 (
... ... @@ -107,8 +113,9 @@ class ColabSearchView(SearchView):
107 113 ),
108 114 ('role', _(u'Role'), self.request.GET.get('role'))
109 115 ),
110   - },
111   - 'attachment': {
  116 + }
  117 +
  118 + types['attachment'] = {
112 119 'name': _(u'Attachment'),
113 120 'fields': (
114 121 (
... ... @@ -128,7 +135,6 @@ class ColabSearchView(SearchView):
128 135 ('size', _(u'Size'), self.request.GET.get('size')),
129 136 )
130 137 }
131   - }
132 138  
133 139 try:
134 140 type_chosen = self.form.cleaned_data.get('type')
... ...
src/super_archives/templatetags/superarchives.py
... ... @@ -2,6 +2,7 @@
2 2 from django import template
3 3  
4 4 from super_archives.utils import url
  5 +from django.conf import settings
5 6  
6 7  
7 8 register = template.Library()
... ... @@ -31,4 +32,4 @@ def pop_from_get(context, **kwargs):
31 32 context['request'].META['PATH_INFO'],
32 33 context['request'].META['QUERY_STRING'],
33 34 **kwargs
34 35 - )
  36 + )
35 37 \ No newline at end of file
... ...
src/templates/base.html
1 1 <!DOCTYPE html>
2   -{% load i18n browserid conversejs gravatar %}
  2 +{% load i18n browserid conversejs gravatar proxy %}
  3 +
  4 +{% is_trac_enable as is_trac %}
  5 +
3 6 <html>
4 7 <head>
5 8 {% block head %}
... ... @@ -57,34 +60,42 @@
57 60 </button>
58 61 <a class="navbar-brand" href="/"><img alt="Colab" src="/static/img/logo_nav.png"></a>
59 62 </div>
60   -
61 63 <div class="collapse navbar-collapse navbar-main">
62 64 <ul class="nav navbar-nav">
63   - <li>
64   - <a href="/timeline">{% trans "Timeline" %}</a></li>
65   - </li>
  65 +
  66 + {% if is_trac %}
  67 + <li>
  68 + <a href="/timeline">{% trans "Timeline" %}</a></li>
  69 + </li>
  70 + {% endif %}
  71 +
66 72 <li>
67 73 <a href="{% url 'thread_list' %}">{% trans "Groups" %}</a>
68 74 </li>
69 75 <li>
70 76 <a href="{% url "feedzilla_index" %}">{% trans "Blogs" %}</a>
71 77 </li>
72   - <li class="dropdown">
73   - <a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Contribute" %} <b class="caret"></b></a>
74   - <ul class="dropdown-menu">
75   - <li><a href="/wiki">Wiki</a></li>
76   - {% if user.is_active %}
77   - <li><a href="/wiki/WikiNewPage">{% trans "New Wiki Page" %}</a></li>
78   - {% endif %}
79   - <li><a href="/report">{% trans "View Tickets" %}</a></li>
80   - {% if user.is_active %}
81   - <li><a href="/newticket">{% trans "New Ticket" %}</a></li>
82   - {% endif %}
83   - <li><a href="/roadmap">{% trans "Roadmap" %}</a></li>
84   - <li><a href="/browser">{% trans "Browse Source" %}</a></li>
85   - <li><a href="/ci">{% trans "Continuous Integration" %}</a></li>
86   - </ul>
87   - </li>
  78 +
  79 + {% if is_trac %}
  80 + <li class="dropdown">
  81 + <a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Contribute" %} <b class="caret"></b></a>
  82 + <ul class="dropdown-menu">
  83 + <li><a href="/wiki">Wiki</a></li>
  84 + {% if user.is_active %}
  85 + <li><a href="/wiki/WikiNewPage">{% trans "New Wiki Page" %}</a></li>
  86 + {% endif %}
  87 + <li><a href="/report">{% trans "View Tickets" %}</a></li>
  88 + {% if user.is_active %}
  89 + <li><a href="/newticket">{% trans "New Ticket" %}</a></li>
  90 + {% endif %}
  91 + <li><a href="/roadmap">{% trans "Roadmap" %}</a></li>
  92 + <li><a href="/browser">{% trans "Browse Source" %}</a></li>
  93 + <!-- TODO: Must be optional like trac and separated --!>
  94 + <li><a href="/ci">{% trans "Continuous Integration" %}</a></li>
  95 + </ul>
  96 + </li>
  97 + {% endif %}
  98 +
88 99 <li class="hidden-lg hidden-md">
89 100 <a href="{% url 'haystack_search' %}?q=">{% trans "Search" %}</a>
90 101 </li>
... ...