Merge Request #36
-
Stop current process and start a new process with Initd Signed-off-by: Alexandre Barbosa <alexandreab@live.com> Signed-off-by: Gustavo Jaruga <darksshades@gmail.com>
-
Signed-off-by: Gustavo Jaruga <darksshades@gmail.com>
-
[skip ci]
- 8 of 34 commits displayed. Click here to show all
| ... | ... | @@ -8,14 +8,14 @@ download() { |
| 8 | 8 | FILE="$2.tgz" |
| 9 | 9 | if [ -f $FILE ]; |
| 10 | 10 | then |
| 11 | - echo "File $FILE exists." | |
| 12 | - tar -zxf $FILE | |
| 11 | + echo "File $FILE exists." | |
| 12 | + tar -zxf $FILE | |
| 13 | 13 | else |
| 14 | - echo "Downloading solr from $1..." | |
| 15 | - curl -O $1 | |
| 16 | - tar -zxf $FILE | |
| 14 | + echo "File $FILE does not exist. Downloading solr from $1..." | |
| 15 | + curl -O $1 | |
| 16 | + tar -zxf $FILE | |
| 17 | 17 | fi |
| 18 | - echo "Downloaded" | |
| 18 | + echo "Downloaded!" | |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | is_solr_up(){ |
| ... | ... | @@ -183,11 +183,7 @@ download_and_run() { |
| 183 | 183 | # copies custom configurations |
| 184 | 184 | for file in $SOLR_CONFS |
| 185 | 185 | do |
| 186 | - if [ -d $file ] | |
| 187 | - then | |
| 188 | - cp $file/* $dir_name/example/solr/$dir_conf | |
| 189 | - echo "Copied directory $file into solr conf directory." | |
| 190 | - elif [ -f $file ] | |
| 186 | + if [ -f $file ] | |
| 191 | 187 | then |
| 192 | 188 | cp $file $dir_name/example/solr/$dir_conf |
| 193 | 189 | echo "Copied $file into solr conf directory." | ... | ... |
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +from re import match | |
| 3 | + | |
| 4 | +from django.db import connections | |
| 5 | + | |
| 6 | +from colab.proxy.trac.models import Attachment, Revision, Ticket, Wiki | |
| 1 | 7 | from colab.proxy.utils.proxy_data_api import ProxyDataAPI |
| 2 | 8 | |
| 3 | 9 | |
| 4 | 10 | class TracDataAPI(ProxyDataAPI): |
| 5 | 11 | |
| 6 | 12 | def fetch_data(self): |
| 7 | - pass | |
| 13 | + """ This is the pricipal method whose function is just make the call the | |
| 14 | + other methods. | |
| 15 | + | |
| 16 | + """ | |
| 17 | + connection = connections['trac'] | |
| 18 | + cursor = connection.cursor() | |
| 19 | + self.fetch_data_wiki(cursor) | |
| 20 | + self.fetch_data_attachment(cursor) | |
| 21 | + self.fetch_data_ticket(cursor) | |
| 22 | + self.fetch_data_revision(cursor) | |
| 23 | + | |
| 24 | + def fetch_data_attachment(self, empty_cursor): | |
| 25 | + """ This method is responsible for seeking the attachment data in | |
| 26 | + trac database and transfer them to the colab database. | |
| 27 | + | |
| 28 | + :param empty_cursor: A cursor coming from connectinos, it is necessary | |
| 29 | + import the connections library from django.db, with it we can run | |
| 30 | + sql commands. | |
| 31 | + | |
| 32 | + :returns: Return is an attachment object with your saved data | |
| 33 | + in the colab database. | |
| 34 | + | |
| 35 | + """ | |
| 36 | + attachment = Attachment() | |
| 37 | + cursor = self.attachment_cursor(empty_cursor) | |
| 38 | + attachment_dict = self.dictfetchall(cursor) | |
| 39 | + for line in attachment_dict: | |
| 40 | + attachment.description = line['description'] | |
| 41 | + attachment.id = line['id'] | |
| 42 | + attachment.filename = line['filename'] | |
| 43 | + attachment.title = attachment.filename | |
| 44 | + attachment.size = line['size'] | |
| 45 | + attachment.author = line['author'] | |
| 46 | + attachment.used_by = line['type'] | |
| 47 | + attachment.ipnr = line['ipnr'] | |
| 48 | + attachment.url = attachment.used_by + "/" + attachment.id \ | |
| 49 | + + "/" + attachment.filename | |
| 50 | + attachment.created = self.get_attachment_created(cursor, | |
| 51 | + line['id']) | |
| 52 | + if match("\.(\w+)$", attachment.filename): | |
| 53 | + attachment.mimetype = attachment.filename.lower() | |
| 54 | + attachment.save() | |
| 55 | + | |
| 56 | + def fetch_data_revision(self, empty_cursor): | |
| 57 | + """ This method is responsible for seeking the revision data in | |
| 58 | + trac database and transfer them to the colab database. | |
| 59 | + | |
| 60 | + :param empty_cursor: A cursor coming from connectinos, it is necessary | |
| 61 | + import the connections library from django.db, with it we can run | |
| 62 | + sql commands. | |
| 63 | + | |
| 64 | + :returns: Return is an revision object with your saved data | |
| 65 | + in the colab database. | |
| 66 | + | |
| 67 | + """ | |
| 68 | + revision = Revision() | |
| 69 | + cursor = self.revision_cursor(empty_cursor) | |
| 70 | + revision_dict = self.dictfetchall(cursor) | |
| 71 | + cursor = self.repository_cursor(empty_cursor) | |
| 72 | + repository_dict = self.dictfetchall(cursor) | |
| 73 | + for line in revision_dict: | |
| 74 | + revision.author = line['author'] | |
| 75 | + revision.rev = line['rev'] | |
| 76 | + revision.message = line['message'] | |
| 77 | + revision.description = revision.message | |
| 78 | + revision.created = self.get_revision_created(cursor, line['rev']) | |
| 79 | + revision.repository_name = line['repos'] | |
| 80 | + revision.save() | |
| 81 | + | |
| 82 | + def fetch_data_ticket(self, empty_cursor): | |
| 83 | + """ This method is responsible for seeking the ticket data in | |
| 84 | + trac database and transfer them to the colab database. | |
| 85 | + | |
| 86 | + :param empty_cursor: A cursor coming from connectinos, it is necessary | |
| 87 | + import the connections library from django.db, with it we can run | |
| 88 | + sql commands. | |
| 89 | + | |
| 90 | + :returns: Return is an ticker object with your saved data | |
| 91 | + in the colab database. | |
| 92 | + | |
| 93 | + """ | |
| 94 | + ticket = Ticket() | |
| 95 | + collaborators = [] | |
| 96 | + cursor = self.ticket_cursor(empty_cursor) | |
| 97 | + ticket_dict = self.dictfetchall(cursor) | |
| 98 | + for line in ticket_dict: | |
| 99 | + ticket.id = line['id'] | |
| 100 | + ticket.summary = line['summary'] | |
| 101 | + ticket.description_ticket = line['description'] | |
| 102 | + ticket.milestone = line['milestone'] | |
| 103 | + ticket.priority = line['priority'] | |
| 104 | + ticket.component = line['component'] | |
| 105 | + ticket.version = line['version'] | |
| 106 | + ticket.severity = line['severity'] | |
| 107 | + ticket.reporter = line['reporter'] | |
| 108 | + ticket.status = line['status'] | |
| 109 | + ticket.tag = ticket.status | |
| 110 | + if line['keywords']: | |
| 111 | + ticket.keywords = line['keywords'] | |
| 112 | + if line['owner']: | |
| 113 | + ticket.owner = line['owner'] | |
| 114 | + else: | |
| 115 | + ticket.owner = 'Anonymous' | |
| 116 | + if line['resolution']: | |
| 117 | + ticket.resolution = line['resolution'] | |
| 118 | + else: | |
| 119 | + ticket.resolution = 'no resolution' | |
| 120 | + ticket.author = ticket.reporter | |
| 121 | + ticket.created = self.get_ticket_created(cursor, line['id']) | |
| 122 | + ticket.modified = self.get_ticket_modified(cursor, line['id']) | |
| 123 | + if line['reporter'] not in collaborators: | |
| 124 | + collaborators.append(line['reporter']) | |
| 125 | + ticket.collaborators = collaborators | |
| 126 | + ticket.update_user(ticket.author) | |
| 127 | + ticket.save() | |
| 128 | + | |
| 129 | + def fetch_data_wiki(self, empty_cursor): | |
| 130 | + """ This method is responsible for seeking the wiki data in | |
| 131 | + trac database and transfer them to the colab database. | |
| 132 | + | |
| 133 | + :param empty_cursor: A cursor coming from connectinos, it is necessary | |
| 134 | + import the connections library from django.db, with it we can run | |
| 135 | + sql commands. | |
| 136 | + | |
| 137 | + :returns: Return is an wiki object with your saved data | |
| 138 | + in the colab database. | |
| 139 | + | |
| 140 | + """ | |
| 141 | + wiki = Wiki() | |
| 142 | + cursor = self.wiki_cursor(empty_cursor) | |
| 143 | + wiki_dict = self.dictfetchall(cursor) | |
| 144 | + collaborators = [] | |
| 145 | + for line in wiki_dict: | |
| 146 | + wiki.update_user(line['author']) | |
| 147 | + wiki.title = line['name'] | |
| 148 | + wiki.wiki_text = line['text'] | |
| 149 | + wiki.author = line['author'] | |
| 150 | + if line['author'] not in collaborators: | |
| 151 | + collaborators.append(line['author']) | |
| 152 | + wiki.collaborators = collaborators | |
| 153 | + wiki.created = self.get_wiki_created(cursor, line['name']) | |
| 154 | + wiki.modified = self.get_wiki_modified(cursor, line['name']) | |
| 155 | + | |
| 156 | + wiki.save() | |
| 157 | + | |
| 158 | + def dictfetchall(self, cursor): | |
| 159 | + """ This method is responsible for taking the cursor content | |
| 160 | + and turn it into a dictionary. | |
| 161 | + | |
| 162 | + The cursor returns an array of tuples, With this method it will return | |
| 163 | + a list of dictionaries.. | |
| 164 | + | |
| 165 | + :param cursor: A cursor coming from connections, it is necessary | |
| 166 | + import the connections from library django.db, with it we can run | |
| 167 | + sql commands. | |
| 168 | + | |
| 169 | + :returns: Return are cursor.fetchall() in the format of dictionary | |
| 170 | + | |
| 171 | + """ | |
| 172 | + desc = cursor.description | |
| 173 | + return [ | |
| 174 | + dict(zip([col[0] for col in desc], row)) | |
| 175 | + for row in cursor.fetchall() | |
| 176 | + ] | |
| 177 | + | |
| 178 | + def wiki_cursor(self, cursor): | |
| 179 | + """ This is the method in charge of getting the wiki table data and | |
| 180 | + put them in the cursor. | |
| 181 | + | |
| 182 | + :param cursor: A cursor coming from connections, it is necessary | |
| 183 | + import the connections from library django.db, with it we can run | |
| 184 | + sql commands. | |
| 185 | + | |
| 186 | + :returns: The return is the result of the desired query | |
| 187 | + | |
| 188 | + """ | |
| 189 | + cursor.execute('''SELECT * FROM wiki;''') | |
| 190 | + return cursor | |
| 191 | + | |
| 192 | + def attachment_cursor(self, cursor): | |
| 193 | + """ This is the method in charge of getting the attachment table data and | |
| 194 | + put them in the cursor. | |
| 195 | + | |
| 196 | + :param cursor: A cursor coming from connections, it is necessary | |
| 197 | + import the connections from library django.db, with it we can run | |
| 198 | + sql commands. | |
| 199 | + | |
| 200 | + :returns: The return is the result of the desired query | |
| 201 | + | |
| 202 | + """ | |
| 203 | + cursor.execute('''SELECT * FROM attachment;''') | |
| 204 | + return cursor | |
| 205 | + | |
| 206 | + def ticket_cursor(self, cursor): | |
| 207 | + """ This is the method in charge of getting the ticket table data and | |
| 208 | + put them in the cursor. | |
| 209 | + | |
| 210 | + :param cursor: A cursor coming from connections, it is necessary | |
| 211 | + import the connections from library django.db, with it we can run | |
| 212 | + sql commands. | |
| 213 | + | |
| 214 | + :returns: The return is the result of the desired query | |
| 215 | + | |
| 216 | + """ | |
| 217 | + cursor.execute('''SELECT * FROM ticket;''') | |
| 218 | + return cursor | |
| 219 | + | |
| 220 | + def revision_cursor(self, cursor): | |
| 221 | + """ This is the method in charge of getting the revision table data and | |
| 222 | + put them in the cursor. | |
| 223 | + | |
| 224 | + :param cursor: A cursor coming from connections, it is necessary | |
| 225 | + import the connections from library django.db, with it we can run | |
| 226 | + sql commands. | |
| 227 | + | |
| 228 | + :returns: The return is the result of the desired query | |
| 229 | + | |
| 230 | + """ | |
| 231 | + cursor.execute('''SELECT * FROM revision;''') | |
| 232 | + return cursor | |
| 233 | + | |
| 234 | + def repository_cursor(self, cursor): | |
| 235 | + """ This is the method in charge of getting the repository table data and | |
| 236 | + put them in the cursor. | |
| 237 | + | |
| 238 | + :param cursor: A cursor coming from connections, it is necessary | |
| 239 | + import the connections from library django.db, with it we can run | |
| 240 | + sql commands. | |
| 241 | + | |
| 242 | + :returns: The return is the result of the desired query | |
| 243 | + | |
| 244 | + """ | |
| 245 | + cursor.execute('''SELECT * FROM repository;''') | |
| 246 | + return cursor | |
| 247 | + | |
| 248 | + def get_wiki_modified(self, cursor, wiki_name): | |
| 249 | + """ This is the method in charge of getting the datetime in the wiki was | |
| 250 | + modified and put it in GMT format. | |
| 251 | + | |
| 252 | + :param cursor: A cursor coming from connections, it is necessary | |
| 253 | + import the connections from library django.db, with it we can run | |
| 254 | + sql commands. | |
| 255 | + | |
| 256 | + :param wiki_name: is the name of the current wiki. | |
| 257 | + | |
| 258 | + :returns: The return is the result of the desired query | |
| 259 | + | |
| 260 | + """ | |
| 261 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 262 | + (MAX(wiki.time)/1000000) * INTERVAL '1s', \ | |
| 263 | + name from wiki where(name=\'""" + wiki_name + """\') \ | |
| 264 | + group by name; """) | |
| 265 | + matriz_data_wiki = cursor.fetchall() | |
| 266 | + modified_data = matriz_data_wiki[0][0] | |
| 267 | + return modified_data | |
| 268 | + | |
| 269 | + def get_wiki_created(self, cursor, wiki_name): | |
| 270 | + """ This is the method in charge of getting the datetime in the wiki was | |
| 271 | + created and put it in GMT format. | |
| 272 | + | |
| 273 | + :param cursor: A cursor coming from connections, it is necessary | |
| 274 | + import the connections from library django.db, with it we can run | |
| 275 | + sql commands. | |
| 276 | + | |
| 277 | + :param wiki_name: is the name of the current wiki. | |
| 278 | + | |
| 279 | + :returns: The return is the result of the desired query | |
| 280 | + | |
| 281 | + """ | |
| 282 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 283 | + (MIN(wiki.time)/1000000) * INTERVAL '1s', \ | |
| 284 | + name from wiki where(name=\'""" + wiki_name + """\') \ | |
| 285 | + group by name; """) | |
| 286 | + matriz_data_wiki = cursor.fetchall() | |
| 287 | + modified_data = matriz_data_wiki[0][0] | |
| 288 | + return modified_data | |
| 289 | + | |
| 290 | + def get_attachment_created(self, cursor, attachment_id): | |
| 291 | + """ This is the method in charge of getting the datetime in the | |
| 292 | + attachment was created and put it in GMT format. | |
| 293 | + | |
| 294 | + :param cursor: A cursor coming from connections, it is necessary | |
| 295 | + import the connections from library django.db, with it we can run | |
| 296 | + sql commands. | |
| 297 | + | |
| 298 | + :param attachment_id: is the id of the current attachment. | |
| 299 | + | |
| 300 | + :returns: The return is the result of the desired query | |
| 301 | + | |
| 302 | + """ | |
| 303 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 304 | + (MIN(attachment.time)/1000000) * INTERVAL '1s', \ | |
| 305 | + id from attachment \ | |
| 306 | + where(id=\'""" + attachment_id + """\') \ | |
| 307 | + group by id; """) | |
| 308 | + matriz_data_attachment = cursor.fetchall() | |
| 309 | + modified_data = matriz_data_attachment[0][0] | |
| 310 | + return modified_data | |
| 311 | + | |
| 312 | + def get_revision_created(self, cursor, revision): | |
| 313 | + """ This is the method in charge of getting the datetime in the revision | |
| 314 | + was modified and put it in GMT format. | |
| 315 | + | |
| 316 | + :param cursor: A cursor coming from connections, it is necessary | |
| 317 | + import the connections from library django.db, with it we can run | |
| 318 | + sql commands. | |
| 319 | + | |
| 320 | + :param revision: is the current revision. | |
| 321 | + | |
| 322 | + :returns: The return is the result of the desired query | |
| 323 | + | |
| 324 | + """ | |
| 325 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 326 | + (MIN(revision.time)/1000000) * INTERVAL '1s', \ | |
| 327 | + rev from revision where(rev=\'""" + revision + """\') \ | |
| 328 | + group by rev; """) | |
| 329 | + matriz_data_revision = cursor.fetchall() | |
| 330 | + modified_data = matriz_data_revision[0][0] | |
| 331 | + return modified_data | |
| 332 | + | |
| 333 | + def get_ticket_created(self, cursor, ticket_id): | |
| 334 | + """ This is the method in charge of getting the datetime in the ticket | |
| 335 | + was created and put it in GMT format. | |
| 336 | + | |
| 337 | + :param cursor: A cursor coming from connections, it is necessary | |
| 338 | + import the connections from library django.db, with it we can run | |
| 339 | + sql commands. | |
| 340 | + | |
| 341 | + :param ticket_id: is the id of the current ticket. | |
| 342 | + | |
| 343 | + :returns: The return is the result of the desired query | |
| 344 | + | |
| 345 | + """ | |
| 346 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 347 | + (MIN(ticket.time)/1000000) * INTERVAL '1s', \ | |
| 348 | + id from ticket where(id=""" + str(ticket_id) + """) \ | |
| 349 | + group by id; """) | |
| 350 | + matriz_data_ticket = cursor.fetchall() | |
| 351 | + modified_data = matriz_data_ticket[0][0] | |
| 352 | + return modified_data | |
| 353 | + | |
| 354 | + def get_ticket_modified(self, cursor, ticket_id): | |
| 355 | + """ This is the method in charge of getting the datetime in the ticket | |
| 356 | + was modified and put it in GMT format. | |
| 357 | + | |
| 358 | + :param cursor: A cursor coming from connections, it is necessary | |
| 359 | + import the connections from library django.db, with it we can run | |
| 360 | + sql commands. | |
| 361 | + | |
| 362 | + :param ticket_id: is the id of the current ticket. | |
| 363 | + | |
| 364 | + :returns: The return is the result of the desired query | |
| 365 | + """ | |
| 366 | + cursor.execute("""SELECT TIMESTAMP WITH TIME ZONE 'epoch' + \ | |
| 367 | + (MAX(ticket.time)/1000000) * INTERVAL '1s', \ | |
| 368 | + id from ticket where(id=""" + str(ticket_id) + """) \ | |
| 369 | + group by id; """) | |
| 370 | + matriz_data_ticket = cursor.fetchall() | |
| 371 | + modified_data = matriz_data_ticket[0][0] | |
| 372 | + return modified_data | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +[{"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.058Z", "user": null}, "model": "trac.wiki", "pk": "CamelCase"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.010Z", "user": null}, "model": "trac.wiki", "pk": "InterMapTxt"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.023Z", "user": null}, "model": "trac.wiki", "pk": "InterTrac"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.017Z", "user": null}, "model": "trac.wiki", "pk": "InterWiki"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.040Z", "user": null}, "model": "trac.wiki", "pk": "PageTemplates"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.122Z", "user": null}, "model": "trac.wiki", "pk": "RecentChanges"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.061Z", "user": null}, "model": "trac.wiki", "pk": "SandBox"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.033Z", "user": null}, "model": "trac.wiki", "pk": "TitleIndex"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.142Z", "user": null}, "model": "trac.wiki", "pk": "TracAccessibility"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.174Z", "user": null}, "model": "trac.wiki", "pk": "TracAdmin"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.206Z", "user": null}, "model": "trac.wiki", "pk": "TracBackup"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.030Z", "user": null}, "model": "trac.wiki", "pk": "TracBatchModify"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.097Z", "user": null}, "model": "trac.wiki", "pk": "TracBrowser"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.050Z", "user": null}, "model": "trac.wiki", "pk": "TracCgi"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.177Z", "user": null}, "model": "trac.wiki", "pk": "TracChangeset"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.046Z", "user": null}, "model": "trac.wiki", "pk": "TracEnvironment"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.196Z", "user": null}, "model": "trac.wiki", "pk": "TracFastCgi"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.190Z", "user": null}, "model": "trac.wiki", "pk": "TracFineGrainedPermissions"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.116Z", "user": null}, "model": "trac.wiki", "pk": "TracGuide"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.100Z", "user": null}, "model": "trac.wiki", "pk": "TracImport"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.180Z", "user": null}, "model": "trac.wiki", "pk": "TracIni"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.087Z", "user": null}, "model": "trac.wiki", "pk": "TracInstall"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.037Z", "user": null}, "model": "trac.wiki", "pk": "TracInterfaceCustomization"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.139Z", "user": null}, "model": "trac.wiki", "pk": "TracLinks"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.020Z", "user": null}, "model": "trac.wiki", "pk": "TracLogging"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.126Z", "user": null}, "model": "trac.wiki", "pk": "TracModPython"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.135Z", "user": null}, "model": "trac.wiki", "pk": "TracModWSGI"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.027Z", "user": null}, "model": "trac.wiki", "pk": "TracNavigation"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.145Z", "user": null}, "model": "trac.wiki", "pk": "TracNotification"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.170Z", "user": null}, "model": "trac.wiki", "pk": "TracPermissions"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.164Z", "user": null}, "model": "trac.wiki", "pk": "TracPlugins"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.119Z", "user": null}, "model": "trac.wiki", "pk": "TracQuery"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.129Z", "user": null}, "model": "trac.wiki", "pk": "TracReports"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.084Z", "user": null}, "model": "trac.wiki", "pk": "TracRepositoryAdmin"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.158Z", "user": null}, "model": "trac.wiki", "pk": "TracRevisionLog"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.183Z", "user": null}, "model": "trac.wiki", "pk": "TracRoadmap"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.154Z", "user": null}, "model": "trac.wiki", "pk": "TracRss"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.067Z", "user": null}, "model": "trac.wiki", "pk": "TracSearch"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.064Z", "user": null}, "model": "trac.wiki", "pk": "TracStandalone"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.151Z", "user": null}, "model": "trac.wiki", "pk": "TracSupport"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.076Z", "user": null}, "model": "trac.wiki", "pk": "TracSyntaxColoring"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.113Z", "user": null}, "model": "trac.wiki", "pk": "TracTickets"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.203Z", "user": null}, "model": "trac.wiki", "pk": "TracTicketsCustomFields"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.071Z", "user": null}, "model": "trac.wiki", "pk": "TracTimeline"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:22Z", "modified": "2015-02-11T16:13:15.054Z", "user": null}, "model": "trac.wiki", "pk": "TracUnicode"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.193Z", "user": null}, "model": "trac.wiki", "pk": "TracUpgrade"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.132Z", "user": null}, "model": "trac.wiki", "pk": "TracWiki"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.080Z", "user": null}, "model": "trac.wiki", "pk": "TracWorkflow"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.110Z", "user": null}, "model": "trac.wiki", "pk": "WikiDeletePage"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.167Z", "user": null}, "model": "trac.wiki", "pk": "WikiFormatting"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.200Z", "user": null}, "model": "trac.wiki", "pk": "WikiHtml"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.107Z", "user": null}, "model": "trac.wiki", "pk": "WikiMacros"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.103Z", "user": null}, "model": "trac.wiki", "pk": "WikiNewPage"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.161Z", "user": null}, "model": "trac.wiki", "pk": "WikiPageNames"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.090Z", "user": null}, "model": "trac.wiki", "pk": "WikiProcessors"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.187Z", "user": null}, "model": "trac.wiki", "pk": "WikiRestructuredText"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.094Z", "user": null}, "model": "trac.wiki", "pk": "WikiRestructuredTextLinks"}, {"fields": {"collaborators": "[u'trac']", "author": "trac", "wiki_text": "", "created": "2015-02-09T19:57:23Z", "modified": "2015-02-11T16:13:15.148Z", "user": null}, "model": "trac.wiki", "pk": "WikiStart"}] | |
| 0 | 2 | \ No newline at end of file | ... | ... |
| 1 | 1 | # -*- coding: utf-8 -*- |
| 2 | 2 | from __future__ import unicode_literals |
| 3 | 3 | |
| 4 | -from django.db import models, migrations, connections | |
| 5 | - | |
| 6 | - | |
| 7 | -def create_views(apps, schema_editor): | |
| 8 | - connection = connections['trac'] | |
| 9 | - | |
| 10 | - cursor = connection.cursor() | |
| 11 | - | |
| 12 | - # revision_view | |
| 13 | - cursor.execute(''' | |
| 14 | - CREATE OR REPLACE VIEW revision_view AS SELECT | |
| 15 | - revision.rev, | |
| 16 | - revision.author, | |
| 17 | - revision.message, | |
| 18 | - repository.value AS repository_name, | |
| 19 | - TIMESTAMP WITH TIME ZONE 'epoch' + (revision.time/1000000) * INTERVAL '1s' AS created, | |
| 20 | - CONCAT(revision.repos, '-', revision.rev) AS key | |
| 21 | - FROM revision | |
| 22 | - INNER JOIN repository ON( | |
| 23 | - repository.id = revision.repos | |
| 24 | - AND repository.name = 'name' | |
| 25 | - AND repository.value != '' | |
| 26 | - ); | |
| 27 | - ''') | |
| 28 | - | |
| 29 | - # attachment_view | |
| 30 | - cursor.execute(''' | |
| 31 | - CREATE OR REPLACE VIEW attachment_view AS SELECT | |
| 32 | - CONCAT(attachment.type, '/' , attachment.id, '/', attachment.filename) AS url, | |
| 33 | - attachment.type AS used_by, | |
| 34 | - attachment.filename AS filename, | |
| 35 | - attachment.id as attach_id, | |
| 36 | - (SELECT LOWER(SUBSTRING(attachment.filename FROM '\.(\w+)$'))) AS mimetype, | |
| 37 | - attachment.author AS author, | |
| 38 | - attachment.description AS description, | |
| 39 | - attachment.size AS size, | |
| 40 | - TIMESTAMP WITH TIME ZONE 'epoch' + (attachment.time/1000000)* INTERVAL '1s' AS created | |
| 41 | - FROM attachment; | |
| 42 | - ''') | |
| 43 | - | |
| 44 | - # wiki_view | |
| 45 | - cursor.execute(''' | |
| 46 | - CREATE OR REPLACE VIEW wiki_view AS SELECT | |
| 47 | - wiki.name AS name, | |
| 48 | - (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name | |
| 49 | - AND wiki2.version = MAX(wiki.version)) AS wiki_text, | |
| 50 | - (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name | |
| 51 | - AND wiki3.version = 1) AS author, | |
| 52 | - string_agg(DISTINCT wiki.author, ', ') AS collaborators, | |
| 53 | - TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created, | |
| 54 | - TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified, | |
| 55 | - (SELECT wiki4.author FROM wiki AS wiki4 WHERE wiki4.name = wiki.name | |
| 56 | - AND wiki4.version = MAX(wiki.version)) AS modified_by | |
| 57 | - FROM wiki | |
| 58 | - GROUP BY wiki.name; | |
| 59 | - ''') | |
| 60 | - | |
| 61 | - # ticket_view | |
| 62 | - cursor.execute(''' | |
| 63 | - CREATE OR REPLACE VIEW ticket_view AS SELECT | |
| 64 | - ticket.id AS id, | |
| 65 | - ticket.summary as summary, | |
| 66 | - ticket.description as description, | |
| 67 | - ticket.milestone as milestone, | |
| 68 | - ticket.priority as priority, | |
| 69 | - ticket.component as component, | |
| 70 | - ticket.version as version, | |
| 71 | - ticket.severity as severity, | |
| 72 | - ticket.reporter as reporter, | |
| 73 | - ticket.reporter as author, | |
| 74 | - ticket.status as status, | |
| 75 | - ticket.keywords as keywords, | |
| 76 | - (SELECT | |
| 77 | - string_agg(DISTINCT ticket_change.author, ', ') | |
| 78 | - FROM ticket_change WHERE ticket_change.ticket = ticket.id | |
| 79 | - GROUP BY ticket_change.ticket) as collaborators, | |
| 80 | - TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created, | |
| 81 | - TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified, | |
| 82 | - (SELECT | |
| 83 | - ticket_change.author | |
| 84 | - FROM ticket_change | |
| 85 | - WHERE ticket_change.ticket = ticket.id | |
| 86 | - AND ticket_change.time = ticket.changetime | |
| 87 | - LIMIT 1 | |
| 88 | - ) AS modified_by | |
| 89 | - FROM ticket; | |
| 90 | - ''') | |
| 91 | - | |
| 92 | - # ticket_collab_count_view | |
| 93 | - cursor.execute(''' | |
| 94 | - CREATE OR REPLACE VIEW ticket_collab_count_view AS | |
| 95 | - SELECT | |
| 96 | - COALESCE (t1.author, t2.author) as author, | |
| 97 | - (COALESCE(t1.count, 0) + COALESCE(t2.count, 0)) as count | |
| 98 | - FROM | |
| 99 | - (SELECT author, count(*) as count | |
| 100 | - FROM ticket_change | |
| 101 | - GROUP BY author | |
| 102 | - ORDER BY author | |
| 103 | - ) AS t1 | |
| 104 | - FULL OUTER JOIN | |
| 105 | - (SELECT reporter as author, count(*) as count | |
| 106 | - FROM ticket | |
| 107 | - GROUP BY reporter | |
| 108 | - ORDER BY reporter | |
| 109 | - ) AS t2 | |
| 110 | - ON t1.author = t2.author; | |
| 111 | - ''') | |
| 112 | - | |
| 113 | - # wiki_collab_count_view | |
| 114 | - cursor.execute(''' | |
| 115 | - CREATE OR REPLACE VIEW wiki_collab_count_view AS | |
| 116 | - SELECT author, count(*) from wiki GROUP BY author; | |
| 117 | - ''') | |
| 118 | - | |
| 119 | - | |
| 120 | -def drop_views(apps, schema_editor): | |
| 121 | - connection = connections['trac'] | |
| 122 | - | |
| 123 | - cursor = connection.cursor() | |
| 124 | - cursor.execute(''' | |
| 125 | - DROP VIEW IF EXISTS revision_view; | |
| 126 | - DROP VIEW IF EXISTS ticket_view; | |
| 127 | - DROP VIEW IF EXISTS wiki_view; | |
| 128 | - DROP VIEW IF EXISTS ticket_collab_count_view; | |
| 129 | - DROP VIEW IF EXISTS wiki_collab_count_view; | |
| 130 | - DROP VIEW IF EXISTS attachment_view; | |
| 131 | - ''') | |
| 4 | +from django.db import models, migrations | |
| 5 | +import django.db.models.deletion | |
| 6 | +import hitcounter.models | |
| 7 | +from django.conf import settings | |
| 132 | 8 | |
| 133 | 9 | |
| 134 | 10 | class Migration(migrations.Migration): |
| 135 | 11 | |
| 136 | 12 | dependencies = [ |
| 13 | + migrations.swappable_dependency(settings.AUTH_USER_MODEL), | |
| 137 | 14 | ] |
| 138 | 15 | |
| 139 | 16 | operations = [ |
| 140 | - migrations.RunPython(code=create_views, reverse_code=drop_views) | |
| 17 | + migrations.CreateModel( | |
| 18 | + name='Attachment', | |
| 19 | + fields=[ | |
| 20 | + ('url', models.TextField(serialize=False, primary_key=True)), | |
| 21 | + ('attach_id', models.TextField()), | |
| 22 | + ('used_by', models.TextField()), | |
| 23 | + ('filename', models.TextField()), | |
| 24 | + ('author', models.TextField(blank=True)), | |
| 25 | + ('title', models.TextField(blank=True)), | |
| 26 | + ('description', models.TextField(blank=True)), | |
| 27 | + ('modified', models.DateTimeField(blank=True)), | |
| 28 | + ('mimetype', models.TextField(blank=True)), | |
| 29 | + ('size', models.IntegerField(blank=True)), | |
| 30 | + ('ipnr', models.TextField(blank=True)), | |
| 31 | + ], | |
| 32 | + options={ | |
| 33 | + 'verbose_name': 'Attachment', | |
| 34 | + 'verbose_name_plural': 'Attachment', | |
| 35 | + }, | |
| 36 | + bases=(models.Model, hitcounter.models.HitCounterModelMixin), | |
| 37 | + ), | |
| 38 | + migrations.CreateModel( | |
| 39 | + name='Revision', | |
| 40 | + fields=[ | |
| 41 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
| 42 | + ('rev', models.TextField(blank=True)), | |
| 43 | + ('author', models.TextField(blank=True)), | |
| 44 | + ('message', models.TextField(blank=True)), | |
| 45 | + ('description', models.TextField(blank=True)), | |
| 46 | + ('repository_name', models.TextField(blank=True)), | |
| 47 | + ('created', models.DateTimeField(null=True, blank=True)), | |
| 48 | + ('modified', models.DateTimeField(null=True, blank=True)), | |
| 49 | + ], | |
| 50 | + options={ | |
| 51 | + 'verbose_name': 'Revision', | |
| 52 | + 'verbose_name_plural': 'Revision', | |
| 53 | + }, | |
| 54 | + bases=(models.Model, hitcounter.models.HitCounterModelMixin), | |
| 55 | + ), | |
| 56 | + migrations.CreateModel( | |
| 57 | + name='Ticket', | |
| 58 | + fields=[ | |
| 59 | + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
| 60 | + ('summary', models.TextField(blank=True)), | |
| 61 | + ('description_ticket', models.TextField(blank=True)), | |
| 62 | + ('milestone', models.TextField(blank=True)), | |
| 63 | + ('priority', models.TextField(blank=True)), | |
| 64 | + ('component', models.TextField(blank=True)), | |
| 65 | + ('version', models.TextField(blank=True)), | |
| 66 | + ('severity', models.TextField(blank=True)), | |
| 67 | + ('reporter', models.TextField(blank=True)), | |
| 68 | + ('author', models.TextField(blank=True)), | |
| 69 | + ('status', models.TextField(blank=True)), | |
| 70 | + ('tag', models.TextField(blank=True)), | |
| 71 | + ('keywords', models.TextField(blank=True)), | |
| 72 | + ('collaborators', models.TextField(blank=True)), | |
| 73 | + ('created', models.DateTimeField(null=True, blank=True)), | |
| 74 | + ('modified', models.DateTimeField(null=True, blank=True)), | |
| 75 | + ('modified_by', models.TextField(blank=True)), | |
| 76 | + ('owner', models.TextField(blank=True)), | |
| 77 | + ('resolution', models.TextField(blank=True)), | |
| 78 | + ], | |
| 79 | + options={ | |
| 80 | + 'verbose_name': 'Ticket', | |
| 81 | + 'verbose_name_plural': 'Ticket', | |
| 82 | + }, | |
| 83 | + bases=(models.Model, hitcounter.models.HitCounterModelMixin), | |
| 84 | + ), | |
| 85 | + migrations.CreateModel( | |
| 86 | + name='Wiki', | |
| 87 | + fields=[ | |
| 88 | + ('title', models.TextField(serialize=False, primary_key=True)), | |
| 89 | + ('wiki_text', models.TextField(blank=True)), | |
| 90 | + ('author', models.TextField(blank=True)), | |
| 91 | + ('collaborators', models.TextField(blank=True)), | |
| 92 | + ('created', models.DateTimeField(null=True, blank=True)), | |
| 93 | + ('modified', models.DateTimeField(null=True, blank=True)), | |
| 94 | + ('comment', models.TextField(blank=True)), | |
| 95 | + ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True)), | |
| 96 | + ], | |
| 97 | + options={ | |
| 98 | + 'verbose_name': 'Wiki', | |
| 99 | + 'verbose_name_plural': 'Wiki', | |
| 100 | + }, | |
| 101 | + bases=(models.Model, hitcounter.models.HitCounterModelMixin), | |
| 102 | + ), | |
| 141 | 103 | ] | ... | ... |
| ... | ... | @@ -7,23 +7,29 @@ from django.conf import settings |
| 7 | 7 | |
| 8 | 8 | from hitcounter.models import HitCounterModelMixin |
| 9 | 9 | |
| 10 | +from colab.proxy.utils.models import Collaboration | |
| 10 | 11 | from colab.accounts.models import User |
| 12 | +from django.utils.translation import ugettext_lazy as _ | |
| 11 | 13 | |
| 12 | 14 | |
| 13 | 15 | class Attachment(models.Model, HitCounterModelMixin): |
| 16 | + type = 'attachment' | |
| 17 | + icon_name = 'file' | |
| 14 | 18 | url = models.TextField(primary_key=True) |
| 15 | 19 | attach_id = models.TextField() |
| 16 | 20 | used_by = models.TextField() |
| 17 | 21 | filename = models.TextField() |
| 18 | 22 | author = models.TextField(blank=True) |
| 23 | + title = models.TextField(blank=True) | |
| 19 | 24 | description = models.TextField(blank=True) |
| 20 | 25 | created = models.DateTimeField(blank=True) |
| 21 | 26 | mimetype = models.TextField(blank=True) |
| 22 | 27 | size = models.IntegerField(blank=True) |
| 28 | + ipnr = models.TextField(blank=True) | |
| 23 | 29 | |
| 24 | 30 | class Meta: |
| 25 | - managed = False | |
| 26 | - db_table = 'attachment_view' | |
| 31 | + verbose_name = _('Attachment') | |
| 32 | + verbose_name_plural = _('Attachment') | |
| 27 | 33 | |
| 28 | 34 | @property |
| 29 | 35 | def filepath(self): |
| ... | ... | @@ -43,18 +49,23 @@ class Attachment(models.Model, HitCounterModelMixin): |
| 43 | 49 | except User.DoesNotExist: |
| 44 | 50 | return None |
| 45 | 51 | |
| 46 | - | |
| 47 | 52 | class Revision(models.Model, HitCounterModelMixin): |
| 48 | - key = models.TextField(blank=True, primary_key=True) | |
| 53 | + update_field = 'created' | |
| 54 | + icon_name = 'align-right' | |
| 49 | 55 | rev = models.TextField(blank=True) |
| 50 | 56 | author = models.TextField(blank=True) |
| 51 | 57 | message = models.TextField(blank=True) |
| 58 | + description = models.TextField(blank=True) | |
| 52 | 59 | repository_name = models.TextField(blank=True) |
| 53 | 60 | created = models.DateTimeField(blank=True, null=True) |
| 54 | 61 | |
| 62 | + @property | |
| 63 | + def title(self): | |
| 64 | + return u'{} [{}]'.format(self.repository_name, self.rev) | |
| 65 | + | |
| 55 | 66 | class Meta: |
| 56 | - managed = False | |
| 57 | - db_table = 'revision_view' | |
| 67 | + verbose_name = _('Revision') | |
| 68 | + verbose_name_plural = _('Revision') | |
| 58 | 69 | |
| 59 | 70 | def get_absolute_url(self): |
| 60 | 71 | return u'/changeset/{}/{}'.format(self.rev, self.repository_name) |
| ... | ... | @@ -66,10 +77,11 @@ class Revision(models.Model, HitCounterModelMixin): |
| 66 | 77 | return None |
| 67 | 78 | |
| 68 | 79 | |
| 69 | -class Ticket(models.Model, HitCounterModelMixin): | |
| 70 | - id = models.IntegerField(primary_key=True) | |
| 80 | +class Ticket(Collaboration, HitCounterModelMixin): | |
| 81 | + icon_name = 'tag' | |
| 82 | + type = 'ticket' | |
| 71 | 83 | summary = models.TextField(blank=True) |
| 72 | - description = models.TextField(blank=True) | |
| 84 | + description_ticket = models.TextField(blank=True) | |
| 73 | 85 | milestone = models.TextField(blank=True) |
| 74 | 86 | priority = models.TextField(blank=True) |
| 75 | 87 | component = models.TextField(blank=True) |
| ... | ... | @@ -78,15 +90,28 @@ class Ticket(models.Model, HitCounterModelMixin): |
| 78 | 90 | reporter = models.TextField(blank=True) |
| 79 | 91 | author = models.TextField(blank=True) |
| 80 | 92 | status = models.TextField(blank=True) |
| 93 | + tag = models.TextField(blank=True) | |
| 81 | 94 | keywords = models.TextField(blank=True) |
| 82 | 95 | collaborators = models.TextField(blank=True) |
| 83 | 96 | created = models.DateTimeField(blank=True, null=True) |
| 84 | 97 | modified = models.DateTimeField(blank=True, null=True) |
| 85 | - modified_by = models.TextField(blank=True) | |
| 98 | + owner = models.TextField(blank=True) | |
| 99 | + resolution = models.TextField(blank=True) | |
| 100 | + | |
| 101 | + @property | |
| 102 | + def title(self): | |
| 103 | + return u'#{} - {}'.format(self.id, self.summary) | |
| 104 | + | |
| 105 | + @property | |
| 106 | + def description(self): | |
| 107 | + return u'{}\n{}\n{}\n{}\n{}\n{}\n{}'.format( | |
| 108 | + self.description_ticket, self.milestone, self.component, | |
| 109 | + self.severity, self.reporter, self.keywords, self.collaborators | |
| 110 | + ) | |
| 86 | 111 | |
| 87 | 112 | class Meta: |
| 88 | - managed = False | |
| 89 | - db_table = 'ticket_view' | |
| 113 | + verbose_name = _('Ticket') | |
| 114 | + verbose_name_plural = _('Ticket') | |
| 90 | 115 | |
| 91 | 116 | def get_absolute_url(self): |
| 92 | 117 | return u'/ticket/{}'.format(self.id) |
| ... | ... | @@ -104,21 +129,26 @@ class Ticket(models.Model, HitCounterModelMixin): |
| 104 | 129 | return None |
| 105 | 130 | |
| 106 | 131 | |
| 107 | -class Wiki(models.Model, HitCounterModelMixin): | |
| 108 | - name = models.TextField(primary_key=True) | |
| 132 | +class Wiki(Collaboration, HitCounterModelMixin): | |
| 133 | + type = "wiki" | |
| 134 | + icon_name = "book" | |
| 135 | + title = models.TextField(primary_key=True) | |
| 109 | 136 | wiki_text = models.TextField(blank=True) |
| 110 | 137 | author = models.TextField(blank=True) |
| 111 | 138 | collaborators = models.TextField(blank=True) |
| 112 | 139 | created = models.DateTimeField(blank=True, null=True) |
| 113 | 140 | modified = models.DateTimeField(blank=True, null=True) |
| 114 | - modified_by = models.TextField(blank=True) | |
| 141 | + | |
| 142 | + @property | |
| 143 | + def description(self): | |
| 144 | + return u'{}\n{}'.format(self.wiki_text, self.collaborators) | |
| 115 | 145 | |
| 116 | 146 | class Meta: |
| 117 | - managed = False | |
| 118 | - db_table = 'wiki_view' | |
| 147 | + verbose_name = _('Wiki') | |
| 148 | + verbose_name_plural = _('Wiki') | |
| 119 | 149 | |
| 120 | 150 | def get_absolute_url(self): |
| 121 | - return u'/wiki/{}'.format(self.name) | |
| 151 | + return u'/wiki/{}'.format(self.title) | |
| 122 | 152 | |
| 123 | 153 | def get_author(self): |
| 124 | 154 | try: |
| ... | ... | @@ -128,6 +158,6 @@ class Wiki(models.Model, HitCounterModelMixin): |
| 128 | 158 | |
| 129 | 159 | def get_modified_by(self): |
| 130 | 160 | try: |
| 131 | - return User.objects.get(username=self.modified_by) | |
| 161 | + return User.objects.get(username=self.author) | |
| 132 | 162 | except User.DoesNotExist: |
| 133 | 163 | return None | ... | ... |
| ... | ... | @@ -75,7 +75,7 @@ class AttachmentIndex(BaseIndex, indexes.Indexable): |
| 75 | 75 | |
| 76 | 76 | |
| 77 | 77 | class WikiIndex(BaseIndex, indexes.Indexable): |
| 78 | - title = indexes.CharField(model_attr='name') | |
| 78 | + title = indexes.CharField(model_attr='title') | |
| 79 | 79 | collaborators = indexes.CharField( |
| 80 | 80 | model_attr='collaborators', |
| 81 | 81 | null=True, | ... | ... |
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +{{ object.filename }} | |
| 2 | +{{ object.filename|slugify }} | |
| 3 | +{{ object.description }} | |
| 4 | +{{ object.description|slugify }} | |
| 5 | +{{ object.used_by }} | |
| 6 | +{{ object.mimetype }} | |
| 7 | +{{ object.get_author.get_full_name }} | |
| 8 | + | |
| 9 | +{% for k, v in extracted.metadata.items %} | |
| 10 | + {% for val in v %} | |
| 11 | + {{ k }}: {{ val|safe }} | |
| 12 | + {% endfor %} | |
| 13 | +{% endfor %} | |
| 14 | + | |
| 15 | +{{ extracted.contents|striptags|safe }} | ... | ... |
| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | +{{ object.repository_name }} | |
| 2 | +{{ object.repository_name|slugify }} | |
| 3 | +{{ object.rev }} | |
| 4 | +{{ object.rev|slugify }} | |
| 5 | +{% firstof object.get_author.get_full_name object.author %} | |
| 6 | +{% firstof object.get_author.get_full_name|slugify object.author|slugify %} | |
| 7 | +{{ object.message }} | |
| 8 | +{{ object.message|slugify }} | ... | ... |
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +{{ object.summary }} | |
| 2 | +{{ object.summary|slugify }} | |
| 3 | +{{ object.description }} | |
| 4 | +{{ object.description|slugify }} | |
| 5 | +{{ object.milestone }} | |
| 6 | +{{ object.milestone|slugify }} | |
| 7 | +{{ object.component|slugify }} | |
| 8 | +{{ object.version }} | |
| 9 | +{{ object.severity }} | |
| 10 | +{{ object.severity|slugify }} | |
| 11 | +{{ object.reporter }} | |
| 12 | +{{ object.reporter|slugify }} | |
| 13 | +{% firstof object.get_author.get_fullname or object.author %} | |
| 14 | +{% firstof object.get_author.get_fullname|slugify or object.author|slugify %} | |
| 15 | +{{ object.status }} | |
| 16 | +{{ object.status|slugify }} | |
| 17 | +{{ object.keywords }} | |
| 18 | +{{ object.keywords|slugify }} | |
| 19 | +{{ object.collaborators }} | |
| 20 | +{{ object.collaborators|slugify }} | ... | ... |
| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | +{{ object.author }} | |
| 2 | +{{ object.get_author.get_full_name }} | |
| 3 | +{{ object.get_author.get_full_name|slugify }} | |
| 4 | +{{ object.name }} | |
| 5 | +{{ object.name|slugify }} | |
| 6 | +{{ object.collaborators }} | |
| 7 | +{{ object.collaborators|slugify }} | |
| 8 | +{{ object.wiki_text }} | |
| 9 | +{{ object.wiki_text|slugify }} | ... | ... |
| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | +""" | |
| 2 | +Test DataAPI class. | |
| 3 | +Objective: Test parameters and behavior. | |
| 4 | +""" | |
| 5 | +from colab.proxy.trac.data_api import TracDataAPI | |
| 6 | + | |
| 7 | +from django.db import connections | |
| 8 | +from django.test import TestCase | |
| 9 | + | |
| 10 | + | |
| 11 | +class TracDataAPITest(TestCase): | |
| 12 | + | |
| 13 | + fixtures = ["trac_data.json"] | |
| 14 | + | |
| 15 | + def setUp(self): | |
| 16 | + self.connection = connections['default'] | |
| 17 | + self.cursor = self.connection.cursor() | |
| 18 | + | |
| 19 | + def tearDown(self): | |
| 20 | + self.connection.close() | |
| 21 | + | |
| 22 | + def test_dict_fetch_all(self): | |
| 23 | + trac_dict = TracDataAPI() | |
| 24 | + self.cursor.execute(''' SELECT * FROM trac_wiki;''') | |
| 25 | + dict_result = trac_dict.dictfetchall(self.cursor) | |
| 26 | + self.assertIn('collaborators', dict_result[0]) | |
| 27 | + | |
| 28 | + def test_dict_fetch_all_is_dict(self): | |
| 29 | + trac_dict = TracDataAPI() | |
| 30 | + self.cursor.execute(''' SELECT * FROM trac_wiki;''') | |
| 31 | + dict_result = trac_dict.dictfetchall(self.cursor) | |
| 32 | + self.assertIsInstance(dict_result[0], dict) | ... | ... |
| ... | ... | @@ -0,0 +1,205 @@ |
| 1 | +""" | |
| 2 | +Test Trac class. | |
| 3 | +Objective: Test parameters and behavior. | |
| 4 | +""" | |
| 5 | +from colab.accounts.models import User | |
| 6 | +from colab.proxy.trac.models import Attachment, Revision, Ticket, Wiki | |
| 7 | +from django.test import TestCase | |
| 8 | + | |
| 9 | + | |
| 10 | +class AttachmentTest(TestCase): | |
| 11 | + | |
| 12 | + def setUp(self): | |
| 13 | + self.attachment = self.create_attachment() | |
| 14 | + | |
| 15 | + def tearDown(self): | |
| 16 | + pass | |
| 17 | + | |
| 18 | + def create_attachment(self): | |
| 19 | + attachment = Attachment() | |
| 20 | + attachment.type = 'attachment' | |
| 21 | + attachment.icon_name = 'file' | |
| 22 | + attachment.url = 'example.com' | |
| 23 | + attachment.attach_id = 'attach_id' | |
| 24 | + attachment.used_by = 'used_by' | |
| 25 | + attachment.filename = 'filename' | |
| 26 | + attachment.author = 'author' | |
| 27 | + attachment.title = 'title' | |
| 28 | + attachment.description = 'description' | |
| 29 | + attachment.modified = '1994-11-05T08:15:30-05:00' | |
| 30 | + attachment.created = '1994-11-05T08:15:30-05:00' | |
| 31 | + attachment.mimetype = 'mimetype' | |
| 32 | + attachment.size = 20 | |
| 33 | + attachment.save() | |
| 34 | + | |
| 35 | + return attachment | |
| 36 | + | |
| 37 | + def test_validade_filepath(self): | |
| 38 | + file_path = '/mnt/trac/attachments/used_by/attach_id/filename' | |
| 39 | + self.assertEqual(file_path, self.attachment.filepath) | |
| 40 | + | |
| 41 | + def test_validade_absolute_url(self): | |
| 42 | + absolute_url = u'/raw-attachment/example.com' | |
| 43 | + self.assertEqual(absolute_url, self.attachment.get_absolute_url()) | |
| 44 | + | |
| 45 | + def test_validade_author(self): | |
| 46 | + author = 'author' | |
| 47 | + self.user = create_user() | |
| 48 | + self.assertEqual(author, str(self.attachment.get_author())) | |
| 49 | + | |
| 50 | + def test_invalidade_author(self): | |
| 51 | + self.assertEqual(None, self.attachment.get_author()) | |
| 52 | + | |
| 53 | + | |
| 54 | +class RevisionTest(TestCase): | |
| 55 | + def setUp(self): | |
| 56 | + self.revision = self.create_revision() | |
| 57 | + | |
| 58 | + def create_revision(self): | |
| 59 | + revision = Revision() | |
| 60 | + revision.update_field = 'created' | |
| 61 | + revision.icon_name = 'align-right' | |
| 62 | + revision.rev = 'rev' | |
| 63 | + revision.author = 'author' | |
| 64 | + revision.message = 'message' | |
| 65 | + revision.description = 'description' | |
| 66 | + revision.repository_name = 'repository' | |
| 67 | + revision.created = '1994-11-05T08:15:30-05:00' | |
| 68 | + revision.modified = '1994-11-05T08:15:30-05:00' | |
| 69 | + revision.save() | |
| 70 | + | |
| 71 | + return revision | |
| 72 | + | |
| 73 | + def test_title(self): | |
| 74 | + title = 'repository [rev]' | |
| 75 | + self.assertEqual(title, self.revision.title) | |
| 76 | + | |
| 77 | + def test_get_absolute_url(self): | |
| 78 | + absolute_url = '/changeset/rev/repository' | |
| 79 | + self.assertEqual(absolute_url, self.revision.get_absolute_url()) | |
| 80 | + | |
| 81 | + def test_get_author(self): | |
| 82 | + author = 'author' | |
| 83 | + self.user = create_user() | |
| 84 | + self.assertEqual(author, str(self.revision.get_author())) | |
| 85 | + | |
| 86 | + def test_invalid_get_author(self): | |
| 87 | + self.assertEqual(None, self.revision.get_author()) | |
| 88 | + | |
| 89 | + | |
| 90 | +class TicketTest(TestCase): | |
| 91 | + def setUp(self): | |
| 92 | + self.ticket = self.create_ticket() | |
| 93 | + | |
| 94 | + def create_ticket(self): | |
| 95 | + ticket = Ticket() | |
| 96 | + ticket.icon_name = 'tag' | |
| 97 | + ticket.type = 'ticket' | |
| 98 | + ticket.id = 20 | |
| 99 | + ticket.summary = 'summary' | |
| 100 | + ticket.description_ticket = 'description' | |
| 101 | + ticket.milestone = 'milestone' | |
| 102 | + ticket.priority = 'priority' | |
| 103 | + ticket.component = 'component' | |
| 104 | + ticket.version = 'version' | |
| 105 | + ticket.severity = 'severity' | |
| 106 | + ticket.reporter = 'reporter' | |
| 107 | + ticket.author = 'author' | |
| 108 | + ticket.status = 'status' | |
| 109 | + ticket.tag = 'tag' | |
| 110 | + ticket.keywords = 'keywords' | |
| 111 | + ticket.collaborators = 'collaborators' | |
| 112 | + ticket.created = '1994-11-05T08:15:30-05:00' | |
| 113 | + ticket.modified = '1994-11-05T08:15:30-05:00' | |
| 114 | + ticket.save() | |
| 115 | + | |
| 116 | + return ticket | |
| 117 | + | |
| 118 | + def test_title(self): | |
| 119 | + title = '#20 - summary' | |
| 120 | + self.assertEqual(title, self.ticket.title) | |
| 121 | + | |
| 122 | + def test_description(self): | |
| 123 | + description1 = u'description\nmilestone\ncomponent\nseverity' | |
| 124 | + description2 = '\nreporter\nkeywords\ncollaborators' | |
| 125 | + description_test = description1 + description2 | |
| 126 | + self.assertEqual(description_test, self.ticket.description) | |
| 127 | + | |
| 128 | + def test_get_absolute_url(self): | |
| 129 | + absolute_url = '/ticket/20' | |
| 130 | + self.assertEqual(absolute_url, self.ticket.get_absolute_url()) | |
| 131 | + | |
| 132 | + def test_get_author(self): | |
| 133 | + author = 'author' | |
| 134 | + self.user = create_user() | |
| 135 | + self.assertEqual(author, str(self.ticket.get_author())) | |
| 136 | + | |
| 137 | + def test_invalid_get_author(self): | |
| 138 | + author = None | |
| 139 | + self.assertEqual(author, self.ticket.get_author()) | |
| 140 | + | |
| 141 | + def test_get_modified_by(self): | |
| 142 | + self.user = create_user() | |
| 143 | + get_modified_by = str(self.ticket.get_modified_by()) | |
| 144 | + self.assertEqual(str(self.ticket.modified_by), get_modified_by) | |
| 145 | + | |
| 146 | + def test_invalid_get_modified_by(self): | |
| 147 | + get_modified_by = self.ticket.get_modified_by() | |
| 148 | + self.assertEqual(None, get_modified_by) | |
| 149 | + | |
| 150 | + | |
| 151 | +class WikiTest(TestCase): | |
| 152 | + def setUp(self): | |
| 153 | + self.wiki = self.create_wiki() | |
| 154 | + | |
| 155 | + def create_wiki(self): | |
| 156 | + wiki = Wiki() | |
| 157 | + wiki.type = "wiki" | |
| 158 | + wiki.icon_name = "book" | |
| 159 | + wiki.title = 'title' | |
| 160 | + wiki.wiki_text = 'wiki_text' | |
| 161 | + wiki.author = 'author' | |
| 162 | + wiki.collaborators = 'collaborators' | |
| 163 | + wiki.created = '1994-11-05T08:15:30-05:00' | |
| 164 | + wiki.modified = '1994-11-05T08:15:30-05:00' | |
| 165 | + wiki.save() | |
| 166 | + | |
| 167 | + return wiki | |
| 168 | + | |
| 169 | + def test_description(self): | |
| 170 | + description_test = u'wiki_text\ncollaborators' | |
| 171 | + self.assertEqual(description_test, self.wiki.description) | |
| 172 | + | |
| 173 | + def test_get_absolute_url(self): | |
| 174 | + absolute_url = u'/wiki/title' | |
| 175 | + self.assertEqual(absolute_url, self.wiki.get_absolute_url()) | |
| 176 | + | |
| 177 | + def test_get_author(self): | |
| 178 | + author = 'author' | |
| 179 | + self.user = create_user() | |
| 180 | + self.assertEqual(author, str(self.wiki.get_author())) | |
| 181 | + | |
| 182 | + def test_invalid_get_author(self): | |
| 183 | + author = None | |
| 184 | + self.assertEqual(author, self.wiki.get_author()) | |
| 185 | + | |
| 186 | + def test_get_modified_by(self): | |
| 187 | + self.user = create_user() | |
| 188 | + get_modified_by = str(self.wiki.get_modified_by()) | |
| 189 | + modified_by = "author" | |
| 190 | + self.assertEqual(modified_by, get_modified_by) | |
| 191 | + | |
| 192 | + def test_invalid_get_modified_by(self): | |
| 193 | + get_modified_by = self.wiki.get_modified_by() | |
| 194 | + self.assertEqual(None, get_modified_by) | |
| 195 | + | |
| 196 | + | |
| 197 | +def create_user(): | |
| 198 | + user = User() | |
| 199 | + user.username = "author" | |
| 200 | + user.first_name = "FisrtName" | |
| 201 | + user.last_name = "LastName" | |
| 202 | + user.modified_by = "author" | |
| 203 | + user.save() | |
| 204 | + | |
| 205 | + return user | ... | ... |
| ... | ... | @@ -18,7 +18,9 @@ import os |
| 18 | 18 | # If extensions (or modules to document with autodoc) are in another directory, |
| 19 | 19 | # add these directories to sys.path here. If the directory is relative to the |
| 20 | 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. |
| 21 | -#sys.path.insert(0, os.path.abspath('.')) | |
| 21 | +sys.path.insert(0, os.path.abspath('../../colab/proxy')) | |
| 22 | +from django.conf import settings | |
| 23 | +settings.configure() | |
| 22 | 24 | |
| 23 | 25 | # -- General configuration ------------------------------------------------ |
| 24 | 26 | ... | ... |
| ... | ... | @@ -16,6 +16,72 @@ Plugins |
| 16 | 16 | ------- |
| 17 | 17 | .. TODO |
| 18 | 18 | |
| 19 | +Trac | |
| 20 | +++++ | |
| 21 | + | |
| 22 | + | |
| 23 | +Since Trac already installed: | |
| 24 | + | |
| 25 | +- Easily, you can install it as follows: | |
| 26 | + | |
| 27 | +.. code-block:: sh | |
| 28 | + | |
| 29 | + $ pip install trac | |
| 30 | + | |
| 31 | +To enable Trac plugin must first configure the trac database in /etc/colab/settings.yml: | |
| 32 | + | |
| 33 | +1. vim /etc/colab/settings.yaml | |
| 34 | + | |
| 35 | +.. code-block:: yaml | |
| 36 | + | |
| 37 | + DATABASES: | |
| 38 | + default: | |
| 39 | + ENGINE: django.db.backends.postgresql_psycopg2 | |
| 40 | + HOST: localhost | |
| 41 | + NAME: colab | |
| 42 | + USER: colab | |
| 43 | + PASSWORD: colab | |
| 44 | + trac: | |
| 45 | + ENGINE: django.db.backends.postgresql_psycopg2 | |
| 46 | + HOST: localhost | |
| 47 | + NAME: trac | |
| 48 | + USER: colab | |
| 49 | + PASSWORD: colab | |
| 50 | + | |
| 51 | +- Yet this file uncomment in PROXIED_APPS the Trac: | |
| 52 | + | |
| 53 | +.. code-block:: yaml | |
| 54 | + | |
| 55 | + PROXIED_APPS: | |
| 56 | + # gitlab: | |
| 57 | + # upstream: 'http://localhost:8090/gitlab/' | |
| 58 | + # private_token: '' | |
| 59 | + trac: | |
| 60 | + upstream: 'http://localhost:5000/trac/' | |
| 61 | + | |
| 62 | +- Create the database in postgresql with user | |
| 63 | + | |
| 64 | +.. code-block:: sh | |
| 65 | + | |
| 66 | + $ sudo -u postgres psql | |
| 67 | + $ create database trac owner colab; | |
| 68 | + | |
| 69 | +- Now, generate the migrations: | |
| 70 | + | |
| 71 | +.. code-block:: sh | |
| 72 | + | |
| 73 | + # Since you are in the folder colab | |
| 74 | + $ workon colab | |
| 75 | + $ colab-admin makemigrations | |
| 76 | + $ colab-admin migrate trac | |
| 77 | + | |
| 78 | +- Finally, just import the Trac data (may take a few minutes): | |
| 79 | + | |
| 80 | +.. code-block:: sh | |
| 81 | + | |
| 82 | + # Since you are in the folder colab | |
| 83 | + $ colab-admin import_proxy_data | |
| 84 | + | |
| 19 | 85 | Settings |
| 20 | 86 | -------- |
| 21 | 87 | ... | ... |
| ... | ... | @@ -6,7 +6,6 @@ import sys |
| 6 | 6 | os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' |
| 7 | 7 | os.environ['COLAB_SETTINGS'] = 'tests/settings.yaml' |
| 8 | 8 | os.environ['COVERAGE_PROCESS_START'] = '.coveragerc' |
| 9 | -os.environ['REUSE_DB'] = '0' | |
| 10 | 9 | |
| 11 | 10 | import django |
| 12 | 11 | import coverage |
| ... | ... | @@ -14,7 +13,6 @@ import coverage |
| 14 | 13 | from django.test.utils import get_runner |
| 15 | 14 | from django.conf import settings |
| 16 | 15 | |
| 17 | - | |
| 18 | 16 | def runtests(): |
| 19 | 17 | if django.VERSION >= (1, 7, 0): |
| 20 | 18 | django.setup() | ... | ... |
| ... | ... | @@ -64,10 +64,10 @@ ROBOTS_NOINDEX: false |
| 64 | 64 | |
| 65 | 65 | ### Colab proxied apps |
| 66 | 66 | PROXIED_APPS: |
| 67 | - gitlab: | |
| 68 | - upstream: 'http://localhost:8090/gitlab/' | |
| 69 | - private_token: '' | |
| 70 | -# trac: | |
| 71 | -# upstream: 'http://localhost:5000/trac/' | |
| 67 | +# gitlab: | |
| 68 | +# upstream: 'http://localhost:8090/gitlab/' | |
| 69 | +# private_token: '' | |
| 70 | + trac: | |
| 71 | + upstream: 'http://localhost:5000/trac/' | |
| 72 | 72 | |
| 73 | 73 | ... | ... |
| ... | ... | @@ -19,7 +19,7 @@ fi |
| 19 | 19 | |
| 20 | 20 | yum -y groupinstall "Development tools" |
| 21 | 21 | |
| 22 | -yum install -y git unzip mercurial libev-devel gettext libxml2-devel libxslt-devel openssl-devel libffi-devel libjpeg-turbo-devel zlib-devel freetype-devel postgresql-devel python-devel postgresql-server | |
| 22 | +yum install -y git unzip mercurial libev-devel gettext libxml2-devel libxslt-devel openssl-devel libffi-devel libjpeg-turbo-devel zlib-devel freetype-devel postgresql-devel python-devel postgresql-server java | |
| 23 | 23 | |
| 24 | 24 | ### Install Virtualenvwrapper |
| 25 | 25 | which pip2.7 > /dev/null || | ... | ... |
| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | +#!/bin/bash | |
| 2 | +# chkconfig: 2345 95 20 | |
| 3 | +# description: Solr | |
| 4 | +# processname: myscript | |
| 5 | +# | |
| 6 | +#----------------------------------------------------- | |
| 7 | +# Script for running solr as a service. | |
| 8 | +# | |
| 9 | +# Usage: service solr {start|stop|restart|status}" | |
| 10 | +# | |
| 11 | +#----------------------------------------------------- | |
| 12 | +# This should be placed in /etc/init.d | |
| 13 | + | |
| 14 | +. /etc/rc.d/init.d/functions | |
| 15 | + | |
| 16 | +# Path to pid file | |
| 17 | +PIDFILE=/var/run/solr.pid | |
| 18 | + | |
| 19 | +# Service name | |
| 20 | +NAME="Solr" | |
| 21 | + | |
| 22 | +# Service description | |
| 23 | +DESC="start/stop Solr Server" | |
| 24 | + | |
| 25 | +SOLR_INIT="/home/vagrant/solr-4.10.3/start.sh" | |
| 26 | + | |
| 27 | +case $1 in | |
| 28 | + start) | |
| 29 | + action "Starting ${NAME}: " daemon --pidfile $PIDFILE $SOLR_INIT | |
| 30 | + ;; | |
| 31 | + stop) | |
| 32 | + action "Stopping ${NAME}: " killproc -p $PIDFILE | |
| 33 | + ;; | |
| 34 | + restart) | |
| 35 | + $0 stop | |
| 36 | + $0 start | |
| 37 | + ;; | |
| 38 | + status) | |
| 39 | + status -p $PIDFILE solr | |
| 40 | + ;; | |
| 41 | + *) | |
| 42 | + echo "Usage: $0 {start|stop|restart|status}" | |
| 43 | + exit 3 | |
| 44 | + ;; | |
| 45 | +esac | ... | ... |
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | set -x |
| 4 | 4 | |
| 5 | +### Configure Colab | |
| 5 | 6 | export VIRTUALENVWRAPPER_PYTHON="/usr/bin/python2.7" |
| 6 | 7 | |
| 7 | 8 | set +e |
| ... | ... | @@ -32,3 +33,22 @@ fi |
| 32 | 33 | |
| 33 | 34 | colab-admin migrate |
| 34 | 35 | colab-admin loaddata /vagrant/tests/test_data.json |
| 36 | + | |
| 37 | + | |
| 38 | +### Install solr | |
| 39 | + | |
| 40 | +colab-admin build_solr_schema -f /tmp/schema.xml | |
| 41 | + | |
| 42 | +export SOLR_VERSION=4.10.3 | |
| 43 | +export SOLR_CONFS="/tmp/schema.xml" | |
| 44 | + | |
| 45 | +$basedir/ci/install_solr.sh | |
| 46 | +/home/vagrant/solr-4.10.3/bin/solr stop -p 8983 | |
| 47 | + | |
| 48 | +# Init.d Solr files | |
| 49 | +sudo cp $basedir/vagrant/misc/etc/init.d/solr /etc/init.d/ | |
| 50 | +cp $basedir/vagrant/solr/start.sh /home/vagrant/solr-$SOLR_VERSION | |
| 51 | +sudo chkconfig --add solr | |
| 52 | +sudo service solr start | |
| 53 | + | |
| 54 | +colab-admin rebuild_index --noinput | ... | ... |
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +#!/bin/bash | |
| 2 | + | |
| 3 | +# Directory where solr is installed | |
| 4 | +SOLR_HOME=/home/vagrant/solr-4.10.3/example | |
| 5 | + | |
| 6 | +# Java options for Solr | |
| 7 | +OPTIONS="-Xmx128m" | |
| 8 | + | |
| 9 | +# Path to pid file | |
| 10 | +PIDFILE=/var/run/solr.pid | |
| 11 | + | |
| 12 | +# Path to log file | |
| 13 | +LOG_FILE=/var/log/solr.log | |
| 14 | + | |
| 15 | +COMMAND="java $OPTIONS -jar start.jar" | |
| 16 | + | |
| 17 | +cd $SOLR_HOME | |
| 18 | +nohup $COMMAND > $LOG_FILE 2>&1 & | |
| 19 | +echo $! > $PIDFILE | |
| 20 | +exit $? | ... | ... |
| ... | ... | @@ -5,7 +5,7 @@ set -ex |
| 5 | 5 | ### Install dependencies |
| 6 | 6 | apt-get update |
| 7 | 7 | |
| 8 | -apt-get install curl git unzip mercurial build-essential libev-dev gettext libxml2-dev libxslt1-dev libssl-dev libffi-dev libjpeg-dev zlib1g-dev libfreetype6-dev libpq-dev python-dev postgresql virtualenvwrapper python-pip -y | |
| 8 | +apt-get install curl git unzip mercurial build-essential libev-dev gettext libxml2-dev libxslt1-dev libssl-dev libffi-dev libjpeg-dev zlib1g-dev libfreetype6-dev libpq-dev python-dev postgresql virtualenvwrapper python-pip java-common -y | |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | ### Create conf directory | ... | ... |
-
Acabei de refatorar a data_api vou fazer testes para ela logo deixem a revisão com menor prioridade.
-
This is pending peer-review, right?
-
The MR is okay. The search filter still needs to be made so it can understand plugin searchObjects but that's another task.
-
@thiagitosouza tests are failing. There are also migrations missing, right @darksshades?
@thiagitosouza this should be tests with and without trac installation to make sure it's all working properly ;)
-
Is this fixed?
-
@kanashiro.duarte do you know the status of this? This MR is drifting away from master and getting harder and harder to get merged. Can you check it with the team please?
-
Status changed to closed
-
This is not necessary anymore, because we are no longer using Trac in Colab (for now).