Commit caf99954c6e522018b30088a78ff416796e00e18

Authored by Sergio Oliveira
2 parents b3223441 9857e341

Merge pull request #126 from TracyWebTech/fixing_by_stmts

Fixing by stmts
src/proxy/migrations/0005_adding_modified_by.py 0 → 100644
... ... @@ -0,0 +1,125 @@
  1 +# -*- coding: utf-8 -*-
  2 +import datetime
  3 +from django.db import connections
  4 +from south.db import db
  5 +from south.v2 import DataMigration
  6 +from django.db import models
  7 +
  8 +class Migration(DataMigration):
  9 +
  10 + def forwards(self, orm):
  11 + # Selecting trac database
  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' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created,
  24 + TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified,
  25 + (SELECT wiki4.author FROM wiki AS wiki4 WHERE wiki4.name = wiki.name
  26 + AND wiki4.version = MAX(wiki.version)) AS modified_by
  27 + FROM wiki
  28 + GROUP BY wiki.name;
  29 +
  30 + CREATE OR REPLACE VIEW ticket_view AS SELECT
  31 + ticket.id AS id,
  32 + ticket.summary as summary,
  33 + ticket.description as description,
  34 + ticket.milestone as milestone,
  35 + ticket.priority as priority,
  36 + ticket.component as component,
  37 + ticket.version as version,
  38 + ticket.severity as severity,
  39 + ticket.reporter as reporter,
  40 + ticket.reporter as author,
  41 + ticket.status as status,
  42 + ticket.keywords as keywords,
  43 + (SELECT
  44 + string_agg(DISTINCT ticket_change.author, ', ')
  45 + FROM ticket_change WHERE ticket_change.ticket = ticket.id
  46 + GROUP BY ticket_change.ticket) as collaborators,
  47 + TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created,
  48 + TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified,
  49 + (SELECT
  50 + ticket_change.author
  51 + FROM ticket_change
  52 + WHERE ticket_change.ticket = ticket.id
  53 + AND ticket_change.time = ticket.changetime
  54 + LIMIT 1
  55 + ) AS modified_by
  56 + FROM ticket;
  57 + ''')
  58 +
  59 +
  60 + def backwards(self, orm):
  61 + # Selecting trac database
  62 + connection = connections['trac']
  63 +
  64 + cursor = connection.cursor()
  65 + cursor.execute('''
  66 + ALTER VIEW wiki_view ALTER COLUMN modified_by DROP DEFAULT;
  67 + ALTER VIEW ticket_view ALTER COLUMN modified_by DROP DEFAULT;
  68 + ''')
  69 +
  70 +
  71 + models = {
  72 + u'proxy.attachment': {
  73 + 'Meta': {'object_name': 'Attachment', 'db_table': "'attachment_view'", 'managed': 'False'},
  74 + 'attach_id': ('django.db.models.fields.TextField', [], {}),
  75 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  76 + 'created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True'}),
  77 + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  78 + 'filename': ('django.db.models.fields.TextField', [], {}),
  79 + 'mimetype': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  80 + 'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
  81 + 'url': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  82 + 'used_by': ('django.db.models.fields.TextField', [], {})
  83 + },
  84 + u'proxy.revision': {
  85 + 'Meta': {'object_name': 'Revision', 'db_table': "'revision_view'", 'managed': 'False'},
  86 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  87 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  88 + 'key': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  89 + 'message': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  90 + 'repository_name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  91 + 'rev': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  92 + },
  93 + u'proxy.ticket': {
  94 + 'Meta': {'object_name': 'Ticket', 'db_table': "'ticket_view'", 'managed': 'False'},
  95 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  96 + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  97 + 'component': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  98 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  99 + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  100 + 'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}),
  101 + 'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  102 + 'milestone': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  103 + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  104 + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  105 + 'priority': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  106 + 'reporter': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  107 + 'severity': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  108 + 'status': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  109 + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  110 + 'version': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  111 + },
  112 + u'proxy.wiki': {
  113 + 'Meta': {'object_name': 'Wiki', 'db_table': "'wiki_view'", 'managed': 'False'},
  114 + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  115 + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  116 + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  117 + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
  118 + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
  119 + 'name': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}),
  120 + 'wiki_text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
  121 + }
  122 + }
  123 +
  124 + complete_apps = ['proxy']
  125 + symmetrical = True
... ...
src/proxy/models.py
... ... @@ -81,6 +81,7 @@ class Ticket(models.Model, HitCounterModelMixin):
81 81 collaborators = models.TextField(blank=True)
82 82 created = models.DateTimeField(blank=True, null=True)
83 83 modified = models.DateTimeField(blank=True, null=True)
  84 + modified_by = models.TextField(blank=True)
84 85  
85 86 class Meta:
86 87 managed = False
... ... @@ -95,6 +96,12 @@ class Ticket(models.Model, HitCounterModelMixin):
95 96 except User.DoesNotExist:
96 97 return None
97 98  
  99 + def get_modified_by(self):
  100 + try:
  101 + return User.objects.get(username=self.modified_by)
  102 + except User.DoesNotExist:
  103 + return None
  104 +
98 105  
99 106 class Wiki(models.Model, HitCounterModelMixin):
100 107 name = models.TextField(primary_key=True)
... ... @@ -103,6 +110,7 @@ class Wiki(models.Model, HitCounterModelMixin):
103 110 collaborators = models.TextField(blank=True)
104 111 created = models.DateTimeField(blank=True, null=True)
105 112 modified = models.DateTimeField(blank=True, null=True)
  113 + modified_by = models.TextField(blank=True)
106 114  
107 115 class Meta:
108 116 managed = False
... ... @@ -116,3 +124,9 @@ class Wiki(models.Model, HitCounterModelMixin):
116 124 return User.objects.get(username=self.author)
117 125 except User.DoesNotExist:
118 126 return None
  127 +
  128 + def get_modified_by(self):
  129 + try:
  130 + return User.objects.get(username=self.modified_by)
  131 + except User.DoesNotExist:
  132 + return None
... ...
src/search/base_indexes.py
... ... @@ -19,6 +19,8 @@ class BaseIndex(indexes.SearchIndex):
19 19 icon_name = indexes.CharField(indexed=False)
20 20 fullname_and_username = indexes.CharField(null=True, stored=False)
21 21 hits = indexes.IntegerField(model_attr='hits')
  22 + modified_by = indexes.CharField(null=True)
  23 + modified_by_url = indexes.CharField(null=True)
22 24  
23 25 def get_updated_field(self):
24 26 return 'modified'
... ... @@ -40,6 +42,24 @@ class BaseIndex(indexes.SearchIndex):
40 42 return author.username
41 43 return obj.author
42 44  
  45 + def prepare_author_url(self, obj):
  46 + author = obj.get_author()
  47 + if author:
  48 + return author.get_absolute_url()
  49 + return None
  50 +
  51 + def prepare_fullname(self, obj):
  52 + if hasattr(obj, 'modified_by'):
  53 + modified_by = obj.get_modified_by()
  54 + if modified_by:
  55 + return modified_by.get_full_name()
  56 + return None
  57 + else:
  58 + author = obj.get_author()
  59 + if author:
  60 + return author.get_full_name()
  61 + return obj.author
  62 +
43 63 def prepare_fullname_and_username(self, obj):
44 64 author = obj.get_author()
45 65 if not author:
... ... @@ -49,14 +69,14 @@ class BaseIndex(indexes.SearchIndex):
49 69 author.username,
50 70 )
51 71  
52   - def prepare_author_url(self, obj):
53   - author = obj.get_author()
54   - if author:
55   - return author.get_absolute_url()
  72 + def prepare_modified_by(self, obj):
  73 + if hasattr(obj, 'modified_by'):
  74 + return obj.modified_by
56 75 return None
57 76  
58   - def prepare_fullname(self, obj):
59   - author = obj.get_author()
60   - if author:
61   - return author.get_full_name()
62   - return obj.author
  77 + def prepare_modified_by_url(self, obj):
  78 + if hasattr(obj, 'modified_by'):
  79 + modified_by = obj.get_modified_by()
  80 + if modified_by:
  81 + return modified_by.get_absolute_url()
  82 + return None
... ...
src/super_archives/models.py
... ... @@ -326,9 +326,12 @@ class Message(models.Model):
326 326  
327 327 @property
328 328 def author(self):
329   - from_address = self.from_address
330   - if from_address.user:
331   - return from_address.user.username
  329 + return self.fullname
  330 +
  331 + @property
  332 + def author_url(self):
  333 + if self.from_address.user_id:
  334 + return self.from_address.user.get_absolute_url()
332 335 return None
333 336  
334 337 @property
... ... @@ -336,10 +339,6 @@ class Message(models.Model):
336 339 return self.from_address.get_full_name()
337 340  
338 341 @property
339   - def author_url(self):
340   - return self.from_address.user.get_absolute_url()
341   -
342   - @property
343 342 def icon_name(self):
344 343 return u'envelope'
345 344  
... ...
src/super_archives/search_indexes.py
... ... @@ -58,9 +58,18 @@ class ThreadIndex(BaseIndex, indexes.Indexable):
58 58 return first_message.from_address.user.get_absolute_url()
59 59 return None
60 60  
  61 + def prepare_modified_by(self, obj):
  62 + return obj.latest_message.author
  63 +
  64 + def prepare_modified_by_url(self, obj):
  65 + return obj.latest_message.author_url
  66 +
61 67 def prepare_created(self, obj):
62 68 return obj.message_set.first().received_time
63 69  
  70 + def prepare_fullname(self, obj):
  71 + return obj.latest_message.from_address.get_full_name()
  72 +
64 73 def prepare_icon_name(self, obj):
65 74 return u'envelope'
66 75  
... ...
src/super_archives/templates/message-preview.html
... ... @@ -36,22 +36,28 @@
36 36 </span>
37 37 {% endif %}
38 38  
39   -{% if result.fullname or result.modified %}
  39 +{% if result.fullname or result.modified or result.modified_by %}
40 40 <div class="quiet">
41   - {% if result.fullname %}
  41 + {% if result.fullname or result.modified_by %}
42 42 <span class="pull-left">{% trans "by" %}
43   - {% if result.fullname and result.author_url %}
44   - <a href="{{ result.author_url }}">
  43 + {% if result.fullname and result.author_url or result.modified_by and result.modified_by_url %}
  44 + <a href="{% firstof result.modified_by_url result.author_url %}">
45 45 {% if query %}
46   - {% highlight result.fullname with query %}
  46 + {% if result.modified_by %}
  47 + {% highlight result.modified_by with query %}
  48 + {% else %}
  49 + {% highlight result.fullname with query %}
  50 + {% endif %}
47 51 {% else %}
48   - {{ result.fullname }}
  52 + {% firstof result.modified_by result.fullname %}
49 53 {% endif %}
50 54 </a>
51 55 {% else %}
52 56 <span>{{ result.fullname }}</span>
53 57 {% endif %}
54 58 </span>
  59 + {% else %}
  60 + <span class="pull-left">{% trans "by" %} {% trans "Anonymous" %}</span>
55 61 {% endif %}
56 62 {% if result.modified %}
57 63 <span class="pull-right">{{ result.modified|localtime|timesince }} {% trans "ago" %}</span>
... ...