├── cbd_project ├── cbd │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ └── __init__.pyc │ ├── tests.py │ ├── urls.pyc │ ├── admin.pyc │ ├── models.pyc │ ├── views.pyc │ ├── __init__.pyc │ ├── urls.py │ ├── admin.py │ ├── models.py │ └── views.py ├── cbd_project │ ├── __init__.py │ ├── urls.pyc │ ├── wsgi.pyc │ ├── __init__.pyc │ ├── settings.pyc │ ├── wsgi.py │ ├── urls.py │ └── settings.py ├── static │ ├── less │ │ ├── mixins.less │ │ ├── variables.less │ │ └── sb-admin-2.less │ ├── .DS_Store │ ├── admin │ │ ├── img │ │ │ ├── nav-bg.gif │ │ │ ├── icon-no.gif │ │ │ ├── icon-yes.gif │ │ │ ├── default-bg.gif │ │ │ ├── icon_alert.gif │ │ │ ├── icon_clock.gif │ │ │ ├── icon_error.gif │ │ │ ├── tooltag-add.png │ │ │ ├── changelist-bg.gif │ │ │ ├── icon-unknown.gif │ │ │ ├── icon_addlink.gif │ │ │ ├── icon_calendar.gif │ │ │ ├── icon_searchbox.png │ │ │ ├── icon_success.gif │ │ │ ├── inline-delete.png │ │ │ ├── inline-restore.png │ │ │ ├── nav-bg-grabber.gif │ │ │ ├── nav-bg-reverse.gif │ │ │ ├── selector-icons.gif │ │ │ ├── sorting-icons.gif │ │ │ ├── deleted-overlay.gif │ │ │ ├── icon_changelink.gif │ │ │ ├── icon_deletelink.gif │ │ │ ├── nav-bg-selected.gif │ │ │ ├── selector-search.gif │ │ │ ├── changelist-bg_rtl.gif │ │ │ ├── default-bg-reverse.gif │ │ │ ├── gis │ │ │ │ ├── move_vertex_off.png │ │ │ │ └── move_vertex_on.png │ │ │ ├── inline-delete-8bit.png │ │ │ ├── inline-restore-8bit.png │ │ │ ├── inline-splitter-bg.gif │ │ │ └── tooltag-arrowright.png │ │ ├── js │ │ │ ├── jquery.init.js │ │ │ ├── prepopulate.min.js │ │ │ ├── collapse.min.js │ │ │ ├── collapse.js │ │ │ ├── LICENSE-JQUERY.txt │ │ │ ├── prepopulate.js │ │ │ ├── timeparse.js │ │ │ ├── actions.min.js │ │ │ ├── admin │ │ │ │ └── RelatedObjectLookups.js │ │ │ ├── inlines.min.js │ │ │ ├── SelectBox.js │ │ │ ├── actions.js │ │ │ ├── urlify.js │ │ │ ├── calendar.js │ │ │ ├── core.js │ │ │ ├── SelectFilter2.js │ │ │ └── inlines.js │ │ └── css │ │ │ ├── dashboard.css │ │ │ ├── login.css │ │ │ ├── ie.css │ │ │ ├── rtl.css │ │ │ ├── changelists.css │ │ │ └── forms.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── font-awesome-4.1.0 │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ │ ├── less │ │ │ ├── fixed-width.less │ │ │ ├── core.less │ │ │ ├── bordered-pulled.less │ │ │ ├── rotated-flipped.less │ │ │ ├── larger.less │ │ │ ├── list.less │ │ │ ├── font-awesome.less │ │ │ ├── stacked.less │ │ │ ├── path.less │ │ │ ├── mixins.less │ │ │ └── spinning.less │ │ └── scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _core.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _larger.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _list.scss │ │ │ ├── font-awesome.scss │ │ │ ├── _stacked.scss │ │ │ ├── _path.scss │ │ │ ├── _mixins.scss │ │ │ └── _spinning.scss │ ├── css │ │ ├── plugins │ │ │ ├── morris.css │ │ │ ├── metisMenu │ │ │ │ ├── metisMenu.min.css │ │ │ │ └── metisMenu.css │ │ │ ├── timeline.css │ │ │ └── dataTables.bootstrap.css │ │ └── sb-admin-2.css │ └── js │ │ ├── sb-admin-2.js │ │ └── plugins │ │ ├── metisMenu │ │ ├── metisMenu.min.js │ │ └── metisMenu.js │ │ ├── flot │ │ ├── jquery.flot.resize.js │ │ └── jquery.flot.tooltip.min.js │ │ ├── morris │ │ └── morris-data.js │ │ └── dataTables │ │ └── dataTables.bootstrap.js ├── .DS_Store ├── manage.py └── templates │ └── cbd │ ├── index.html │ └── base.html ├── dashboard.png ├── cronscripts ├── affective_dict.txt ├── injest_twitter.py ├── topicmodelandaffectivelexicon.py └── englishstop.txt └── README.md /cbd_project/cbd/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cbd_project/cbd/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cbd_project/cbd_project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cbd_project/static/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | -------------------------------------------------------------------------------- /dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/dashboard.png -------------------------------------------------------------------------------- /cbd_project/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/.DS_Store -------------------------------------------------------------------------------- /cbd_project/cbd/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /cbd_project/cbd/urls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/urls.pyc -------------------------------------------------------------------------------- /cbd_project/cbd/admin.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/admin.pyc -------------------------------------------------------------------------------- /cbd_project/cbd/models.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/models.pyc -------------------------------------------------------------------------------- /cbd_project/cbd/views.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/views.pyc -------------------------------------------------------------------------------- /cbd_project/cbd/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/__init__.pyc -------------------------------------------------------------------------------- /cbd_project/static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/.DS_Store -------------------------------------------------------------------------------- /cbd_project/cbd_project/urls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd_project/urls.pyc -------------------------------------------------------------------------------- /cbd_project/cbd_project/wsgi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd_project/wsgi.pyc -------------------------------------------------------------------------------- /cbd_project/cbd_project/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd_project/__init__.pyc -------------------------------------------------------------------------------- /cbd_project/cbd_project/settings.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd_project/settings.pyc -------------------------------------------------------------------------------- /cbd_project/cbd/migrations/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/cbd/migrations/__init__.pyc -------------------------------------------------------------------------------- /cbd_project/static/admin/img/nav-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/nav-bg.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon-no.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon-no.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon-yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon-yes.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/default-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/default-bg.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_alert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_alert.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_clock.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_error.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/tooltag-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/tooltag-add.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/changelist-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/changelist-bg.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon-unknown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon-unknown.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_addlink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_addlink.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_calendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_calendar.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_searchbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_searchbox.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_success.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_success.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/inline-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/inline-delete.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/inline-restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/inline-restore.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/nav-bg-grabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/nav-bg-grabber.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/nav-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/nav-bg-reverse.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/selector-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/selector-icons.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/sorting-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/sorting-icons.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/deleted-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/deleted-overlay.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_changelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_changelink.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/icon_deletelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/icon_deletelink.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/nav-bg-selected.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/nav-bg-selected.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/selector-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/selector-search.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/changelist-bg_rtl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/changelist-bg_rtl.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/default-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/default-bg-reverse.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/gis/move_vertex_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/gis/move_vertex_off.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/gis/move_vertex_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/gis/move_vertex_on.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/inline-delete-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/inline-delete-8bit.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/inline-restore-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/inline-restore-8bit.png -------------------------------------------------------------------------------- /cbd_project/static/admin/img/inline-splitter-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/inline-splitter-bg.gif -------------------------------------------------------------------------------- /cbd_project/static/admin/img/tooltag-arrowright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/admin/img/tooltag-arrowright.png -------------------------------------------------------------------------------- /cbd_project/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /cbd_project/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/font-awesome-4.1.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /cbd_project/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aneesha/cbd/master/cbd_project/static/font-awesome-4.1.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /cbd_project/cbd/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.conf import settings 3 | from cbd import views 4 | 5 | urlpatterns = patterns('', 6 | 7 | ) 8 | -------------------------------------------------------------------------------- /cronscripts/affective_dict.txt: -------------------------------------------------------------------------------- 1 | {'sadness': 695, 'anticipation': 630, 'disgust': 864, 'positive': 1433, 'anger': 842, 'joy': 729, 'fear': 639, 'trust': 864, 'negative': 1846, 'surprise': 325} 2 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /cbd_project/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cbd_project.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /* Puts the included jQuery into our own namespace using noConflict and passing 2 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 3 | * namespace (i.e. this preserves pre-existing values for both window.$ and 4 | * window.jQuery). 5 | */ 6 | var django = django || {}; 7 | django.jQuery = jQuery.noConflict(true); 8 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery); 2 | -------------------------------------------------------------------------------- /cbd_project/static/less/variables.less: -------------------------------------------------------------------------------- 1 | // Variables 2 | 3 | @gray-darker: lighten(#000, 13.5%); 4 | @gray-dark: lighten(#000, 20%); 5 | @gray: lighten(#000, 33.5%); 6 | @gray-light: lighten(#000, 60%); 7 | @gray-lighter: lighten(#000, 93.5%); 8 | @gray-lightest: lighten(#000, 97.25%); 9 | @brand-primary: #428bca; 10 | @brand-success: #5cb85c; 11 | @brand-info: #5bc0de; 12 | @brand-warning: #f0ad4e; 13 | @brand-danger: #d9534f; 14 | 15 | -------------------------------------------------------------------------------- /cbd_project/cbd/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from cbd.models import UserProfile, ProcessedSocialMediaMessage, MLCache, IncorrectClassification 4 | from django.contrib.auth.models import User 5 | from django.contrib.auth.admin import UserAdmin as AuthUserAdmin 6 | 7 | admin.site.register(UserProfile) 8 | admin.site.register(ProcessedSocialMediaMessage) 9 | admin.site.register(IncorrectClassification) 10 | admin.site.register(MLCache) 11 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /cbd_project/static/css/plugins/morris.css: -------------------------------------------------------------------------------- 1 | .morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0} 2 | .morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0} 3 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /cbd_project/cbd_project/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for cbd_project project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cbd_project.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /cbd_project/cbd_project/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | from django.contrib import admin 3 | admin.autodiscover() 4 | from cbd import views 5 | 6 | urlpatterns = [ 7 | url(r'^admin/', include(admin.site.urls)), 8 | url(r'^$', views.index, name='index'), 9 | url(r'^dashboard/$', views.dashboard, name='dashboard'), 10 | url(r'^save_coding/$', views.save_coding, name='save_coding'), 11 | url(r'^moderate/$', views.moderate, name='moderate'), 12 | url(r'^logout/$', views.user_logout, name='logout'), 13 | ] 14 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "spinning.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /cbd_project/static/admin/css/dashboard.css: -------------------------------------------------------------------------------- 1 | /* DASHBOARD */ 2 | 3 | .dashboard .module table th { 4 | width: 100%; 5 | } 6 | 7 | .dashboard .module table td { 8 | white-space: nowrap; 9 | } 10 | 11 | .dashboard .module table td a { 12 | display: block; 13 | padding-right: .6em; 14 | } 15 | 16 | /* RECENT ACTIONS MODULE */ 17 | 18 | .module ul.actionlist { 19 | margin-left: 0; 20 | } 21 | 22 | ul.actionlist li { 23 | list-style-type: none; 24 | } 25 | 26 | ul.actionlist li { 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | -o-text-overflow: ellipsis; 30 | } 31 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /cbd_project/static/css/plugins/metisMenu/metisMenu.min.css: -------------------------------------------------------------------------------- 1 | .arrow{float:right}.glyphicon.arrow:before{content:"\e079"}.active>a>.glyphicon.arrow:before{content:"\e114"}.fa.arrow:before{content:"\f104"}.active>a>.fa.arrow:before{content:"\f107"}.plus-times{float:right}.fa.plus-times:before{content:"\f067"}.active>a>.fa.plus-times{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.plus-minus{float:right}.fa.plus-minus:before{content:"\f067"}.active>a>.fa.plus-minus:before{content:"\f068"} -------------------------------------------------------------------------------- /cbd_project/static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return false})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /cronscripts/injest_twitter.py: -------------------------------------------------------------------------------- 1 | from twython import Twython 2 | 3 | #Setup API Keys 4 | app_key = "" 5 | app_secret = "" 6 | oauth_token = "" 7 | oauth_token_secret = "" 8 | 9 | twitter = Twython(app_key, app_secret, oauth_token, oauth_token_secret) 10 | 11 | # see https://dev.twitter.com/rest/reference/get/search/tweets for search options 12 | results = twitter.search(q="#GoT", count=100) 13 | for tweet in results['statuses']: 14 | body = tweet['text'] 15 | id = tweet['id'] 16 | timestamp = tweet['created_at'] 17 | location = tweet['user']['location'] 18 | userid = tweet['user']['id'] 19 | username = tweet['user']['screen_name'] 20 | print id, timestamp, location, userid, username, body 21 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')"; 7 | src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')", 8 | ~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')", 9 | ~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')", 10 | ~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')"; 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cbd_project/static/font-awesome-4.1.0/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @keyframes spin { 24 | 0% { 25 | -webkit-transform: rotate(0deg); 26 | transform: rotate(0deg); 27 | } 28 | 100% { 29 | -webkit-transform: rotate(359deg); 30 | transform: rotate(359deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/collapse.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(document).ready(function() { 3 | // Add anchor tag for Show/Hide link 4 | $("fieldset.collapse").each(function(i, elem) { 5 | // Don't hide if fields in this fieldset have errors 6 | if ($(elem).find("div.errors").length == 0) { 7 | $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + 9 | ')'); 10 | } 11 | }); 12 | // Add toggle to anchor tag 13 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 14 | if ($(this).closest("fieldset").hasClass("collapsed")) { 15 | // Show 16 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 17 | } else { 18 | // Hide 19 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 20 | } 21 | return false; 22 | }); 23 | }); 24 | })(django.jQuery); 25 | -------------------------------------------------------------------------------- /cbd_project/static/js/sb-admin-2.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | $('#side-menu').metisMenu(); 4 | 5 | }); 6 | 7 | //Loads the correct sidebar on window load, 8 | //collapses the sidebar on window resize. 9 | // Sets the min-height of #page-wrapper to window size 10 | $(function() { 11 | $(window).bind("load resize", function() { 12 | topOffset = 50; 13 | width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width; 14 | if (width < 768) { 15 | $('div.navbar-collapse').addClass('collapse') 16 | topOffset = 100; // 2-row-menu 17 | } else { 18 | $('div.navbar-collapse').removeClass('collapse') 19 | } 20 | 21 | height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height; 22 | height = height - topOffset; 23 | if (height < 1) height = 1; 24 | if (height > topOffset) { 25 | $("#page-wrapper").css("min-height", (height) + "px"); 26 | } 27 | }) 28 | }) 29 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/LICENSE-JQUERY.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /cbd_project/static/admin/css/login.css: -------------------------------------------------------------------------------- 1 | /* LOGIN FORM */ 2 | 3 | body.login { 4 | background: #eee; 5 | } 6 | 7 | .login #container { 8 | background: white; 9 | border: 1px solid #ccc; 10 | width: 28em; 11 | min-width: 300px; 12 | margin-left: auto; 13 | margin-right: auto; 14 | margin-top: 100px; 15 | } 16 | 17 | .login #content-main { 18 | width: 100%; 19 | } 20 | 21 | .login form { 22 | margin-top: 1em; 23 | } 24 | 25 | .login .form-row { 26 | padding: 4px 0; 27 | float: left; 28 | width: 100%; 29 | } 30 | 31 | .login .form-row label { 32 | padding-right: 0.5em; 33 | line-height: 2em; 34 | font-size: 1em; 35 | clear: both; 36 | color: #333; 37 | } 38 | 39 | .login .form-row #id_username, .login .form-row #id_password { 40 | clear: both; 41 | padding: 6px; 42 | width: 100%; 43 | -webkit-box-sizing: border-box; 44 | -moz-box-sizing: border-box; 45 | box-sizing: border-box; 46 | } 47 | 48 | .login span.help { 49 | font-size: 10px; 50 | display: block; 51 | } 52 | 53 | .login .submit-row { 54 | clear: both; 55 | padding: 1em 0 0 9.4em; 56 | } 57 | 58 | .login .password-reset-link { 59 | text-align: center; 60 | } 61 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/metisMenu/metisMenu.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.0.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumuş 7 | * Under MIT License 8 | */ 9 | !function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document); -------------------------------------------------------------------------------- /cbd_project/static/css/plugins/metisMenu/metisMenu.css: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.0.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumuş 7 | * Under MIT License 8 | */ 9 | .arrow { 10 | float: right; 11 | } 12 | 13 | .glyphicon.arrow:before { 14 | content: "\e079"; 15 | } 16 | 17 | .active > a > .glyphicon.arrow:before { 18 | content: "\e114"; 19 | } 20 | 21 | 22 | /* 23 | * Require Font-Awesome 24 | * http://fortawesome.github.io/Font-Awesome/ 25 | */ 26 | 27 | 28 | .fa.arrow:before { 29 | content: "\f104"; 30 | } 31 | 32 | .active > a > .fa.arrow:before { 33 | content: "\f107"; 34 | } 35 | 36 | .plus-times { 37 | float: right; 38 | } 39 | 40 | .fa.plus-times:before { 41 | content: "\f067"; 42 | } 43 | 44 | .active > a > .fa.plus-times { 45 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 46 | -webkit-transform: rotate(45deg); 47 | -moz-transform: rotate(45deg); 48 | -ms-transform: rotate(45deg); 49 | -o-transform: rotate(45deg); 50 | transform: rotate(45deg); 51 | } 52 | 53 | .plus-minus { 54 | float: right; 55 | } 56 | 57 | .fa.plus-minus:before { 58 | content: "\f067"; 59 | } 60 | 61 | .active > a > .fa.plus-minus:before { 62 | content: "\f068"; 63 | } -------------------------------------------------------------------------------- /cbd_project/static/admin/css/ie.css: -------------------------------------------------------------------------------- 1 | /* IE 6 & 7 */ 2 | 3 | /* Proper fixed width for dashboard in IE6 */ 4 | 5 | .dashboard #content { 6 | *width: 768px; 7 | } 8 | 9 | .dashboard #content-main { 10 | *width: 535px; 11 | } 12 | 13 | /* IE 6 ONLY */ 14 | 15 | /* Keep header from flowing off the page */ 16 | 17 | #container { 18 | _position: static; 19 | } 20 | 21 | /* Put the right sidebars back on the page */ 22 | 23 | .colMS #content-related { 24 | _margin-right: 0; 25 | _margin-left: 10px; 26 | _position: static; 27 | } 28 | 29 | /* Put the left sidebars back on the page */ 30 | 31 | .colSM #content-related { 32 | _margin-right: 10px; 33 | _margin-left: -115px; 34 | _position: static; 35 | } 36 | 37 | .form-row { 38 | _height: 1%; 39 | } 40 | 41 | /* Fix right margin for changelist filters in IE6 */ 42 | 43 | #changelist-filter ul { 44 | _margin-right: -10px; 45 | } 46 | 47 | /* IE ignores min-height, but treats height as if it were min-height */ 48 | 49 | .change-list .filtered { 50 | _height: 400px; 51 | } 52 | 53 | /* IE doesn't know alpha transparency in PNGs */ 54 | 55 | .inline-deletelink { 56 | background: transparent url(../img/inline-delete-8bit.png) no-repeat; 57 | } 58 | 59 | /* IE7 doesn't support inline-block */ 60 | .change-list ul.toplinks li { 61 | zoom: 1; 62 | *display: inline; 63 | } -------------------------------------------------------------------------------- /cbd_project/static/admin/js/prepopulate.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $.fn.prepopulate = function(dependencies, maxLength) { 3 | /* 4 | Depends on urlify.js 5 | Populates a selected field with the values of the dependent fields, 6 | URLifies and shortens the string. 7 | dependencies - array of dependent fields ids 8 | maxLength - maximum length of the URLify'd string 9 | */ 10 | return this.each(function() { 11 | var prepopulatedField = $(this); 12 | 13 | var populate = function () { 14 | // Bail if the field's value has been changed by the user 15 | if (prepopulatedField.data('_changed')) { 16 | return; 17 | } 18 | 19 | var values = []; 20 | $.each(dependencies, function(i, field) { 21 | field = $(field); 22 | if (field.val().length > 0) { 23 | values.push(field.val()); 24 | } 25 | }); 26 | prepopulatedField.val(URLify(values.join(' '), maxLength)); 27 | }; 28 | 29 | prepopulatedField.data('_changed', false); 30 | prepopulatedField.change(function() { 31 | prepopulatedField.data('_changed', true); 32 | }); 33 | 34 | if (!prepopulatedField.val()) { 35 | $(dependencies.join(',')).keyup(populate).change(populate).focus(populate); 36 | } 37 | }); 38 | }; 39 | })(django.jQuery); 40 | -------------------------------------------------------------------------------- /cbd_project/cbd/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.db import models 3 | from django.contrib.auth.models import User 4 | 5 | class UserProfile(models.Model): 6 | 7 | VIEWER = 'Viewer' 8 | MODERATOR = 'Moderatior' 9 | USERTYPE_OPTIONS = ( 10 | (VIEWER, VIEWER), 11 | (MODERATOR, MODERATOR), 12 | ) 13 | user_type = models.CharField(max_length=50, choices=USERTYPE_OPTIONS, default=VIEWER) 14 | 15 | 16 | # Override the __unicode__() method to return out something meaningful! 17 | def __unicode__(self): 18 | return self.user.username 19 | 20 | class ProcessedSocialMediaMessage(models.Model): 21 | postid = models.TextField(blank=True) 22 | body = models.TextField(blank=True) 23 | date = models.DateTimeField() 24 | username = models.TextField(blank=True) 25 | location = models.TextField(blank=True) 26 | 27 | YES = 'Yes' 28 | NO = 'No' 29 | BULLY_OPTIONS = ( 30 | (YES, YES), 31 | (NO, NO) 32 | ) 33 | 34 | has_bullying = models.CharField(max_length=200, choices=BULLY_OPTIONS, default=YES) 35 | 36 | def __unicode__(self): 37 | return str(self.postid) 38 | 39 | class IncorrectClassification(models.Model): 40 | user = models.OneToOneField(User) 41 | post = models.OneToOneField(ProcessedSocialMediaMessage) 42 | comment = models.TextField(blank=True) 43 | 44 | def __unicode__(self): 45 | return str(self.id) 46 | 47 | class MLCache(models.Model): 48 | topic_model_json = models.TextField(blank=True) 49 | topic_model_cyberbullying_json = models.TextField(blank=True) 50 | affective_counts_json = models.TextField(blank=True) 51 | affective_counts_cyberbullying_json = models.TextField(blank=True) 52 | 53 | def __unicode__(self): 54 | return str(self.id) 55 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/metisMenu/metisMenu.js: -------------------------------------------------------------------------------- 1 | /* 2 | * metismenu - v1.0.3 3 | * Easy menu jQuery plugin for Twitter Bootstrap 3 4 | * https://github.com/onokumus/metisMenu 5 | * 6 | * Made by Osman Nuri Okumuş 7 | * Under MIT License 8 | */ 9 | ;(function ($, window, document, undefined) { 10 | 11 | var pluginName = "metisMenu", 12 | defaults = { 13 | toggle: true 14 | }; 15 | 16 | function Plugin(element, options) { 17 | this.element = element; 18 | this.settings = $.extend({}, defaults, options); 19 | this._defaults = defaults; 20 | this._name = pluginName; 21 | this.init(); 22 | } 23 | 24 | Plugin.prototype = { 25 | init: function () { 26 | 27 | var $this = $(this.element), 28 | $toggle = this.settings.toggle; 29 | 30 | if (this.isIE() <= 9) { 31 | $this.find("li.active").has("ul").children("ul").collapse("show"); 32 | $this.find("li").not(".active").has("ul").children("ul").collapse("hide"); 33 | } else { 34 | $this.find("li.active").has("ul").children("ul").addClass("collapse in"); 35 | $this.find("li").not(".active").has("ul").children("ul").addClass("collapse"); 36 | } 37 | 38 | $this.find("li").has("ul").children("a").on("click", function (e) { 39 | e.preventDefault(); 40 | 41 | $(this).parent("li").toggleClass("active").children("ul").collapse("toggle"); 42 | 43 | if ($toggle) { 44 | $(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide"); 45 | } 46 | }); 47 | }, 48 | 49 | isIE: function() {//https://gist.github.com/padolsey/527683 50 | var undef, 51 | v = 3, 52 | div = document.createElement("div"), 53 | all = div.getElementsByTagName("i"); 54 | 55 | while ( 56 | div.innerHTML = "", 57 | all[0] 58 | ) { 59 | return v > 4 ? v : undef; 60 | } 61 | } 62 | }; 63 | 64 | $.fn[ pluginName ] = function (options) { 65 | return this.each(function () { 66 | if (!$.data(this, "plugin_" + pluginName)) { 67 | $.data(this, "plugin_" + pluginName, new Plugin(this, options)); 68 | } 69 | }); 70 | }; 71 | 72 | })(jQuery, window, document); 73 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/flot/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2013 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | 23 | (function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this); 24 | 25 | (function ($) { 26 | var options = { }; // no options 27 | 28 | function init(plot) { 29 | function onResize() { 30 | var placeholder = plot.getPlaceholder(); 31 | 32 | // somebody might have hidden us and we can't plot 33 | // when we don't have the dimensions 34 | if (placeholder.width() == 0 || placeholder.height() == 0) 35 | return; 36 | 37 | plot.resize(); 38 | plot.setupGrid(); 39 | plot.draw(); 40 | } 41 | 42 | function bindEvents(plot, eventHolder) { 43 | plot.getPlaceholder().resize(onResize); 44 | } 45 | 46 | function shutdown(plot, eventHolder) { 47 | plot.getPlaceholder().unbind("resize", onResize); 48 | } 49 | 50 | plot.hooks.bindEvents.push(bindEvents); 51 | plot.hooks.shutdown.push(shutdown); 52 | } 53 | 54 | $.plot.plugins.push({ 55 | init: init, 56 | options: options, 57 | name: 'resize', 58 | version: '1.0' 59 | }); 60 | })(jQuery); -------------------------------------------------------------------------------- /cbd_project/static/admin/js/timeparse.js: -------------------------------------------------------------------------------- 1 | var timeParsePatterns = [ 2 | // 9 3 | { re: /^\d{1,2}$/i, 4 | handler: function(bits) { 5 | if (bits[0].length == 1) { 6 | return '0' + bits[0] + ':00'; 7 | } else { 8 | return bits[0] + ':00'; 9 | } 10 | } 11 | }, 12 | // 13:00 13 | { re: /^\d{2}[:.]\d{2}$/i, 14 | handler: function(bits) { 15 | return bits[0].replace('.', ':'); 16 | } 17 | }, 18 | // 9:00 19 | { re: /^\d[:.]\d{2}$/i, 20 | handler: function(bits) { 21 | return '0' + bits[0].replace('.', ':'); 22 | } 23 | }, 24 | // 3 am / 3 a.m. / 3am 25 | { re: /^(\d+)\s*([ap])(?:.?m.?)?$/i, 26 | handler: function(bits) { 27 | var hour = parseInt(bits[1]); 28 | if (hour == 12) { 29 | hour = 0; 30 | } 31 | if (bits[2].toLowerCase() == 'p') { 32 | if (hour == 12) { 33 | hour = 0; 34 | } 35 | return (hour + 12) + ':00'; 36 | } else { 37 | if (hour < 10) { 38 | return '0' + hour + ':00'; 39 | } else { 40 | return hour + ':00'; 41 | } 42 | } 43 | } 44 | }, 45 | // 3.30 am / 3:15 a.m. / 3.00am 46 | { re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i, 47 | handler: function(bits) { 48 | var hour = parseInt(bits[1]); 49 | var mins = parseInt(bits[2]); 50 | if (mins < 10) { 51 | mins = '0' + mins; 52 | } 53 | if (hour == 12) { 54 | hour = 0; 55 | } 56 | if (bits[3].toLowerCase() == 'p') { 57 | if (hour == 12) { 58 | hour = 0; 59 | } 60 | return (hour + 12) + ':' + mins; 61 | } else { 62 | if (hour < 10) { 63 | return '0' + hour + ':' + mins; 64 | } else { 65 | return hour + ':' + mins; 66 | } 67 | } 68 | } 69 | }, 70 | // noon 71 | { re: /^no/i, 72 | handler: function(bits) { 73 | return '12:00'; 74 | } 75 | }, 76 | // midnight 77 | { re: /^mid/i, 78 | handler: function(bits) { 79 | return '00:00'; 80 | } 81 | } 82 | ]; 83 | 84 | function parseTimeString(s) { 85 | for (var i = 0; i < timeParsePatterns.length; i++) { 86 | var re = timeParsePatterns[i].re; 87 | var handler = timeParsePatterns[i].handler; 88 | var bits = re.exec(s); 89 | if (bits) { 90 | return handler(bits); 91 | } 92 | } 93 | return s; 94 | } 95 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/actions.min.js: -------------------------------------------------------------------------------- 1 | (function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide(); 2 | a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass); 3 | h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass, 4 | d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))}); 5 | a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})}; 6 | a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery); 7 | -------------------------------------------------------------------------------- /cbd_project/templates/cbd/index.html: -------------------------------------------------------------------------------- 1 | {% extends "cbd/base.html" %} 2 | {% load static %} 3 | 4 | {% block title %}Welcome to the Cyberbully Detection System{% endblock %} 5 | {% block pageheading %}Welcome to the Cyberbully Detection System{% endblock %} 6 | 7 | {% block navbar %} 8 | 23 | {% endblock %} 24 | 25 | {% block body_block %} 26 |
27 |
28 | 29 |
30 |
31 |
32 |
33 |
34 | 66 |
67 |
68 |
69 | 70 | {% endblock %} 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cbd - Cyberbullying Detection System 2 | 3 | ## About the project 4 | This project was funded by a small grant provided by AUDA Foundation for a project entitled [Developing an online cloud-based cyberbullying detection system](http://www.audafoundation.org.au/grant-recipients/2013-grant-recipients/university-of-technology-sydney/) to Bhuva Narayan at UTS. 5 | 6 | ## What is included in the project? 7 | * The project consists of a web-based application build in django (i.e. Python) that includes a dashboard for users to monitor cyberbullying (located in the cbd_project folder). 8 | * A machine learning classification algorithm (eg Support Vector Machine) can be trained to identify cyberbullying messages and then the classified messages can be imported into a database and is summarised on a dashboard. 9 | * The dashboard displays timeseries data, topic models (for cyberbullying messages and non cyber bullying messages) and a summary of the affective dimensions found in the test messages (for cyberbullying messages and non cyber bullying messages) 10 | * Cron scripts (in the cronscripts) folder that must be scheduled to perform topic modeling and affective sentiment analysis (i.e. topicmodelandaffectivelexicon.py) 11 | * A moderation role that is able to mark classified messages as mis-classified. 12 | * A sample python script to get data from Twitter (i.e. injest_twitter.py) 13 | 14 | ![Dashbaord](https://github.com/aneesha/cbd/blob/master/dashboard.png "Cyberbullying Dashboard") 15 | 16 | ## Installation Requirements 17 | * Django 18 | * gensim (for LDA topic modeling) 19 | * django-qsstats-magic for timeseries display for graphing (https://pypi.python.org/pypi/django-qsstats-magic/0.7.2) 20 | * twython (for running injest_twitter.py) 21 | 22 | ## Building a Classifier 23 | In order to build a cyberbullying classifier a manually labelled dataset is required. A few labeled datasets are available (http://chatcoder.com/DataDownload) but it is recommended that you create and label your own dataset based upon the social media platform that you need to integrate with. Weka can be used to train and evaluate the classification algorithm. It is recommended that training and testing be performed with a Support Vector Machine, Mutinomial Naive Bayes and Random Forest. A good tutorial to follow is https://www.youtube.com/watch?v=IY29uC4uem8 24 | 25 | ## Topic Modeling and Affective Sentiment Analysis 26 | * The gensim library is used to perform topic modeling using the Latent Dirichlet Allocation algorithm. The dashboard displays topics for non cyberbullying messages and cyberbullying messages. 10 topics are displayed along with 5 of the top words in the topic. 27 | * The affective sentiment analysis uses a publically available NRC Word-Emotion Association Lexicon - Version 0.92 (http://www.saifmohammad.com/WebPages/ResearchInterests.html). Words in the corpus are matched to the lexicon and counted for both non cyberbullying messages and cyberbullying messages in topicmodelandaffectivelexicon.py. The resulting counts across the affective dimensions are displayed on a radar plot on the dashboard. 28 | 29 | ## Dashboard Template 30 | The project uses the sb-admin2 twitter bootstrap admin template (http://startbootstrap.com/template-overviews/sb-admin-2/). 31 | 32 | 33 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/morris/morris-data.js: -------------------------------------------------------------------------------- 1 | /* 2 | $(function() { 3 | 4 | Morris.Area({ 5 | element: 'morris-area-chart', 6 | data: [{ 7 | period: '2010 Q1', 8 | iphone: 2666, 9 | ipad: null, 10 | itouch: 2647 11 | }, { 12 | period: '2010 Q2', 13 | iphone: 2778, 14 | ipad: 2294, 15 | itouch: 2441 16 | }, { 17 | period: '2010 Q3', 18 | iphone: 4912, 19 | ipad: 1969, 20 | itouch: 2501 21 | }, { 22 | period: '2010 Q4', 23 | iphone: 3767, 24 | ipad: 3597, 25 | itouch: 5689 26 | }, { 27 | period: '2011 Q1', 28 | iphone: 6810, 29 | ipad: 1914, 30 | itouch: 2293 31 | }, { 32 | period: '2011 Q2', 33 | iphone: 5670, 34 | ipad: 4293, 35 | itouch: 1881 36 | }, { 37 | period: '2011 Q3', 38 | iphone: 4820, 39 | ipad: 3795, 40 | itouch: 1588 41 | }, { 42 | period: '2011 Q4', 43 | iphone: 15073, 44 | ipad: 5967, 45 | itouch: 5175 46 | }, { 47 | period: '2012 Q1', 48 | iphone: 10687, 49 | ipad: 4460, 50 | itouch: 2028 51 | }, { 52 | period: '2012 Q2', 53 | iphone: 8432, 54 | ipad: 5713, 55 | itouch: 1791 56 | }], 57 | xkey: 'period', 58 | ykeys: ['iphone', 'ipad', 'itouch'], 59 | labels: ['iPhone', 'iPad', 'iPod Touch'], 60 | pointSize: 2, 61 | hideHover: 'auto', 62 | resize: true 63 | }); 64 | 65 | Morris.Donut({ 66 | element: 'morris-donut-chart', 67 | data: [{ 68 | label: "Download Sales", 69 | value: 12 70 | }, { 71 | label: "In-Store Sales", 72 | value: 30 73 | }, { 74 | label: "Mail-Order Sales", 75 | value: 20 76 | }], 77 | resize: true 78 | }); 79 | 80 | Morris.Bar({ 81 | element: 'morris-bar-chart', 82 | data: [{ 83 | y: '2006', 84 | a: 100, 85 | b: 90 86 | }, { 87 | y: '2007', 88 | a: 75, 89 | b: 65 90 | }, { 91 | y: '2008', 92 | a: 50, 93 | b: 40 94 | }, { 95 | y: '2009', 96 | a: 75, 97 | b: 65 98 | }, { 99 | y: '2010', 100 | a: 50, 101 | b: 40 102 | }, { 103 | y: '2011', 104 | a: 75, 105 | b: 65 106 | }, { 107 | y: '2012', 108 | a: 100, 109 | b: 90 110 | }], 111 | xkey: 'y', 112 | ykeys: ['a', 'b'], 113 | labels: ['Series A', 'Series B'], 114 | hideHover: 'auto', 115 | resize: true 116 | }); 117 | 118 | }); 119 | */ -------------------------------------------------------------------------------- /cbd_project/static/admin/js/admin/RelatedObjectLookups.js: -------------------------------------------------------------------------------- 1 | // Handles related-objects functionality: lookup link for raw_id_fields 2 | // and Add Another links. 3 | 4 | function html_unescape(text) { 5 | // Unescape a string that was escaped using django.utils.html.escape. 6 | text = text.replace(/</g, '<'); 7 | text = text.replace(/>/g, '>'); 8 | text = text.replace(/"/g, '"'); 9 | text = text.replace(/'/g, "'"); 10 | text = text.replace(/&/g, '&'); 11 | return text; 12 | } 13 | 14 | // IE doesn't accept periods or dashes in the window name, but the element IDs 15 | // we use to generate popup window names may contain them, therefore we map them 16 | // to allowed characters in a reversible way so that we can locate the correct 17 | // element when the popup window is dismissed. 18 | function id_to_windowname(text) { 19 | text = text.replace(/\./g, '__dot__'); 20 | text = text.replace(/\-/g, '__dash__'); 21 | return text; 22 | } 23 | 24 | function windowname_to_id(text) { 25 | text = text.replace(/__dot__/g, '.'); 26 | text = text.replace(/__dash__/g, '-'); 27 | return text; 28 | } 29 | 30 | function showRelatedObjectLookupPopup(triggeringLink) { 31 | var name = triggeringLink.id.replace(/^lookup_/, ''); 32 | name = id_to_windowname(name); 33 | var href; 34 | if (triggeringLink.href.search(/\?/) >= 0) { 35 | href = triggeringLink.href + '&_popup=1'; 36 | } else { 37 | href = triggeringLink.href + '?_popup=1'; 38 | } 39 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 40 | win.focus(); 41 | return false; 42 | } 43 | 44 | function dismissRelatedLookupPopup(win, chosenId) { 45 | var name = windowname_to_id(win.name); 46 | var elem = document.getElementById(name); 47 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 48 | elem.value += ',' + chosenId; 49 | } else { 50 | document.getElementById(name).value = chosenId; 51 | } 52 | win.close(); 53 | } 54 | 55 | function showAddAnotherPopup(triggeringLink) { 56 | var name = triggeringLink.id.replace(/^add_/, ''); 57 | name = id_to_windowname(name); 58 | var href = triggeringLink.href; 59 | if (href.indexOf('?') == -1) { 60 | href += '?_popup=1'; 61 | } else { 62 | href += '&_popup=1'; 63 | } 64 | var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); 65 | win.focus(); 66 | return false; 67 | } 68 | 69 | function dismissAddAnotherPopup(win, newId, newRepr) { 70 | // newId and newRepr are expected to have previously been escaped by 71 | // django.utils.html.escape. 72 | newId = html_unescape(newId); 73 | newRepr = html_unescape(newRepr); 74 | var name = windowname_to_id(win.name); 75 | var elem = document.getElementById(name); 76 | var o; 77 | if (elem) { 78 | var elemName = elem.nodeName.toUpperCase(); 79 | if (elemName == 'SELECT') { 80 | o = new Option(newRepr, newId); 81 | elem.options[elem.options.length] = o; 82 | o.selected = true; 83 | } else if (elemName == 'INPUT') { 84 | if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { 85 | elem.value += ',' + newId; 86 | } else { 87 | elem.value = newId; 88 | } 89 | } 90 | } else { 91 | var toId = name + "_to"; 92 | o = new Option(newRepr, newId); 93 | SelectBox.add_to_cache(toId, o); 94 | SelectBox.redisplay(toId); 95 | } 96 | win.close(); 97 | } 98 | -------------------------------------------------------------------------------- /cbd_project/cbd_project/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for cbd_project project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.8/ref/settings/ 11 | """ 12 | 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 14 | import os 15 | 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '32h&*7pd@ryr=%kfrpq*2@#zb8-5@k0c+vm0c!b*id27(b@yc3' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = ( 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'cbd' 41 | ) 42 | 43 | MIDDLEWARE_CLASSES = ( 44 | 'django.contrib.sessions.middleware.SessionMiddleware', 45 | 'django.middleware.common.CommonMiddleware', 46 | 'django.middleware.csrf.CsrfViewMiddleware', 47 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 48 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | 'django.middleware.security.SecurityMiddleware', 52 | ) 53 | 54 | ROOT_URLCONF = 'cbd_project.urls' 55 | 56 | TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates') 57 | 58 | TEMPLATES = [ 59 | { 60 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 61 | 'DIRS': [TEMPLATE_PATH], 62 | 'APP_DIRS': True, 63 | 'OPTIONS': { 64 | 'context_processors': [ 65 | 'django.template.context_processors.debug', 66 | 'django.template.context_processors.request', 67 | 'django.contrib.auth.context_processors.auth', 68 | 'django.contrib.messages.context_processors.messages', 69 | ], 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = 'cbd_project.wsgi.application' 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 79 | 80 | DATABASES = { 81 | 'default': { 82 | 'ENGINE': 'django.db.backends.sqlite3', 83 | 'NAME': os.path.join(BASE_DIR, 'cyber.sqlite3'), 84 | } 85 | } 86 | 87 | 88 | # Internationalization 89 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 90 | 91 | LANGUAGE_CODE = 'en-us' 92 | 93 | TIME_ZONE = 'UTC' 94 | 95 | USE_I18N = True 96 | 97 | USE_L10N = True 98 | 99 | USE_TZ = True 100 | 101 | 102 | # web accessible folder 103 | STATIC_ROOT = BASE_DIR #os.path.join(BASE_DIR, 'static') 104 | 105 | # URL prefix for static files. 106 | STATIC_URL = '/static/' 107 | 108 | STATIC_PATH = os.path.join(BASE_DIR,'static') 109 | 110 | # Additional locations of static files 111 | STATICFILES_DIRS = ( 112 | # location of your application, should not be public web accessible 113 | STATIC_PATH, 114 | ) 115 | 116 | # List of finder classes that know how to find static files in 117 | # various locations. 118 | STATICFILES_FINDERS = ( 119 | 'django.contrib.staticfiles.finders.FileSystemFinder', 120 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 121 | ) 122 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/flot/jquery.flot.tooltip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.flot.tooltip 3 | * 4 | * description: easy-to-use tooltips for Flot charts 5 | * version: 0.6.2 6 | * author: Krzysztof Urbas @krzysu [myviews.pl] 7 | * website: https://github.com/krzysu/flot.tooltip 8 | * 9 | * build on 2013-09-30 10 | * released under MIT License, 2012 11 | */ 12 | (function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("
").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery); -------------------------------------------------------------------------------- /cbd_project/static/admin/js/inlines.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a.fn.formset=function(g){var b=a.extend({},a.fn.formset.defaults,g),i=a(this);g=i.parent();var m=function(e,k,h){var j=RegExp("("+k+"-(\\d+|__prefix__))");k=k+"-"+h;a(e).prop("for")&&a(e).prop("for",a(e).prop("for").replace(j,k));if(e.id)e.id=e.id.replace(j,k);if(e.name)e.name=e.name.replace(j,k)},l=a("#id_"+b.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),d=parseInt(l.val(),10),c=a("#id_"+b.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off");l=c.val()===""||c.val()-l.val()>0;i.each(function(){a(this).not("."+ 2 | b.emptyCssClass).addClass(b.formCssClass)});if(i.length&&l){var f;if(i.prop("tagName")=="TR"){i=this.eq(-1).children().length;g.append(''+b.addText+"");f=g.find("tr:last a")}else{i.filter(":last").after('
'+b.addText+"
");f=i.filter(":last").next().find("a")}f.click(function(e){e.preventDefault();var k=a("#id_"+b.prefix+"-TOTAL_FORMS");e=a("#"+ 3 | b.prefix+"-empty");var h=e.clone(true);h.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+"-"+d);if(h.is("tr"))h.children(":last").append('
'+b.deleteText+"
");else h.is("ul")||h.is("ol")?h.append('
  • '+b.deleteText+"
  • "):h.children(":first").append(''+b.deleteText+""); 4 | h.find("*").each(function(){m(this,b.prefix,k.val())});h.insertBefore(a(e));a(k).val(parseInt(k.val(),10)+1);d+=1;c.val()!==""&&c.val()-k.val()<=0&&f.parent().hide();h.find("a."+b.deleteCssClass).click(function(j){j.preventDefault();j=a(this).parents("."+b.formCssClass);j.remove();d-=1;b.removed&&b.removed(j);j=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(j.length);if(c.val()===""||c.val()-j.length>0)f.parent().show();for(var n=0,o=j.length;n li { 19 | position: relative; 20 | margin-bottom: 20px; 21 | } 22 | 23 | .timeline > li:before, 24 | .timeline > li:after { 25 | content: " "; 26 | display: table; 27 | } 28 | 29 | .timeline > li:after { 30 | clear: both; 31 | } 32 | 33 | .timeline > li:before, 34 | .timeline > li:after { 35 | content: " "; 36 | display: table; 37 | } 38 | 39 | .timeline > li:after { 40 | clear: both; 41 | } 42 | 43 | .timeline > li > .timeline-panel { 44 | float: left; 45 | position: relative; 46 | width: 46%; 47 | padding: 20px; 48 | border: 1px solid #d4d4d4; 49 | border-radius: 2px; 50 | -webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.175); 51 | box-shadow: 0 1px 6px rgba(0,0,0,0.175); 52 | } 53 | 54 | .timeline > li > .timeline-panel:before { 55 | content: " "; 56 | display: inline-block; 57 | position: absolute; 58 | top: 26px; 59 | right: -15px; 60 | border-top: 15px solid transparent; 61 | border-right: 0 solid #ccc; 62 | border-bottom: 15px solid transparent; 63 | border-left: 15px solid #ccc; 64 | } 65 | 66 | .timeline > li > .timeline-panel:after { 67 | content: " "; 68 | display: inline-block; 69 | position: absolute; 70 | top: 27px; 71 | right: -14px; 72 | border-top: 14px solid transparent; 73 | border-right: 0 solid #fff; 74 | border-bottom: 14px solid transparent; 75 | border-left: 14px solid #fff; 76 | } 77 | 78 | .timeline > li > .timeline-badge { 79 | z-index: 100; 80 | position: absolute; 81 | top: 16px; 82 | left: 50%; 83 | width: 50px; 84 | height: 50px; 85 | margin-left: -25px; 86 | border-radius: 50% 50% 50% 50%; 87 | text-align: center; 88 | font-size: 1.4em; 89 | line-height: 50px; 90 | color: #fff; 91 | background-color: #999999; 92 | } 93 | 94 | .timeline > li.timeline-inverted > .timeline-panel { 95 | float: right; 96 | } 97 | 98 | .timeline > li.timeline-inverted > .timeline-panel:before { 99 | right: auto; 100 | left: -15px; 101 | border-right-width: 15px; 102 | border-left-width: 0; 103 | } 104 | 105 | .timeline > li.timeline-inverted > .timeline-panel:after { 106 | right: auto; 107 | left: -14px; 108 | border-right-width: 14px; 109 | border-left-width: 0; 110 | } 111 | 112 | .timeline-badge.primary { 113 | background-color: #2e6da4 !important; 114 | } 115 | 116 | .timeline-badge.success { 117 | background-color: #3f903f !important; 118 | } 119 | 120 | .timeline-badge.warning { 121 | background-color: #f0ad4e !important; 122 | } 123 | 124 | .timeline-badge.danger { 125 | background-color: #d9534f !important; 126 | } 127 | 128 | .timeline-badge.info { 129 | background-color: #5bc0de !important; 130 | } 131 | 132 | .timeline-title { 133 | margin-top: 0; 134 | color: inherit; 135 | } 136 | 137 | .timeline-body > p, 138 | .timeline-body > ul { 139 | margin-bottom: 0; 140 | } 141 | 142 | .timeline-body > p + p { 143 | margin-top: 5px; 144 | } 145 | 146 | @media(max-width:767px) { 147 | ul.timeline:before { 148 | left: 40px; 149 | } 150 | 151 | ul.timeline > li > .timeline-panel { 152 | width: calc(100% - 90px); 153 | width: -moz-calc(100% - 90px); 154 | width: -webkit-calc(100% - 90px); 155 | } 156 | 157 | ul.timeline > li > .timeline-badge { 158 | top: 16px; 159 | left: 15px; 160 | margin-left: 0; 161 | } 162 | 163 | ul.timeline > li > .timeline-panel { 164 | float: right; 165 | } 166 | 167 | ul.timeline > li > .timeline-panel:before { 168 | right: auto; 169 | left: -15px; 170 | border-right-width: 15px; 171 | border-left-width: 0; 172 | } 173 | 174 | ul.timeline > li > .timeline-panel:after { 175 | right: auto; 176 | left: -14px; 177 | border-right-width: 14px; 178 | border-left-width: 0; 179 | } 180 | } -------------------------------------------------------------------------------- /cbd_project/templates/cbd/base.html: -------------------------------------------------------------------------------- 1 | 2 | {% load static %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Cyberbully Detection - {% block title %}Title to go here!{% endblock %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 48 |
    49 | 50 | 51 | 79 | 80 |
    81 |
    82 |
    83 |

    {% block pageheading %}Dashboard{% endblock %}

    84 |
    85 | 86 |
    87 | {% block body_block %} 88 | 89 | {% endblock %} 90 |
    91 | 92 | 93 |
    94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | {% block jscripts %} 116 | 117 | {% endblock %} 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/SelectBox.js: -------------------------------------------------------------------------------- 1 | var SelectBox = { 2 | cache: new Object(), 3 | init: function(id) { 4 | var box = document.getElementById(id); 5 | var node; 6 | SelectBox.cache[id] = new Array(); 7 | var cache = SelectBox.cache[id]; 8 | for (var i = 0; (node = box.options[i]); i++) { 9 | cache.push({value: node.value, text: node.text, displayed: 1}); 10 | } 11 | }, 12 | redisplay: function(id) { 13 | // Repopulate HTML select box from cache 14 | var box = document.getElementById(id); 15 | box.options.length = 0; // clear all options 16 | for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { 17 | var node = SelectBox.cache[id][i]; 18 | if (node.displayed) { 19 | var new_option = new Option(node.text, node.value, false, false); 20 | // Shows a tooltip when hovering over the option 21 | new_option.setAttribute("title", node.text); 22 | box.options[box.options.length] = new_option; 23 | } 24 | } 25 | }, 26 | filter: function(id, text) { 27 | // Redisplay the HTML select box, displaying only the choices containing ALL 28 | // the words in text. (It's an AND search.) 29 | var tokens = text.toLowerCase().split(/\s+/); 30 | var node, token; 31 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 32 | node.displayed = 1; 33 | for (var j = 0; (token = tokens[j]); j++) { 34 | if (node.text.toLowerCase().indexOf(token) == -1) { 35 | node.displayed = 0; 36 | } 37 | } 38 | } 39 | SelectBox.redisplay(id); 40 | }, 41 | delete_from_cache: function(id, value) { 42 | var node, delete_index = null; 43 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 44 | if (node.value == value) { 45 | delete_index = i; 46 | break; 47 | } 48 | } 49 | var j = SelectBox.cache[id].length - 1; 50 | for (var i = delete_index; i < j; i++) { 51 | SelectBox.cache[id][i] = SelectBox.cache[id][i+1]; 52 | } 53 | SelectBox.cache[id].length--; 54 | }, 55 | add_to_cache: function(id, option) { 56 | SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); 57 | }, 58 | cache_contains: function(id, value) { 59 | // Check if an item is contained in the cache 60 | var node; 61 | for (var i = 0; (node = SelectBox.cache[id][i]); i++) { 62 | if (node.value == value) { 63 | return true; 64 | } 65 | } 66 | return false; 67 | }, 68 | move: function(from, to) { 69 | var from_box = document.getElementById(from); 70 | var to_box = document.getElementById(to); 71 | var option; 72 | for (var i = 0; (option = from_box.options[i]); i++) { 73 | if (option.selected && SelectBox.cache_contains(from, option.value)) { 74 | SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); 75 | SelectBox.delete_from_cache(from, option.value); 76 | } 77 | } 78 | SelectBox.redisplay(from); 79 | SelectBox.redisplay(to); 80 | }, 81 | move_all: function(from, to) { 82 | var from_box = document.getElementById(from); 83 | var to_box = document.getElementById(to); 84 | var option; 85 | for (var i = 0; (option = from_box.options[i]); i++) { 86 | if (SelectBox.cache_contains(from, option.value)) { 87 | SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); 88 | SelectBox.delete_from_cache(from, option.value); 89 | } 90 | } 91 | SelectBox.redisplay(from); 92 | SelectBox.redisplay(to); 93 | }, 94 | sort: function(id) { 95 | SelectBox.cache[id].sort( function(a, b) { 96 | a = a.text.toLowerCase(); 97 | b = b.text.toLowerCase(); 98 | try { 99 | if (a > b) return 1; 100 | if (a < b) return -1; 101 | } 102 | catch (e) { 103 | // silently fail on IE 'unknown' exception 104 | } 105 | return 0; 106 | } ); 107 | }, 108 | select_all: function(id) { 109 | var box = document.getElementById(id); 110 | for (var i = 0; i < box.options.length; i++) { 111 | box.options[i].selected = 'selected'; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /cbd_project/static/admin/css/rtl.css: -------------------------------------------------------------------------------- 1 | body { 2 | direction: rtl; 3 | } 4 | 5 | /* LOGIN */ 6 | 7 | .login .form-row { 8 | float: right; 9 | } 10 | 11 | .login .form-row label { 12 | float: right; 13 | padding-left: 0.5em; 14 | padding-right: 0; 15 | text-align: left; 16 | } 17 | 18 | .login .submit-row { 19 | clear: both; 20 | padding: 1em 9.4em 0 0; 21 | } 22 | 23 | /* GLOBAL */ 24 | 25 | th { 26 | text-align: right; 27 | } 28 | 29 | .module h2, .module caption { 30 | text-align: right; 31 | } 32 | 33 | .addlink, .changelink { 34 | padding-left: 0px; 35 | padding-right: 12px; 36 | background-position: 100% 0.2em; 37 | } 38 | 39 | .deletelink { 40 | padding-left: 0px; 41 | padding-right: 12px; 42 | background-position: 100% 0.25em; 43 | } 44 | 45 | .object-tools { 46 | float: left; 47 | } 48 | 49 | thead th:first-child, 50 | tfoot td:first-child { 51 | border-left: 1px solid #ddd !important; 52 | } 53 | 54 | /* LAYOUT */ 55 | 56 | #user-tools { 57 | right: auto; 58 | left: 0; 59 | text-align: left; 60 | } 61 | 62 | div.breadcrumbs { 63 | text-align: right; 64 | } 65 | 66 | #content-main { 67 | float: right; 68 | } 69 | 70 | #content-related { 71 | float: left; 72 | margin-left: -19em; 73 | margin-right: auto; 74 | } 75 | 76 | .colMS { 77 | margin-left: 20em !important; 78 | margin-right: 10px !important; 79 | } 80 | 81 | /* SORTABLE TABLES */ 82 | 83 | table thead th.sorted .sortoptions { 84 | float: left; 85 | } 86 | 87 | thead th.sorted .text { 88 | padding-right: 0; 89 | padding-left: 42px; 90 | } 91 | 92 | /* dashboard styles */ 93 | 94 | .dashboard .module table td a { 95 | padding-left: .6em; 96 | padding-right: 12px; 97 | } 98 | 99 | /* changelists styles */ 100 | 101 | .change-list .filtered { 102 | background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important; 103 | } 104 | 105 | .change-list .filtered table { 106 | border-left: 1px solid #ddd; 107 | border-right: 0px none; 108 | } 109 | 110 | #changelist-filter { 111 | right: auto; 112 | left: 0; 113 | border-left: 0px none; 114 | border-right: 1px solid #ddd; 115 | } 116 | 117 | .change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { 118 | margin-right: 0px !important; 119 | margin-left: 160px !important; 120 | } 121 | 122 | #changelist-filter li.selected { 123 | border-left: 0px none; 124 | padding-left: 0px; 125 | margin-left: 0; 126 | border-right: 5px solid #ccc; 127 | padding-right: 5px; 128 | margin-right: -10px; 129 | } 130 | 131 | .filtered .actions { 132 | border-left:1px solid #DDDDDD; 133 | margin-left:160px !important; 134 | border-right: 0 none; 135 | margin-right:0 !important; 136 | } 137 | 138 | #changelist table tbody td:first-child, #changelist table tbody th:first-child { 139 | border-right: 0; 140 | border-left: 1px solid #ddd; 141 | } 142 | 143 | /* FORMS */ 144 | 145 | .aligned label { 146 | padding: 0 0 3px 1em; 147 | float: right; 148 | } 149 | 150 | .submit-row { 151 | text-align: left 152 | } 153 | 154 | .submit-row p.deletelink-box { 155 | float: right; 156 | } 157 | 158 | .submit-row .deletelink { 159 | background: url(../img/icon_deletelink.gif) 0 50% no-repeat; 160 | padding-right: 14px; 161 | } 162 | 163 | .vDateField, .vTimeField { 164 | margin-left: 2px; 165 | } 166 | 167 | form ul.inline li { 168 | float: right; 169 | padding-right: 0; 170 | padding-left: 7px; 171 | } 172 | 173 | input[type=submit].default, .submit-row input.default { 174 | float: left; 175 | } 176 | 177 | fieldset .field-box { 178 | float: right; 179 | margin-left: 20px; 180 | margin-right: 0; 181 | } 182 | 183 | .errorlist li { 184 | background-position: 100% .3em; 185 | padding: 4px 25px 4px 5px; 186 | } 187 | 188 | .errornote { 189 | background-position: 100% .3em; 190 | padding: 4px 25px 4px 5px; 191 | } 192 | 193 | /* WIDGETS */ 194 | 195 | .calendarnav-previous { 196 | top: 0; 197 | left: auto; 198 | right: 0; 199 | } 200 | 201 | .calendarnav-next { 202 | top: 0; 203 | right: auto; 204 | left: 0; 205 | } 206 | 207 | .calendar caption, .calendarbox h2 { 208 | text-align: center; 209 | } 210 | 211 | .selector { 212 | float: right; 213 | } 214 | 215 | .selector .selector-filter { 216 | text-align: right; 217 | } 218 | 219 | .inline-deletelink { 220 | float: left; 221 | } 222 | 223 | /* MISC */ 224 | 225 | .inline-related h2, .inline-group h2 { 226 | text-align: right 227 | } 228 | 229 | .inline-related h3 span.delete { 230 | padding-right: 20px; 231 | padding-left: inherit; 232 | left: 10px; 233 | right: inherit; 234 | float:left; 235 | } 236 | 237 | .inline-related h3 span.delete label { 238 | margin-left: inherit; 239 | margin-right: 2px; 240 | } 241 | 242 | /* IE7 specific bug fixes */ 243 | 244 | div.colM { 245 | position: relative; 246 | } 247 | 248 | .submit-row input { 249 | float: left; 250 | } -------------------------------------------------------------------------------- /cbd_project/static/admin/js/actions.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | var lastChecked; 3 | 4 | $.fn.actions = function(opts) { 5 | var options = $.extend({}, $.fn.actions.defaults, opts); 6 | var actionCheckboxes = $(this); 7 | var list_editable_changed = false; 8 | var checker = function(checked) { 9 | if (checked) { 10 | showQuestion(); 11 | } else { 12 | reset(); 13 | } 14 | $(actionCheckboxes).prop("checked", checked) 15 | .parent().parent().toggleClass(options.selectedClass, checked); 16 | }, 17 | updateCounter = function() { 18 | var sel = $(actionCheckboxes).filter(":checked").length; 19 | // _actions_icnt is defined in the generated HTML 20 | // and contains the total amount of objects in the queryset 21 | $(options.counterContainer).html(interpolate( 22 | ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { 23 | sel: sel, 24 | cnt: _actions_icnt 25 | }, true)); 26 | $(options.allToggle).prop("checked", function() { 27 | var value; 28 | if (sel == actionCheckboxes.length) { 29 | value = true; 30 | showQuestion(); 31 | } else { 32 | value = false; 33 | clearAcross(); 34 | } 35 | return value; 36 | }); 37 | }, 38 | showQuestion = function() { 39 | $(options.acrossClears).hide(); 40 | $(options.acrossQuestions).show(); 41 | $(options.allContainer).hide(); 42 | }, 43 | showClear = function() { 44 | $(options.acrossClears).show(); 45 | $(options.acrossQuestions).hide(); 46 | $(options.actionContainer).toggleClass(options.selectedClass); 47 | $(options.allContainer).show(); 48 | $(options.counterContainer).hide(); 49 | }, 50 | reset = function() { 51 | $(options.acrossClears).hide(); 52 | $(options.acrossQuestions).hide(); 53 | $(options.allContainer).hide(); 54 | $(options.counterContainer).show(); 55 | }, 56 | clearAcross = function() { 57 | reset(); 58 | $(options.acrossInput).val(0); 59 | $(options.actionContainer).removeClass(options.selectedClass); 60 | }; 61 | // Show counter by default 62 | $(options.counterContainer).show(); 63 | // Check state of checkboxes and reinit state if needed 64 | $(this).filter(":checked").each(function(i) { 65 | $(this).parent().parent().toggleClass(options.selectedClass); 66 | updateCounter(); 67 | if ($(options.acrossInput).val() == 1) { 68 | showClear(); 69 | } 70 | }); 71 | $(options.allToggle).show().click(function() { 72 | checker($(this).prop("checked")); 73 | updateCounter(); 74 | }); 75 | $("a", options.acrossQuestions).click(function(event) { 76 | event.preventDefault(); 77 | $(options.acrossInput).val(1); 78 | showClear(); 79 | }); 80 | $("a", options.acrossClears).click(function(event) { 81 | event.preventDefault(); 82 | $(options.allToggle).prop("checked", false); 83 | clearAcross(); 84 | checker(0); 85 | updateCounter(); 86 | }); 87 | lastChecked = null; 88 | $(actionCheckboxes).click(function(event) { 89 | if (!event) { event = window.event; } 90 | var target = event.target ? event.target : event.srcElement; 91 | if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) { 92 | var inrange = false; 93 | $(lastChecked).prop("checked", target.checked) 94 | .parent().parent().toggleClass(options.selectedClass, target.checked); 95 | $(actionCheckboxes).each(function() { 96 | if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) { 97 | inrange = (inrange) ? false : true; 98 | } 99 | if (inrange) { 100 | $(this).prop("checked", target.checked) 101 | .parent().parent().toggleClass(options.selectedClass, target.checked); 102 | } 103 | }); 104 | } 105 | $(target).parent().parent().toggleClass(options.selectedClass, target.checked); 106 | lastChecked = target; 107 | updateCounter(); 108 | }); 109 | $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() { 110 | list_editable_changed = true; 111 | }); 112 | $('form#changelist-form button[name="index"]').click(function(event) { 113 | if (list_editable_changed) { 114 | return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.")); 115 | } 116 | }); 117 | $('form#changelist-form input[name="_save"]').click(function(event) { 118 | var action_changed = false; 119 | $('select option:selected', options.actionContainer).each(function() { 120 | if ($(this).val()) { 121 | action_changed = true; 122 | } 123 | }); 124 | if (action_changed) { 125 | if (list_editable_changed) { 126 | return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")); 127 | } else { 128 | return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.")); 129 | } 130 | } 131 | }); 132 | }; 133 | /* Setup plugin defaults */ 134 | $.fn.actions.defaults = { 135 | actionContainer: "div.actions", 136 | counterContainer: "span.action-counter", 137 | allContainer: "div.actions span.all", 138 | acrossInput: "div.actions input.select-across", 139 | acrossQuestions: "div.actions span.question", 140 | acrossClears: "div.actions span.clear", 141 | allToggle: "#action-toggle", 142 | selectedClass: "selected" 143 | }; 144 | })(django.jQuery); 145 | -------------------------------------------------------------------------------- /cronscripts/topicmodelandaffectivelexicon.py: -------------------------------------------------------------------------------- 1 | # Generate a topic model for messages containing 2 | # ---- Cyberbullying Traces 3 | # ---- No Cyberbullying Traces 4 | # Calculate words counts against an affective lexicon for 5 | # ---- Cyberbullying Traces 6 | # ---- No Cyberbullying Traces 7 | 8 | from gensim import corpora, models, similarities 9 | from collections import defaultdict 10 | from pprint import pprint 11 | from sqlalchemy.engine import create_engine 12 | import json 13 | 14 | def save_summaryobject (table, row): 15 | 16 | keys = row.keys(); 17 | sql = "INSERT INTO " + table + " (" 18 | sql = sql + ", ".join(keys) 19 | sql = sql + ") VALUES (" 20 | sql = sql + ", ".join([ ("'" + str(row[key]) + "'") for key in keys]) 21 | sql = sql + ")" 22 | 23 | id = connection.execute(sql); 24 | 25 | return id 26 | 27 | def loadStopWords(stopWordFile): 28 | stopWords = [] 29 | for line in open(stopWordFile): 30 | for word in line.split( ): #in case more than one per line 31 | stopWords.append(word) 32 | return stopWords 33 | 34 | def loadAffectiveDictionary(affectiveWordFile): 35 | affectiveWords = {} 36 | linecount = 0 37 | for line in open(affectiveWordFile): 38 | if linecount>2: 39 | words = line.split("\t") 40 | if words[0] not in affectiveWords: 41 | affectiveWords[words[0]] = {'anger': 0, 'anticipation': 0, 'disgust': 0, 'fear': 0, 'joy': 0, 'negative': 0, 'positive': 0, 'sadness': 0, 'surprise': 0, 'trust':0 } 42 | affective_senses = affectiveWords[words[0]] 43 | affective_senses[words[1]] = int(words[2]) 44 | linecount = linecount + 1 45 | return affectiveWords 46 | 47 | # calculate affective senses counts 48 | def affective_sense_counts(texts, affectivelexicon_dict): 49 | affective_senses_counts = {'anger': 0, 'anticipation': 0, 'disgust': 0, 'fear': 0, 'joy': 0, 'negative': 0, 'positive': 0, 'sadness': 0, 'surprise': 0, 'trust':0 } 50 | for text in texts: 51 | for token in text: 52 | if token in affectivelexicon_dict: 53 | affective_senses = affectivelexicon_dict[token] 54 | for sense in affective_senses_counts: 55 | affective_senses_counts[sense] = affective_senses_counts[sense] + int(affective_senses[sense]) 56 | 57 | affective_counts_json = json.dumps(affective_senses_counts) 58 | return affective_counts_json 59 | 60 | # remove common words and tokenize 61 | def remove_stopwords(documents): 62 | stoplist = loadStopWords('englishstop.txt') 63 | texts = [[word for word in document.lower().split() if word not in stoplist] for document in documents] 64 | 65 | # remove words that appear only once 66 | frequency = defaultdict(int) 67 | for text in texts: 68 | for token in text: 69 | frequency[token] += 1 70 | 71 | texts = [[token for token in text if frequency[token] > 1] for text in texts] 72 | 73 | return texts 74 | 75 | def get_LDAasJSON(texts): 76 | # Make dictionary 77 | dictionary = corpora.Dictionary(texts) 78 | #dictionary.save('test.dict') # store the dictionary, for future reference 79 | 80 | #Create and save corpus 81 | corpus = [dictionary.doc2bow(text) for text in texts] 82 | #corpora.MmCorpus.serialize('test.mm', corpus) # store to disk, for later use 83 | 84 | #Run LDA 85 | model = models.ldamodel.LdaModel(corpus, id2word=dictionary, num_topics=20) 86 | #Save Model 87 | #model.save('ldamodel.m') 88 | 89 | tmp = model.show_topics(num_topics=20, num_words=5, log=False, formatted=False) 90 | 91 | #print tmp 92 | json_tm = json.dumps(tmp) 93 | 94 | return json_tm 95 | 96 | #load affective text lexicon 97 | affectivelexicon_dict = loadAffectiveDictionary('NRC-emotion-lexicon-wordlevel-alphabetized-v0.92.txt') 98 | 99 | # Create database connection 100 | documents = [] 101 | engine = create_engine("sqlite:///cyber.sqlite3") 102 | connection = engine.connect() 103 | 104 | # Delete stored topics and affective lexicon counts 105 | connection.execute("DELETE FROM cbd_mlcache"); 106 | 107 | # load documents (i.e. posts or messages containing cyberbullying traces) from database 108 | sql = "SELECT id, body FROM cbd_processedsocialmediamessage WHERE has_bullying='Yes'" 109 | result = connection.execute(sql); 110 | for row in result: 111 | documents.append(row[1].replace('#039;','')) 112 | 113 | cyberbullyingdocs = remove_stopwords(documents) 114 | 115 | documents = [] 116 | # load documents (i.e. posts or messages NOT containing cyberbullying traces) from database 117 | sql = "SELECT id, body FROM cbd_processedsocialmediamessage WHERE has_bullying='No'" 118 | result = connection.execute(sql); 119 | for row in result: 120 | documents.append(row[1].replace('#039;','')) 121 | 122 | noncyberbullyingdocs = remove_stopwords(documents) 123 | 124 | topic_model_json = get_LDAasJSON(noncyberbullyingdocs) 125 | topic_model_cyberbullying_json = get_LDAasJSON(cyberbullyingdocs) 126 | 127 | affective_counts_json = affective_sense_counts(noncyberbullyingdocs, affectivelexicon_dict) 128 | affective_counts_cyberbullying_json = affective_sense_counts(cyberbullyingdocs, affectivelexicon_dict) 129 | 130 | record = {"topic_model_json": topic_model_json.replace("'", "''"), "topic_model_cyberbullying_json": topic_model_cyberbullying_json.replace("'", "''"), "affective_counts_json": affective_counts_json.replace("'", "''"), 'affective_counts_cyberbullying_json': affective_counts_cyberbullying_json.replace("'", "''")} 131 | save_summaryobject ("cbd_mlcache", record) 132 | -------------------------------------------------------------------------------- /cbd_project/static/css/plugins/dataTables.bootstrap.css: -------------------------------------------------------------------------------- 1 | div.dataTables_length label { 2 | float: left; 3 | text-align: left; 4 | font-weight: normal; 5 | } 6 | 7 | div.dataTables_length select { 8 | width: 75px; 9 | } 10 | 11 | div.dataTables_filter label { 12 | float: right; 13 | font-weight: normal; 14 | } 15 | 16 | div.dataTables_filter input { 17 | width: 16em; 18 | } 19 | 20 | div.dataTables_info { 21 | padding-top: 8px; 22 | } 23 | 24 | div.dataTables_paginate { 25 | float: right; 26 | margin: 0; 27 | } 28 | 29 | div.dataTables_paginate ul.pagination { 30 | margin: 2px 0; 31 | white-space: nowrap; 32 | } 33 | 34 | table.dataTable, 35 | table.dataTable td, 36 | table.dataTable th { 37 | -webkit-box-sizing: content-box; 38 | -moz-box-sizing: content-box; 39 | box-sizing: content-box; 40 | } 41 | 42 | table.dataTable { 43 | clear: both; 44 | margin-top: 6px !important; 45 | margin-bottom: 6px !important; 46 | max-width: none !important; 47 | } 48 | 49 | table.dataTable thead .sorting, 50 | table.dataTable thead .sorting_asc, 51 | table.dataTable thead .sorting_desc, 52 | table.dataTable thead .sorting_asc_disabled, 53 | table.dataTable thead .sorting_desc_disabled { 54 | cursor: pointer; 55 | } 56 | 57 | table.dataTable thead .sorting { 58 | background: url('../images/sort_both.png') no-repeat center right; 59 | } 60 | 61 | table.dataTable thead .sorting_asc { 62 | background: url('../images/sort_asc.png') no-repeat center right; 63 | } 64 | 65 | table.dataTable thead .sorting_desc { 66 | background: url('../images/sort_desc.png') no-repeat center right; 67 | } 68 | 69 | table.dataTable thead .sorting_asc_disabled { 70 | background: url('../images/sort_asc_disabled.png') no-repeat center right; 71 | } 72 | 73 | table.dataTable thead .sorting_desc_disabled { 74 | background: url('../images/sort_desc_disabled.png') no-repeat center right; 75 | } 76 | 77 | table.dataTable th:active { 78 | outline: none; 79 | } 80 | 81 | /* Scrolling */ 82 | 83 | div.dataTables_scrollHead table { 84 | margin-bottom: 0 !important; 85 | border-bottom-left-radius: 0; 86 | border-bottom-right-radius: 0; 87 | } 88 | 89 | div.dataTables_scrollHead table thead tr:last-child th:first-child, 90 | div.dataTables_scrollHead table thead tr:last-child td:first-child { 91 | border-bottom-left-radius: 0 !important; 92 | border-bottom-right-radius: 0 !important; 93 | } 94 | 95 | div.dataTables_scrollBody table { 96 | margin-top: 0 !important; 97 | margin-bottom: 0 !important; 98 | border-top: none; 99 | } 100 | 101 | div.dataTables_scrollBody tbody tr:first-child th, 102 | div.dataTables_scrollBody tbody tr:first-child td { 103 | border-top: none; 104 | } 105 | 106 | div.dataTables_scrollFoot table { 107 | margin-top: 0 !important; 108 | border-top: none; 109 | } 110 | 111 | /* 112 | * TableTools styles 113 | */ 114 | 115 | .table tbody tr.active td, 116 | .table tbody tr.active th { 117 | color: white; 118 | background-color: #08C; 119 | } 120 | 121 | .table tbody tr.active:hover td, 122 | .table tbody tr.active:hover th { 123 | background-color: #0075b0 !important; 124 | } 125 | 126 | .table tbody tr.active a { 127 | color: white; 128 | } 129 | 130 | .table-striped tbody tr.active:nth-child(odd) td, 131 | .table-striped tbody tr.active:nth-child(odd) th { 132 | background-color: #017ebc; 133 | } 134 | 135 | table.DTTT_selectable tbody tr { 136 | cursor: pointer; 137 | } 138 | 139 | div.DTTT .btn { 140 | font-size: 12px; 141 | color: #333 !important; 142 | } 143 | 144 | div.DTTT .btn:hover { 145 | text-decoration: none !important; 146 | } 147 | 148 | ul.DTTT_dropdown.dropdown-menu { 149 | z-index: 2003; 150 | } 151 | 152 | ul.DTTT_dropdown.dropdown-menu a { 153 | color: #333 !important; /* needed only when demo_page.css is included */ 154 | } 155 | 156 | ul.DTTT_dropdown.dropdown-menu li { 157 | position: relative; 158 | } 159 | 160 | ul.DTTT_dropdown.dropdown-menu li:hover a { 161 | color: white !important; 162 | background-color: #0088cc; 163 | } 164 | 165 | div.DTTT_collection_background { 166 | z-index: 2002; 167 | } 168 | 169 | /* TableTools information display */ 170 | 171 | div.DTTT_print_info.modal { 172 | height: 150px; 173 | margin-top: -75px; 174 | text-align: center; 175 | } 176 | 177 | div.DTTT_print_info h6 { 178 | margin: 1em; 179 | font-size: 28px; 180 | font-weight: normal; 181 | line-height: 28px; 182 | } 183 | 184 | div.DTTT_print_info p { 185 | font-size: 14px; 186 | line-height: 20px; 187 | } 188 | 189 | /* 190 | * FixedColumns styles 191 | */ 192 | 193 | div.DTFC_LeftHeadWrapper table, 194 | div.DTFC_LeftFootWrapper table, 195 | div.DTFC_RightHeadWrapper table, 196 | div.DTFC_RightFootWrapper table, 197 | table.DTFC_Cloned tr.even { 198 | background-color: white; 199 | } 200 | 201 | div.DTFC_RightHeadWrapper table, 202 | div.DTFC_LeftHeadWrapper table { 203 | margin-bottom: 0 !important; 204 | border-top-right-radius: 0 !important; 205 | border-bottom-left-radius: 0 !important; 206 | border-bottom-right-radius: 0 !important; 207 | } 208 | 209 | div.DTFC_RightHeadWrapper table thead tr:last-child th:first-child, 210 | div.DTFC_RightHeadWrapper table thead tr:last-child td:first-child, 211 | div.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child, 212 | div.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child { 213 | border-bottom-left-radius: 0 !important; 214 | border-bottom-right-radius: 0 !important; 215 | } 216 | 217 | div.DTFC_RightBodyWrapper table, 218 | div.DTFC_LeftBodyWrapper table { 219 | margin-bottom: 0 !important; 220 | border-top: none; 221 | } 222 | 223 | div.DTFC_RightBodyWrapper tbody tr:first-child th, 224 | div.DTFC_RightBodyWrapper tbody tr:first-child td, 225 | div.DTFC_LeftBodyWrapper tbody tr:first-child th, 226 | div.DTFC_LeftBodyWrapper tbody tr:first-child td { 227 | border-top: none; 228 | } 229 | 230 | div.DTFC_RightFootWrapper table, 231 | div.DTFC_LeftFootWrapper table { 232 | border-top: none; 233 | } -------------------------------------------------------------------------------- /cbd_project/static/admin/js/urlify.js: -------------------------------------------------------------------------------- 1 | var LATIN_MAP = { 2 | 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 3 | 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', 4 | 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': 5 | 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', 6 | 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 7 | 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 8 | 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 9 | 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 10 | 'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' 11 | }; 12 | var LATIN_SYMBOLS_MAP = { 13 | '©':'(c)' 14 | }; 15 | var GREEK_MAP = { 16 | 'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8', 17 | 'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p', 18 | 'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', 19 | 'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', 20 | 'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', 21 | 'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', 22 | 'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', 23 | 'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W', 24 | 'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', 25 | 'Ϋ':'Y' 26 | }; 27 | var TURKISH_MAP = { 28 | 'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U', 29 | 'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G' 30 | }; 31 | var RUSSIAN_MAP = { 32 | 'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh', 33 | 'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', 34 | 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', 35 | 'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', 36 | 'я':'ya', 37 | 'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh', 38 | 'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O', 39 | 'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C', 40 | 'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', 41 | 'Я':'Ya' 42 | }; 43 | var UKRAINIAN_MAP = { 44 | 'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g' 45 | }; 46 | var CZECH_MAP = { 47 | 'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', 48 | 'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T', 49 | 'Ů':'U', 'Ž':'Z' 50 | }; 51 | var POLISH_MAP = { 52 | 'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z', 53 | 'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S', 54 | 'Ź':'Z', 'Ż':'Z' 55 | }; 56 | var LATVIAN_MAP = { 57 | 'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n', 58 | 'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I', 59 | 'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z' 60 | }; 61 | var ARABIC_MAP = { 62 | 'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d', 63 | 'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t', 64 | 'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', 65 | 'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' 66 | }; 67 | var LITHUANIAN_MAP = { 68 | 'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', 69 | 'ž':'z', 70 | 'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U', 71 | 'Ž':'Z' 72 | }; 73 | var SERBIAN_MAP = { 74 | 'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj', 75 | 'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj' 76 | }; 77 | var AZERBAIJANI_MAP = { 78 | 'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u', 79 | 'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U' 80 | }; 81 | 82 | var ALL_DOWNCODE_MAPS = [ 83 | LATIN_MAP, 84 | LATIN_SYMBOLS_MAP, 85 | GREEK_MAP, 86 | TURKISH_MAP, 87 | RUSSIAN_MAP, 88 | UKRAINIAN_MAP, 89 | CZECH_MAP, 90 | POLISH_MAP, 91 | LATVIAN_MAP, 92 | ARABIC_MAP, 93 | LITHUANIAN_MAP, 94 | SERBIAN_MAP, 95 | AZERBAIJANI_MAP 96 | ]; 97 | 98 | var Downcoder = { 99 | 'Initialize': function() { 100 | if (Downcoder.map) { // already made 101 | return; 102 | } 103 | Downcoder.map = {}; 104 | Downcoder.chars = []; 105 | for (var i=0; ia>.fa.arrow:before { 110 | content: "\f107"; 111 | } 112 | 113 | .sidebar .nav-second-level li, 114 | .sidebar .nav-third-level li { 115 | border-bottom: 0!important; 116 | } 117 | 118 | .sidebar .nav-second-level li a { 119 | padding-left: 37px; 120 | } 121 | 122 | .sidebar .nav-third-level li a { 123 | padding-left: 52px; 124 | } 125 | 126 | @media(min-width:768px) { 127 | .sidebar { 128 | z-index: 1; 129 | position: absolute; 130 | width: 250px; 131 | margin-top: 51px; 132 | } 133 | 134 | .navbar-top-links .dropdown-messages, 135 | .navbar-top-links .dropdown-tasks, 136 | .navbar-top-links .dropdown-alerts { 137 | margin-left: auto; 138 | } 139 | } 140 | 141 | .btn-outline { 142 | color: inherit; 143 | background-color: transparent; 144 | transition: all .5s; 145 | } 146 | 147 | .btn-primary.btn-outline { 148 | color: #428bca; 149 | } 150 | 151 | .btn-success.btn-outline { 152 | color: #5cb85c; 153 | } 154 | 155 | .btn-info.btn-outline { 156 | color: #5bc0de; 157 | } 158 | 159 | .btn-warning.btn-outline { 160 | color: #f0ad4e; 161 | } 162 | 163 | .btn-danger.btn-outline { 164 | color: #d9534f; 165 | } 166 | 167 | .btn-primary.btn-outline:hover, 168 | .btn-success.btn-outline:hover, 169 | .btn-info.btn-outline:hover, 170 | .btn-warning.btn-outline:hover, 171 | .btn-danger.btn-outline:hover { 172 | color: #fff; 173 | } 174 | 175 | .chat { 176 | margin: 0; 177 | padding: 0; 178 | list-style: none; 179 | } 180 | 181 | .chat li { 182 | margin-bottom: 10px; 183 | padding-bottom: 5px; 184 | border-bottom: 1px dotted #999; 185 | } 186 | 187 | .chat li.left .chat-body { 188 | margin-left: 60px; 189 | } 190 | 191 | .chat li.right .chat-body { 192 | margin-right: 60px; 193 | } 194 | 195 | .chat li .chat-body p { 196 | margin: 0; 197 | } 198 | 199 | .panel .slidedown .glyphicon, 200 | .chat .glyphicon { 201 | margin-right: 5px; 202 | } 203 | 204 | .chat-panel .panel-body { 205 | height: 350px; 206 | overflow-y: scroll; 207 | } 208 | 209 | .login-panel { 210 | margin-top: 25%; 211 | } 212 | 213 | .flot-chart { 214 | display: block; 215 | height: 400px; 216 | } 217 | 218 | .flot-chart-content { 219 | width: 100%; 220 | height: 100%; 221 | } 222 | 223 | table.dataTable thead .sorting, 224 | table.dataTable thead .sorting_asc, 225 | table.dataTable thead .sorting_desc, 226 | table.dataTable thead .sorting_asc_disabled, 227 | table.dataTable thead .sorting_desc_disabled { 228 | background: 0 0; 229 | } 230 | 231 | table.dataTable thead .sorting_asc:after { 232 | content: "\f0de"; 233 | float: right; 234 | font-family: fontawesome; 235 | } 236 | 237 | table.dataTable thead .sorting_desc:after { 238 | content: "\f0dd"; 239 | float: right; 240 | font-family: fontawesome; 241 | } 242 | 243 | table.dataTable thead .sorting:after { 244 | content: "\f0dc"; 245 | float: right; 246 | font-family: fontawesome; 247 | color: rgba(50,50,50,.5); 248 | } 249 | 250 | .btn-circle { 251 | width: 30px; 252 | height: 30px; 253 | padding: 6px 0; 254 | border-radius: 15px; 255 | text-align: center; 256 | font-size: 12px; 257 | line-height: 1.428571429; 258 | } 259 | 260 | .btn-circle.btn-lg { 261 | width: 50px; 262 | height: 50px; 263 | padding: 10px 16px; 264 | border-radius: 25px; 265 | font-size: 18px; 266 | line-height: 1.33; 267 | } 268 | 269 | .btn-circle.btn-xl { 270 | width: 70px; 271 | height: 70px; 272 | padding: 10px 16px; 273 | border-radius: 35px; 274 | font-size: 24px; 275 | line-height: 1.33; 276 | } 277 | 278 | .show-grid [class^=col-] { 279 | padding-top: 10px; 280 | padding-bottom: 10px; 281 | border: 1px solid #ddd; 282 | background-color: #eee!important; 283 | } 284 | 285 | .show-grid { 286 | margin: 15px 0; 287 | } 288 | 289 | .huge { 290 | font-size: 40px; 291 | } 292 | 293 | .panel-green { 294 | border-color: #5cb85c; 295 | } 296 | 297 | .panel-green .panel-heading { 298 | border-color: #5cb85c; 299 | color: #fff; 300 | background-color: #5cb85c; 301 | } 302 | 303 | .panel-green a { 304 | color: #5cb85c; 305 | } 306 | 307 | .panel-green a:hover { 308 | color: #3d8b3d; 309 | } 310 | 311 | .panel-red { 312 | border-color: #d9534f; 313 | } 314 | 315 | .panel-red .panel-heading { 316 | border-color: #d9534f; 317 | color: #fff; 318 | background-color: #d9534f; 319 | } 320 | 321 | .panel-red a { 322 | color: #d9534f; 323 | } 324 | 325 | .panel-red a:hover { 326 | color: #b52b27; 327 | } 328 | 329 | .panel-yellow { 330 | border-color: #f0ad4e; 331 | } 332 | 333 | .panel-yellow .panel-heading { 334 | border-color: #f0ad4e; 335 | color: #fff; 336 | background-color: #f0ad4e; 337 | } 338 | 339 | .panel-yellow a { 340 | color: #f0ad4e; 341 | } 342 | 343 | .panel-yellow a:hover { 344 | color: #df8a13; 345 | } -------------------------------------------------------------------------------- /cbd_project/static/admin/css/forms.css: -------------------------------------------------------------------------------- 1 | @import url('widgets.css'); 2 | 3 | /* FORM ROWS */ 4 | 5 | .form-row { 6 | overflow: hidden; 7 | padding: 8px 12px; 8 | font-size: 11px; 9 | border-bottom: 1px solid #eee; 10 | } 11 | 12 | .form-row img, .form-row input { 13 | vertical-align: middle; 14 | } 15 | 16 | form .form-row p { 17 | padding-left: 0; 18 | font-size: 11px; 19 | } 20 | 21 | .hidden { 22 | display: none; 23 | } 24 | 25 | /* FORM LABELS */ 26 | 27 | form h4 { 28 | margin: 0 !important; 29 | padding: 0 !important; 30 | border: none !important; 31 | } 32 | 33 | label { 34 | font-weight: normal !important; 35 | color: #666; 36 | font-size: 12px; 37 | } 38 | 39 | .required label, label.required { 40 | font-weight: bold !important; 41 | color: #333 !important; 42 | } 43 | 44 | /* RADIO BUTTONS */ 45 | 46 | form ul.radiolist li { 47 | list-style-type: none; 48 | } 49 | 50 | form ul.radiolist label { 51 | float: none; 52 | display: inline; 53 | } 54 | 55 | form ul.inline { 56 | margin-left: 0; 57 | padding: 0; 58 | } 59 | 60 | form ul.inline li { 61 | float: left; 62 | padding-right: 7px; 63 | } 64 | 65 | /* ALIGNED FIELDSETS */ 66 | 67 | .aligned label { 68 | display: block; 69 | padding: 3px 10px 0 0; 70 | float: left; 71 | width: 8em; 72 | word-wrap: break-word; 73 | } 74 | 75 | .aligned ul label { 76 | display: inline; 77 | float: none; 78 | width: auto; 79 | } 80 | 81 | .colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { 82 | width: 350px; 83 | } 84 | 85 | form .aligned p, form .aligned ul { 86 | margin-left: 7em; 87 | padding-left: 30px; 88 | } 89 | 90 | form .aligned table p { 91 | margin-left: 0; 92 | padding-left: 0; 93 | } 94 | 95 | form .aligned p.help { 96 | padding-left: 38px; 97 | } 98 | 99 | .aligned .vCheckboxLabel { 100 | float: none !important; 101 | display: inline; 102 | padding-left: 4px; 103 | } 104 | 105 | .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { 106 | width: 610px; 107 | } 108 | 109 | .checkbox-row p.help { 110 | margin-left: 0; 111 | padding-left: 0 !important; 112 | } 113 | 114 | fieldset .field-box { 115 | float: left; 116 | margin-right: 20px; 117 | } 118 | 119 | /* WIDE FIELDSETS */ 120 | 121 | .wide label { 122 | width: 15em !important; 123 | } 124 | 125 | form .wide p { 126 | margin-left: 15em; 127 | } 128 | 129 | form .wide p.help { 130 | padding-left: 38px; 131 | } 132 | 133 | .colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { 134 | width: 450px; 135 | } 136 | 137 | /* COLLAPSED FIELDSETS */ 138 | 139 | fieldset.collapsed * { 140 | display: none; 141 | } 142 | 143 | fieldset.collapsed h2, fieldset.collapsed { 144 | display: block !important; 145 | } 146 | 147 | fieldset.collapsed h2 { 148 | background-image: url(../img/nav-bg.gif); 149 | background-position: bottom left; 150 | color: #999; 151 | } 152 | 153 | fieldset.collapsed .collapse-toggle { 154 | background: transparent; 155 | display: inline !important; 156 | } 157 | 158 | /* MONOSPACE TEXTAREAS */ 159 | 160 | fieldset.monospace textarea { 161 | font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; 162 | } 163 | 164 | /* SUBMIT ROW */ 165 | 166 | .submit-row { 167 | padding: 5px 7px; 168 | text-align: right; 169 | background: white url(../img/nav-bg.gif) 0 100% repeat-x; 170 | border: 1px solid #ccc; 171 | margin: 5px 0; 172 | overflow: hidden; 173 | } 174 | 175 | body.popup .submit-row { 176 | overflow: auto; 177 | } 178 | 179 | .submit-row input { 180 | margin: 0 0 0 5px; 181 | } 182 | 183 | .submit-row p { 184 | margin: 0.3em; 185 | } 186 | 187 | .submit-row p.deletelink-box { 188 | float: left; 189 | } 190 | 191 | .submit-row .deletelink { 192 | background: url(../img/icon_deletelink.gif) 0 50% no-repeat; 193 | padding-left: 14px; 194 | } 195 | 196 | /* CUSTOM FORM FIELDS */ 197 | 198 | .vSelectMultipleField { 199 | vertical-align: top !important; 200 | } 201 | 202 | .vCheckboxField { 203 | border: none; 204 | } 205 | 206 | .vDateField, .vTimeField { 207 | margin-right: 2px; 208 | } 209 | 210 | .vDateField { 211 | min-width: 6.85em; 212 | } 213 | 214 | .vTimeField { 215 | min-width: 4.7em; 216 | } 217 | 218 | .vURLField { 219 | width: 30em; 220 | } 221 | 222 | .vLargeTextField, .vXMLLargeTextField { 223 | width: 48em; 224 | } 225 | 226 | .flatpages-flatpage #id_content { 227 | height: 40.2em; 228 | } 229 | 230 | .module table .vPositiveSmallIntegerField { 231 | width: 2.2em; 232 | } 233 | 234 | .vTextField { 235 | width: 20em; 236 | } 237 | 238 | .vIntegerField { 239 | width: 5em; 240 | } 241 | 242 | .vBigIntegerField { 243 | width: 10em; 244 | } 245 | 246 | .vForeignKeyRawIdAdminField { 247 | width: 5em; 248 | } 249 | 250 | /* INLINES */ 251 | 252 | .inline-group { 253 | padding: 0; 254 | border: 1px solid #ccc; 255 | margin: 10px 0; 256 | } 257 | 258 | .inline-group .aligned label { 259 | width: 8em; 260 | } 261 | 262 | .inline-related { 263 | position: relative; 264 | } 265 | 266 | .inline-related h3 { 267 | margin: 0; 268 | color: #666; 269 | padding: 3px 5px; 270 | font-size: 11px; 271 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 272 | border-bottom: 1px solid #ddd; 273 | } 274 | 275 | .inline-related h3 span.delete { 276 | float: right; 277 | } 278 | 279 | .inline-related h3 span.delete label { 280 | margin-left: 2px; 281 | font-size: 11px; 282 | } 283 | 284 | .inline-related fieldset { 285 | margin: 0; 286 | background: #fff; 287 | border: none; 288 | width: 100%; 289 | } 290 | 291 | .inline-related fieldset.module h3 { 292 | margin: 0; 293 | padding: 2px 5px 3px 5px; 294 | font-size: 11px; 295 | text-align: left; 296 | font-weight: bold; 297 | background: #bcd; 298 | color: #fff; 299 | } 300 | 301 | .inline-group .tabular fieldset.module { 302 | border: none; 303 | border-bottom: 1px solid #ddd; 304 | } 305 | 306 | .inline-related.tabular fieldset.module table { 307 | width: 100%; 308 | } 309 | 310 | .last-related fieldset { 311 | border: none; 312 | } 313 | 314 | .inline-group .tabular tr.has_original td { 315 | padding-top: 2em; 316 | } 317 | 318 | .inline-group .tabular tr td.original { 319 | padding: 2px 0 0 0; 320 | width: 0; 321 | _position: relative; 322 | } 323 | 324 | .inline-group .tabular th.original { 325 | width: 0px; 326 | padding: 0; 327 | } 328 | 329 | .inline-group .tabular td.original p { 330 | position: absolute; 331 | left: 0; 332 | height: 1.1em; 333 | padding: 2px 7px; 334 | overflow: hidden; 335 | font-size: 9px; 336 | font-weight: bold; 337 | color: #666; 338 | _width: 700px; 339 | } 340 | 341 | .inline-group ul.tools { 342 | padding: 0; 343 | margin: 0; 344 | list-style: none; 345 | } 346 | 347 | .inline-group ul.tools li { 348 | display: inline; 349 | padding: 0 5px; 350 | } 351 | 352 | .inline-group div.add-row, 353 | .inline-group .tabular tr.add-row td { 354 | color: #666; 355 | padding: 3px 5px; 356 | border-bottom: 1px solid #ddd; 357 | background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; 358 | } 359 | 360 | .inline-group .tabular tr.add-row td { 361 | padding: 4px 5px 3px; 362 | border-bottom: none; 363 | } 364 | 365 | .inline-group ul.tools a.add, 366 | .inline-group div.add-row a, 367 | .inline-group .tabular tr.add-row td a { 368 | background: url(../img/icon_addlink.gif) 0 50% no-repeat; 369 | padding-left: 14px; 370 | font-size: 11px; 371 | outline: 0; /* Remove dotted border around link */ 372 | } 373 | 374 | .empty-form { 375 | display: none; 376 | } 377 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/core.js: -------------------------------------------------------------------------------- 1 | // Core javascript helper functions 2 | 3 | // basic browser identification & version 4 | var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion); 5 | var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]); 6 | 7 | // Cross-browser event handlers. 8 | function addEvent(obj, evType, fn) { 9 | if (obj.addEventListener) { 10 | obj.addEventListener(evType, fn, false); 11 | return true; 12 | } else if (obj.attachEvent) { 13 | var r = obj.attachEvent("on" + evType, fn); 14 | return r; 15 | } else { 16 | return false; 17 | } 18 | } 19 | 20 | function removeEvent(obj, evType, fn) { 21 | if (obj.removeEventListener) { 22 | obj.removeEventListener(evType, fn, false); 23 | return true; 24 | } else if (obj.detachEvent) { 25 | obj.detachEvent("on" + evType, fn); 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | 32 | function cancelEventPropagation(e) { 33 | if (!e) e = window.event; 34 | e.cancelBubble = true; 35 | if (e.stopPropagation) e.stopPropagation(); 36 | } 37 | 38 | // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); 39 | function quickElement() { 40 | var obj = document.createElement(arguments[0]); 41 | if (arguments[2]) { 42 | var textNode = document.createTextNode(arguments[2]); 43 | obj.appendChild(textNode); 44 | } 45 | var len = arguments.length; 46 | for (var i = 3; i < len; i += 2) { 47 | obj.setAttribute(arguments[i], arguments[i+1]); 48 | } 49 | arguments[1].appendChild(obj); 50 | return obj; 51 | } 52 | 53 | // "a" is reference to an object 54 | function removeChildren(a) { 55 | while (a.hasChildNodes()) a.removeChild(a.lastChild); 56 | } 57 | 58 | // ---------------------------------------------------------------------------- 59 | // Cross-browser xmlhttp object 60 | // from http://jibbering.com/2002/4/httprequest.html 61 | // ---------------------------------------------------------------------------- 62 | var xmlhttp; 63 | /*@cc_on @*/ 64 | /*@if (@_jscript_version >= 5) 65 | try { 66 | xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 67 | } catch (e) { 68 | try { 69 | xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 70 | } catch (E) { 71 | xmlhttp = false; 72 | } 73 | } 74 | @else 75 | xmlhttp = false; 76 | @end @*/ 77 | if (!xmlhttp && typeof XMLHttpRequest != 'undefined') { 78 | xmlhttp = new XMLHttpRequest(); 79 | } 80 | 81 | // ---------------------------------------------------------------------------- 82 | // Find-position functions by PPK 83 | // See http://www.quirksmode.org/js/findpos.html 84 | // ---------------------------------------------------------------------------- 85 | function findPosX(obj) { 86 | var curleft = 0; 87 | if (obj.offsetParent) { 88 | while (obj.offsetParent) { 89 | curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft); 90 | obj = obj.offsetParent; 91 | } 92 | // IE offsetParent does not include the top-level 93 | if (isIE && obj.parentElement){ 94 | curleft += obj.offsetLeft - obj.scrollLeft; 95 | } 96 | } else if (obj.x) { 97 | curleft += obj.x; 98 | } 99 | return curleft; 100 | } 101 | 102 | function findPosY(obj) { 103 | var curtop = 0; 104 | if (obj.offsetParent) { 105 | while (obj.offsetParent) { 106 | curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop); 107 | obj = obj.offsetParent; 108 | } 109 | // IE offsetParent does not include the top-level 110 | if (isIE && obj.parentElement){ 111 | curtop += obj.offsetTop - obj.scrollTop; 112 | } 113 | } else if (obj.y) { 114 | curtop += obj.y; 115 | } 116 | return curtop; 117 | } 118 | 119 | //----------------------------------------------------------------------------- 120 | // Date object extensions 121 | // ---------------------------------------------------------------------------- 122 | 123 | Date.prototype.getTwelveHours = function() { 124 | hours = this.getHours(); 125 | if (hours == 0) { 126 | return 12; 127 | } 128 | else { 129 | return hours <= 12 ? hours : hours-12 130 | } 131 | } 132 | 133 | Date.prototype.getTwoDigitMonth = function() { 134 | return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1); 135 | } 136 | 137 | Date.prototype.getTwoDigitDate = function() { 138 | return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); 139 | } 140 | 141 | Date.prototype.getTwoDigitTwelveHour = function() { 142 | return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); 143 | } 144 | 145 | Date.prototype.getTwoDigitHour = function() { 146 | return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); 147 | } 148 | 149 | Date.prototype.getTwoDigitMinute = function() { 150 | return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); 151 | } 152 | 153 | Date.prototype.getTwoDigitSecond = function() { 154 | return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); 155 | } 156 | 157 | Date.prototype.getHourMinute = function() { 158 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); 159 | } 160 | 161 | Date.prototype.getHourMinuteSecond = function() { 162 | return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); 163 | } 164 | 165 | Date.prototype.strftime = function(format) { 166 | var fields = { 167 | c: this.toString(), 168 | d: this.getTwoDigitDate(), 169 | H: this.getTwoDigitHour(), 170 | I: this.getTwoDigitTwelveHour(), 171 | m: this.getTwoDigitMonth(), 172 | M: this.getTwoDigitMinute(), 173 | p: (this.getHours() >= 12) ? 'PM' : 'AM', 174 | S: this.getTwoDigitSecond(), 175 | w: '0' + this.getDay(), 176 | x: this.toLocaleDateString(), 177 | X: this.toLocaleTimeString(), 178 | y: ('' + this.getFullYear()).substr(2, 4), 179 | Y: '' + this.getFullYear(), 180 | '%' : '%' 181 | }; 182 | var result = '', i = 0; 183 | while (i < format.length) { 184 | if (format.charAt(i) === '%') { 185 | result = result + fields[format.charAt(i + 1)]; 186 | ++i; 187 | } 188 | else { 189 | result = result + format.charAt(i); 190 | } 191 | ++i; 192 | } 193 | return result; 194 | } 195 | 196 | // ---------------------------------------------------------------------------- 197 | // String object extensions 198 | // ---------------------------------------------------------------------------- 199 | String.prototype.pad_left = function(pad_length, pad_string) { 200 | var new_string = this; 201 | for (var i = 0; new_string.length < pad_length; i++) { 202 | new_string = pad_string + new_string; 203 | } 204 | return new_string; 205 | } 206 | 207 | // ---------------------------------------------------------------------------- 208 | // Get the computed style for and element 209 | // ---------------------------------------------------------------------------- 210 | function getStyle(oElm, strCssRule){ 211 | var strValue = ""; 212 | if(document.defaultView && document.defaultView.getComputedStyle){ 213 | strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); 214 | } 215 | else if(oElm.currentStyle){ 216 | strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ 217 | return p1.toUpperCase(); 218 | }); 219 | strValue = oElm.currentStyle[strCssRule]; 220 | } 221 | return strValue; 222 | } 223 | -------------------------------------------------------------------------------- /cbd_project/static/less/sb-admin-2.less: -------------------------------------------------------------------------------- 1 | @import "variables.less"; 2 | @import "mixins.less"; 3 | 4 | // Global Styles 5 | 6 | body { 7 | background-color: @gray-lightest; 8 | } 9 | 10 | // Wrappers 11 | 12 | #wrapper { 13 | width: 100%; 14 | } 15 | 16 | #page-wrapper { 17 | padding: 0 15px; 18 | min-height: 568px; 19 | background-color: white; 20 | } 21 | 22 | @media(min-width:768px) { 23 | #page-wrapper { 24 | position: inherit; 25 | margin: 0 0 0 250px; 26 | padding: 0 30px; 27 | border-left: 1px solid darken(@gray-lightest, 6.5%); 28 | } 29 | } 30 | 31 | // Navigation 32 | 33 | // --Topbar 34 | 35 | .navbar-top-links li { 36 | display: inline-block; 37 | } 38 | 39 | .navbar-top-links li:last-child { 40 | margin-right: 15px; 41 | } 42 | 43 | .navbar-top-links li a { 44 | padding: 15px; 45 | min-height: 50px; 46 | } 47 | 48 | .navbar-top-links .dropdown-menu li { 49 | display: block; 50 | } 51 | 52 | .navbar-top-links .dropdown-menu li:last-child { 53 | margin-right: 0; 54 | } 55 | 56 | .navbar-top-links .dropdown-menu li a { 57 | padding: 3px 20px; 58 | min-height: 0; 59 | } 60 | 61 | .navbar-top-links .dropdown-menu li a div { 62 | white-space: normal; 63 | } 64 | 65 | .navbar-top-links .dropdown-messages, 66 | .navbar-top-links .dropdown-tasks, 67 | .navbar-top-links .dropdown-alerts { 68 | width: 310px; 69 | min-width: 0; 70 | } 71 | 72 | .navbar-top-links .dropdown-messages { 73 | margin-left: 5px; 74 | } 75 | 76 | .navbar-top-links .dropdown-tasks { 77 | margin-left: -59px; 78 | } 79 | 80 | .navbar-top-links .dropdown-alerts { 81 | margin-left: -123px; 82 | } 83 | 84 | .navbar-top-links .dropdown-user { 85 | right: 0; 86 | left: auto; 87 | } 88 | 89 | // --Sidebar 90 | 91 | .sidebar { 92 | .sidebar-nav.navbar-collapse { 93 | padding-left: 0; 94 | padding-right: 0; 95 | } 96 | } 97 | 98 | .sidebar .sidebar-search { 99 | padding: 15px; 100 | } 101 | 102 | .sidebar ul li { 103 | border-bottom: 1px solid darken(@gray-lightest, 6.5%); 104 | a { 105 | &.active { 106 | background-color: @gray-lighter; 107 | } 108 | } 109 | } 110 | 111 | .sidebar .arrow { 112 | float: right; 113 | } 114 | 115 | .sidebar .fa.arrow:before { 116 | content: "\f104"; 117 | } 118 | 119 | .sidebar .active > a > .fa.arrow:before { 120 | content: "\f107"; 121 | } 122 | 123 | .sidebar .nav-second-level li, 124 | .sidebar .nav-third-level li { 125 | border-bottom: none !important; 126 | } 127 | 128 | .sidebar .nav-second-level li a { 129 | padding-left: 37px; 130 | } 131 | 132 | .sidebar .nav-third-level li a { 133 | padding-left: 52px; 134 | } 135 | 136 | @media(min-width:768px) { 137 | .sidebar { 138 | z-index: 1; 139 | position: absolute; 140 | width: 250px; 141 | margin-top: 51px; 142 | } 143 | 144 | .navbar-top-links .dropdown-messages, 145 | .navbar-top-links .dropdown-tasks, 146 | .navbar-top-links .dropdown-alerts { 147 | margin-left: auto; 148 | } 149 | } 150 | 151 | // Buttons 152 | 153 | .btn-outline { 154 | color: inherit; 155 | background-color: transparent; 156 | transition: all .5s; 157 | } 158 | 159 | .btn-primary.btn-outline { 160 | color: @brand-primary; 161 | } 162 | 163 | .btn-success.btn-outline { 164 | color: @brand-success; 165 | } 166 | 167 | .btn-info.btn-outline { 168 | color: @brand-info; 169 | } 170 | 171 | .btn-warning.btn-outline { 172 | color: @brand-warning; 173 | } 174 | 175 | .btn-danger.btn-outline { 176 | color: @brand-danger; 177 | } 178 | 179 | .btn-primary.btn-outline:hover, 180 | .btn-success.btn-outline:hover, 181 | .btn-info.btn-outline:hover, 182 | .btn-warning.btn-outline:hover, 183 | .btn-danger.btn-outline:hover { 184 | color: white; 185 | } 186 | 187 | // Chat Widget 188 | 189 | .chat { 190 | margin: 0; 191 | padding: 0; 192 | list-style: none; 193 | } 194 | 195 | .chat li { 196 | margin-bottom: 10px; 197 | padding-bottom: 5px; 198 | border-bottom: 1px dotted @gray-light; 199 | } 200 | 201 | .chat li.left .chat-body { 202 | margin-left: 60px; 203 | } 204 | 205 | .chat li.right .chat-body { 206 | margin-right: 60px; 207 | } 208 | 209 | .chat li .chat-body p { 210 | margin: 0; 211 | } 212 | 213 | .panel .slidedown .glyphicon, 214 | .chat .glyphicon { 215 | margin-right: 5px; 216 | } 217 | 218 | .chat-panel .panel-body { 219 | height: 350px; 220 | overflow-y: scroll; 221 | } 222 | 223 | // Login Page 224 | 225 | .login-panel { 226 | margin-top: 25%; 227 | } 228 | 229 | // Flot Charts Containers 230 | 231 | .flot-chart { 232 | display: block; 233 | height: 400px; 234 | } 235 | 236 | .flot-chart-content { 237 | width: 100%; 238 | height: 100%; 239 | } 240 | 241 | // DataTables Overrides 242 | 243 | table.dataTable thead .sorting, 244 | table.dataTable thead .sorting_asc, 245 | table.dataTable thead .sorting_desc, 246 | table.dataTable thead .sorting_asc_disabled, 247 | table.dataTable thead .sorting_desc_disabled { 248 | background: transparent; 249 | } 250 | 251 | table.dataTable thead .sorting_asc:after { 252 | content: "\f0de"; 253 | float: right; 254 | font-family: fontawesome; 255 | } 256 | 257 | table.dataTable thead .sorting_desc:after { 258 | content: "\f0dd"; 259 | float: right; 260 | font-family: fontawesome; 261 | } 262 | 263 | table.dataTable thead .sorting:after { 264 | content: "\f0dc"; 265 | float: right; 266 | font-family: fontawesome; 267 | color: rgba(50,50,50,.5); 268 | } 269 | 270 | // Circle Buttons 271 | 272 | .btn-circle { 273 | width: 30px; 274 | height: 30px; 275 | padding: 6px 0; 276 | border-radius: 15px; 277 | text-align: center; 278 | font-size: 12px; 279 | line-height: 1.428571429; 280 | } 281 | 282 | .btn-circle.btn-lg { 283 | width: 50px; 284 | height: 50px; 285 | padding: 10px 16px; 286 | border-radius: 25px; 287 | font-size: 18px; 288 | line-height: 1.33; 289 | } 290 | 291 | .btn-circle.btn-xl { 292 | width: 70px; 293 | height: 70px; 294 | padding: 10px 16px; 295 | border-radius: 35px; 296 | font-size: 24px; 297 | line-height: 1.33; 298 | } 299 | 300 | // Grid Demo Elements 301 | 302 | .show-grid [class^="col-"] { 303 | padding-top: 10px; 304 | padding-bottom: 10px; 305 | border: 1px solid #ddd; 306 | background-color: #eee !important; 307 | } 308 | 309 | .show-grid { 310 | margin: 15px 0; 311 | } 312 | 313 | // Custom Colored Panels 314 | 315 | .huge { 316 | font-size: 40px; 317 | } 318 | 319 | .panel-green { 320 | border-color: @brand-success; 321 | .panel-heading { 322 | border-color: @brand-success; 323 | color: white; 324 | background-color: @brand-success; 325 | } 326 | a { 327 | color: @brand-success; 328 | &:hover { 329 | color: darken(@brand-success, 15%); 330 | } 331 | } 332 | } 333 | 334 | .panel-red { 335 | border-color: @brand-danger; 336 | .panel-heading { 337 | border-color: @brand-danger; 338 | color: white; 339 | background-color: @brand-danger; 340 | } 341 | a { 342 | color: @brand-danger; 343 | &:hover { 344 | color: darken(@brand-danger, 15%); 345 | } 346 | } 347 | } 348 | 349 | .panel-yellow { 350 | border-color: @brand-warning; 351 | .panel-heading { 352 | border-color: @brand-warning; 353 | color: white; 354 | background-color: @brand-warning; 355 | } 356 | a { 357 | color: @brand-warning; 358 | &:hover { 359 | color: darken(@brand-warning, 15%); 360 | } 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/SelectFilter2.js: -------------------------------------------------------------------------------- 1 | /* 2 | SelectFilter2 - Turns a multiple-select box into a filter interface. 3 | 4 | Requires core.js, SelectBox.js and addevent.js. 5 | */ 6 | (function($) { 7 | function findForm(node) { 8 | // returns the node of the form containing the given node 9 | if (node.tagName.toLowerCase() != 'form') { 10 | return findForm(node.parentNode); 11 | } 12 | return node; 13 | } 14 | 15 | window.SelectFilter = { 16 | init: function(field_id, field_name, is_stacked, admin_static_prefix) { 17 | if (field_id.match(/__prefix__/)){ 18 | // Don't intialize on empty forms. 19 | return; 20 | } 21 | var from_box = document.getElementById(field_id); 22 | from_box.id += '_from'; // change its ID 23 | from_box.className = 'filtered'; 24 | 25 | var ps = from_box.parentNode.getElementsByTagName('p'); 26 | for (var i=0; i, because it just gets in the way. 29 | from_box.parentNode.removeChild(ps[i]); 30 | } else if (ps[i].className.indexOf("help") != -1) { 31 | // Move help text up to the top so it isn't below the select 32 | // boxes or wrapped off on the side to the right of the add 33 | // button: 34 | from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); 35 | } 36 | } 37 | 38 | //
    or
    39 | var selector_div = quickElement('div', from_box.parentNode); 40 | selector_div.className = is_stacked ? 'selector stacked' : 'selector'; 41 | 42 | //
    43 | var selector_available = quickElement('div', selector_div); 44 | selector_available.className = 'selector-available'; 45 | var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); 46 | quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); 47 | 48 | var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); 49 | filter_p.className = 'selector-filter'; 50 | 51 | var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); 52 | 53 | var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); 54 | 55 | filter_p.appendChild(document.createTextNode(' ')); 56 | 57 | var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); 58 | filter_input.id = field_id + '_input'; 59 | 60 | selector_available.appendChild(from_box); 61 | var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); 62 | choose_all.className = 'selector-chooseall'; 63 | 64 | //
      65 | var selector_chooser = quickElement('ul', selector_div); 66 | selector_chooser.className = 'selector-chooser'; 67 | var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); 68 | add_link.className = 'selector-add'; 69 | var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); 70 | remove_link.className = 'selector-remove'; 71 | 72 | //
      73 | var selector_chosen = quickElement('div', selector_div); 74 | selector_chosen.className = 'selector-chosen'; 75 | var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); 76 | quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); 77 | 78 | var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); 79 | to_box.className = 'filtered'; 80 | var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); 81 | clear_all.className = 'selector-clearall'; 82 | 83 | from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); 84 | 85 | // Set up the JavaScript event handlers for the select box filter interface 86 | addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); 87 | addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); 88 | addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); 89 | addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); 90 | addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); 91 | addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); 92 | addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); 93 | SelectBox.init(field_id + '_from'); 94 | SelectBox.init(field_id + '_to'); 95 | // Move selected from_box options to to_box 96 | SelectBox.move(field_id + '_from', field_id + '_to'); 97 | 98 | if (!is_stacked) { 99 | // In horizontal mode, give the same height to the two boxes. 100 | var j_from_box = $(from_box); 101 | var j_to_box = $(to_box); 102 | var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } 103 | if (j_from_box.outerHeight() > 0) { 104 | resize_filters(); // This fieldset is already open. Resize now. 105 | } else { 106 | // This fieldset is probably collapsed. Wait for its 'show' event. 107 | j_to_box.closest('fieldset').one('show.fieldset', resize_filters); 108 | } 109 | } 110 | 111 | // Initial icon refresh 112 | SelectFilter.refresh_icons(field_id); 113 | }, 114 | refresh_icons: function(field_id) { 115 | var from = $('#' + field_id + '_from'); 116 | var to = $('#' + field_id + '_to'); 117 | var is_from_selected = from.find('option:selected').length > 0; 118 | var is_to_selected = to.find('option:selected').length > 0; 119 | // Active if at least one item is selected 120 | $('#' + field_id + '_add_link').toggleClass('active', is_from_selected); 121 | $('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); 122 | // Active if the corresponding box isn't empty 123 | $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); 124 | $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); 125 | }, 126 | filter_key_up: function(event, field_id) { 127 | var from = document.getElementById(field_id + '_from'); 128 | // don't submit form if user pressed Enter 129 | if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) { 130 | from.selectedIndex = 0; 131 | SelectBox.move(field_id + '_from', field_id + '_to'); 132 | from.selectedIndex = 0; 133 | return false; 134 | } 135 | var temp = from.selectedIndex; 136 | SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); 137 | from.selectedIndex = temp; 138 | return true; 139 | }, 140 | filter_key_down: function(event, field_id) { 141 | var from = document.getElementById(field_id + '_from'); 142 | // right arrow -- move across 143 | if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { 144 | var old_index = from.selectedIndex; 145 | SelectBox.move(field_id + '_from', field_id + '_to'); 146 | from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; 147 | return false; 148 | } 149 | // down arrow -- wrap around 150 | if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { 151 | from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; 152 | } 153 | // up arrow -- wrap around 154 | if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { 155 | from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; 156 | } 157 | return true; 158 | } 159 | } 160 | 161 | })(django.jQuery); 162 | -------------------------------------------------------------------------------- /cbd_project/static/js/plugins/dataTables/dataTables.bootstrap.js: -------------------------------------------------------------------------------- 1 | /* Set the defaults for DataTables initialisation */ 2 | $.extend(true, $.fn.dataTable.defaults, { 3 | "sDom": "<'row'<'col-sm-6'l><'col-sm-6'f>r>" + "t" + "<'row'<'col-sm-6'i><'col-sm-6'p>>", 4 | "oLanguage": { 5 | "sLengthMenu": "_MENU_ records per page" 6 | } 7 | }); 8 | 9 | 10 | /* Default class modification */ 11 | $.extend($.fn.dataTableExt.oStdClasses, { 12 | "sWrapper": "dataTables_wrapper form-inline", 13 | "sFilterInput": "form-control input-sm", 14 | "sLengthSelect": "form-control input-sm" 15 | }); 16 | 17 | // In 1.10 we use the pagination renderers to draw the Bootstrap paging, 18 | // rather than custom plug-in 19 | if ($.fn.dataTable.Api) { 20 | $.fn.dataTable.defaults.renderer = 'bootstrap'; 21 | $.fn.dataTable.ext.renderer.pageButton.bootstrap = function(settings, host, idx, buttons, page, pages) { 22 | var api = new $.fn.dataTable.Api(settings); 23 | var classes = settings.oClasses; 24 | var lang = settings.oLanguage.oPaginate; 25 | var btnDisplay, btnClass; 26 | 27 | var attach = function(container, buttons) { 28 | var i, ien, node, button; 29 | var clickHandler = function(e) { 30 | e.preventDefault(); 31 | if (e.data.action !== 'ellipsis') { 32 | api.page(e.data.action).draw(false); 33 | } 34 | }; 35 | 36 | for (i = 0, ien = buttons.length; i < ien; i++) { 37 | button = buttons[i]; 38 | 39 | if ($.isArray(button)) { 40 | attach(container, button); 41 | } else { 42 | btnDisplay = ''; 43 | btnClass = ''; 44 | 45 | switch (button) { 46 | case 'ellipsis': 47 | btnDisplay = '…'; 48 | btnClass = 'disabled'; 49 | break; 50 | 51 | case 'first': 52 | btnDisplay = lang.sFirst; 53 | btnClass = button + (page > 0 ? 54 | '' : ' disabled'); 55 | break; 56 | 57 | case 'previous': 58 | btnDisplay = lang.sPrevious; 59 | btnClass = button + (page > 0 ? 60 | '' : ' disabled'); 61 | break; 62 | 63 | case 'next': 64 | btnDisplay = lang.sNext; 65 | btnClass = button + (page < pages - 1 ? 66 | '' : ' disabled'); 67 | break; 68 | 69 | case 'last': 70 | btnDisplay = lang.sLast; 71 | btnClass = button + (page < pages - 1 ? 72 | '' : ' disabled'); 73 | break; 74 | 75 | default: 76 | btnDisplay = button + 1; 77 | btnClass = page === button ? 78 | 'active' : ''; 79 | break; 80 | } 81 | 82 | if (btnDisplay) { 83 | node = $('
    • ', { 84 | 'class': classes.sPageButton + ' ' + btnClass, 85 | 'aria-controls': settings.sTableId, 86 | 'tabindex': settings.iTabIndex, 87 | 'id': idx === 0 && typeof button === 'string' ? settings.sTableId + '_' + button : null 88 | }) 89 | .append($('', { 90 | 'href': '#' 91 | }) 92 | .html(btnDisplay) 93 | ) 94 | .appendTo(container); 95 | 96 | settings.oApi._fnBindAction( 97 | node, { 98 | action: button 99 | }, clickHandler 100 | ); 101 | } 102 | } 103 | } 104 | }; 105 | 106 | attach( 107 | $(host).empty().html('
        ').children('ul'), 108 | buttons 109 | ); 110 | } 111 | } else { 112 | // Integration for 1.9- 113 | $.fn.dataTable.defaults.sPaginationType = 'bootstrap'; 114 | 115 | /* API method to get paging information */ 116 | $.fn.dataTableExt.oApi.fnPagingInfo = function(oSettings) { 117 | return { 118 | "iStart": oSettings._iDisplayStart, 119 | "iEnd": oSettings.fnDisplayEnd(), 120 | "iLength": oSettings._iDisplayLength, 121 | "iTotal": oSettings.fnRecordsTotal(), 122 | "iFilteredTotal": oSettings.fnRecordsDisplay(), 123 | "iPage": oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength), 124 | "iTotalPages": oSettings._iDisplayLength === -1 ? 0 : Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength) 125 | }; 126 | }; 127 | 128 | /* Bootstrap style pagination control */ 129 | $.extend($.fn.dataTableExt.oPagination, { 130 | "bootstrap": { 131 | "fnInit": function(oSettings, nPaging, fnDraw) { 132 | var oLang = oSettings.oLanguage.oPaginate; 133 | var fnClickHandler = function(e) { 134 | e.preventDefault(); 135 | if (oSettings.oApi._fnPageChange(oSettings, e.data.action)) { 136 | fnDraw(oSettings); 137 | } 138 | }; 139 | 140 | $(nPaging).append( 141 | '' 145 | ); 146 | var els = $('a', nPaging); 147 | $(els[0]).bind('click.DT', { 148 | action: "previous" 149 | }, fnClickHandler); 150 | $(els[1]).bind('click.DT', { 151 | action: "next" 152 | }, fnClickHandler); 153 | }, 154 | 155 | "fnUpdate": function(oSettings, fnDraw) { 156 | var iListLength = 5; 157 | var oPaging = oSettings.oInstance.fnPagingInfo(); 158 | var an = oSettings.aanFeatures.p; 159 | var i, ien, j, sClass, iStart, iEnd, iHalf = Math.floor(iListLength / 2); 160 | 161 | if (oPaging.iTotalPages < iListLength) { 162 | iStart = 1; 163 | iEnd = oPaging.iTotalPages; 164 | } else if (oPaging.iPage <= iHalf) { 165 | iStart = 1; 166 | iEnd = iListLength; 167 | } else if (oPaging.iPage >= (oPaging.iTotalPages - iHalf)) { 168 | iStart = oPaging.iTotalPages - iListLength + 1; 169 | iEnd = oPaging.iTotalPages; 170 | } else { 171 | iStart = oPaging.iPage - iHalf + 1; 172 | iEnd = iStart + iListLength - 1; 173 | } 174 | 175 | for (i = 0, ien = an.length; i < ien; i++) { 176 | // Remove the middle elements 177 | $('li:gt(0)', an[i]).filter(':not(:last)').remove(); 178 | 179 | // Add the new list items and their event handlers 180 | for (j = iStart; j <= iEnd; j++) { 181 | sClass = (j == oPaging.iPage + 1) ? 'class="active"' : ''; 182 | $('
      • ' + j + '
      • ') 183 | .insertBefore($('li:last', an[i])[0]) 184 | .bind('click', function(e) { 185 | e.preventDefault(); 186 | oSettings._iDisplayStart = (parseInt($('a', this).text(), 10) - 1) * oPaging.iLength; 187 | fnDraw(oSettings); 188 | }); 189 | } 190 | 191 | // Add / remove disabled classes from the static elements 192 | if (oPaging.iPage === 0) { 193 | $('li:first', an[i]).addClass('disabled'); 194 | } else { 195 | $('li:first', an[i]).removeClass('disabled'); 196 | } 197 | 198 | if (oPaging.iPage === oPaging.iTotalPages - 1 || oPaging.iTotalPages === 0) { 199 | $('li:last', an[i]).addClass('disabled'); 200 | } else { 201 | $('li:last', an[i]).removeClass('disabled'); 202 | } 203 | } 204 | } 205 | } 206 | }); 207 | } 208 | 209 | 210 | /* 211 | * TableTools Bootstrap compatibility 212 | * Required TableTools 2.1+ 213 | */ 214 | if ($.fn.DataTable.TableTools) { 215 | // Set the classes that TableTools uses to something suitable for Bootstrap 216 | $.extend(true, $.fn.DataTable.TableTools.classes, { 217 | "container": "DTTT btn-group", 218 | "buttons": { 219 | "normal": "btn btn-default", 220 | "disabled": "disabled" 221 | }, 222 | "collection": { 223 | "container": "DTTT_dropdown dropdown-menu", 224 | "buttons": { 225 | "normal": "", 226 | "disabled": "disabled" 227 | } 228 | }, 229 | "print": { 230 | "info": "DTTT_print_info modal" 231 | }, 232 | "select": { 233 | "row": "active" 234 | } 235 | }); 236 | 237 | // Have the collection use a bootstrap compatible dropdown 238 | $.extend(true, $.fn.DataTable.TableTools.DEFAULTS.oTags, { 239 | "collection": { 240 | "container": "ul", 241 | "button": "li", 242 | "liner": "a" 243 | } 244 | }); 245 | } 246 | -------------------------------------------------------------------------------- /cbd_project/cbd/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.http import HttpResponse 3 | from django.template import RequestContext 4 | from django.shortcuts import render_to_response 5 | 6 | from django.contrib.auth import authenticate, login 7 | from django.http import HttpResponseRedirect 8 | from django.contrib.auth.decorators import login_required 9 | from django.contrib.auth import logout 10 | from django.db.models import Count 11 | 12 | import json 13 | import datetime 14 | 15 | from django.db.models import Max 16 | from django.db.models import Min 17 | 18 | import datetime, qsstats 19 | 20 | from cbd.models import ProcessedSocialMediaMessage, MLCache, IncorrectClassification 21 | 22 | from django.core import serializers 23 | from django.views.decorators.http import require_http_methods 24 | from django.views.decorators.csrf import csrf_exempt 25 | 26 | def index(request): 27 | context = RequestContext(request) 28 | 29 | if request.method == 'POST': 30 | username = request.POST['username'] 31 | password = request.POST['password'] 32 | 33 | user = authenticate(username=username, password=password) 34 | 35 | if user is not None: 36 | # Is the account active? It could have been disabled. 37 | if user.is_active: 38 | # If the account is valid and active, we can log the user in. 39 | # We'll send the user back to the homepage. 40 | login(request, user) 41 | return HttpResponseRedirect('/dashboard/') 42 | else: 43 | # An inactive account was used - no logging in! 44 | return HttpResponse("Your account is disabled.") 45 | else: 46 | # Bad login details were provided. So we can't log the user in. 47 | print "Invalid login details: {0}, {1}".format(username, password) 48 | return HttpResponse("Invalid login details supplied.") 49 | 50 | # The request is not a HTTP POST, so display the login form. 51 | # This scenario would most likely be a HTTP GET. 52 | else: 53 | # No context variables to pass to the template system, hence the 54 | # blank dictionary object... 55 | return render_to_response('cbd/index.html', {}, context) 56 | 57 | @login_required 58 | def user_logout(request): 59 | logout(request) 60 | return HttpResponseRedirect('/cbd/index.html') 61 | 62 | @login_required 63 | def moderate(request): 64 | context = RequestContext(request) 65 | threadid = request.GET.get('threadid') 66 | 67 | user = request.user 68 | userid = user.id 69 | 70 | messages = SocialMediaMessage.objects.filter(threadid=threadid).order_by('id') 71 | 72 | coded_messages = SocialMediaCodedMessage.objects.filter(userid=userid, threadid=threadid) 73 | coded_messages_dict = {} 74 | 75 | for msg in coded_messages: 76 | coded_messages_dict[msg.postid] = {"comment": msg.message_comment, "role": msg.author_role, "evidence": msg.bullying_evidence_in_message, "usedurbandict": msg.message_contains_urban_dictionary_acronym } 77 | 78 | saved_codes_json = json.dumps(coded_messages_dict) 79 | 80 | context_dict = {'messages': messages, 'threadid': threadid, 'saved_codes_json': saved_codes_json} 81 | 82 | return render_to_response('cbd/messages.html', context_dict, context) 83 | 84 | @csrf_exempt 85 | @require_http_methods(["POST"]) 86 | def save_coding(request): 87 | user = request.user 88 | userid = user.id 89 | postid = request.POST['postid'] 90 | evidenceoption = request.POST['evidenceoption'] 91 | acronymcheckbox = request.POST['acronymcheckbox'] 92 | comment = request.POST['comment'] 93 | role = request.POST['role'] 94 | threadid = request.POST['threadid'] 95 | urbandictcheckbox = False 96 | if acronymcheckbox=="true": 97 | urbandictcheckbox = True 98 | codedMessage = SocialMediaCodedMessage(userid=userid, postid=postid, author_role=role, message_comment=comment, bullying_evidence_in_message=evidenceoption, message_contains_urban_dictionary_acronym=urbandictcheckbox, threadid=threadid) 99 | codedMessage.save() 100 | return HttpResponse("Saved") 101 | 102 | @login_required 103 | def dashboard(request): 104 | # Get data for dashboard widgets 105 | nosocialmediausers = ProcessedSocialMediaMessage.objects.values_list('username', flat=True).distinct().count() #SocialMediaUser.objects.count() 106 | nosocialmediamessages = ProcessedSocialMediaMessage.objects.count() #SocialMediaMessage.objects.count() 107 | 108 | nobullytraces = ProcessedSocialMediaMessage.objects.filter(has_bullying='Yes').count() #SocialMediaMessage.objects.filter(bullying_trace=True).count() 109 | 110 | missclassifiedcount = IncorrectClassification.objects.count() 111 | 112 | #grouped count of bullying roles 113 | ''' 114 | bullyrolecount = #SocialMediaMessage.objects.values('author_role').annotate(Count('author_role')) 115 | #print json.dumps(bullyrolecount, ensure_ascii=False) 116 | bullyrolecount_dict="[" 117 | for bullyrole in bullyrolecount: 118 | bullyroleobj_dict="{'label': '" + bullyrole["author_role"] + "', 'value': '" + str(bullyrole["author_role__count"]) + "'}," 119 | bullyrolecount_dict = bullyrolecount_dict + bullyroleobj_dict 120 | bullyrolecount_dict= bullyrolecount_dict + "]" 121 | ''' 122 | # dummy values are added as no labled data is available for training a model 123 | bullyrolecount_dict="[" 124 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Bystander', 'value': '1'}," 125 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Reinforcer', 'value': '1'}," 126 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Assistant', 'value': '1'}," 127 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Defender', 'value': '2'}," 128 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Bully', 'value': '12'}," 129 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Victim', 'value': '17'}," 130 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Reporter', 'value': '4'}," 131 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'Accuser', 'value': '2'}," 132 | bullyrolecount_dict = bullyrolecount_dict + "{'label': 'None', 'value': '100'}," 133 | bullyrolecount_dict= bullyrolecount_dict + "]" 134 | 135 | maxdate = ProcessedSocialMediaMessage.objects.all().aggregate(Max('date')) 136 | mindate = ProcessedSocialMediaMessage.objects.all().aggregate(Min('date')) 137 | 138 | qs = ProcessedSocialMediaMessage.objects.filter(has_bullying='Yes') 139 | 140 | qss = qsstats.QuerySetStats(qs, 'date') 141 | 142 | start, end = mindate['date__min'], maxdate['date__max'] 143 | sales_by_month_ts = qss.time_series(start, end, interval='months') 144 | MonthL = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'] 145 | months_dict="[" 146 | for t in sales_by_month_ts: 147 | monthobj_dict="{'month': '" + t[0].strftime("%Y-%m") + "', 'incidents': '" + str(t[1]) + "'}," 148 | months_dict = months_dict + monthobj_dict 149 | months_dict= months_dict + "]" 150 | # timeseries for last 7 days 151 | today = maxdate['date__max'] # datetime.date.today() 152 | seven_days_ago = today - datetime.timedelta(days=7) 153 | 154 | time_series = qss.time_series(seven_days_ago, today) 155 | DayL = ['Mon','Tues','Wed','Thurs','Fri','Sat','Sun'] 156 | weekts_dict="[" 157 | for t in time_series: 158 | dayobj_dict="{'y': '" + DayL[t[0].weekday()] + "', 'a': '" + str(t[1]) + "'}," 159 | weekts_dict = weekts_dict + dayobj_dict 160 | weekts_dict= weekts_dict + "]" 161 | 162 | #get most recent bullying incidents/traces 163 | recentincidents = ProcessedSocialMediaMessage.objects.filter(has_bullying='Yes').order_by('date')[:5] 164 | 165 | context = RequestContext(request) 166 | 167 | # load affective word counts 168 | mlcache = MLCache.objects.all()[:1] 169 | topic_model_json = '' 170 | topic_model_cyberbullying_json = '' 171 | affective_counts_json = '' 172 | affective_counts_cyberbullying_json = '' 173 | 174 | for x in mlcache: 175 | affective_counts_json = x.affective_counts_json 176 | affective_counts_cyberbullying_json = x.affective_counts_cyberbullying_json 177 | topic_model_json = x.topic_model_json 178 | topic_model_cyberbullying_json = x.topic_model_cyberbullying_json 179 | 180 | affective_dict = json.loads(affective_counts_json) 181 | 182 | affective_count_list = [] #must be in order 183 | affective_count_list.append(affective_dict['sadness']) 184 | affective_count_list.append(affective_dict['anticipation']) 185 | affective_count_list.append(affective_dict['disgust']) 186 | affective_count_list.append(affective_dict['positive']) 187 | affective_count_list.append(affective_dict['anger']) 188 | affective_count_list.append(affective_dict['joy']) 189 | affective_count_list.append(affective_dict['fear']) 190 | affective_count_list.append(affective_dict['trust']) 191 | affective_count_list.append(affective_dict['negative']) 192 | affective_count_list.append(affective_dict['surprise']) 193 | 194 | affective_count_list_str = ','.join(map(str, affective_count_list)) 195 | 196 | # Load and print up to 10 Topics 197 | tm_dict = json.loads(topic_model_json) 198 | count = 1 199 | tm_str = "
          " 200 | for tp in tm_dict: 201 | tm_str = tm_str + "
        • Topic %d
          " % (count) 202 | words_in_topic = [] 203 | for t in tp: 204 | words_in_topic.append(t[1]) 205 | wrds = ','.join(map(str, words_in_topic)) 206 | tm_str = tm_str + wrds + "
        • " 207 | count = count + 1 208 | if count==11: break 209 | tm_str = tm_str + "
        " 210 | 211 | affective_cyber_dict = json.loads(affective_counts_cyberbullying_json) 212 | 213 | affective_count_list = [] #must be in order 214 | affective_count_list.append(affective_cyber_dict['sadness']) 215 | affective_count_list.append(affective_cyber_dict['anticipation']) 216 | affective_count_list.append(affective_cyber_dict['disgust']) 217 | affective_count_list.append(affective_cyber_dict['positive']) 218 | affective_count_list.append(affective_cyber_dict['anger']) 219 | affective_count_list.append(affective_cyber_dict['joy']) 220 | affective_count_list.append(affective_cyber_dict['fear']) 221 | affective_count_list.append(affective_cyber_dict['trust']) 222 | affective_count_list.append(affective_cyber_dict['negative']) 223 | affective_count_list.append(affective_cyber_dict['surprise']) 224 | 225 | affective_cyber_count_list_str = ','.join(map(str, affective_count_list)) 226 | 227 | # Load and print up to 10 Topics 228 | tm_dict = json.loads(topic_model_cyberbullying_json) 229 | count = 1 230 | tm_cyber_str = "
          " 231 | for tp in tm_dict: 232 | tm_cyber_str = tm_cyber_str + "
        • Topic %d
          " % (count) 233 | words_in_topic = [] 234 | for t in tp: 235 | words_in_topic.append(t[1]) 236 | wrds = ','.join(map(str, words_in_topic)) 237 | tm_cyber_str = tm_cyber_str + wrds + "
        • " 238 | count = count + 1 239 | if count==11: break 240 | tm_cyber_str = tm_cyber_str + "
        " 241 | 242 | context_dict = {'tm_str': tm_str, 'tm_cyber_str':tm_cyber_str, 'affective_count_list_str': affective_count_list_str, 'affective_cyber_count_list_str': affective_cyber_count_list_str, 'nosocialmediausers': nosocialmediausers, 'nosocialmediamessages': nosocialmediamessages, 'nobullytraces': nobullytraces, 'missclassifiedcount': missclassifiedcount, 'rolejson': bullyrolecount_dict, 'recentincidents': recentincidents, 'weekts_dict': weekts_dict, 'months_dict': months_dict} 243 | 244 | return render_to_response('cbd/dashboard.html', context_dict, context) 245 | -------------------------------------------------------------------------------- /cbd_project/static/admin/js/inlines.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Django admin inlines 3 | * 4 | * Based on jQuery Formset 1.1 5 | * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) 6 | * @requires jQuery 1.2.6 or later 7 | * 8 | * Copyright (c) 2009, Stanislaus Madueke 9 | * All rights reserved. 10 | * 11 | * Spiced up with Code from Zain Memon's GSoC project 2009 12 | * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. 13 | * 14 | * Licensed under the New BSD License 15 | * See: http://www.opensource.org/licenses/bsd-license.php 16 | */ 17 | (function($) { 18 | $.fn.formset = function(opts) { 19 | var options = $.extend({}, $.fn.formset.defaults, opts); 20 | var $this = $(this); 21 | var $parent = $this.parent(); 22 | var updateElementIndex = function(el, prefix, ndx) { 23 | var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); 24 | var replacement = prefix + "-" + ndx; 25 | if ($(el).prop("for")) { 26 | $(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); 27 | } 28 | if (el.id) { 29 | el.id = el.id.replace(id_regex, replacement); 30 | } 31 | if (el.name) { 32 | el.name = el.name.replace(id_regex, replacement); 33 | } 34 | }; 35 | var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); 36 | var nextIndex = parseInt(totalForms.val(), 10); 37 | var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); 38 | // only show the add button if we are allowed to add more items, 39 | // note that max_num = None translates to a blank string. 40 | var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0; 41 | $this.each(function(i) { 42 | $(this).not("." + options.emptyCssClass).addClass(options.formCssClass); 43 | }); 44 | if ($this.length && showAddButton) { 45 | var addButton; 46 | if ($this.prop("tagName") == "TR") { 47 | // If forms are laid out as table rows, insert the 48 | // "add" button in a new table row: 49 | var numCols = this.eq(-1).children().length; 50 | $parent.append('' + options.addText + ""); 51 | addButton = $parent.find("tr:last a"); 52 | } else { 53 | // Otherwise, insert it immediately after the last form: 54 | $this.filter(":last").after('"); 55 | addButton = $this.filter(":last").next().find("a"); 56 | } 57 | addButton.click(function(e) { 58 | e.preventDefault(); 59 | var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS"); 60 | var template = $("#" + options.prefix + "-empty"); 61 | var row = template.clone(true); 62 | row.removeClass(options.emptyCssClass) 63 | .addClass(options.formCssClass) 64 | .attr("id", options.prefix + "-" + nextIndex); 65 | if (row.is("tr")) { 66 | // If the forms are laid out in table rows, insert 67 | // the remove button into the last table cell: 68 | row.children(":last").append('"); 69 | } else if (row.is("ul") || row.is("ol")) { 70 | // If they're laid out as an ordered/unordered list, 71 | // insert an
      • after the last list item: 72 | row.append('
      • ' + options.deleteText + "
      • "); 73 | } else { 74 | // Otherwise, just insert the remove button as the 75 | // last child element of the form's container: 76 | row.children(":first").append('' + options.deleteText + ""); 77 | } 78 | row.find("*").each(function() { 79 | updateElementIndex(this, options.prefix, totalForms.val()); 80 | }); 81 | // Insert the new form when it has been fully edited 82 | row.insertBefore($(template)); 83 | // Update number of total forms 84 | $(totalForms).val(parseInt(totalForms.val(), 10) + 1); 85 | nextIndex += 1; 86 | // Hide add button in case we've hit the max, except we want to add infinitely 87 | if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) { 88 | addButton.parent().hide(); 89 | } 90 | // The delete button of each row triggers a bunch of other things 91 | row.find("a." + options.deleteCssClass).click(function(e) { 92 | e.preventDefault(); 93 | // Remove the parent form containing this button: 94 | var row = $(this).parents("." + options.formCssClass); 95 | row.remove(); 96 | nextIndex -= 1; 97 | // If a post-delete callback was provided, call it with the deleted form: 98 | if (options.removed) { 99 | options.removed(row); 100 | } 101 | // Update the TOTAL_FORMS form count. 102 | var forms = $("." + options.formCssClass); 103 | $("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length); 104 | // Show add button again once we drop below max 105 | if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) { 106 | addButton.parent().show(); 107 | } 108 | // Also, update names and ids for all remaining form controls 109 | // so they remain in sequence: 110 | for (var i=0, formCount=forms.length; i