├── agora ├── __init__.py ├── templatetags │ ├── __init__.py │ └── cmarkdown.py ├── tests.py ├── static │ └── agora │ │ ├── img │ │ ├── stars.png │ │ ├── fullreps.png │ │ ├── physvote.png │ │ ├── emptystars.png │ │ ├── topictree.png │ │ ├── voteflow-icon3.ico │ │ ├── voteflow-logo3.jpg │ │ ├── voteflow-logo3.png │ │ ├── default_profile_pic.png │ │ └── ratings │ │ │ ├── ratings.css │ │ │ ├── 2.svg │ │ │ ├── 7.svg │ │ │ ├── 6.svg │ │ │ ├── 4.svg │ │ │ ├── 5.svg │ │ │ ├── 3.svg │ │ │ ├── 1.svg │ │ │ ├── orig-2.svg │ │ │ ├── orig-7.svg │ │ │ ├── orig-6.svg │ │ │ ├── orig-1.svg │ │ │ ├── orig-4.svg │ │ │ ├── orig-5.svg │ │ │ └── orig-3.svg │ │ ├── fontawesome │ │ └── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.svgz │ │ │ └── fontawesome-webfont.woff │ │ ├── js │ │ ├── voteflow.js │ │ ├── crsf.js │ │ ├── wweditor.js │ │ ├── inlinesvg.min.js │ │ ├── rangy-selectionsaverestore.js │ │ ├── dselect.js │ │ ├── to-markdown.js │ │ ├── sankey.js │ │ └── showdown.js │ │ ├── css │ │ └── hallo.css │ │ └── style.css ├── templates │ └── agora │ │ ├── inc_user_micro.html │ │ ├── grouppath │ │ ├── pathto_ul.html │ │ ├── fullpath_ul.html │ │ ├── pathto.html │ │ └── fullpath.html │ │ ├── topicpath │ │ ├── pathto_ul.html │ │ ├── fullpath_ul.html │ │ ├── pathto.html │ │ ├── autopath.html │ │ └── fullpath.html │ │ ├── inc_vote_mini.html │ │ ├── api_post_list.html │ │ ├── posts │ │ ├── filtering.html │ │ ├── autopath.html │ │ ├── inc_dselect.html │ │ ├── inc_filter.html │ │ └── scatterplus.html │ │ ├── api_tag_list_parents.html │ │ ├── api_user_list.html │ │ ├── api_post_list_recur.html │ │ ├── api_post_list_parents.html │ │ ├── inc_topic_mini_recur.html │ │ ├── inc_post_mini_recur.html │ │ ├── inc_post_mini_pparent.html │ │ ├── inc_vote_notification.html │ │ ├── api_user_rep_picker.html │ │ ├── groups │ │ ├── inc_micro.html │ │ ├── api_pending_members_list.html │ │ ├── pending_members_list.html │ │ ├── rules_list.html │ │ └── members_list.html │ │ ├── inc_stars.html │ │ ├── index.html │ │ ├── search.html │ │ ├── inc_topic_micro.html │ │ ├── newuser.html │ │ ├── inc_user_li.html │ │ ├── inc_group_mini.html │ │ ├── inc_user.html │ │ ├── all_groups.html │ │ ├── newtopic.html │ │ ├── inc_topic_mini.html │ │ ├── users.html │ │ ├── alltags.html │ │ ├── basic_form.html │ │ ├── new_rep_confirm.html │ │ ├── util │ │ ├── hallohead.html │ │ └── halloitem.html │ │ ├── ratings │ │ └── mixed7.html │ │ ├── advlogin.html │ │ ├── notifications.html │ │ ├── inc_post_mini.html │ │ ├── all_topics.html │ │ ├── fancy_group.html │ │ ├── base_template.html │ │ ├── login.html │ │ ├── topics.html │ │ ├── navbar.html │ │ ├── tags.html │ │ ├── group.html │ │ ├── user.html │ │ ├── root.html │ │ ├── new_rep.html │ │ ├── sunburst.html │ │ ├── forcearrows.html │ │ ├── fancy_post.html │ │ ├── sankey.html │ │ ├── inc_search.html │ │ └── inc_post_list.html ├── admin.py ├── pipeline.py ├── compare_user.py ├── forms.py └── urls.py ├── MeshDemoc ├── __init__.py ├── wsgi.py ├── urls.py └── settings.py ├── manage.py ├── localsettings.json.example ├── .gitignore └── README.md /agora/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MeshDemoc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /agora/static/agora/img/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/stars.png -------------------------------------------------------------------------------- /agora/static/agora/img/fullreps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/fullreps.png -------------------------------------------------------------------------------- /agora/static/agora/img/physvote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/physvote.png -------------------------------------------------------------------------------- /agora/static/agora/img/emptystars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/emptystars.png -------------------------------------------------------------------------------- /agora/static/agora/img/topictree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/topictree.png -------------------------------------------------------------------------------- /agora/static/agora/img/voteflow-icon3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/voteflow-icon3.ico -------------------------------------------------------------------------------- /agora/static/agora/img/voteflow-logo3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/voteflow-logo3.jpg -------------------------------------------------------------------------------- /agora/static/agora/img/voteflow-logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/voteflow-logo3.png -------------------------------------------------------------------------------- /agora/static/agora/img/default_profile_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/img/default_profile_pic.png -------------------------------------------------------------------------------- /agora/static/agora/fontawesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/fontawesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /agora/templates/agora/inc_user_micro.html: -------------------------------------------------------------------------------- 1 | {{ user.username }} 2 | -------------------------------------------------------------------------------- /agora/static/agora/fontawesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/fontawesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /agora/static/agora/fontawesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/fontawesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /agora/static/agora/fontawesome/fonts/fontawesome-webfont.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/fontawesome/fonts/fontawesome-webfont.svgz -------------------------------------------------------------------------------- /agora/static/agora/fontawesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chozabu/VoteFlow/HEAD/agora/static/agora/fontawesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /agora/templates/agora/grouppath/pathto_ul.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/templates/agora/grouppath/fullpath_ul.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/templates/agora/grouppath/pathto.html: -------------------------------------------------------------------------------- 1 | {% for p_group in group.path %} 2 |
  • 3 | {{ p_group.name }} 4 |
  • 5 | {% endfor %} -------------------------------------------------------------------------------- /agora/templates/agora/topicpath/pathto_ul.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/templates/agora/grouppath/fullpath.html: -------------------------------------------------------------------------------- 1 | {% for p_group in group.full_path %} 2 |
  • 3 | {{ p_group.name }} 4 |
  • 5 | {% endfor %} -------------------------------------------------------------------------------- /agora/templates/agora/topicpath/fullpath_ul.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/templates/agora/topicpath/pathto.html: -------------------------------------------------------------------------------- 1 | {% for p_topic in current_topic.path %} 2 |
  • 3 | {{ p_topic.name }} 4 |
  • 5 | {% endfor %} -------------------------------------------------------------------------------- /agora/templates/agora/topicpath/autopath.html: -------------------------------------------------------------------------------- 1 | {% if post %} 2 | {% include "agora/topicpath/fullpath.html" %} 3 | {% elif current_topic %} 4 | {% include "agora/topicpath/pathto.html" %} 5 | {% endif %} -------------------------------------------------------------------------------- /agora/templates/agora/topicpath/fullpath.html: -------------------------------------------------------------------------------- 1 | {% for p_topic in current_topic.full_path %} 2 |
  • 3 | {{ p_topic.name }} 4 |
  • 5 | {% endfor %} -------------------------------------------------------------------------------- /agora/templates/agora/inc_vote_mini.html: -------------------------------------------------------------------------------- 1 |
  • {{ v.value }} @ 2 | {{ v.parent.name }} 3 | in 4 | {{ v.parent.topic.name }} 5 |
  • -------------------------------------------------------------------------------- /agora/templatetags/cmarkdown.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from markdown import markdown 3 | 4 | register = template.Library() 5 | 6 | @register.filter(name='markdown', is_safe=True) 7 | def markdown_processor(text): 8 | return markdown(text) 9 | -------------------------------------------------------------------------------- /agora/templates/agora/api_post_list.html: -------------------------------------------------------------------------------- 1 | 6 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 7 | -------------------------------------------------------------------------------- /agora/templates/agora/posts/filtering.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ group.name }} 5 | {% endblock %} 6 | {% load cmarkdown %} 7 | 8 | {% block body_block %} 9 | {% include 'agora/posts/inc_filter.html' %} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /agora/templates/agora/api_tag_list_parents.html: -------------------------------------------------------------------------------- 1 | 6 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 7 | -------------------------------------------------------------------------------- /agora/templates/agora/api_user_list.html: -------------------------------------------------------------------------------- 1 | 6 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 7 | -------------------------------------------------------------------------------- /agora/templates/agora/api_post_list_recur.html: -------------------------------------------------------------------------------- 1 | 6 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 7 | -------------------------------------------------------------------------------- /agora/templates/agora/api_post_list_parents.html: -------------------------------------------------------------------------------- 1 | 6 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 7 | -------------------------------------------------------------------------------- /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", "MeshDemoc.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_topic_mini_recur.html: -------------------------------------------------------------------------------- 1 | {% include "agora/inc_topic_mini.html" %} 2 | 7 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_post_mini_recur.html: -------------------------------------------------------------------------------- 1 | 2 | {% include "agora/inc_post_mini.html" %} 3 | 8 | -------------------------------------------------------------------------------- /localsettings.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "MEDIA_ROOT":"/MeshDemoc/public/media/", 3 | "MEDIA_URL":"/media/", 4 | "secret_key":"adjangosecretkeyadjangosecretkeyadjangosecretkeya", 5 | "SOCIAL_AUTH_FACEBOOK_KEY":"fbk", 6 | "SOCIAL_AUTH_FACEBOOK_SECRET":"fbs", 7 | "SOCIAL_AUTH_GOOGLE_OAUTH2_KEY":"gk", 8 | "SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET":"gs" 9 | } -------------------------------------------------------------------------------- /agora/templates/agora/inc_post_mini_pparent.html: -------------------------------------------------------------------------------- 1 | 2 | {% if post.parent %} 3 | {% include "agora/inc_post_mini.html" with post=post.parent %} 4 | {% else %} 5 | {% include "agora/inc_topic_mini.html" with topic=post.topic %} 6 | {% endif %} 7 | 10 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_vote_notification.html: -------------------------------------------------------------------------------- 1 |
  • 2 | {% include 'agora/inc_user_micro.html' with user=v.author %}
    3 | {{ v.value }} @ 4 | {{ v.parent.name }} 5 | in 6 | {{ v.parent.topic.name }} 7 |
    8 |
  • -------------------------------------------------------------------------------- /agora/templates/agora/api_user_rep_picker.html: -------------------------------------------------------------------------------- 1 | 8 | items: {{ start_at }} ~ {{ got_num }} of {{ total_num }} 9 | -------------------------------------------------------------------------------- /agora/templates/agora/groups/inc_micro.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | {{ group.name }} 5 | 6 |
    7 |
    8 | [{{ group.memberships.all|length }}, {{ group.group_set.all|length }}, {{ group.post_set.all|length }}] 9 |
    10 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_stars.html: -------------------------------------------------------------------------------- 1 | 2 | {% load staticfiles %} 3 |
    4 |
    5 | 6 |
    7 |
    8 | 9 |
    10 |
    -------------------------------------------------------------------------------- /agora/templates/agora/index.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Agora 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 |
    8 |
    9 |

    Posts

    10 |
    11 |
    12 | {% include 'agora/inc_post_list.html' with divid='mainpostlist' postfilter='{"parent":null }' showpath=1 %} 13 | 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /agora/templates/agora/search.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | Search 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | 10 |

    Search

    11 | 15 |

    Results

    16 | {% include 'agora/inc_search.html' with table="Post" %} 17 | 18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_topic_micro.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | {{ topic.name }} 5 | 6 |
    7 |
    8 | [{{ topic.subscription_set.all|length }}, {{ topic.topic_set.all|length }}, {{ topic.post_set.all|length }}] 9 | 10 |
    -------------------------------------------------------------------------------- /agora/templates/agora/posts/autopath.html: -------------------------------------------------------------------------------- 1 | {% if post.topic %} 2 | {% include "agora/topicpath/fullpath_ul.html" with current_topic=post.topic %} 3 | {% elif post.group %} 4 | {% include "agora/grouppath/fullpath_ul.html" with group=post.group %} 5 | {% endif %} 6 | 13 | -------------------------------------------------------------------------------- /agora/templates/agora/groups/api_pending_members_list.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /MeshDemoc/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for MeshDemoc 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", "MeshDemoc.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/ratings.css: -------------------------------------------------------------------------------- 1 | 2 | #svgr1 * { 3 | 4 | stroke: red !important; 5 | } 6 | #svgr2 * { 7 | 8 | stroke: #DC154C !important; 9 | } 10 | #svgr3 * { 11 | 12 | stroke: #B81ACC !important; 13 | } 14 | #svgr4 * { 15 | 16 | stroke: #1319E0 !important; 17 | } 18 | #svgr5 * { 19 | 20 | stroke: #328FC5 !important; 21 | } 22 | #svgr6 * { 23 | 24 | stroke: green !important; 25 | } 26 | #svgr7 * { 27 | 28 | stroke: #00D600 !important; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /agora/templates/agora/newuser.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Create User 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 | {% if form.errors %} 8 |

    Oops, invalid username or password

    9 | {% endif %} 10 |
    11 | {% csrf_token %} 12 | {{ form.as_p }} 13 | 14 |
    15 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/inc_user_li.html: -------------------------------------------------------------------------------- 1 | {% if user.is_authenticated %} 2 |
  • {{ user.username }}
  • 3 |
  • Logout
  • 4 | {% else %} 5 |
  • Sign Up
  • 6 |
  • Login
  • 7 | {% endif %} 8 | -------------------------------------------------------------------------------- /agora/templates/agora/groups/pending_members_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ group.name }} Members 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | 10 | {% include "agora/grouppath/pathto_ul.html" %} 11 |

    12 | 13 | {{ group.name }} 14 | Pending Members

    15 | {% include 'agora/groups/api_pending_members_list.html' with User=group.pending_members %} 16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_group_mini.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | {{ group.name }} 4 | 5 |
    6 |
    author: 7 | {{ group.author.username }} @ {{ group.created_at }} 8 |
    type: {{ group.subtype }} 9 |
    Members: {{ group.memberships.all|length }} 10 |
    sub-groups: {{ group.group_set.all|length }} Posts {{ group.post_set.all|length }} 11 | -------------------------------------------------------------------------------- /agora/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import UserRepCache, UserExtra, DGroup, Notification, Topic, Post, Tag, Representation, PostVote, TagVote, Subscription 5 | 6 | 7 | admin.site.register(Topic) 8 | admin.site.register(Post) 9 | admin.site.register(Tag) 10 | admin.site.register(Representation) 11 | admin.site.register(PostVote) 12 | admin.site.register(TagVote) 13 | admin.site.register(Subscription) 14 | admin.site.register(Notification) 15 | admin.site.register(UserExtra) 16 | admin.site.register(DGroup) 17 | admin.site.register(UserRepCache) 18 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_user.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /agora/templates/agora/all_groups.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | Groups 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 |

    Groups

    10 | {% if group_list %} 11 | 18 | {% else %} 19 |

    No groups found...

    20 | {% endif %} 21 | 22 | New Group 23 | 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /agora/templates/agora/newtopic.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Create Topic 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 | {% include "agora/topicpath/fullpath_ul.html" %} 8 | {% if form.errors %} 9 |

    FORM ERROR!!

    10 | {% endif %} 11 |
    12 | {% csrf_token %} 13 | 16 | {{ form.as_p }} 17 | 18 |
    19 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/inc_topic_mini.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 | {{ topic.name }} 4 | 5 | {{ topic.subscription_set.all|length }} 6 |
    7 |
    author: 8 | {{ topic.author.username }} @ {{ topic.created_at }} 9 |
    sub-topics: {{ topic.topic_set.all|length }} Posts {{ topic.post_set.all|length }} 10 | -------------------------------------------------------------------------------- /agora/templates/agora/users.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | All Users 5 | {% endblock %} 6 | 7 | {% block head_block %} 8 | 9 | {% endblock %} 10 | 11 | 12 | {% block body_block %} 13 | {{ selected_user }} 14 |

    All Users

    15 | 16 | 24 | 25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /agora/templates/agora/alltags.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% load cmarkdown %} 3 | {% block title %} 4 | {% if current_topic %} 5 | {{ current_topic.name }} : {{ post.name }} : {{ tag.name }} 6 | {% else %} 7 | Post 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block head_block %} 12 | 13 | {% endblock %} 14 | 15 | 16 | {% block body_block %} 17 |

    18 | Tagged: {{ tag_word }} 19 |

    20 | 25 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /agora/pipeline.py: -------------------------------------------------------------------------------- 1 | from models import UserExtra 2 | from django.core.files.base import File 3 | import urllib2 as urllib 4 | from io import BytesIO 5 | 6 | def save_profile_picture(backend, user, response, details, 7 | is_new=False,*args,**kwargs): 8 | 9 | if backend.__class__.__name__ == 'FacebookOAuth2': 10 | up = UserExtra.objects.get_or_create(user=user) #RETURNS TUPLE (instance, created(boolean)) 11 | if not up[0].photo: 12 | url = 'http://graph.facebook.com/{0}/picture'.format(response['id']) 13 | print url 14 | response = urllib.urlopen(url) 15 | io = BytesIO(response.read()) 16 | up[0].photo.save('profile_pic_{}.jpg'.format(user.pk), File(io)) 17 | up[0].save() 18 | -------------------------------------------------------------------------------- /agora/templates/agora/basic_form.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | {{ title }} 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 | {% if form.errors %} 8 | {% for field in form %} 9 | {% for error in field.errors %} 10 |
    11 | {{ error|escape }} 12 |
    13 | {% endfor %} 14 | {% endfor %} 15 | {% for error in form.non_field_errors %} 16 |
    17 | {{ error|escape }} 18 |
    19 | {% endfor %} 20 | {% endif %} 21 |
    22 | {% csrf_token %} 23 | {{ form.as_p }} 24 | 25 |
    26 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /agora/static/agora/js/voteflow.js: -------------------------------------------------------------------------------- 1 | 2 | function castvote(item){ 3 | console.log("---castvote----"); 4 | console.log(item); 5 | console.log($(this)); 6 | var votelink = $(item)[0] 7 | var voteint = parseInt(votelink.getAttribute("vval")); 8 | var perc = (voteint)/6.0*100.0; 9 | console.log(perc); 10 | 11 | var pid = parseInt(item.parentNode.getAttribute("postid")); 12 | console.log(pid); 13 | 14 | $.post( "/agora/posts/"+pid+"/quickvote/", { 15 | "voteslider":perc 16 | }, function( data ) { 17 | location.reload(); 18 | }); 19 | } 20 | 21 | 22 | 23 | function link_as_post_reload(event){ 24 | $.post( $(this)[0].getAttribute("plink"), { 25 | }, function( data ) { 26 | location.reload(); 27 | }); 28 | } 29 | 30 | jQuery(document).ready(function () { 31 | $('.link_as_post_reload').click(link_as_post_reload); 32 | }); -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /agora/templates/agora/new_rep_confirm.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Pick {{ rep.username }} as Representative for {{ current_topic }} 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 | {% include "agora/topicpath/fullpath_ul.html" %} 8 |

    Confirm Representative

    9 |

    Are you sure you want {{ rep.username }} to represent you for {{ current_topic }}

    10 | {% include "agora/inc_user_micro.html" with user=rep %} {% include "agora/inc_topic_micro.html" with topic=current_topic %} 11 | 12 |
    13 | {% csrf_token %} 14 | 15 | 16 | 17 |
    18 | 19 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /agora/templates/agora/util/hallohead.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /agora/templates/agora/ratings/mixed7.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 |
    3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python template 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | # Created by .ignore support plugin (hsz.mobi) 62 | -------------------------------------------------------------------------------- /agora/compare_user.py: -------------------------------------------------------------------------------- 1 | __author__ = 'chozabu' 2 | 3 | from models import PostVote, User 4 | 5 | def compare_all_users(): 6 | users = User.objects.all() 7 | usercount = users.count() 8 | print usercount 9 | for ui in range(usercount-1): 10 | u=users[ui] 11 | for ui2 in range(ui+1, usercount): 12 | u2 = users[ui2] 13 | usrcmp = compareusers(u,u2) 14 | if usrcmp: 15 | print u, u2, compareusers(u,u2) 16 | 17 | def compareusers(a,b, topic=None): 18 | #get all votes by a on an item b also voted on 19 | va = PostVote.objects.filter(author=a, parent__postvote__author=b).order_by('parent') 20 | #and the reverse 21 | vb = PostVote.objects.filter(author=b, parent__postvote__author=a).order_by('parent') 22 | count = va.count() 23 | if count == 0: return None 24 | tdiff = 0 25 | #get cumlitiave difference between votes 26 | for x in range(count): 27 | ia = va[x] 28 | ib = vb[x] 29 | diff = abs(ia.value-ib.value) 30 | tdiff+=diff 31 | #convert to percent 32 | rdiff=100-(tdiff/count*50.) 33 | return rdiff,tdiff,count 34 | #UserCompare(a,b,rdiff,tdiff,count) 35 | -------------------------------------------------------------------------------- /agora/templates/agora/advlogin.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | {{ title }} 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 |
    8 |

    Third-party authentication demo

    9 | 10 |

    11 |

    35 |

    36 |
    37 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/js/crsf.js: -------------------------------------------------------------------------------- 1 | // using jQuery 2 | function getCookie(name) { 3 | var cookieValue = null; 4 | if (document.cookie && document.cookie != '') { 5 | var cookies = document.cookie.split(';'); 6 | for (var i = 0; i < cookies.length; i++) { 7 | var cookie = jQuery.trim(cookies[i]); 8 | // Does this cookie string begin with the name we want? 9 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 10 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 11 | break; 12 | } 13 | } 14 | } 15 | return cookieValue; 16 | } 17 | var csrftoken = getCookie('csrftoken'); 18 | 19 | function csrfSafeMethod(method) { 20 | // these HTTP methods do not require CSRF protection 21 | return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 22 | } 23 | $.ajaxSetup({ 24 | beforeSend: function(xhr, settings) { 25 | if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 26 | xhr.setRequestHeader("X-CSRFToken", csrftoken); 27 | } 28 | } 29 | }); 30 | 31 | -------------------------------------------------------------------------------- /agora/templates/agora/notifications.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Agora 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 |
    8 | Mark all as Read
    9 | {% for n in notifications %} 10 |
    11 | 12 | {{ n.name }} 13 | {% if n.content_type.name == "post" %} 14 | {% include "agora/posts/autopath.html" with post=n.content_object %} 15 | {% if n.content_object.parent %} 16 |
  • {% include "agora/inc_post_mini.html" with post=n.content_object.parent %}
  • 17 | {% endif %} 18 |
  • {% include "agora/inc_post_mini.html" with post=n.content_object %}
  • 19 | {% endif %} 20 | {% if n.content_type.name == "post vote" %} 21 | {% include "agora/posts/autopath.html" with post=n.content_object.parent %} 22 | {% include "agora/inc_vote_notification.html" with v=n.content_object %} 23 | {% endif %} 24 |
    25 | {% endfor %} 26 |
    27 | {% endblock %} 28 | -------------------------------------------------------------------------------- /MeshDemoc/urls.py: -------------------------------------------------------------------------------- 1 | """MeshDemoc URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.conf.urls import include, url 17 | from django.contrib import admin 18 | from agora import views as agora_views 19 | 20 | from django.conf import settings 21 | from django.conf.urls.static import static 22 | 23 | urlpatterns = [ 24 | url(r'^agora/', include('agora.urls', namespace="agora")), 25 | url(r'^$', agora_views.root, name='index'), 26 | url(r'^admin/', include(admin.site.urls)), 27 | url('', include('social.apps.django_app.urls', namespace='social')), 28 | url('', include('django.contrib.auth.urls', namespace='auth')), 29 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 30 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_post_mini.html: -------------------------------------------------------------------------------- 1 | {% load cmarkdown %} 2 | {% if showpath %} 3 | 4 | {% include "agora/posts/autopath.html" %} 5 |

    6 | {% endif %} 7 | {% if post.name %} 8 | 9 | {{ post.name }} 10 | 11 |
    12 | {% endif %} 13 |
    14 | 15 | {% include "agora/inc_user_micro.html" with user=post.author %} 16 | @ {{ post.created_at }}, with: 17 | 18 | {{ post.post_set.all|length }} comments 19 | 20 |
    21 |
    22 | {{ post.safetext|markdown }} 23 |
    24 | 28 | 29 | Vote 30 | 31 |
    32 | 33 | Full average: {{ post.liquid_value_percent|floatformat }}%
    34 | full sum: {{ post.liquid_sum|floatformat }}
    35 | full vote count: {{ post.liquid_vote_count }}
    36 |
    37 | 38 |
    39 | 40 |
    41 | 42 | -------------------------------------------------------------------------------- /agora/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | from .models import Topic, Post, Tag, Representation, PostVote, TagVote 4 | from django.contrib.auth.models import User 5 | 6 | class TopicForm(forms.Form): 7 | topic_parent_id = forms.ModelChoiceField(label='Parent Topic', queryset = Topic.objects.all(),required=False) 8 | topic_name = forms.CharField(label='Topic Name', max_length=100) 9 | 10 | 11 | class PostForm(forms.Form): 12 | topic_id = forms.ModelChoiceField(label='Parent Topic', queryset = Topic.objects.all()) 13 | post_parent_id = forms.ModelChoiceField(label='Parent Post', queryset = Post.objects.all(),required=False) 14 | post_name = forms.CharField(label='Message', max_length=100) 15 | 16 | class PostVoteForm(forms.Form): 17 | post_id = forms.ModelChoiceField(label='Parent',queryset = Post.objects.all()) 18 | value = forms.FloatField(label='Vote (between -1 and 1, eg: .5)', max_value=1, min_value=-1) 19 | 20 | class TagForm(forms.Form): 21 | post_parent_id = forms.ModelChoiceField(label='Parent Post', queryset = Post.objects.all(),required=False) 22 | tag_name = forms.CharField(label='Tag', max_length=100) 23 | 24 | class TagVoteForm(forms.Form): 25 | tag_id = forms.ModelChoiceField(label='Tag',queryset = Tag.objects.all()) 26 | value = forms.FloatField(label='Vote (between 0 and 1, eg: .5)', max_value=1, min_value=0) 27 | 28 | class RepForm(forms.Form): 29 | topic_id = forms.ModelChoiceField(label='Topic', queryset = Topic.objects.all()) 30 | representative_id = forms.ModelChoiceField(label='Representitive', queryset = User.objects.all()) 31 | 32 | 33 | -------------------------------------------------------------------------------- /agora/templates/agora/all_topics.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | Topics 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | 10 |

    Topics

    11 | 12 |

    Representation Map
    13 | Show Sunburst Map

    14 |

    15 | {% if recur %} 16 | Hide sub-topics 17 | {% else %} 18 | Show Full Tree 19 | {% endif %} 20 |

    21 | 22 |

    sort method: {{ sort_method }} ( 23 | created_at 24 | subscription_set 25 | post_set 26 | )

    27 | 28 | {% if topic_list %} 29 | 40 | {% else %} 41 |

    No sub-topics found...

    42 | {% endif %} 43 | 44 | 45 | 47 | 48 | 49 | 50 | {% endblock %} 51 | -------------------------------------------------------------------------------- /agora/templates/agora/groups/rules_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ group.name }} Members 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | 10 | {% include "agora/grouppath/pathto_ul.html" %} 11 |

    12 | 13 | {{ group.name }} 14 | Rules

    15 | 16 |

    In Voteflow groups have "rules" or "permissions" that say who may create/delete posts, topics, 17 | or perform other actions inside that group
    18 | Each member of a group also has a "level" for their group. 19 |

    20 |

    21 | Your level must be at least as high as the rule to perform an action.
    22 | In this group, your level must be at least equal to "edit_rules" to make any changes on this page. 23 |

    24 | 25 | {% for rule in group.permission_reqs.all %} 26 | {{ rule.name }} requires level {{ rule.level }}
    27 | {% endfor %} 28 |
    {% csrf_token %} 29 | 38 | requires level: 39 | 40 | 41 |
    42 | 43 | 44 | {% endblock %} 45 | -------------------------------------------------------------------------------- /agora/templates/agora/fancy_group.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | New Group 4 | {% endblock %} 5 | 6 | {% block head_block %} 7 | {% load staticfiles %} 8 | 9 | {% include 'agora/util/hallohead.html' %} 10 | 11 | {% endblock %} 12 | 13 | {% block body_block %} 14 |

    New Group

    15 | {% if group %} 16 | In Group: 17 | {% include "agora/inc_group_mini.html" %} 18 | {% endif %} 19 |
    20 | {% csrf_token %} 21 | 22 |

    Group Name:

    23 |
    24 |
    25 |

    Group Type:

    26 |
    27 | 28 |
    29 | 32 |
    33 | 34 |
    35 |
    36 | {% include "agora/util/halloitem.html" with itemid=group rname="body_text" initial_text="Type Group Info Here." %} 37 | 38 |
    39 |
    40 | 41 |
    42 | 43 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/js/wweditor.js: -------------------------------------------------------------------------------- 1 | var hallosettings = { 2 | plugins: { 3 | 'halloformat': {}, 4 | 'halloheadings': {}, 5 | 'hallolists': {}, 6 | //'halloblacklist': {"tags":["div"]}, 7 | 'hallo-image-insert-edit': {}, 8 | 'hallolink': {}, 9 | 'halloreundo': {}, 10 | 'hallocleanhtml': { 11 | format: false, 12 | allowedTags: [ 13 | 'p', 14 | 'em', 15 | 'strong', 16 | 'br', 17 | 'h1', 18 | 'h2', 19 | 'h3', 20 | 'h4', 21 | 'ol', 22 | 'ul', 23 | 'li', 24 | 'img', 25 | 'a'], 26 | allowedAttributes: ['style'] 27 | } 28 | }, 29 | toolbar: 'halloToolbarFixed' 30 | } 31 | 32 | var markdownize = function (content) { 33 | var html = content.split("\n").map($.trim).filter(function (line) { 34 | return line != ""; 35 | }).join("\n"); 36 | //next line for chrome... 37 | html = html.replace(/\/g, "
    ").replace(/\<\/div\>/g, ""); 38 | return toMarkdown(html); 39 | /*md= toMarkdown(html); 40 | md = md.replace(/\<\;/g, "<"); 41 | md = md.replace(/\>\;/g, ">"); 42 | md = md.replace(/\ \;/g, "\ \ \n"); 43 | md = md.replace(/\n/g, "\ \ \n"); 44 | return md;*/ 45 | }; 46 | 47 | 48 | 49 | var converter = new Showdown.converter(); 50 | var htmlize = function (content) { 51 | return converter.makeHtml(content); 52 | }; -------------------------------------------------------------------------------- /agora/templates/agora/base_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% load staticfiles %} 5 | 6 | VoteFlow: {% block title %}Agora{% endblock %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% block head_block %}{% endblock %} 17 | 18 | 19 | 20 | 21 | {% include "agora/navbar.html" %} 22 | 23 |
    24 | {% block body_block %}{% endblock %} 25 |
    26 | 27 |
    28 | 29 |
    30 | 42 |
    43 | 44 | -------------------------------------------------------------------------------- /agora/templates/agora/util/halloitem.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    4 | {{ initial_text }} 5 |

    6 |
    7 |
    8 | 12 |
    13 | Source:
    14 | 16 |
    17 | 18 | -------------------------------------------------------------------------------- /agora/templates/agora/posts/inc_dselect.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 16 | 17 | 18 | 19 | 27 | 28 | 29 | 37 | 38 | 39 |
    40 |
    41 | 43 |
    44 | 45 | {% load staticfiles %} 46 | 47 | 52 |
    53 | -------------------------------------------------------------------------------- /agora/templates/agora/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | {{ title }} 4 | {% endblock %} 5 | 6 | {% block head_block %} 7 | {% load staticfiles %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block body_block %} 14 | {% if user and not user.is_anonymous %} 15 | 26 | {{ friends }} 27 | {% else %} 28 |
    29 | 39 |
    40 | {% if form.errors %} 41 |

    Oops, invalid username or password

    42 | {% endif %} 43 |
    44 | {% csrf_token %} 45 | {{ form.as_p }} 46 | 47 | 48 |
    49 |
    50 |
    51 | {% endif %} 52 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/topics.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ current_topic.name }} 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | {% include "agora/topicpath/pathto_ul.html" %} 10 | 11 |

    {{ current_topic.name }}

    12 | 13 | 14 | 15 | {% if user.is_authenticated %} 16 | {% if sub %} 17 |

    Subscribed! (unsub)

    18 | {% else %} 19 |

    20 | {% endif %} 21 | 22 | {% if rep %} 23 | Representitive: {{ rep.rep }} 24 |
    25 | 26 | 27 | 28 | {% else %} 29 | 30 | 31 | 32 | {% endif %} 33 | {% endif %} 34 |

    Sub Topics

    35 | 36 | {% if topic_list %} 37 |
    38 | {% for topic in topic_list %} 39 | {% include "agora/inc_topic_micro.html" with topic=topic %} 40 | {% endfor %} 41 |
    .
    42 | {% else %} 43 |

    No sub-topics found...

    44 | {% endif %} 45 | 46 | 47 | 49 | 50 | 51 |
    52 |

    Posts

    53 | {% if current_topic %} 54 | 55 | 57 | 58 | {% endif %} 59 |
    60 | 61 | {% include 'agora/inc_post_list.html' with divid='mainpostlist' %} 62 | 63 | {% endblock %} 64 | -------------------------------------------------------------------------------- /agora/static/agora/js/inlinesvg.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * InlineSVG 3 | * 4 | * This is a jQuery plugin that takes an image selector as an argument having a 5 | * SVG as source. Then it inlines the SVG so that the SVG stroke and path can 6 | * be manipulated using plain CSS. 7 | * 8 | * @license MIT 9 | * @version 2.0.0 10 | * @see {@link https://github.com/createlogic/InlineSVG|GitHub} 11 | * 12 | * The MIT License (MIT) 13 | * 14 | * Copyright (c) 2010-2015 Bilal Niaz Awan 15 | * 16 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 17 | * this software and associated documentation files (the "Software"), to deal in 18 | * the Software without restriction, including without limitation the rights to 19 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 20 | * the Software, and to permit persons to whom the Software is furnished to do so, 21 | * subject to the following conditions: 22 | * 23 | * The above copyright notice and this permission notice shall be included in all 24 | * copies or substantial portions of the Software. 25 | * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 28 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 29 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 30 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | */ 33 | !function(e){"use strict";e.fn.inlineSVG=function(t){t=e.extend({eachAfter:null,allAfter:null,beforeReplace:null,replacedClass:"replaced-svg",keepSize:!0,keepStyle:!0},t||{});var l=this,a=0;return l.each(function(){var r=e(this),n=r.attr("id"),c=r.attr("class"),i=r.attr("src");e.get(i,function(i){function s(n){n="boolean"===e.type(n)?n:!0,n?(r.replaceWith(f),t.eachAfter&&t.eachAfter.call(f.get(0))):f.remove(),++a===l.length&&t.allAfter&&t.allAfter.call(null)}var f=e(i).find("svg"),h=[];if(n&&f.attr("id",n),c&&h.push(c),t.replacedClass&&h.push(t.replacedClass),f.attr("class",h.join(" ")),f.removeAttr("xmlns:a"),t.keepSize){var p=r.attr("width"),u=r.attr("height");p&&f.attr("width",p),u&&f.attr("height",u)}if(t.keepStyle){var o=r.attr("style");o&&f.attr("style",o)}t.beforeReplace?t.beforeReplace.call(null,r,f,s):s()},"xml")})}}(jQuery); -------------------------------------------------------------------------------- /agora/static/agora/css/hallo.css: -------------------------------------------------------------------------------- 1 | div.hallotoolbar { 2 | border: 1px solid #babdb6; 3 | padding: 2px; 4 | background-color: #eeeeec; 5 | border-radius: 6px; 6 | font-size: 12pt; 7 | line-height: 1.1em; 8 | z-index: 500; 9 | } 10 | 11 | div.halloEditIndicator { 12 | background-color: #000000; 13 | color: #ffffff; 14 | padding: 4px; 15 | border-radius: 4px; 16 | } 17 | 18 | /* Drag n Drop */ 19 | [contenteditable] .tmp { 20 | opacity: 0.3 21 | } 22 | 23 | [contenteditable] .tmpLine{ 24 | background-color: #ffffff; 25 | width: 98%; 26 | height: 2px; 27 | margin: 0 auto 10px auto; 28 | border-top: 2px solid #1cb8d6; 29 | border-bottom: 2px solid #1cb8d6; 30 | opacity: 1; 31 | padding: 1px; 32 | } 33 | 34 | .dropdown-menu { 35 | width: "200px"; 36 | background-color: #eeeeec; 37 | } 38 | 39 | .dropdown-target .selected { 40 | background-color: #729fcf; 41 | } 42 | 43 | button.blockselector, button.blockselector:focus{ 44 | display:block; 45 | width: 100%; 46 | margin:0px; 47 | padding: 0px; 48 | background: transparent; 49 | border: none; 50 | -moz-appearance: none; 51 | -webkit-appearance: none; 52 | outline: none; 53 | } 54 | 55 | .bigOverlay, .smallOverlay { 56 | display: none; 57 | position: absolute; 58 | top: 0; 59 | left: 0; 60 | background-color: rgba(28, 184, 214, 0.4); 61 | } 62 | 63 | .bigOverlayRight{ 64 | display : block; 65 | border-right : 3px dashed rgb(28, 184, 214); 66 | border-left : none; 67 | } 68 | 69 | .bigOverlayLeft{ 70 | display : block; 71 | border-left : 3px dashed rgb(28, 184, 214); 72 | border-right : none; 73 | } 74 | 75 | .smallOverlayLeft{ 76 | border-right : 3px dashed rgb(28, 184, 214); 77 | } 78 | 79 | .smallOverlayRight{ 80 | border-left : 3px dashed rgb(28, 184, 214); 81 | } 82 | 83 | .ui-draggable{ 84 | cursor: move; 85 | } 86 | 87 | .ui-draggable-dragging{ 88 | border: 3px solid white; 89 | } 90 | 91 | [contenteditable] img.ui-state-disabled { 92 | opacity: 1; 93 | } 94 | 95 | .customHelper{ 96 | background-size: cover; 97 | width: 100px; 98 | height: 100px; 99 | z-index: 1050; 100 | } 101 | 102 | .trashcan{ 103 | width: 50px; 104 | height: 50px; 105 | position: relative; 106 | top: 25px; 107 | left: 25px; 108 | background: rgba(0,0,0,0.8) url('images/trash.png') no-repeat 12px 12px; 109 | border-radius: 10px; 110 | cursor: none; 111 | } 112 | -------------------------------------------------------------------------------- /agora/templates/agora/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 66 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 66 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /agora/templates/agora/tags.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% load cmarkdown %} 3 | {% block title %} 4 | {% if current_topic %} 5 | {{ current_topic.name }} : {{ post.name }} : {{ tag.name }} 6 | {% else %} 7 | Post 8 | {% endif %} 9 | {% endblock %} 10 | 11 | {% block head_block %} 12 | 13 | {% endblock %} 14 | 15 | 16 | {% block body_block %} 17 | {% include "agora/topicpath/fullpath_ul.html" %} 18 | 25 | 26 |

    27 | {{ tag.name }} 28 | 32 |

    33 |

    by {{ tag.author.username }} @ {{ tag.created_at }}

    34 | 35 | 36 | 42 |
    43 | Full average: {{ tag.liquid_value_percent|floatformat }}%
    44 | full sum: {{ tag.liquid_sum|floatformat }}
    45 | full vote count: {{ tag.liquid_vote_count }}
    46 | 49 |
    50 | direct 51 | average: {{ tag.direct_value_percent }}% {% include "agora/inc_stars.html" with percent=tag.direct_value_percent %} 52 |
    53 | direct sum: {{ tag.direct_sum }}
    54 | direct vote count: {{ tag.tagvote_set.all|length }}
    55 | your vote: {{ user_vote.value }}
    56 |
    57 |
    58 |
    59 | 60 |
    61 | {% csrf_token %} 62 | 64 | 65 | 66 |
    67 |
    68 | {% endblock %} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Voteflow 2 | ============================== 3 | 4 | VoteFlow is a website/app built on django to try out a LiquidDemocracy-like system. 5 | Currently in early stages - expect some uglyness and broken bits. 6 | 7 | Previously known as "MeshDemocracy: Agora" 8 | 9 | Live Demo: [Click here - very pre-alpha!](http://voteflow.net/) 10 | 11 | ###Topic Tree 12 | The topic tree is a central component - anyone can create a topic as a subtopic of any other topic - or top-level 13 | 14 | ###Posting 15 | Posting lets people place messages directly inside topics, or as a reply to an existing message 16 | 17 | ###Representation 18 | A user may pick a representitive for a topic - this also applies to sub-topics, and can chain. 19 | So, Theo is representing 100 people in Science. 20 | Theo and 9 other people also representing 100 people in science make Albert their representitive for Science->Physics. 21 | Albert is now representing 1000 people in physics. 22 | 23 | ###Voting 24 | Any user may vote on any Posting/Message. 25 | 26 | ##Todo 27 | - ~~Correct Liquid Counting~~ 28 | - ~~Use Agora as DevMap/Todo list for its-self~~ 29 | - Sorting, by user selectable methods ~~partial~~ 30 | - ~~Full Tree View - for topics and posts~~ 31 | - images 32 | - user profile page ~~partial~~ 33 | - ~~representation graph~~ - show representation for a topic 34 | - ~~vote graph - should representation for a vote~~ 35 | - groups/circles 36 | - AJAX/Dynamic Updates ~~partial~~ 37 | - Template Styling/CSS ~~partial~~ 38 | - search/filter 39 | - ~~notifications~~ 40 | - ~~OAUTH FB/Goog/~~ GitHub login 41 | - loads more 42 | 43 | ---------------------------- 44 | ##Running MD: Agora 45 | ###Linux 46 | 47 | dependencies: 48 | 49 | pip install django 50 | pip install markdown 51 | pip install python-social-auth 52 | pip install oauthlib 53 | pip install pillow 54 | pip install html2text 55 | 56 | install 57 | 58 | #Install Dependencies then 59 | git clone https://github.com/chozabu/VoteFlow.git #Clone the project 60 | cd VoteFlow #enter project 61 | python manage.py migrate #create DB 62 | python manage.py runserver #Run Server 63 | firefox http://127.0.0.1:8000/agora/ #Try it out! 64 | 65 | or in a virtualenv 66 | 67 | git clone https://github.com/chozabu/VoteFlow 68 | cd VoteFlow/ 69 | virtualenv env 70 | source env/bin/activate 71 | #Install Dependencies HERE 72 | python manage.py migrate 73 | python manage.py runserver 74 | 75 | ###Other OS 76 | 77 | add me 78 | 79 | 80 | ##Project Structure 81 | Project setup should be fairly standard for django. 82 | Important files are in agora/: 83 | - urls.py - based on browser URL, directs you to a view 84 | - views.py - Pulls data from models, returns through a template 85 | - models.py - Database models 86 | - templates/agora/* - HTML templates 87 | - static/agora/* - CSS and other files 88 | 89 | ##Licence 90 | Agora is published under the GNU AGPL 91 | https://gnu.org/licenses/agpl.html 92 | -------------------------------------------------------------------------------- /agora/templates/agora/groups/members_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ group.name }} Members 5 | {% endblock %} 6 | 7 | 8 | {% block body_block %} 9 | 10 | {% include "agora/grouppath/pathto_ul.html" %} 11 |

    12 | 13 | {{ group.name }} 14 | Members

    15 | 28 | 29 | 30 | 55 | 56 | 74 | 75 | {% endblock %} 76 | -------------------------------------------------------------------------------- /agora/templates/agora/group.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ group.name }} 5 | {% endblock %} 6 | {% load cmarkdown %} 7 | 8 | {% block body_block %} 9 | {% include "agora/grouppath/pathto_ul.html" %} 10 |
    11 |

    12 | 13 | {{ group.name }} 14 |

    15 |
    16 | {{ group.safetext|markdown }} 17 |
    18 | {% if membership %} 19 | You are a member of this group. Your level is: {{ membership.level }} 20 | 24 | 29 | {% else %} 30 | {% if pending_membership %} 31 | You have requested to join this group. Cancel 32 | {% else %} 33 | You are not a member of this group. Join Group 34 | {% endif %} 35 | {% endif %} 36 |
    37 | {{ group.memberships.all|length }} Members ({{ group.applications.all|length }} Pending)
    38 | 39 | {{ group.permission_reqs.all|length }} Rules
    40 |
    41 |
    author: 42 | {{ group.author.username }} @ {{ group.created_at }} 43 |
    type: {{ group.subtype }} 44 |
    sub-groups: {{ group.group_set.all|length }} Posts {{ group.post_set.all|length }} 45 |
    46 |

    Sub Groups

    47 | {% if group_list %} 48 |
    49 | {% for group in group_list %} 50 | {% include "agora/groups/inc_micro.html" %} 51 | {% endfor %} 52 |
    .
    53 | {% else %} 54 |

    No sub-groups found...

    55 | {% endif %} 56 | 57 | 59 | 60 | 61 |
    62 |

    Posts

    63 | 64 | 66 | 67 |
    68 | 69 | {% include 'agora/inc_post_list.html' with divid='mainpostlist' %} 70 | 71 |
    72 | 73 | 74 | 83 | 84 | {% endblock %} 85 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 67 | 72 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /agora/templates/agora/user.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | {{ selected_user.username }} 5 | {% endblock %} 6 | 7 | {% block head_block %} 8 | 9 | {% endblock %} 10 | 11 | 12 | {% block body_block %} 13 |

    {{ selected_user }}

    14 | {% if similarity %} 15 |

    {{ similarity }}% similar votes to you over {{ compared_vote_count }} vote(s)

    16 | {% endif %} 17 | {% if own_profile %} 18 | {% if fb_ss %} 19 |

    Connected with FaceBook!

    20 | {% else %} 21 |

    Connect with Facebook

    22 | {% endif %} 23 | 24 | {% if goog_ss %} 25 |

    Connected with Google!

    26 | {% else %} 27 | Connect with Google 28 | {% endif %} 29 | {% endif %} 30 | 31 |

    Representees

    32 | 47 |
    48 | 49 |

    Representitives:

    50 | 63 |
    64 | 65 |

    Posts

    66 | 71 |
    72 | 73 | 74 |

    Votes

    75 | 80 |
    81 | 82 |

    Subscriptions

    83 | 88 |
    89 | 90 |

    Topics Created

    91 |
    98 | 99 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/js/rangy-selectionsaverestore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Selection save and restore module for Rangy. 3 | * Saves and restores user selections using marker invisible elements in the DOM. 4 | * 5 | * Part of Rangy, a cross-browser JavaScript range and selection library 6 | * https://github.com/timdown/rangy 7 | * 8 | * Depends on Rangy core. 9 | * 10 | * Copyright 2015, Tim Down 11 | * Licensed under the MIT license. 12 | * Version: 1.3.0 13 | * Build date: 10 May 2015 14 | */ 15 | !function(e,n){"function"==typeof define&&define.amd?define(["./rangy-core"],e):"undefined"!=typeof module&&"object"==typeof exports?module.exports=e(require("rangy")):e(n.rangy)}(function(e){return e.createModule("SaveRestore",["WrappedRange"],function(e,n){function r(e,n){return(n||document).getElementById(e)}function t(e,n){var r,t="selectionBoundary_"+ +new Date+"_"+(""+Math.random()).slice(2),a=m.getDocument(e.startContainer),o=e.cloneRange();return o.collapse(n),r=a.createElement("span"),r.id=t,r.style.lineHeight="0",r.style.display="none",r.className="rangySelectionBoundary",r.appendChild(a.createTextNode(k)),o.insertNode(r),r}function a(e,t,a,o){var s=r(a,e);s?(t[o?"setStartBefore":"setEndBefore"](s),p(s)):n.warn("Marker element has been removed. Cannot restore selection.")}function o(e,n){return n.compareBoundaryPoints(e.START_TO_START,e)}function s(n,r){var a,o,s=e.DomRange.getRangeDocument(n),i=n.toString(),d=v(r);return n.collapsed?(o=t(n,!1),{document:s,markerId:o.id,collapsed:!0}):(o=t(n,!1),a=t(n,!0),{document:s,startMarkerId:a.id,endMarkerId:o.id,collapsed:!1,backward:d,toString:function(){return"original text: '"+i+"', new text: '"+n.toString()+"'"}})}function i(t,o){var s=t.document;"undefined"==typeof o&&(o=!0);var i=e.createRange(s);if(t.collapsed){var d=r(t.markerId,s);if(d){d.style.display="inline";var l=d.previousSibling;l&&3==l.nodeType?(p(d),i.collapseToPoint(l,l.length)):(i.collapseBefore(d),p(d))}else n.warn("Marker element has been removed. Cannot restore selection.")}else a(s,i,t.startMarkerId,!0),a(s,i,t.endMarkerId,!1);return o&&i.normalizeBoundaries(),i}function d(n,t){var a,i,d=[],l=v(t);n=n.slice(0),n.sort(o);for(var c=0,u=n.length;u>c;++c)d[c]=s(n[c],l);for(c=u-1;c>=0;--c)a=n[c],i=e.DomRange.getRangeDocument(a),a.collapsed?a.collapseAfter(r(d[c].markerId,i)):(a.setEndBefore(r(d[c].endMarkerId,i)),a.setStartAfter(r(d[c].startMarkerId,i)));return d}function l(r){if(!e.isSelectionValid(r))return n.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus."),null;var t=e.getSelection(r),a=t.getAllRanges(),o=1==a.length&&t.isBackward(),s=d(a,o);return o?t.setSingleRange(a[0],o):t.setRanges(a),{win:r,rangeInfos:s,restored:!1}}function c(e){for(var n=[],r=e.length,t=r-1;t>=0;t--)n[t]=i(e[t],!0);return n}function u(n,r){if(!n.restored){var t=n.rangeInfos,a=e.getSelection(n.win),o=c(t),s=t.length;1==s&&r&&e.features.selectionHasExtend&&t[0].backward?(a.removeAllRanges(),a.addRange(o[0],!0)):a.setRanges(o),n.restored=!0}}function f(e,n){var t=r(n,e);t&&p(t)}function g(e){for(var n,r=e.rangeInfos,t=0,a=r.length;a>t;++t)n=r[t],n.collapsed?f(e.doc,n.markerId):(f(e.doc,n.startMarkerId),f(e.doc,n.endMarkerId))}var m=e.dom,p=m.removeNode,v=e.Selection.isDirectionBackward,k="";e.util.extend(e,{saveRange:s,restoreRange:i,saveRanges:d,restoreRanges:c,saveSelection:l,restoreSelection:u,removeMarkerElement:f,removeMarkers:g})}),e},this); -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | svgl1 53 | 54 | 55 | 56 | 62 | 67 | 74 | 79 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 67 | 74 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 67 | 74 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /agora/static/agora/img/ratings/orig-3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 67 | 74 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /agora/templates/agora/root.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Social Representation 4 | {% endblock %} 5 | 6 | {% load staticfiles %} 7 | {% block head_block %} 8 | 9 | VoteFlow 10 | 11 | {% endblock %} 12 | 13 | {% block body_block %} 14 |
    15 | Fork me on GitHub 16 | 17 |
    18 |

    VoteFlow

    19 |
    20 | 21 |

    VoteFlow lets people represent people for things they trust them about

    22 | 23 |
    24 |
    25 |

    Rather than one person Represent you for everything, you can pick representatives for topics. 26 |
    You should pick someone you know and trust as a representative for you on a topic. 27 |
    Representatives can pick people to represent them in the same or subtopics 28 |
    Meaning you get Chains, or trees of representation. 29 |
    Particularly as you get deeper into sub-topics, a person may be able to represent a massive number of people. 30 |
    You are always able see what your representatives do, override their decisions - or pick someone else. 31 |

    32 |

    This is a Discussion & voting system inspired by Liquid Democracy

    33 |

    Shortcuts

    34 | {% load staticfiles %} 35 |
    36 | 38 | 40 | 42 |
    43 | 44 |

    Friends

    45 | 53 | 54 | 55 |

    56 | UserInfo
    57 | {% include "agora/inc_user.html" %} 58 |

    59 |
    60 | {% endblock %} 61 | -------------------------------------------------------------------------------- /agora/templates/agora/new_rep.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Pick Representative for {{ current_topic }} 4 | {% endblock %} 5 | 6 | {% block body_block %} 7 | {% include "agora/topicpath/fullpath_ul.html" %} 8 |

    Pick Representative in: {{ current_topic }}

    9 | {% if current_rep %} 10 |
    11 |

    Current Rep:

    {% include "agora/inc_user_micro.html" with user=current_rep.rep %} 12 | 13 |
    14 | {% endif %} 15 |
    17 | 18 |

    New Rep:

    19 | UserName: 20 |
    21 |
    22 |
    23 |
    24 | 25 | 96 | 97 | 98 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/sunburst.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Representation 4 | {% endblock %} 5 | {% block head_block %} 6 | 16 | {% endblock %} 17 | 18 | {% block body_block %} 19 | {% load staticfiles %} 20 | 24 | 25 | 100 |

    This chart based on mbostock’s block 101 | #5480307

    102 | 103 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/forcearrows.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Representation 4 | {% endblock %} 5 | {% block head_block %} 6 | 41 | {% endblock %} 42 | 43 | {% block body_block %} 44 | {% load staticfiles %} 45 | 49 | 50 | 137 |

    This chart based on mbostock’s block 138 | #1153292

    139 | 140 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/fancy_post.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | New Post 4 | {% endblock %} 5 | 6 | {% block head_block %} 7 | {% load staticfiles %} 8 | 9 | {% include 'agora/util/hallohead.html' %} 10 | 11 | 12 | {% endblock %} 13 | 14 | {% block body_block %} 15 |
    16 | {% if topic %} 17 | In Topic: 18 | {% include "agora/topicpath/fullpath_ul.html" %} 19 | {% endif %} 20 | {% if group %} 21 | In Group: 22 | {% include "agora/inc_group_mini.html" %} 23 | {% endif %} 24 |

    New Post

    25 |
    26 | {% csrf_token %} 27 | 28 | 29 |
    30 |
    31 | 32 |
    33 |
    34 | 35 |
    36 |
    37 | 38 |
    39 |
    40 | 41 |

    42 |
    43 | 46 |
    47 |
    48 | 49 | {% include "agora/util/halloitem.html" with itemid=post rname="body_text" initial_text="Type Post Body Here." %} 50 | 51 |
    52 |
    53 |
    54 | 57 | 60 |
    61 | 62 |
    63 |
    64 | 65 | 66 | 109 | {% endblock %} -------------------------------------------------------------------------------- /agora/templates/agora/sankey.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | {% block title %} 3 | Vote Results for {{ post.name }} 4 | {% endblock %} 5 | {% block head_block %} 6 | 37 | {% endblock %} 38 | 39 | {% block body_block %} 40 | {% include "agora/topicpath/fullpath_ul.html" %} 41 | {% load staticfiles %} 42 | 46 | 47 |

    Vote Results for 48 | {{ post.name }} 49 |

    50 |

    This chart shows who is being represented in the votes on this post 51 |

    56 |

    57 | 58 | 59 | 143 | 150 |

    This chart based on mbostock’s Sankey Diagrams 151 | 152 | {% endblock %} -------------------------------------------------------------------------------- /agora/static/agora/js/dselect.js: -------------------------------------------------------------------------------- 1 | var dselect_rdict = { 2 | "liquid_value":"Rating (Vote Average)", 3 | "liquid_sum":"Sum (Vote Count)", 4 | "created_at":"Date", 5 | "direct_value":"Direct Rating", 6 | "direct_sum":"Direct Sum", 7 | "tag":"Tag ..." 8 | } 9 | function getdselectitem(achild){ 10 | var mainbox = $(this).parentsUntil(".ruleitem"); 11 | if (mainbox.length == 0){ 12 | //console.log(achild.parent()); 13 | return achild.parent(); 14 | } 15 | //console.log(mainbox.parent()); 16 | return mainbox.parent(); 17 | 18 | } 19 | function getrealdselectitem(achild){ 20 | var mainbox = $(this).parentsUntil(".dselectitem"); 21 | if (mainbox.length == 0){ 22 | //console.log(achild.parent()); 23 | return achild.parent(); 24 | } 25 | //console.log(mainbox.parent()); 26 | return mainbox.parent(); 27 | 28 | } 29 | 30 | function postdselectbox_changed(event){ 31 | //console.log("---") 32 | //console.log($(this)); 33 | var mainbox = getdselectitem($(this)) 34 | var newval = $(this)[0].value; 35 | //console.log(newval); 36 | var tagbox = mainbox.find('#tagselectcontainer'); 37 | //console.log(floatbox); 38 | if( $.inArray( newval, [ "tag" ] ) != -1){ 39 | tagbox.show(); 40 | } else { 41 | tagbox.hide(); 42 | } 43 | } 44 | 45 | function get_dselects(fcontainername){ 46 | var fbox = $(fcontainername).children(); 47 | return get_dselect(fbox); 48 | } 49 | function set_dselects(fcontainername, query){ 50 | var fbox = $(fcontainername).children(); 51 | return set_dselect(fbox, query); 52 | } 53 | function print_dselect(event){ 54 | console.log("printing dselect") 55 | var mainbox = $(this).parent().parent() 56 | console.log(mainbox); 57 | dselect = get_dselect(mainbox); 58 | console.log(dselect); 59 | mainbox.find('#outbox')[0].textContent=JSON.stringify(dselect); 60 | } 61 | 62 | 63 | function get_dselect(mainbox){ 64 | //console.log("mainbox"); 65 | //console.log(mainbox); 66 | //console.log(mainbox.find('#postdselectbox')); 67 | 68 | var first = mainbox.find('#postdselectbox')[0].value; 69 | if( $.inArray( first, [ "tag" ] ) != -1){ 70 | var second = mainbox.find('#tagnamebox')[0].value; 71 | var third = mainbox.find('#tagdselectbox')[0].value; 72 | return first+"__"+second+"__"+third; 73 | } 74 | return first; 75 | } 76 | function set_dselect(mainbox, query){ 77 | var items = query.split("__"); 78 | //console.log("##########DEBUG LVAL#######"); 79 | //console.log("mainbox"); 80 | //console.log(mainbox); 81 | //console.log(mainbox.find('#postdselectbox')); 82 | 83 | console.log("ITEMS:", items, items.length) 84 | var first = items[0]; 85 | var second = ""; 86 | var third = ""; 87 | if (items.length>1) 88 | second = items[1]; 89 | if (items.length>2) 90 | third = items[2]; 91 | //console.log("ITEMS:", first, second, third) 92 | 93 | mainbox.find('#postdselectbox')[0].value = first; 94 | mainbox.find('#postdselectbox').trigger('change'); 95 | console.log("first!!!!!:") 96 | console.log(first) 97 | if( $.inArray( first, [ "tag" ] ) != -1){ 98 | console.log("tagnamebox:") 99 | console.log(mainbox.find('#tagnamebox')[0]) 100 | mainbox.find('#tagnamebox')[0].value = second; 101 | mainbox.find('#tagdselectbox')[0].value = third; 102 | //mainbox.find('#tagdselectbox')[0].value = second; 103 | //mainbox.find('#tagdselectbox').trigger('change'); 104 | } 105 | } 106 | 107 | //$('#postdselectbox').change(postdselectbox_changed); 108 | 109 | 110 | 111 | function new_dselect_action(foe){ 112 | //console.log("new dselect"); 113 | //console.log($('#dselectproto')); 114 | var newdselect = $('#dselectproto').clone(true); 115 | newdselect.find('#postdselectbox').change(); 116 | newdselect[0].id="adselect"; 117 | newdselect.show(); 118 | $(foe).append(newdselect); 119 | $('#newrulebutton').click(new_rule); 120 | return newdselect; 121 | } 122 | 123 | function new_dselect_from_json(jin, foe){ 124 | if (foe==undefined)foe = '#currentdselectsbox'; 125 | newdselect = new_dselect_action(foe); 126 | //get the key and value object 127 | 128 | var query = ""; 129 | var val = ""; 130 | a=newdselect.find('#postdselectpair') 131 | var first = true; 132 | for (k in jin){ 133 | query=k; 134 | val=jin[k]; 135 | if (first==false) a=new_rule_on(newdselect); 136 | set_dselect(a, query, val); 137 | first = false; 138 | } 139 | //split key by __s? 140 | //same structure as getdselect, but setting values 141 | 142 | var rootbox = $(foe); 143 | var psf = rootbox.find('#presetdselects'); 144 | console.log("SETTING dselect",JSON.stringify(jin)) 145 | psf[0].value=JSON.stringify(jin); 146 | 147 | } 148 | function set_dselect_from_json(jin, dselectbox){ 149 | var query = ""; 150 | var val = ""; 151 | dselectbox.find('#postdselectpair').remove() 152 | var first = true; 153 | for (k in jin){ 154 | query=k; 155 | val=jin[k]; 156 | a=new_rule_on(dselectbox); 157 | set_dselect(a, query, val); 158 | first = false; 159 | } 160 | //split key by __s? 161 | //same structure as getdselect, but setting values 162 | } 163 | -------------------------------------------------------------------------------- /agora/templates/agora/posts/inc_filter.html: -------------------------------------------------------------------------------- 1 | 5 |

    6 |
    7 | 17 |
    18 |
    19 |
    20 | 34 | 35 | 43 | 44 | 48 | 49 | 53 | 54 | 58 | 59 | 60 | 64 | 65 | 66 | 67 | 68 | 69 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 90 | 91 | 96 |
    97 |
    98 | 99 | 100 | 101 | 102 |
    103 | 104 | 105 | 106 |
    107 | Filters: 108 |
    109 |
    110 |
    111 |
    112 | Excludes: 113 |
    114 |
    115 |
    116 | {% load staticfiles %} 117 | 118 | 144 |
    145 | -------------------------------------------------------------------------------- /MeshDemoc/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for MeshDemoc project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.4. 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 | import json 13 | with open('localsettings.json') as data_file: 14 | localsettings = json.load(data_file) 15 | def gl(attr): 16 | if attr in localsettings: 17 | return localsettings[attr] 18 | print "error, json setting not found:",attr 19 | return '' 20 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 21 | import os 22 | 23 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 24 | 25 | 26 | # Quick-start development settings - unsuitable for production 27 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 28 | 29 | # SECURITY WARNING: keep the secret key used in production secret! 30 | SECRET_KEY = gl('secret_key') 31 | 32 | # SECURITY WARNING: don't run with debug turned on in production! 33 | DEBUG = True 34 | 35 | ALLOWED_HOSTS = [] 36 | 37 | 38 | # Application definition 39 | 40 | INSTALLED_APPS = ( 41 | 'django.contrib.admin', 42 | 'django.contrib.auth', 43 | 'django.contrib.contenttypes', 44 | 'django.contrib.sessions', 45 | 'django.contrib.messages', 46 | 'django.contrib.staticfiles', 47 | 'social.apps.django_app.default', 48 | 'agora', 49 | ) 50 | 51 | MIDDLEWARE_CLASSES = ( 52 | 'django.contrib.sessions.middleware.SessionMiddleware', 53 | 'django.middleware.common.CommonMiddleware', 54 | 'django.middleware.csrf.CsrfViewMiddleware', 55 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 56 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 57 | 'django.contrib.messages.middleware.MessageMiddleware', 58 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 59 | 'django.middleware.security.SecurityMiddleware', 60 | ) 61 | 62 | ROOT_URLCONF = 'MeshDemoc.urls' 63 | 64 | TEMPLATES = [ 65 | { 66 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 67 | 'DIRS': [], 68 | 'APP_DIRS': True, 69 | 'OPTIONS': { 70 | 'context_processors': [ 71 | 'django.template.context_processors.debug', 72 | 'django.template.context_processors.request', 73 | 'django.contrib.auth.context_processors.auth', 74 | 'django.contrib.messages.context_processors.messages', 75 | ], 76 | }, 77 | }, 78 | ] 79 | 80 | WSGI_APPLICATION = 'MeshDemoc.wsgi.application' 81 | 82 | 83 | # Database 84 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 85 | 86 | DATABASES = { 87 | 'default': { 88 | 'ENGINE': 'django.db.backends.sqlite3', 89 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 90 | } 91 | } 92 | 93 | 94 | # Internationalization 95 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 96 | 97 | LANGUAGE_CODE = 'en-us' 98 | 99 | TIME_ZONE = 'UTC' 100 | 101 | USE_I18N = True 102 | 103 | USE_L10N = True 104 | 105 | USE_TZ = True 106 | 107 | 108 | # Static files (CSS, JavaScript, Images) 109 | # https://docs.djangoproject.com/en/1.8/howto/static-files/ 110 | 111 | STATIC_URL = '/static/' 112 | if 'STATIC_ROOT' in localsettings: 113 | STATIC_ROOT = os.path.dirname(BASE_DIR) + localsettings['STATIC_ROOT'] 114 | if 'MEDIA_ROOT' in localsettings: 115 | MEDIA_ROOT = os.path.dirname(BASE_DIR) + localsettings['MEDIA_ROOT'] 116 | if 'MEDIA_URL' in localsettings: 117 | MEDIA_URL = localsettings['MEDIA_URL'] 118 | print MEDIA_ROOT 119 | 120 | TEMPLATE_CONTEXT_PROCESSORS = ( 121 | 'django.contrib.auth.context_processors.auth', 122 | 'django.core.context_processors.debug', 123 | 'django.core.context_processors.i18n', 124 | 'django.core.context_processors.media', 125 | 'django.core.context_processors.static', 126 | 'django.core.context_processors.tz', 127 | 'django.contrib.messages.context_processors.messages', 128 | 'social.apps.django_app.context_processors.backends', 129 | 'social.apps.django_app.context_processors.login_redirect', 130 | ) 131 | 132 | 133 | AUTHENTICATION_BACKENDS = ( 134 | 'social.backends.facebook.FacebookOAuth2', 135 | 'social.backends.google.GoogleOAuth2', 136 | 'social.backends.twitter.TwitterOAuth', 137 | 'django.contrib.auth.backends.ModelBackend', 138 | ) 139 | 140 | SOCIAL_AUTH_PIPELINE = ( 141 | 'social.pipeline.social_auth.social_details', 142 | 'social.pipeline.social_auth.social_uid', 143 | 'social.pipeline.social_auth.auth_allowed', 144 | 'social.pipeline.social_auth.social_user', 145 | 'social.pipeline.user.get_username', 146 | 'social.pipeline.social_auth.associate_by_email', 147 | 'social.pipeline.user.create_user', 148 | 'social.pipeline.social_auth.associate_user', 149 | 'social.pipeline.social_auth.load_extra_data', 150 | 'social.pipeline.user.user_details', 151 | 'agora.pipeline.save_profile_picture', #save facebook profile image, 152 | ) 153 | 154 | SOCIAL_AUTH_FACEBOOK_KEY = localsettings['SOCIAL_AUTH_FACEBOOK_KEY'] 155 | SOCIAL_AUTH_FACEBOOK_SECRET = gl('SOCIAL_AUTH_FACEBOOK_SECRET') 156 | SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = gl('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY') 157 | SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = gl('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET') 158 | #SOCIAL_AUTH_TWITTER_KEY = 159 | #SOCIAL_AUTH_TWITTER_SECRET = 160 | 161 | SOCIAL_AUTH_FACEBOOK_SCOPE = [ 162 | 'email', 163 | 'user_friends', 164 | 'public_profile', 165 | #user_location 166 | ] 167 | SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [ 168 | 'https://www.googleapis.com/auth/plus.login' 169 | ] 170 | 171 | EMAIL_BACKEND = gl('EMAIL_BACKEND') 172 | EMAIL_HOST = gl('EMAIL_HOST') 173 | EMAIL_PORT = gl('EMAIL_PORT') 174 | EMAIL_HOST_USER = gl('EMAIL_HOST_USER') 175 | EMAIL_HOST_PASSWORD = gl('EMAIL_HOST_PASSWORD') 176 | EMAIL_USE_TLS = gl('EMAIL_USE_TLS') 177 | -------------------------------------------------------------------------------- /agora/static/agora/js/to-markdown.js: -------------------------------------------------------------------------------- 1 | /* 2 | * to-markdown - an HTML to Markdown converter 3 | * 4 | * Copyright 2011, Dom Christie 5 | * Licenced under the MIT licence 6 | * 7 | */ 8 | 9 | var toMarkdown = function(string) { 10 | 11 | var ELEMENTS = [ 12 | { 13 | patterns: 'p', 14 | replacement: function(str, attrs, innerHTML) { 15 | return innerHTML ? '\n\n' + innerHTML + '\n' : ''; 16 | } 17 | }, 18 | { 19 | patterns: 'br', 20 | type: 'void', 21 | replacement: '\n' 22 | }, 23 | { 24 | patterns: 'h([1-6])', 25 | replacement: function(str, hLevel, attrs, innerHTML) { 26 | var hPrefix = ''; 27 | for(var i = 0; i < hLevel; i++) { 28 | hPrefix += '#'; 29 | } 30 | return '\n\n' + hPrefix + ' ' + innerHTML + '\n'; 31 | } 32 | }, 33 | { 34 | patterns: 'hr', 35 | type: 'void', 36 | replacement: '\n\n* * *\n' 37 | }, 38 | { 39 | patterns: 'a', 40 | replacement: function(str, attrs, innerHTML) { 41 | var href = attrs.match(attrRegExp('href')), 42 | title = attrs.match(attrRegExp('title')); 43 | return href ? '[' + innerHTML + ']' + '(' + href[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')' : str; 44 | } 45 | }, 46 | { 47 | patterns: ['b', 'strong'], 48 | replacement: function(str, attrs, innerHTML) { 49 | return innerHTML ? '**' + innerHTML + '**' : ''; 50 | } 51 | }, 52 | { 53 | patterns: ['i', 'em'], 54 | replacement: function(str, attrs, innerHTML) { 55 | return innerHTML ? '_' + innerHTML + '_' : ''; 56 | } 57 | }, 58 | { 59 | patterns: 'code', 60 | replacement: function(str, attrs, innerHTML) { 61 | return innerHTML ? '`' + innerHTML + '`' : ''; 62 | } 63 | }, 64 | { 65 | patterns: 'img', 66 | type: 'void', 67 | replacement: function(str, attrs, innerHTML) { 68 | var src = attrs.match(attrRegExp('src')), 69 | alt = attrs.match(attrRegExp('alt')), 70 | title = attrs.match(attrRegExp('title')); 71 | return '![' + (alt && alt[1] ? alt[1] : '') + ']' + '(' + src[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')'; 72 | } 73 | } 74 | ]; 75 | 76 | for(var i = 0, len = ELEMENTS.length; i < len; i++) { 77 | if(typeof ELEMENTS[i].patterns === 'string') { 78 | string = replaceEls(string, { tag: ELEMENTS[i].patterns, replacement: ELEMENTS[i].replacement, type: ELEMENTS[i].type }); 79 | } 80 | else { 81 | for(var j = 0, pLen = ELEMENTS[i].patterns.length; j < pLen; j++) { 82 | string = replaceEls(string, { tag: ELEMENTS[i].patterns[j], replacement: ELEMENTS[i].replacement, type: ELEMENTS[i].type }); 83 | } 84 | } 85 | } 86 | 87 | function replaceEls(html, elProperties) { 88 | var pattern = elProperties.type === 'void' ? '<' + elProperties.tag + '\\b([^>]*)\\/?>' : '<' + elProperties.tag + '\\b([^>]*)>([\\s\\S]*?)<\\/' + elProperties.tag + '>', 89 | regex = new RegExp(pattern, 'gi'), 90 | markdown = ''; 91 | if(typeof elProperties.replacement === 'string') { 92 | markdown = html.replace(regex, elProperties.replacement); 93 | } 94 | else { 95 | markdown = html.replace(regex, function(str, p1, p2, p3) { 96 | return elProperties.replacement.call(this, str, p1, p2, p3); 97 | }); 98 | } 99 | return markdown; 100 | } 101 | 102 | function attrRegExp(attr) { 103 | return new RegExp(attr + '\\s*=\\s*["\']?([^"\']*)["\']?', 'i'); 104 | } 105 | 106 | // Pre code blocks 107 | 108 | string = string.replace(/]*>`([\s\S]*)`<\/pre>/gi, function(str, innerHTML) { 109 | innerHTML = innerHTML.replace(/^\t+/g, ' '); // convert tabs to spaces (you know it makes sense) 110 | innerHTML = innerHTML.replace(/\n/g, '\n '); 111 | return '\n\n ' + innerHTML + '\n'; 112 | }); 113 | 114 | // Lists 115 | 116 | // Escape numbers that could trigger an ol 117 | string = string.replace(/(\d+). /g, '$1\\. '); 118 | 119 | // Converts lists that have no child lists (of same type) first, then works it's way up 120 | var noChildrenRegex = /<(ul|ol)\b[^>]*>(?:(?!/gi; 121 | while(string.match(noChildrenRegex)) { 122 | string = string.replace(noChildrenRegex, function(str) { 123 | return replaceLists(str); 124 | }); 125 | } 126 | 127 | function replaceLists(html) { 128 | 129 | html = html.replace(/<(ul|ol)\b[^>]*>([\s\S]*?)<\/\1>/gi, function(str, listType, innerHTML) { 130 | var lis = innerHTML.split(''); 131 | lis.splice(lis.length - 1, 1); 132 | 133 | for(i = 0, len = lis.length; i < len; i++) { 134 | if(lis[i]) { 135 | var prefix = (listType === 'ol') ? (i + 1) + ". " : "* "; 136 | lis[i] = lis[i].replace(/\s*]*>([\s\S]*)/i, function(str, innerHTML) { 137 | 138 | innerHTML = innerHTML.replace(/^\s+/, ''); 139 | innerHTML = innerHTML.replace(/\n\n/g, '\n\n '); 140 | // indent nested lists 141 | innerHTML = innerHTML.replace(/\n([ ]*)+(\*|\d+\.) /g, '\n$1 $2 '); 142 | return prefix + innerHTML; 143 | }); 144 | } 145 | } 146 | return lis.join('\n'); 147 | }); 148 | return '\n\n' + html.replace(/[ \t]+\n|\s+$/g, ''); 149 | } 150 | 151 | // Blockquotes 152 | var deepest = /]*>((?:(?!/gi; 153 | while(string.match(deepest)) { 154 | string = string.replace(deepest, function(str) { 155 | return replaceBlockquotes(str); 156 | }); 157 | } 158 | 159 | function replaceBlockquotes(html) { 160 | html = html.replace(/]*>([\s\S]*?)<\/blockquote>/gi, function(str, inner) { 161 | inner = inner.replace(/^\s+|\s+$/g, ''); 162 | inner = cleanUp(inner); 163 | inner = inner.replace(/^/gm, '> '); 164 | inner = inner.replace(/^(>([ \t]{2,}>)+)/gm, '> >'); 165 | return inner; 166 | }); 167 | return html; 168 | } 169 | 170 | function cleanUp(string) { 171 | string = string.replace(/^[\t\r\n]+|[\t\r\n]+$/g, ''); // trim leading/trailing whitespace 172 | string = string.replace(/\n\s+\n/g, '\n\n'); 173 | string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2 174 | return string; 175 | } 176 | 177 | return cleanUp(string); 178 | }; 179 | 180 | if (typeof exports === 'object') { 181 | exports.toMarkdown = toMarkdown; 182 | } 183 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_search.html: -------------------------------------------------------------------------------- 1 |
    4 | 5 | Search In 10 |
    11 | 12 | {% include 'agora/posts/inc_filter.html' with filterdivid="searchfilter" %} 13 | 14 |
    15 | Sorting 23 | 27 | 30 |
    31 |
    32 | 35 | 38 |
    39 | 40 | -------------------------------------------------------------------------------- /agora/urls.py: -------------------------------------------------------------------------------- 1 | 2 | from django.conf.urls import url 3 | 4 | from . import views 5 | 6 | urlpatterns = [ 7 | url(r'^woi_query/$', views.woi_query, name='woi_query'), 8 | url(r'^woi/$', views.woi, name='woi'), 9 | url(r'^filtertest/$', views.filtertest, name='filtertest'), 10 | # ex: /agora/ 11 | url(r'^$', views.index, name='index'), 12 | # ex: /agora/basic_api/ 13 | url(r'^basic_api/$', views.db_query, name='basic_api'), 14 | # ex: /agora/search/ 15 | url(r'^search/$', views.search, name='search'), 16 | # ex: /agora/new_user/ 17 | url(r'^new_user/$', views.new_user, name='new_user'), 18 | # ex: /agora/login/ 19 | url(r'^login/$', views.login_user, name='login'), 20 | # ex: /agora/login2/ 21 | url(r'^login2/$', views.home, name='home'), 22 | # ex: /agora/logout/ 23 | url(r'^logout/$', views.logout_user, name='logout'), 24 | # ex: /agora/notifications/ 25 | url(r'^notifications/$', views.notifications, name='notifications'), 26 | #url(r'^notifications/mark_read$', views.clear_notifications, name='notifications'), 27 | # ex: /agora/all_topics/ 28 | url(r'^all_topics/$', views.all_topics, name='all_topics'), 29 | # ex: /agora/groups/ 30 | url(r'^groups/$', views.groups, name='groups'), 31 | # ex: /agora/groups/5/ 32 | url(r'^groups/(?P[0-9]+)/$', views.group, name='group'), 33 | url(r'^groups/(?P[0-9]+)/new/$', views.fancy_group, name='newgroup'), 34 | url(r'^groups/(?P[0-9]+)/members/$', views.group_members, name='groupmembers'), 35 | url(r'^groups/(?P[0-9]+)/members/setlevel_submit/$', views.group_member_setlevel_submit, name='groupsetmemberlevel'), 36 | url(r'^groups/(?P[0-9]+)/rules/$', views.group_rules, name='grouprules'), 37 | url(r'^groups/(?P[0-9]+)/pending_members/$', views.group_pending_members, name='grouppending_members'), 38 | url(r'^groups/(?P[0-9]+)/pending_members/(?P[0-9]+)/(?P[0-9]+)/$', views.group_pending_member_answer, name='group_pending_member_answer'), 39 | url(r'^groups/(?P[0-9]+)/join_group/$', views.join_group, name='grouprules'), 40 | url(r'^groups/(?P[0-9]+)/rules/setrule_submit/$', views.group_rules_quick, name='setgrouprule'), 41 | url(r'^groups/(?P[0-9]+)/new/newgroup_submit/$', views.group_quick, name='newgroup_submit'), 42 | url(r'^groups/new/$', views.fancy_group, name='newgroup'), 43 | url(r'^groups/new/newgroup_submit/$', views.group_quick, name='newgroup_submit'), 44 | # ex: /agora/topics/5/sort/sort-method 45 | #(?P[\w-]+) 46 | url(r'^all_topics/sort/(?P[\w-]+)/$', views.all_topics, name='all_topics'), 47 | # ex: /agora/topics/ 48 | url(r'^topics/$', views.all_topics, name='all_topics'), 49 | # ex: /agora/topics/5/ 50 | url(r'^topics/(?P[0-9]+)/$', views.topics, name='topics'), 51 | # ex: /agora/tags/5/ 52 | url(r'^tags/(?P[0-9]+)/$', views.tags, name='tags'), 53 | # ex: /agora/alltags/completed/ 54 | #url(r'^alltags/(?P[\w-]+)/$', views.alltags, name='alltags'), 55 | url(r'^alltags/(?P[\w+]+)/$', views.alltags, name='alltags'), 56 | # ex: /agora/tags/5/quickvote/ 57 | url(r'^tags/(?P[0-9]+)/quickvote/$', views.vote_tag_quick, name='tagsvote'), 58 | # ex: /agora/users/ 59 | url(r'^users/$', views.view_users, name='users'), 60 | # ex: /agora/user/5/ 61 | url(r'^user/(?P[0-9]+)/$', views.view_user, name='user'), 62 | 63 | url(r'^newpost/$', views.fancy_post, name='newpost'), 64 | url(r'^newpost/newpost_submit/$', views.post_quick, name='newpost_submit'), 65 | 66 | # ex: /agora/topics/5/sort/sort-method 67 | #(?P[\w-]+) 68 | url(r'^topics/(?P[0-9]+)/sort/(?P[\w-]+)/$', views.topics, name='topics'), 69 | # ex: /agora/topics/new/ 70 | url(r'^topics/new/$', views.new_topic, name='newtopic'), 71 | # ex: /agora/topics/new/ 72 | url(r'^topics/new/(?P[0-9]+)/$', views.new_topic, name='newtopic'), 73 | # ex: /agora/topics/5/newrep/ 74 | url(r'^topics/(?P[0-9]+)/newrep/$', views.new_rep, name='newrep'), 75 | # ex: /agora/topics/5/newrep/ 76 | url(r'^topics/(?P[0-9]+)/newrep/(?P[0-9]+)/$', views.confirm_rep, name='newrep'), 77 | # ex: /agora/topics/5/subs/ 78 | url(r'^topics/(?P[0-9]+)/subs/', views.subscribe_topic, name='subs'), 79 | # ex: /agora/topics/sankey/ 80 | #url(r'^all_topics/sankey/', views.post_sankey, name='post_sankey'), 81 | # ex: /agora/topics/5/forcearrows/ 82 | url(r'^all_topics/forcearrows/', views.topic_forcearrows, name='topic_forcearrows'), 83 | url(r'^topics/forcearrows/', views.topic_forcearrows, name='topic_forcearrows'), 84 | url(r'^all_topics/sunburst/', views.topic_sunburst, name='topic_sunburst'), 85 | url(r'^topics/sunburst/', views.topic_sunburst, name='topic_sunburst'), 86 | # ex: /agora/topics/5/forcearrows/ 87 | url(r'^topics/(?P[0-9]+)/forcearrows/', views.topic_forcearrows, name='topic_forcearrows'), 88 | # ex: /agora/topics/new/ 89 | #url(r'^topics/(?P[0-9]+)/old_newpost/$', views.new_post, name='oldnewpost'), 90 | #url(r'^topics/(?P[0-9]+)/newpost/$', views.fancy_post, name='newpost'), 91 | #url(r'^topics/(?P[0-9]+)/newpost/newpost_submit/$', views.post_quick, name='newpost_submit'), 92 | # ex: /agora/topics/new/ 93 | url(r'^topics/(?P[0-9]+)/newpost/(?P[0-9]+)$', views.new_post, name='newpost'), 94 | # ex: /agora/topics/5/posts/5/ 95 | url(r'^posts/(?P[0-9]+)/$', views.posts, name='posts'), 96 | # ex: /agora/topics/5/posts/5/vote/ 97 | url(r'^posts/(?P[0-9]+)/vote/$', views.vote_post, name='vote_post'), 98 | # ex: /agora/topics/5/posts/5/newtag/ 99 | url(r'^posts/(?P[0-9]+)/newtag/$', views.new_tag, name='newtag'), 100 | # ex: /agora/topics/5/posts/5/sankey/ 101 | url(r'^posts/(?P[0-9]+)/sankey/$', views.post_sankey, name='post_sankey'), 102 | # ex: /agora/topics/5/posts/5/quickvote/ 103 | url(r'^posts/(?P[0-9]+)/quickvote/$', views.vote_post_quick, name='quickvote'), 104 | # ex: /agora/topics/5/posts/5/quickvote/ 105 | url(r'^posts/(?P[0-9]+)/unvote/$', views.unvote_post_quick, name='quickunvote'), 106 | # ex: /agora/topics/5/posts/5/add_option/ 107 | url(r'^posts/(?P[0-9]+)/add_(?P[\w-]+)/$', views.post_quick, name='quickreply'), 108 | # ex: /agora/5/vote/ 109 | #url(r'^(?P[0-9]+)/vote/$', views.vote, name='vote'), 110 | ] 111 | 112 | -------------------------------------------------------------------------------- /agora/templates/agora/inc_post_list.html: -------------------------------------------------------------------------------- 1 | 4 | {% load staticfiles %} 5 |
    8 | 9 | {% include 'agora/posts/inc_filter.html' with filterdivid=divid %} 10 | 11 | Sorting 22 | 25 |
      26 | {% if items %} 27 | {% for child_post in items %} 28 | {% if recur_posts %} 29 |
    • {% include "agora/inc_post_mini_recur.html" with post=child_post %}
    • 30 | {% else %} 31 |
    • {% include "agora/inc_post_mini.html" with post=child_post %}
    • 32 | {% endif %} 33 | {% endfor %} 34 | {% endif %} 35 |
    36 | 39 | 42 | 47 | 48 | 83 | -------------------------------------------------------------------------------- /agora/templates/agora/posts/scatterplus.html: -------------------------------------------------------------------------------- 1 | {% extends 'agora/base_template.html' %} 2 | 3 | {% block title %} 4 | Wall of Ideas 5 | {% endblock %} 6 | 7 | 8 | {% block head_block %} 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% endblock %} 17 | 18 | {% block body_block %} 19 | 20 |

    Wall Of Ideas

    21 | 22 |

    This is a sytem to let you graph posts in voteflow - much like on 23 | the physical "wall of ideas" 24 |
    25 | Though, rather than being limited to 2 fixed axies, you can customise!
    26 | Have a look at a graph of 28 | Posts popularity and how challenging they are 29 |
    30 | Or 32 | The difference representation makes 33 |
    34 | Perhaps 36 | Time Posted, and rating 37 | 38 |

    39 | 40 | X-Axis: {% include 'agora/posts/inc_dselect.html' with dselectdivid="xaxis" %}
    41 | Y-Axis: {% include 'agora/posts/inc_dselect.html' with dselectdivid="yaxis" %}
    42 | 43 | {% include 'agora/posts/inc_filter.html' with filterdivid="woithing" %} 44 | 45 | 46 | 47 |
    48 | 49 |
    Shareable Link:
    50 | This should take someone to the page you are looking at *now*
    51 | 52 | 194 | {% endblock %} 195 | 196 | -------------------------------------------------------------------------------- /agora/static/agora/js/sankey.js: -------------------------------------------------------------------------------- 1 | d3.sankey = function() { 2 | var sankey = {}, 3 | nodeWidth = 24, 4 | nodePadding = 8, 5 | size = [1, 1], 6 | nodes = [], 7 | links = []; 8 | 9 | sankey.nodeWidth = function(_) { 10 | if (!arguments.length) return nodeWidth; 11 | nodeWidth = +_; 12 | return sankey; 13 | }; 14 | 15 | sankey.nodePadding = function(_) { 16 | if (!arguments.length) return nodePadding; 17 | nodePadding = +_; 18 | return sankey; 19 | }; 20 | 21 | sankey.nodes = function(_) { 22 | if (!arguments.length) return nodes; 23 | nodes = _; 24 | return sankey; 25 | }; 26 | 27 | sankey.links = function(_) { 28 | if (!arguments.length) return links; 29 | links = _; 30 | return sankey; 31 | }; 32 | 33 | sankey.size = function(_) { 34 | if (!arguments.length) return size; 35 | size = _; 36 | return sankey; 37 | }; 38 | 39 | sankey.layout = function(iterations) { 40 | computeNodeLinks(); 41 | computeNodeValues(); 42 | computeNodeBreadths(); 43 | computeNodeDepths(iterations); 44 | computeLinkDepths(); 45 | return sankey; 46 | }; 47 | 48 | sankey.relayout = function() { 49 | computeLinkDepths(); 50 | return sankey; 51 | }; 52 | 53 | sankey.link = function() { 54 | var curvature = .5; 55 | 56 | function link(d) { 57 | var x0 = d.source.x + d.source.dx, 58 | x1 = d.target.x, 59 | xi = d3.interpolateNumber(x0, x1), 60 | x2 = xi(curvature), 61 | x3 = xi(1 - curvature), 62 | y0 = d.source.y + d.sy + d.dy / 2, 63 | y1 = d.target.y + d.ty + d.dy / 2; 64 | return "M" + x0 + "," + y0 65 | + "C" + x2 + "," + y0 66 | + " " + x3 + "," + y1 67 | + " " + x1 + "," + y1; 68 | } 69 | 70 | link.curvature = function(_) { 71 | if (!arguments.length) return curvature; 72 | curvature = +_; 73 | return link; 74 | }; 75 | 76 | return link; 77 | }; 78 | 79 | // Populate the sourceLinks and targetLinks for each node. 80 | // Also, if the source and target are not objects, assume they are indices. 81 | function computeNodeLinks() { 82 | nodes.forEach(function(node) { 83 | node.sourceLinks = []; 84 | node.targetLinks = []; 85 | }); 86 | links.forEach(function(link) { 87 | var source = link.source, 88 | target = link.target; 89 | if (typeof source === "number") source = link.source = nodes[link.source]; 90 | if (typeof target === "number") target = link.target = nodes[link.target]; 91 | source.sourceLinks.push(link); 92 | target.targetLinks.push(link); 93 | }); 94 | } 95 | 96 | // Compute the value (size) of each node by summing the associated links. 97 | function computeNodeValues() { 98 | nodes.forEach(function(node) { 99 | node.value = Math.max( 100 | d3.sum(node.sourceLinks, value), 101 | d3.sum(node.targetLinks, value) 102 | ); 103 | }); 104 | } 105 | 106 | // Iteratively assign the breadth (x-position) for each node. 107 | // Nodes are assigned the maximum breadth of incoming neighbors plus one; 108 | // nodes with no incoming links are assigned breadth zero, while 109 | // nodes with no outgoing links are assigned the maximum breadth. 110 | function computeNodeBreadths() { 111 | var remainingNodes = nodes, 112 | nextNodes, 113 | x = 0; 114 | 115 | while (remainingNodes.length) { 116 | nextNodes = []; 117 | remainingNodes.forEach(function(node) { 118 | node.x = x; 119 | node.dx = nodeWidth; 120 | node.sourceLinks.forEach(function(link) { 121 | nextNodes.push(link.target); 122 | }); 123 | }); 124 | remainingNodes = nextNodes; 125 | ++x; 126 | } 127 | 128 | // 129 | moveSinksRight(x); 130 | scaleNodeBreadths((width - nodeWidth) / (x - 1)); 131 | } 132 | 133 | function moveSourcesRight() { 134 | nodes.forEach(function(node) { 135 | if (!node.targetLinks.length) { 136 | node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1; 137 | } 138 | }); 139 | } 140 | 141 | function moveSinksRight(x) { 142 | nodes.forEach(function(node) { 143 | if (!node.sourceLinks.length) { 144 | node.x = x - 1; 145 | } 146 | }); 147 | } 148 | 149 | function scaleNodeBreadths(kx) { 150 | nodes.forEach(function(node) { 151 | node.x *= kx; 152 | }); 153 | } 154 | 155 | function computeNodeDepths(iterations) { 156 | var nodesByBreadth = d3.nest() 157 | .key(function(d) { return d.x; }) 158 | .sortKeys(d3.ascending) 159 | .entries(nodes) 160 | .map(function(d) { return d.values; }); 161 | 162 | // 163 | initializeNodeDepth(); 164 | resolveCollisions(); 165 | for (var alpha = 1; iterations > 0; --iterations) { 166 | relaxRightToLeft(alpha *= .99); 167 | resolveCollisions(); 168 | relaxLeftToRight(alpha); 169 | resolveCollisions(); 170 | } 171 | 172 | function initializeNodeDepth() { 173 | var ky = d3.min(nodesByBreadth, function(nodes) { 174 | return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value); 175 | }); 176 | 177 | nodesByBreadth.forEach(function(nodes) { 178 | nodes.forEach(function(node, i) { 179 | node.y = i; 180 | node.dy = node.value * ky; 181 | }); 182 | }); 183 | 184 | links.forEach(function(link) { 185 | link.dy = link.value * ky; 186 | }); 187 | } 188 | 189 | function relaxLeftToRight(alpha) { 190 | nodesByBreadth.forEach(function(nodes, breadth) { 191 | nodes.forEach(function(node) { 192 | if (node.targetLinks.length) { 193 | var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value); 194 | node.y += (y - center(node)) * alpha; 195 | } 196 | }); 197 | }); 198 | 199 | function weightedSource(link) { 200 | return center(link.source) * link.value; 201 | } 202 | } 203 | 204 | function relaxRightToLeft(alpha) { 205 | nodesByBreadth.slice().reverse().forEach(function(nodes) { 206 | nodes.forEach(function(node) { 207 | if (node.sourceLinks.length) { 208 | var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value); 209 | node.y += (y - center(node)) * alpha; 210 | } 211 | }); 212 | }); 213 | 214 | function weightedTarget(link) { 215 | return center(link.target) * link.value; 216 | } 217 | } 218 | 219 | function resolveCollisions() { 220 | nodesByBreadth.forEach(function(nodes) { 221 | var node, 222 | dy, 223 | y0 = 0, 224 | n = nodes.length, 225 | i; 226 | 227 | // Push any overlapping nodes down. 228 | nodes.sort(ascendingDepth); 229 | for (i = 0; i < n; ++i) { 230 | node = nodes[i]; 231 | dy = y0 - node.y; 232 | if (dy > 0) node.y += dy; 233 | y0 = node.y + node.dy + nodePadding; 234 | } 235 | 236 | // If the bottommost node goes outside the bounds, push it back up. 237 | dy = y0 - nodePadding - size[1]; 238 | if (dy > 0) { 239 | y0 = node.y -= dy; 240 | 241 | // Push any overlapping nodes back up. 242 | for (i = n - 2; i >= 0; --i) { 243 | node = nodes[i]; 244 | dy = node.y + node.dy + nodePadding - y0; 245 | if (dy > 0) node.y -= dy; 246 | y0 = node.y; 247 | } 248 | } 249 | }); 250 | } 251 | 252 | function ascendingDepth(a, b) { 253 | return a.y - b.y; 254 | } 255 | } 256 | 257 | function computeLinkDepths() { 258 | nodes.forEach(function(node) { 259 | node.sourceLinks.sort(ascendingTargetDepth); 260 | node.targetLinks.sort(ascendingSourceDepth); 261 | }); 262 | nodes.forEach(function(node) { 263 | var sy = 0, ty = 0; 264 | node.sourceLinks.forEach(function(link) { 265 | link.sy = sy; 266 | sy += link.dy; 267 | }); 268 | node.targetLinks.forEach(function(link) { 269 | link.ty = ty; 270 | ty += link.dy; 271 | }); 272 | }); 273 | 274 | function ascendingSourceDepth(a, b) { 275 | return a.source.y - b.source.y; 276 | } 277 | 278 | function ascendingTargetDepth(a, b) { 279 | return a.target.y - b.target.y; 280 | } 281 | } 282 | 283 | function center(node) { 284 | return node.y + node.dy / 2; 285 | } 286 | 287 | function value(link) { 288 | return link.value; 289 | } 290 | 291 | return sankey; 292 | }; 293 | -------------------------------------------------------------------------------- /agora/static/agora/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("http://chozabu.net/autopush/cloud_background.png") no-repeat center center fixed; 3 | background-size: cover; 4 | font-family: verdana; 5 | } 6 | 7 | h1 { 8 | font-family: 'Roboto' light; 9 | padding-top: 20px; 10 | text-align: center; 11 | font-size: 56px; 12 | } 13 | 14 | h2 { 15 | font-family: 'Roboto'; 16 | padding-top: 0px; 17 | text-align: center; 18 | font-size: 36px; 19 | } 20 | 21 | h3 { 22 | font-family: 'Roboto'; 23 | padding: 10px; 24 | text-align: center; 25 | font-size: 20px; 26 | color: rgba(042, 036, 004, 0.98); 27 | } 28 | 29 | p { 30 | margin: 10px 42px 10px; 31 | font-family: 'Roboto' light; 32 | } 33 | 34 | #mainContentPanel+ svg { 35 | 10px: inherit;display: block;margin: auto;} 36 | hr { 37 | margin: 20px; 38 | border: none; 39 | border-bottom: thin solid rgba(255, 255, 255, .1); 40 | } 41 | div.title { 42 | font-size: 2em; 43 | } 44 | h1 span { 45 | font-weight: 300; 46 | color: #Fd4; 47 | } 48 | .userimage{ 49 | float:left; 50 | margin: 2px; 51 | } 52 | .postminicontent { 53 | display:inline-block; 54 | text-align: left; 55 | } 56 | .topicminititle, .groupminititle { 57 | font-size: 150%; 58 | background-color: rgba(222, 226, 234, 0.48); 59 | display: inline-block; 60 | width: 100%; 61 | margin: .1em; 62 | margin-left: -.45em; 63 | /* margin-right: -.8em; */ 64 | padding: .3em; 65 | border-radius: .1em; 66 | } 67 | 68 | .align-mid { 69 | text-align: center; 70 | } 71 | 72 | .notificationbox{ 73 | margin: 5px; 74 | } 75 | 76 | #topicslist > li > .topicminititle { 77 | background-color: rgba(226, 96, 0, 0.23); 78 | } 79 | 80 | span.topicsubsspan { 81 | /* height: 30px; */ 82 | /* width: 60px; */ 83 | /* line-height: 60px; */ 84 | -moz-border-radius: 30px;/* or 50% */ 85 | border-radius: 30px;/* or 50% */ 86 | background-color: rgba(58, 187, 99, 0.78); 87 | color: white; 88 | text-align: center; 89 | font-size: 1.3em; 90 | padding-left: .3em; 91 | padding-right: .3em; 92 | } 93 | 94 | #miniul:first-child { 95 | background-color: rgba(0, 255, 255, 0.48); 96 | } 97 | .topicmicrotitle { 98 | font-size: 150%; 99 | /* background-color: rgba(178, 196, 212, 0.31); */ 100 | display: inline-block; 101 | margin: .1em; 102 | padding: .2em; 103 | border-radius: .5em; 104 | text-align: center; 105 | } 106 | .topicmicroitem { 107 | background-color: rgba(213, 111, 236, 0.31); 108 | display: inline-block; 109 | margin: .1em; 110 | padding: .2em; 111 | border-radius: .5em; 112 | text-align: center; 113 | } 114 | .mincotopicholder { 115 | background-color: rgba(245, 242, 255, 0); 116 | margin: .1em; 117 | padding: .2em; 118 | /* border-radius: .7em; */ 119 | text-align: center; 120 | /* display: inline-block; */ 121 | } 122 | .postminititle { 123 | font-size: 150%; 124 | } 125 | .ilb { 126 | display: inline-block; 127 | vertical-align: text-top; 128 | border-radius: 4px; 129 | border-width: 1px; 130 | padding: 4px; 131 | margin-left: 2px; 132 | border: #bdb8b2 1px solid; 133 | text-align: center; 134 | margin-left: 0.4em; 135 | box-shadow: 0px 0px 50px rgba(29, 120, 144, 0.11); 136 | } 137 | .ilb h2 { 138 | background-color: transparent; 139 | box-shadow: none; 140 | padding: 2px; 141 | margin: 2px; 142 | } 143 | .ilb li { 144 | list-style-type: none; 145 | } 146 | .ilb li:nth-of-type(odd) { 147 | border: #bdb8b2 1px solid; 148 | margin-left: 0.4em; 149 | border-radius: 5px; 150 | background-color: #f3f3f3; 151 | } 152 | .ilb li:nth-of-type(even) { 153 | border: #f4eee7 1px solid; 154 | margin-left: 0.4em; 155 | border-radius: 5px; 156 | background-color: #e8e8e8; 157 | } 158 | #basic-post-info, 159 | #extra-post-info { 160 | padding-left: .5em; 161 | } 162 | #starscontainer { 163 | width: 100px; 164 | height: 20px; 165 | position: relative; 166 | display: inline-block; 167 | } 168 | #fullstars, 169 | #emptystars { 170 | width: 100px; 171 | height: 20px; 172 | position: absolute; 173 | top: 0; 174 | left: 0; 175 | } 176 | #emptystars { 177 | z-index: 10; 178 | background-image: url("/static/agora/img/emptystars.png"); 179 | } 180 | #fullstars { 181 | background-image: url("/static/agora/img/stars.png"); 182 | } 183 | ul { 184 | list-style-type: none; 185 | margin-top: 10px; 186 | } 187 | 188 | ul.miniul { 189 | margin-right: -.2%; 190 | /* margin-right: 10px; */ 191 | } 192 | .miniul li, 193 | .postpreview { 194 | padding: 9px; 195 | padding-right: 0px; 196 | /* margin-left: 2px; */ 197 | border-radius: 4px; 198 | /* border: #FFFFFF 1px solid; */ 199 | /* margin-left: 0.4em; */ 200 | box-shadow: 0px 0px 2px rgba(50, 50, 50, 0.22); 201 | /* margin-right: -.1px; */ 202 | } 203 | .postpreview { 204 | text-align: center; 205 | 206 | } 207 | #mainContentPanel { 208 | padding: 5px; 209 | border-radius: 10px; 210 | border: 1px solid rgb(189, 184, 178); 211 | margin-left: auto; 212 | box-shadow: -4px 4px 5px rgba(50, 50, 50, 0.1); 213 | margin-right: auto; 214 | width: 80%; 215 | min-width: 600px; 216 | background-color: rgba(255, 255, 255, 0.82); 217 | } 218 | .floatonright { 219 | padding: 5px; 220 | margin-left: 2px; 221 | border-radius: 4px; 222 | border: #bdb8b2 1px solid; 223 | margin-left: 0.4em; 224 | box-shadow: -4px 4px 5px rgba(50, 50, 50, 0.2); 225 | float: right; 226 | max-width: 70%; 227 | } 228 | h1, 229 | h2 { 230 | background-color: rgba(225, 230, 239, 0.43); 231 | color: #3B646B; 232 | padding: 15px 16%; 233 | border-radius: 2px; 234 | text-align: center; 235 | /* margin-left: -.2em; */ 236 | /* box-shadow: -4px 4px 5px rgba(50, 50, 50, 0.2); */ 237 | } 238 | 239 | h2 { 240 | font-size: 26px; 241 | text-align: center; 242 | /* color: aqua; */ 243 | } 244 | 245 | h2 a { 246 | color: #3B646B; 247 | } 248 | .tagspan { 249 | background-color: #e2fff6; 250 | color: #000000; 251 | padding: 5px 5px; 252 | text-decoration: none; 253 | border-radius: 5px; 254 | } 255 | ul#topic_path { 256 | margin-top: 7px; 257 | padding: 0; 258 | display: inline-block; 259 | } 260 | ul#topic_path li { 261 | display: inline; 262 | } 263 | /* 264 | ul#topic_path li:not(:last-child)::after { 265 | content: "⇒"; 266 | }*/ 267 | ul#topic_path li::after { 268 | content: "⇒"; 269 | } 270 | ul#topic_path li a { 271 | background-color: #ECF3EB; 272 | color: #000000; 273 | margin-top: -10px; 274 | padding: 10px 20px; 275 | text-decoration: none; 276 | border-radius: 5px; 277 | } 278 | ul#topic_path li a:hover { 279 | background-color: #caffca; 280 | } 281 | ul#post_path { 282 | padding: .2em; 283 | display: inline-block; 284 | } 285 | ul#post_path li { 286 | display: inline; 287 | } 288 | ul#post_path li::after { 289 | content: "▶"; 290 | } 291 | ul#post_path li a { 292 | background-color: #c9daff; 293 | color: #000000; 294 | padding: 5px 10px; 295 | margin: 1px 1px; 296 | text-decoration: none; 297 | border-radius: 5px; 298 | border-color: black; 299 | } 300 | ul#post_path li a:hover { 301 | background-color: #bfc7ff; 302 | } 303 | .mainContentPanel { 304 | margin-top: 2em padding: 1em; 305 | } 306 | a { 307 | color: #3E302E; 308 | text-shadow: 0 0 2px rgba(200, 200, 255, 128); 309 | font-family: 'Roboto'; 310 | } 311 | a:hover { 312 | color: #3783ff; 313 | } 314 | .tinyUserThumb { 315 | margin: 2px; 316 | width: 32px; 317 | float: left; 318 | } 319 | 320 | #post_middle{ 321 | } 322 | 323 | .votepics { 324 | width:intrinsic; /* For Safari, see https://developer.mozilla.org/en-US/docs/CSS/width */ 325 | width:-moz-fit-content; 326 | width:-webkit-fit-content; 327 | width:fit-content; 328 | margin:0 auto; 329 | overflow:hidden; /* Contain the floated li elements */ 330 | } 331 | .votepics svg { 332 | width: 50px; 333 | height: 50px; 334 | -webkit-transition: width .2s; /* Safari */ 335 | transition: width .2s; 336 | } 337 | .votepics svg:hover { 338 | -webkit-filter: drop-shadow( -0px -0px 5px #77F ); 339 | filter: drop-shadow( -0px -0px 5px #AAF ); /* Same syntax as box-shadow */ 340 | 341 | } 342 | .svgwrapper { 343 | width: 50px; 344 | height: 50px; 345 | position: relative; 346 | z-index: 100; 347 | } 348 | 349 | 350 | #svgr1 * { 351 | 352 | stroke: red !important; 353 | } 354 | #svgr2 * { 355 | 356 | stroke: #DC154C !important; 357 | } 358 | #svgr3 * { 359 | 360 | stroke: #B81ACC !important; 361 | } 362 | #svgr4 * { 363 | 364 | stroke: #1319E0 !important; 365 | } 366 | #svgr5 * { 367 | 368 | stroke: #328FC5 !important; 369 | } 370 | #svgr6 * { 371 | 372 | stroke: green !important; 373 | } 374 | #svgr7 * { 375 | 376 | stroke: #00D600 !important; 377 | } 378 | 379 | .voteslider{ 380 | width: 300px; 381 | position:relative; 382 | height:20px; 383 | /* border:1px solid #cccccc; */ 384 | width:90% !important; 385 | margin: auto; 386 | } 387 | 388 | .post-main { 389 | text-align: center; 390 | } 391 | .authorinfo { 392 | display:inline-block; 393 | } 394 | 395 | .popover{ 396 | max-width: 100%; /* Max Width of the popover (depending on the container!) */ 397 | } 398 | 399 | .filterouterbox { 400 | background-color: rgba(133, 255, 133, 0.12); 401 | border: 2px solid rgba(177, 255, 177, 0.22); 402 | border-radius: 10px; 403 | padding: 2px; 404 | margin: 2px; 405 | } 406 | .excludeouterbox { 407 | background-color: rgba(255, 133, 133, 0.12); 408 | border: 2px solid rgba(255, 177, 177, 0.22); 409 | border-radius: 10px; 410 | padding: 2px; 411 | margin: 2px; 412 | } -------------------------------------------------------------------------------- /agora/static/agora/js/showdown.js: -------------------------------------------------------------------------------- 1 | /* 2 | A A L Source code at: 3 | T C A 4 | T K B 5 | */ 6 | 7 | var Showdown={}; 8 | Showdown.converter=function(){ 9 | var _1; 10 | var _2; 11 | var _3; 12 | var _4=0; 13 | this.makeHtml=function(_5){ 14 | _1=new Array(); 15 | _2=new Array(); 16 | _3=new Array(); 17 | _5=_5.replace(/~/g,"~T"); 18 | _5=_5.replace(/\$/g,"~D"); 19 | _5=_5.replace(/\r\n/g,"\n"); 20 | _5=_5.replace(/\r/g,"\n"); 21 | _5="\n\n"+_5+"\n\n"; 22 | _5=_6(_5); 23 | _5=_5.replace(/^[ \t]+$/mg,""); 24 | _5=_7(_5); 25 | _5=_8(_5); 26 | _5=_9(_5); 27 | _5=_a(_5); 28 | _5=_5.replace(/~D/g,"$$"); 29 | _5=_5.replace(/~T/g,"~"); 30 | return _5; 31 | }; 32 | var _8=function(_b){ 33 | var _b=_b.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,function(_c,m1,m2,m3,m4){ 34 | m1=m1.toLowerCase(); 35 | _1[m1]=_11(m2); 36 | if(m3){ 37 | return m3+m4; 38 | }else{ 39 | if(m4){ 40 | _2[m1]=m4.replace(/"/g,"""); 41 | } 42 | } 43 | return ""; 44 | }); 45 | return _b; 46 | }; 47 | var _7=function(_12){ 48 | _12=_12.replace(/\n/g,"\n\n"); 49 | var _13="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del"; 50 | var _14="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math"; 51 | _12=_12.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,_15); 52 | _12=_12.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,_15); 53 | _12=_12.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,_15); 54 | _12=_12.replace(/(\n\n[ ]{0,3}[ \t]*(?=\n{2,}))/g,_15); 55 | _12=_12.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,_15); 56 | _12=_12.replace(/\n\n/g,"\n"); 57 | return _12; 58 | }; 59 | var _15=function(_16,m1){ 60 | var _18=m1; 61 | _18=_18.replace(/\n\n/g,"\n"); 62 | _18=_18.replace(/^\n/,""); 63 | _18=_18.replace(/\n+$/g,""); 64 | _18="\n\n~K"+(_3.push(_18)-1)+"K\n\n"; 65 | return _18; 66 | }; 67 | var _9=function(_19){ 68 | _19=_1a(_19); 69 | var key=_1c("
    "); 70 | _19=_19.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key); 71 | _19=_19.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key); 72 | _19=_19.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key); 73 | _19=_1d(_19); 74 | _19=_1e(_19); 75 | _19=_1f(_19); 76 | _19=_7(_19); 77 | _19=_20(_19); 78 | return _19; 79 | }; 80 | var _21=function(_22){ 81 | _22=_23(_22); 82 | _22=_24(_22); 83 | _22=_25(_22); 84 | _22=_26(_22); 85 | _22=_27(_22); 86 | _22=_28(_22); 87 | _22=_11(_22); 88 | _22=_29(_22); 89 | _22=_22.replace(/ +\n/g,"
    \n"); 90 | return _22; 91 | }; 92 | var _24=function(_2a){ 93 | var _2b=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi; 94 | _2a=_2a.replace(_2b,function(_2c){ 95 | var tag=_2c.replace(/(.)<\/?code>(?=.)/g,"$1`"); 96 | tag=_2e(tag,"\\`*_"); 97 | return tag; 98 | }); 99 | return _2a; 100 | }; 101 | var _27=function(_2f){ 102 | _2f=_2f.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,_30); 103 | _2f=_2f.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,_30); 104 | _2f=_2f.replace(/(\[([^\[\]]+)\])()()()()()/g,_30); 105 | return _2f; 106 | }; 107 | var _30=function(_31,m1,m2,m3,m4,m5,m6,m7){ 108 | if(m7==undefined){ 109 | m7=""; 110 | } 111 | var _39=m1; 112 | var _3a=m2; 113 | var _3b=m3.toLowerCase(); 114 | var url=m4; 115 | var _3d=m7; 116 | if(url==""){ 117 | if(_3b==""){ 118 | _3b=_3a.toLowerCase().replace(/ ?\n/g," "); 119 | } 120 | url="#"+_3b; 121 | if(_1[_3b]!=undefined){ 122 | url=_1[_3b]; 123 | if(_2[_3b]!=undefined){ 124 | _3d=_2[_3b]; 125 | } 126 | }else{ 127 | if(_39.search(/\(\s*\)$/m)>-1){ 128 | url=""; 129 | }else{ 130 | return _39; 131 | } 132 | } 133 | } 134 | url=_2e(url,"*_"); 135 | var _3e=""; 142 | return _3e; 143 | }; 144 | var _26=function(_3f){ 145 | _3f=_3f.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,_40); 146 | _3f=_3f.replace(/(!\[(.*?)\]\s?\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,_40); 147 | return _3f; 148 | }; 149 | var _40=function(_41,m1,m2,m3,m4,m5,m6,m7){ 150 | var _49=m1; 151 | var _4a=m2; 152 | var _4b=m3.toLowerCase(); 153 | var url=m4; 154 | var _4d=m7; 155 | if(!_4d){ 156 | _4d=""; 157 | } 158 | if(url==""){ 159 | if(_4b==""){ 160 | _4b=_4a.toLowerCase().replace(/ ?\n/g," "); 161 | } 162 | url="#"+_4b; 163 | if(_1[_4b]!=undefined){ 164 | url=_1[_4b]; 165 | if(_2[_4b]!=undefined){ 166 | _4d=_2[_4b]; 167 | } 168 | }else{ 169 | return _49; 170 | } 171 | } 172 | _4a=_4a.replace(/"/g,"""); 173 | url=_2e(url,"*_"); 174 | var _4e="\""+_4a+"\"";"+_21(m1)+""); 184 | }); 185 | _4f=_4f.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,function(_52,m1){ 186 | return _1c("

    "+_21(m1)+"

    "); 187 | }); 188 | _4f=_4f.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,function(_54,m1,m2){ 189 | var _57=m1.length; 190 | return _1c(""+_21(m2)+""); 191 | }); 192 | return _4f; 193 | }; 194 | var _58; 195 | var _1d=function(_59){ 196 | _59+="~0"; 197 | var _5a=/^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; 198 | if(_4){ 199 | _59=_59.replace(_5a,function(_5b,m1,m2){ 200 | var _5e=m1; 201 | var _5f=(m2.search(/[*+-]/g)>-1)?"ul":"ol"; 202 | _5e=_5e.replace(/\n{2,}/g,"\n\n\n"); 203 | var _60=_58(_5e); 204 | _60=_60.replace(/\s+$/,""); 205 | _60="<"+_5f+">"+_60+"\n"; 206 | return _60; 207 | }); 208 | }else{ 209 | _5a=/(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; 210 | _59=_59.replace(_5a,function(_61,m1,m2,m3){ 211 | var _65=m1; 212 | var _66=m2; 213 | var _67=(m3.search(/[*+-]/g)>-1)?"ul":"ol"; 214 | var _66=_66.replace(/\n{2,}/g,"\n\n\n"); 215 | var _68=_58(_66); 216 | _68=_65+"<"+_67+">\n"+_68+"\n"; 217 | return _68; 218 | }); 219 | } 220 | _59=_59.replace(/~0/,""); 221 | return _59; 222 | }; 223 | _58=function(_69){ 224 | _4++; 225 | _69=_69.replace(/\n{2,}$/,"\n"); 226 | _69+="~0"; 227 | _69=_69.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,function(_6a,m1,m2,m3,m4){ 228 | var _6f=m4; 229 | var _70=m1; 230 | var _71=m2; 231 | if(_70||(_6f.search(/\n{2,}/)>-1)){ 232 | _6f=_9(_72(_6f)); 233 | }else{ 234 | _6f=_1d(_72(_6f)); 235 | _6f=_6f.replace(/\n$/,""); 236 | _6f=_21(_6f); 237 | } 238 | return "
  • "+_6f+"
  • \n"; 239 | }); 240 | _69=_69.replace(/~0/g,""); 241 | _4--; 242 | return _69; 243 | }; 244 | var _1e=function(_73){ 245 | _73+="~0"; 246 | _73=_73.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,function(_74,m1,m2){ 247 | var _77=m1; 248 | var _78=m2; 249 | _77=_79(_72(_77)); 250 | _77=_6(_77); 251 | _77=_77.replace(/^\n+/g,""); 252 | _77=_77.replace(/\n+$/g,""); 253 | _77="
    "+_77+"\n
    "; 254 | return _1c(_77)+_78; 255 | }); 256 | _73=_73.replace(/~0/,""); 257 | return _73; 258 | }; 259 | var _1c=function(_7a){ 260 | _7a=_7a.replace(/(^\n+|\n+$)/g,""); 261 | return "\n\n~K"+(_3.push(_7a)-1)+"K\n\n"; 262 | }; 263 | var _23=function(_7b){ 264 | _7b=_7b.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(_7c,m1,m2,m3,m4){ 265 | var c=m3; 266 | c=c.replace(/^([ \t]*)/g,""); 267 | c=c.replace(/[ \t]*$/g,""); 268 | c=_79(c); 269 | return m1+""+c+""; 270 | }); 271 | return _7b; 272 | }; 273 | var _79=function(_82){ 274 | _82=_82.replace(/&/g,"&"); 275 | _82=_82.replace(//g,">"); 277 | _82=_2e(_82,"*_{}[]\\",false); 278 | return _82; 279 | }; 280 | var _29=function(_83){ 281 | _83=_83.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,"$2"); 282 | _83=_83.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,"$2"); 283 | return _83; 284 | }; 285 | var _1f=function(_84){ 286 | _84=_84.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,function(_85,m1){ 287 | var bq=m1; 288 | bq=bq.replace(/^[ \t]*>[ \t]?/gm,"~0"); 289 | bq=bq.replace(/~0/g,""); 290 | bq=bq.replace(/^[ \t]+$/gm,""); 291 | bq=_9(bq); 292 | bq=bq.replace(/(^|\n)/g,"$1 "); 293 | bq=bq.replace(/(\s*
    [^\r]+?<\/pre>)/gm,function(_88,m1){
    294 | var pre=m1;
    295 | pre=pre.replace(/^  /mg,"~0");
    296 | pre=pre.replace(/~0/g,"");
    297 | return pre;
    298 | });
    299 | return _1c("
    \n"+bq+"\n
    "); 300 | }); 301 | return _84; 302 | }; 303 | var _20=function(_8b){ 304 | _8b=_8b.replace(/^\n+/g,""); 305 | _8b=_8b.replace(/\n+$/g,""); 306 | var _8c=_8b.split(/\n{2,}/g); 307 | var _8d=new Array(); 308 | var end=_8c.length; 309 | for(var i=0;i=0){ 312 | _8d.push(str); 313 | }else{ 314 | if(str.search(/\S/)>=0){ 315 | str=_21(str); 316 | str=str.replace(/^([ \t]*)/g,"

    "); 317 | str+="

    "; 318 | _8d.push(str); 319 | } 320 | } 321 | } 322 | end=_8d.length; 323 | for(var i=0;i=0){ 325 | var _91=_3[RegExp.$1]; 326 | _91=_91.replace(/\$/g,"$$$$"); 327 | _8d[i]=_8d[i].replace(/~K\d+K/,_91); 328 | } 329 | } 330 | return _8d.join("\n\n"); 331 | }; 332 | var _11=function(_92){ 333 | _92=_92.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"); 334 | _92=_92.replace(/<(?![a-z\/?\$!])/gi,"<"); 335 | return _92; 336 | }; 337 | var _25=function(_93){ 338 | _93=_93.replace(/\\(\\)/g,_94); 339 | _93=_93.replace(/\\([`*_{}\[\]()>#+-.!])/g,_94); 340 | return _93; 341 | }; 342 | var _28=function(_95){ 343 | _95=_95.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"
    $1"); 344 | _95=_95.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,function(_96,m1){ 345 | return _98(_a(m1)); 346 | }); 347 | return _95; 348 | }; 349 | var _98=function(_99){ 350 | function char2hex(ch){ 351 | var _9b="0123456789ABCDEF"; 352 | var dec=ch.charCodeAt(0); 353 | return (_9b.charAt(dec>>4)+_9b.charAt(dec&15)); 354 | } 355 | var _9d=[function(ch){ 356 | return "&#"+ch.charCodeAt(0)+";"; 357 | },function(ch){ 358 | return "&#x"+char2hex(ch)+";"; 359 | },function(ch){ 360 | return ch; 361 | }]; 362 | _99="mailto:"+_99; 363 | _99=_99.replace(/./g,function(ch){ 364 | if(ch=="@"){ 365 | ch=_9d[Math.floor(Math.random()*2)](ch); 366 | }else{ 367 | if(ch!=":"){ 368 | var r=Math.random(); 369 | ch=(r>0.9?_9d[2](ch):r>0.45?_9d[1](ch):_9d[0](ch)); 370 | } 371 | } 372 | return ch; 373 | }); 374 | _99=""+_99+""; 375 | _99=_99.replace(/">.+:/g,"\">"); 376 | return _99; 377 | }; 378 | var _a=function(_a3){ 379 | _a3=_a3.replace(/~E(\d+)E/g,function(_a4,m1){ 380 | var _a6=parseInt(m1); 381 | return String.fromCharCode(_a6); 382 | }); 383 | return _a3; 384 | }; 385 | var _72=function(_a7){ 386 | _a7=_a7.replace(/^(\t|[ ]{1,4})/gm,"~0"); 387 | _a7=_a7.replace(/~0/g,""); 388 | return _a7; 389 | }; 390 | var _6=function(_a8){ 391 | _a8=_a8.replace(/\t(?=\t)/g," "); 392 | _a8=_a8.replace(/\t/g,"~A~B"); 393 | _a8=_a8.replace(/~B(.+?)~A/g,function(_a9,m1,m2){ 394 | var _ac=m1; 395 | var _ad=4-_ac.length%4; 396 | for(var i=0;i<_ad;i++){ 397 | _ac+=" "; 398 | } 399 | return _ac; 400 | }); 401 | _a8=_a8.replace(/~A/g," "); 402 | _a8=_a8.replace(/~B/g,""); 403 | return _a8; 404 | }; 405 | var _2e=function(_af,_b0,_b1){ 406 | var _b2="(["+_b0.replace(/([\[\]\\])/g,"\\$1")+"])"; 407 | if(_b1){ 408 | _b2="\\\\"+_b2; 409 | } 410 | var _b3=new RegExp(_b2,"g"); 411 | _af=_af.replace(_b3,_94); 412 | return _af; 413 | }; 414 | var _94=function(_b4,m1){ 415 | var _b6=m1.charCodeAt(0); 416 | return "~E"+_b6+"E"; 417 | }; 418 | }; 419 | if(typeof exports!='undefined')exports.Showdown=Showdown; --------------------------------------------------------------------------------