Commit b3108e39972cb29c7da6cf724e74fc6bbf1269bb

Authored by Gust
1 parent 1e7861da

Fixing and extracting Trac dependencies

-Trac filters and search options only show if trac enabled
-Chart only shows trac data if enabled
-Fix rollback migration of Trac

Signed-off-by: Gustavo Jaruga <darksshades@gmail.com>
Signed-off-by: Matheus Faria <matheus.sousa.faria@gmail.com>
src/accounts/search_indexes.py
... ... @@ -3,7 +3,7 @@
3 3 from haystack import indexes
4 4 from django.db.models import Count
5 5  
6   -from proxy.trac.models import Revision, Ticket, Wiki
  6 +from proxy.models import Revision, Ticket, Wiki
7 7 from badger.utils import get_users_counters
8 8 from .models import User
9 9  
... ...
src/accounts/views.py
... ... @@ -25,7 +25,7 @@ from haystack.query import SearchQuerySet
25 25 from super_archives.models import EmailAddress, Message
26 26 from super_archives.utils.email import send_email_lists
27 27 from search.utils import trans
28   -from proxy.trac.models import WikiCollabCount, TicketCollabCount
  28 +from proxy.models import WikiCollabCount, TicketCollabCount
29 29 from .forms import (UserCreationForm, ListsForm, UserUpdateForm,
30 30 ChangeXMPPPasswordForm)
31 31 from .errors import XMPPChangePwdException
... ...
src/api/resources.py
... ... @@ -7,7 +7,7 @@ from tastypie.constants import ALL_WITH_RELATIONS, ALL
7 7 from tastypie.resources import ModelResource
8 8  
9 9 from super_archives.models import Message, EmailAddress
10   -from proxy.trac.models import Revision, Ticket, Wiki
  10 +from proxy.models import Revision, Ticket, Wiki
11 11  
12 12  
13 13 User = get_user_model()
... ...
src/badger/utils.py
... ... @@ -2,7 +2,7 @@
2 2  
3 3 from django.db.models import Count
4 4  
5   -from proxy.trac.models import (Revision, Ticket, Wiki,
  5 +from proxy.models import (Revision, Ticket, Wiki,
6 6 WikiCollabCount, TicketCollabCount)
7 7 from accounts.models import User
8 8  
... ...
src/colab/custom_settings.py
... ... @@ -255,18 +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   - INSTALLED_APPS = INSTALLED_APPS + (
266   - 'proxy.trac',
267   - )
268   -
269   -
270 258 ### Feedzilla (planet)
271 259 from feedzilla.settings import *
272 260 FEEDZILLA_PAGE_SIZE = 5
... ... @@ -321,7 +309,19 @@ DPASTE_EXPIRE_DEFAULT = DPASTE_EXPIRE_CHOICES[4][0]
321 309 DPASTE_DEFAULT_GIST_DESCRIPTION = 'Gist created on Colab Interlegis'
322 310 DPASTE_DEFAULT_GIST_NAME = 'colab_paste'
323 311  
  312 +
  313 +### Trac
  314 +TRAC_ENABLED = False
  315 +
  316 +from trac_settings import *
  317 +DATABASES['trac'] = TRAC_DATABASE
  318 +
324 319 try:
325 320 from local_settings import *
326 321 except ImportError:
327 322 pass
  323 +
  324 +if TRAC_ENABLED:
  325 + INSTALLED_APPS = INSTALLED_APPS + (
  326 + 'proxy.trac',
  327 + )
328 328 \ No newline at end of file
... ...
src/home/views.py
... ... @@ -9,7 +9,7 @@ from django.http import HttpResponse, Http404
9 9 from search.utils import trans
10 10 from haystack.query import SearchQuerySet
11 11  
12   -from proxy.trac.models import WikiCollabCount, TicketCollabCount
  12 +from proxy.models import WikiCollabCount, TicketCollabCount
13 13 from super_archives.models import Thread
14 14  
15 15  
... ... @@ -23,12 +23,16 @@ 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()
  26 + count_types['thread'] = SearchQuerySet().filter(
  27 + type='thread',
  28 + ).count()
30 29  
31 30 if settings.TRAC_ENABLED:
  31 + for type in ['changeset', 'attachment']:
  32 + count_types[type] = SearchQuerySet().filter(
  33 + type=type,
  34 + ).count()
  35 +
32 36 count_types['ticket'] = sum([
33 37 ticket.count for ticket in TicketCollabCount.objects.all()
34 38 ])
... ...
src/proxy/models.py
1 1 # -*- coding: utf-8 -*-
2 2 from django.db import models
3 3 from django.conf import settings
  4 +import os
  5 +import urllib2
4 6  
5   -if settings.TRAC_ENABLED:
6   - import trac.trac.models
  7 +from django.conf import settings
  8 +from django.db import models, connections
  9 +from django.db.models.signals import post_save
  10 +from django.dispatch import receiver
  11 +
  12 +from accounts.models import User
  13 +from hitcounter.models import HitCounterModelMixin
  14 +
  15 +class Attachment(models.Model, HitCounterModelMixin):
  16 + url = models.TextField(primary_key=True)
  17 + attach_id = models.TextField()
  18 + used_by = models.TextField()
  19 + filename = models.TextField()
  20 + author = models.TextField(blank=True)
  21 + description = models.TextField(blank=True)
  22 + created = models.DateTimeField(blank=True)
  23 + mimetype = models.TextField(blank=True)
  24 + size = models.IntegerField(blank=True)
  25 +
  26 + class Meta:
  27 + managed = False
  28 + db_table = 'attachment_view'
  29 +
  30 + @property
  31 + def filepath(self):
  32 + return os.path.join(
  33 + settings.ATTACHMENTS_FOLDER_PATH,
  34 + self.used_by,
  35 + self.attach_id,
  36 + urllib2.quote(self.filename.encode('utf8'))
  37 + )
  38 +
  39 + def get_absolute_url(self):
  40 + return u'/raw-attachment/{}'.format(self.url)
  41 +
  42 + def get_author(self):
  43 + try:
  44 + return User.objects.get(username=self.author)
  45 + except User.DoesNotExist:
  46 + return None
  47 +
  48 +
  49 +class Revision(models.Model, HitCounterModelMixin):
  50 + key = models.TextField(blank=True, primary_key=True)
  51 + rev = models.TextField(blank=True)
  52 + author = models.TextField(blank=True)
  53 + message = models.TextField(blank=True)
  54 + repository_name = models.TextField(blank=True)
  55 + created = models.DateTimeField(blank=True, null=True)
  56 +
  57 + class Meta:
  58 + managed = False
  59 + db_table = 'revision_view'
  60 +
  61 + def get_absolute_url(self):
  62 + return u'/changeset/{}/{}'.format(self.rev, self.repository_name)
  63 +
  64 + def get_author(self):
  65 + try:
  66 + return User.objects.get(username=self.author)
  67 + except User.DoesNotExist:
  68 + return None
  69 +
  70 +class Ticket(models.Model, HitCounterModelMixin):
  71 + id = models.IntegerField(primary_key=True)
  72 + summary = models.TextField(blank=True)
  73 + description = models.TextField(blank=True)
  74 + milestone = models.TextField(blank=True)
  75 + priority = models.TextField(blank=True)
  76 + component = models.TextField(blank=True)
  77 + version = models.TextField(blank=True)
  78 + severity = models.TextField(blank=True)
  79 + reporter = models.TextField(blank=True)
  80 + author = models.TextField(blank=True)
  81 + status = models.TextField(blank=True)
  82 + keywords = models.TextField(blank=True)
  83 + collaborators = models.TextField(blank=True)
  84 + created = models.DateTimeField(blank=True, null=True)
  85 + modified = models.DateTimeField(blank=True, null=True)
  86 + modified_by = models.TextField(blank=True)
  87 +
  88 + class Meta:
  89 + managed = False
  90 + db_table = 'ticket_view'
  91 +
  92 + def get_absolute_url(self):
  93 + return u'/ticket/{}'.format(self.id)
  94 +
  95 + def get_author(self):
  96 + try:
  97 + return User.objects.get(username=self.author)
  98 + except User.DoesNotExist:
  99 + return None
  100 +
  101 + def get_modified_by(self):
  102 + try:
  103 + return User.objects.get(username=self.modified_by)
  104 + except User.DoesNotExist:
  105 + return None
  106 +
  107 +class Wiki(models.Model, HitCounterModelMixin):
  108 + name = models.TextField(primary_key=True)
  109 + wiki_text = models.TextField(blank=True)
  110 + author = models.TextField(blank=True)
  111 + collaborators = models.TextField(blank=True)
  112 + created = models.DateTimeField(blank=True, null=True)
  113 + modified = models.DateTimeField(blank=True, null=True)
  114 + modified_by = models.TextField(blank=True)
  115 +
  116 + class Meta:
  117 + managed = False
  118 + db_table = 'wiki_view'
  119 +
  120 + def get_absolute_url(self):
  121 + return u'/wiki/{}'.format(self.name)
  122 +
  123 + def get_author(self):
  124 + try:
  125 + return User.objects.get(username=self.author)
  126 + except User.DoesNotExist:
  127 + return None
  128 +
  129 + def get_modified_by(self):
  130 + try:
  131 + return User.objects.get(username=self.modified_by)
  132 + except User.DoesNotExist:
  133 + return None
  134 +
  135 +
  136 +class WikiCollabCount(models.Model):
  137 + author = models.TextField(primary_key=True)
  138 + count = models.IntegerField()
  139 +
  140 + class Meta:
  141 + managed = False
  142 + db_table = 'wiki_collab_count_view'
  143 +
  144 +
  145 +class TicketCollabCount(models.Model):
  146 + author = models.TextField(primary_key=True)
  147 + count = models.IntegerField()
  148 +
  149 + class Meta:
  150 + managed = False
  151 + db_table = 'ticket_collab_count_view'
  152 +
  153 +
  154 +@receiver(post_save, sender=User)
  155 +def change_session_attribute_email(sender, instance, **kwargs):
  156 + cursor = connections['trac'].cursor()
  157 +
  158 + cursor.execute(("UPDATE session_attribute SET value=%s "
  159 + "WHERE name='email' AND sid=%s"),
  160 + [instance.email, instance.username])
  161 + cursor.execute(("UPDATE session_attribute SET value=%s "
  162 + "WHERE name='name' AND sid=%s"),
  163 + [instance.get_full_name(), instance.username])
  164 +
  165 + cursor.execute(("INSERT INTO session_attribute "
  166 + "(sid, authenticated, name, value) "
  167 + "SELECT %s, '1', 'email', %s WHERE NOT EXISTS "
  168 + "(SELECT 1 FROM session_attribute WHERE sid=%s "
  169 + "AND name='email')"),
  170 + [instance.username, instance.email, instance.username])
  171 +
  172 + cursor.execute(("INSERT INTO session_attribute "
  173 + "(sid, authenticated, name, value) "
  174 + "SELECT %s, '1', 'name', %s WHERE NOT EXISTS "
  175 + "(SELECT 1 FROM session_attribute WHERE sid=%s "
  176 + "AND name='name')"),
  177 + [instance.username, instance.get_full_name(),
  178 + instance.username])
... ...
src/proxy/search_indexes.py
... ... @@ -9,7 +9,7 @@ from haystack import indexes
9 9 from haystack.utils import log as logging
10 10  
11 11 from search.base_indexes import BaseIndex
12   -from trac.models import Attachment, Ticket, Wiki, Revision
  12 +from proxy.models import Attachment, Ticket, Wiki, Revision
13 13  
14 14  
15 15 logger = logging.getLogger('haystack')
... ...
src/proxy/trac/migrations/0001_initial.py
... ... @@ -9,7 +9,7 @@ from django.db import models
9 9 class Migration(SchemaMigration):
10 10  
11 11 def forwards(self, orm):
12   - connection = connections['trac']
  12 + connection = connections['trac']
13 13  
14 14 cursor = connection.cursor()
15 15 cursor.execute('''
... ... @@ -60,111 +60,111 @@ class Migration(SchemaMigration):
60 60 );
61 61 ''')
62 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   -''')
  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 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   -''')
  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 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   -''')
  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 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;
  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 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   -''')
  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 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;
  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 164  
165   -CREATE OR REPLACE VIEW wiki_collab_count_view AS
166   -SELECT author, count(*) from wiki GROUP BY author;
167   -''')
  165 + CREATE OR REPLACE VIEW wiki_collab_count_view AS
  166 + SELECT author, count(*) from wiki GROUP BY author;
  167 + ''')
168 168  
169 169 pass
170 170  
... ... @@ -173,13 +173,15 @@ SELECT author, count(*) from wiki GROUP BY author;
173 173  
174 174 cursor = connection.cursor()
175 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;')
  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 + ''')
181 183  
182   - pass
  184 + pass
183 185  
184 186 models = {
185 187 u'proxy.attachment': {
... ... @@ -245,4 +247,4 @@ DROP VIEW IF EXISTS wiki_view;
245 247 }
246 248  
247 249 complete_apps = ['proxy']
248 250 - symmetrical = True
  251 + symmetrical = True
249 252 \ No newline at end of file
... ...
src/proxy/trac/models.py
... ... @@ -1,178 +0,0 @@
1   -# -*- coding: utf-8 -*-
2   -
3   -import os
4   -import urllib2
5   -
6   -from django.conf import settings
7   -from django.db import models, connections
8   -from django.db.models.signals import post_save
9   -from django.dispatch import receiver
10   -
11   -from accounts.models import User
12   -from hitcounter.models import HitCounterModelMixin
13   -
14   -
15   -class Attachment(models.Model, HitCounterModelMixin):
16   - url = models.TextField(primary_key=True)
17   - attach_id = models.TextField()
18   - used_by = models.TextField()
19   - filename = models.TextField()
20   - author = models.TextField(blank=True)
21   - description = models.TextField(blank=True)
22   - created = models.DateTimeField(blank=True)
23   - mimetype = models.TextField(blank=True)
24   - size = models.IntegerField(blank=True)
25   -
26   - class Meta:
27   - managed = False
28   - db_table = 'attachment_view'
29   -
30   - @property
31   - def filepath(self):
32   - return os.path.join(
33   - settings.ATTACHMENTS_FOLDER_PATH,
34   - self.used_by,
35   - self.attach_id,
36   - urllib2.quote(self.filename.encode('utf8'))
37   - )
38   -
39   - def get_absolute_url(self):
40   - return u'/raw-attachment/{}'.format(self.url)
41   -
42   - def get_author(self):
43   - try:
44   - return User.objects.get(username=self.author)
45   - except User.DoesNotExist:
46   - return None
47   -
48   -
49   -class Revision(models.Model, HitCounterModelMixin):
50   - key = models.TextField(blank=True, primary_key=True)
51   - rev = models.TextField(blank=True)
52   - author = models.TextField(blank=True)
53   - message = models.TextField(blank=True)
54   - repository_name = models.TextField(blank=True)
55   - created = models.DateTimeField(blank=True, null=True)
56   -
57   - class Meta:
58   - managed = False
59   - db_table = 'revision_view'
60   -
61   - def get_absolute_url(self):
62   - return u'/changeset/{}/{}'.format(self.rev, self.repository_name)
63   -
64   - def get_author(self):
65   - try:
66   - return User.objects.get(username=self.author)
67   - except User.DoesNotExist:
68   - return None
69   -
70   -class Ticket(models.Model, HitCounterModelMixin):
71   - id = models.IntegerField(primary_key=True)
72   - summary = models.TextField(blank=True)
73   - description = models.TextField(blank=True)
74   - milestone = models.TextField(blank=True)
75   - priority = models.TextField(blank=True)
76   - component = models.TextField(blank=True)
77   - version = models.TextField(blank=True)
78   - severity = models.TextField(blank=True)
79   - reporter = models.TextField(blank=True)
80   - author = models.TextField(blank=True)
81   - status = models.TextField(blank=True)
82   - keywords = models.TextField(blank=True)
83   - collaborators = models.TextField(blank=True)
84   - created = models.DateTimeField(blank=True, null=True)
85   - modified = models.DateTimeField(blank=True, null=True)
86   - modified_by = models.TextField(blank=True)
87   -
88   - class Meta:
89   - managed = False
90   - db_table = 'ticket_view'
91   -
92   - def get_absolute_url(self):
93   - return u'/ticket/{}'.format(self.id)
94   -
95   - def get_author(self):
96   - try:
97   - return User.objects.get(username=self.author)
98   - except User.DoesNotExist:
99   - return None
100   -
101   - def get_modified_by(self):
102   - try:
103   - return User.objects.get(username=self.modified_by)
104   - except User.DoesNotExist:
105   - return None
106   -
107   -class Wiki(models.Model, HitCounterModelMixin):
108   - name = models.TextField(primary_key=True)
109   - wiki_text = models.TextField(blank=True)
110   - author = models.TextField(blank=True)
111   - collaborators = models.TextField(blank=True)
112   - created = models.DateTimeField(blank=True, null=True)
113   - modified = models.DateTimeField(blank=True, null=True)
114   - modified_by = models.TextField(blank=True)
115   -
116   - class Meta:
117   - managed = False
118   - db_table = 'wiki_view'
119   -
120   - def get_absolute_url(self):
121   - return u'/wiki/{}'.format(self.name)
122   -
123   - def get_author(self):
124   - try:
125   - return User.objects.get(username=self.author)
126   - except User.DoesNotExist:
127   - return None
128   -
129   - def get_modified_by(self):
130   - try:
131   - return User.objects.get(username=self.modified_by)
132   - except User.DoesNotExist:
133   - return None
134   -
135   -
136   -class WikiCollabCount(models.Model):
137   - author = models.TextField(primary_key=True)
138   - count = models.IntegerField()
139   -
140   - class Meta:
141   - managed = False
142   - db_table = 'wiki_collab_count_view'
143   -
144   -
145   -class TicketCollabCount(models.Model):
146   - author = models.TextField(primary_key=True)
147   - count = models.IntegerField()
148   -
149   - class Meta:
150   - managed = False
151   - db_table = 'ticket_collab_count_view'
152   -
153   -
154   -@receiver(post_save, sender=User)
155   -def change_session_attribute_email(sender, instance, **kwargs):
156   - cursor = connections['trac'].cursor()
157   -
158   - cursor.execute(("UPDATE session_attribute SET value=%s "
159   - "WHERE name='email' AND sid=%s"),
160   - [instance.email, instance.username])
161   - cursor.execute(("UPDATE session_attribute SET value=%s "
162   - "WHERE name='name' AND sid=%s"),
163   - [instance.get_full_name(), instance.username])
164   -
165   - cursor.execute(("INSERT INTO session_attribute "
166   - "(sid, authenticated, name, value) "
167   - "SELECT %s, '1', 'email', %s WHERE NOT EXISTS "
168   - "(SELECT 1 FROM session_attribute WHERE sid=%s "
169   - "AND name='email')"),
170   - [instance.username, instance.email, instance.username])
171   -
172   - cursor.execute(("INSERT INTO session_attribute "
173   - "(sid, authenticated, name, value) "
174   - "SELECT %s, '1', 'name', %s WHERE NOT EXISTS "
175   - "(SELECT 1 FROM session_attribute WHERE sid=%s "
176   - "AND name='name')"),
177   - [instance.username, instance.get_full_name(),
178   - instance.username])
src/proxy/views.py
... ... @@ -4,7 +4,7 @@ import os
4 4 from django.conf import settings
5 5  
6 6 from revproxy.views import ProxyView
7   -from trac.models import Wiki, Ticket, Revision
  7 +from .models import Wiki, Ticket, Revision
8 8 from hitcounter.views import HitCounterViewMixin
9 9  
10 10  
... ...
src/search/templates/search/includes/search_filters.html
... ... @@ -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
... ... @@ -5,7 +5,7 @@ from django.utils.translation import ugettext as _
5 5  
6 6 from haystack.views import SearchView
7 7  
8   -from proxy.trac.models import Attachment
  8 +from proxy.models import Attachment
9 9  
10 10  
11 11 class ColabSearchView(SearchView):
... ... @@ -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 +
  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()
... ... @@ -32,3 +33,7 @@ def pop_from_get(context, **kwargs):
32 33 context['request'].META['QUERY_STRING'],
33 34 **kwargs
34 35 )
  36 +
  37 +@register.assignment_tag
  38 +def is_trac_enable():
  39 + return settings.TRAC_ENABLED
35 40 \ No newline at end of file
... ...