<commit_before>#encoding: utf-8
import urllib, urllib2, difflib, logging, datetime, os
from time import mktime
from django.utils.translation import ugettext_lazy
from django.utils.translation import ugettext as _
from django.utils import simplejson as json
from django.views.generic.list_detail import object_list, object_detail
from django.conf import settings
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseNotAllowed, HttpResponseBadRequest
from django.db.models import Count, Q
from django.db import IntegrityError
from django.shortcuts import render_to_response, get_object_or_404
from django.template import loader, RequestContext
from django.core.urlresolvers import reverse
from django.core.exceptions import ObjectDoesNotExist
from django.utils.decorators import method_decorator
from django.core.files.storage import default_storage

from tagging.models import Tag, TaggedItem
from tagging.views import tagged_object_list
from tagging.utils import get_tag
import tagging
import voting
from actstream import action
from knesset.utils import limit_by_request, notify_responsible_adult
from mks.models import Member
from tagvotes.models import TagVote
from hashnav import DetailView, ListView
from agendas.models import Agenda,UserSuggestedVote
from auxiliary.views import CsvView
from forms import VoteSelectForm, BillSelectForm, BudgetEstimateForm
from models import *

logger = logging.getLogger("open-knesset.laws.views")

def bill_tags_cloud(request, min_posts_count=1):
    member = None
    if 'member' in request.GET:
        member = get_object_or_404(Member, pk=request.GET['member'])
        tags_cloud = Tag.objects.usage_for_queryset(member.bills.all(),counts=True)
        tags_cloud = tagging.utils.calculate_cloud(tags_cloud)
        title = _('Bills by %(member)s by tag') % {'member':member.name}
    else:
        title = _('Bills by tag')
        tags_cloud = Tag.objects.cloud_for_model(Bill)
    return render_to_response("laws/bill_tags_cloud.html",
        {"tags_cloud": tags_cloud, "title":title, "member":member}, context_instance=RequestContext(request))

def bill_tag(request, tag):
    tag_instance = get_tag(tag)
    if tag_instance is None:
        raise Http404(_('No Tag found matching "%s".') % tag)

    extra_context = {'tag':tag_instance}
    extra_context['tag_url'] = reverse('bill-tag',args=[tag_instance])
    if 'member' in request.GET:
        try:
            member_id = int(request.GET['member'])
        except ValueError:
            raise Http404(_('No Member found matching "%s".') % request.GET['member'])
        extra_context['member'] = get_object_or_404(Member, pk=request.GET['member'])
        extra_context['member_url'] = reverse('member-detail',args=[extra_context['member'].id])
        extra_context['title'] = _('Bills tagged %(tag)s by %(member)s') % {'tag': tag, 'member':extra_context['member'].name}
        qs = extra_context['member'].bills.all()
    else: # only tag is given
        extra_context['title'] = _('Bills tagged %(tag)s') % {'tag': tag}
        qs = Bill

    queryset = TaggedItem.objects.get_by_model(qs, tag_instance)
    bill_proposers = [b.proposers.all() for b in TaggedItem.objects.get_by_model(Bill, tag_instance)]
    d = {}
    for bill in bill_proposers:
        for p in bill:
            d[p] = d.get(p,0)+1
    # now d is a dict: MK -> number of proposals in this tag
    mks = d.keys()
    for mk in mks:
        mk.count = d[mk]
    mks = tagging.utils.calculate_cloud(mks)
    extra_context['members'] = mks
    return object_list(request, queryset,
    #return tagged_object_list(request, queryset_or_model=qs, tag=tag,
        template_name='laws/bill_list_by_tag.html', extra_context=extra_context)

def bill_auto_complete(request):
    if request.method != 'GET':
        raise Http404

    if not 'query' in request.GET:
        raise Http404

    options = Bill.objects.filter(full_title__icontains=request.GET['query'])[:30]
    data = []
    suggestions = []
    for i in options:
        data.append(i.id)
        suggestions.append(i.full_title)

    result = { 'query': request.GET['query'], 'suggestions':suggestions, 'data':data }

    return HttpResponse(json.dumps(result), mimetype='application/json')

def vote_tags_cloud(request, min_posts_count=1):
    member = None
    if 'member' in request.GET:
        member = get_object_or_404(Member, pk=request.GET['member'])
        tags_cloud = Tag.objects.usage_for_queryset(member.votes.all(),counts=True)
        tags_cloud = tagging.utils.calculate_cloud(tags_cloud)
        title = _('Votes by %(member)s by tag') % {'member':member.name}
    else:
        title = _('Votes by tag')
        tags_cloud = Tag.objects.cloud_for_model(Vote)
    return render_to_response("laws/vote_tags_cloud.html",
        {"tags_cloud": tags_cloud, "title":title, "member":member}, context_instance=RequestContext(request))

def vote_tag(request, tag):
    tag_instance = get_tag(tag)
    if tag_instance is None:
        raise Http404(_('No Tag found matching "%s".') % tag)

    extra_context = {'tag':tag_instance}
    extra_context['tag_url'] = reverse('vote-tag',args=[tag_instance])
    if 'member' in request.GET:
        extra_context['member'] = get_object_or_404(Member, pk=request.GET['member'])
        extra_context['member_url'] = reverse('member-detail',args=[extra_context['member'].id])
        extra_context['title'] = ugettext_lazy('Votes tagged %(tag)s by %(member)s') % {'tag': tag, 'member':extra_context['member'].name}
        qs = extra_context['member'].votes.all()
    else: # only tag is given
        extra_context['title'] = ugettext_lazy('Votes tagged %(tag)s') % {'tag': tag}
        qs = Vote

    queryset = TaggedItem.objects.get_by_model(qs, tag_instance)
    vote_attendence = [v.votes.all() for v in TaggedItem.objects.get_by_model(Vote, tag_instance)]
    d = {}
    for vote in vote_attendence:
        for v in vote:
            d[v] = d.get(v,0)+1
    # now d is a dict: MK -> number of votes in this tag
    mks = d.keys()
    if mks:
        for mk in mks:
            mk.count = d[mk]
        average = float(sum([mk.count for mk in mks]))/len(mks)
        mks = [mk for mk in mks if mk.count>=average]
        mks = tagging.utils.calculate_cloud(mks)
        extra_context['members'] = mks
    if request.user.is_authenticated():
        extra_context['watched_members'] = \
            request.user.get_profile().members
    else:
        extra_context['watched_members'] = False

    return object_list(request, queryset,
    #return tagged_object_list(request, queryset_or_model=qs, tag=tag,
        template_name='laws/vote_list_by_tag.html', extra_context=extra_context)



def votes_to_bar_widths(v_count, v_for, v_against):
    """ a helper function to compute presentation widths for user votes bars.
        v_count - the total votes count
        v_for - votes for
        v_against - votes against
        returns: a tuple (width of for bar, width of against bar) in percent

    """
    m = 12 # minimal width for small bar
    T = 96 # total width for the 2 bars
    if v_count: # use votes/count, with margin m
        width_for = min(max(int(float(v_for) / v_count * T), m), 100-m)
    else: # 0 votes, use 50:50 width
        width_for = round(T/2)
    width_against = T-width_for
    return (width_for, width_against)

class BillCsvView(CsvView):
    model = Bill
    filename = 'bills.csv'
    list_display = (('full_title', _('Full Title')),
                    ('popular_name', _('Popular Name')),
                    ('get_stage_display', _('Stage')),
                    ('stage_date', _('Stage Date')),
                    ('pre_votes', _('Pre-Votes')),
                    ('first_committee_meetings', _('First Committee Meetings')),
                    ('first_vote', _('First Vote')),
                    ('second_committee_meetings', _('Second Committee Meetings')),
                    ('approval_vote', _('Approval Vote')),
                    ('proposers', _('Proposers')),
                    ('joiners', _('Joiners')))

    def community_meeting_gen(self, obj, attr):
        '''<commit_msg>significantly reduce number of db queries in bill csv export<commit_after>#encoding: utf-8
import urllib, urllib2, difflib, logging, datetime, os
from time import mktime
from django.utils.translation import ugettext_lazy
from django.utils.translation import ugettext as _
from django.utils import simplejson as json
from django.views.generic.list_detail import object_list, object_detail
from django.conf import settings
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseNotAllowed, HttpResponseBadRequest
from django.db.models import Count, Q
from django.db import IntegrityError
from django.shortcuts import render_to_response, get_object_or_404
from django.template import loader, RequestContext
from django.core.urlresolvers import reverse
from django.core.exceptions import ObjectDoesNotExist
from django.utils.decorators import method_decorator
from django.core.files.storage import default_storage

from tagging.models import Tag, TaggedItem
from tagging.views import tagged_object_list
from tagging.utils import get_tag
import tagging
import voting
from actstream import action
from knesset.utils import limit_by_request, notify_responsible_adult
from mks.models import Member
from tagvotes.models import TagVote
from hashnav import DetailView, ListView
from agendas.models import Agenda,UserSuggestedVote
from auxiliary.views import CsvView
from forms import VoteSelectForm, BillSelectForm, BudgetEstimateForm
from models import *

logger = logging.getLogger("open-knesset.laws.views")

def bill_tags_cloud(request, min_posts_count=1):
    member = None
    if 'member' in request.GET:
        member = get_object_or_404(Member, pk=request.GET['member'])
        tags_cloud = Tag.objects.usage_for_queryset(member.bills.all(),counts=True)
        tags_cloud = tagging.utils.calculate_cloud(tags_cloud)
        title = _('Bills by %(member)s by tag') % {'member':member.name}
    else:
        title = _('Bills by tag')
        tags_cloud = Tag.objects.cloud_for_model(Bill)
    return render_to_response("laws/bill_tags_cloud.html",
        {"tags_cloud": tags_cloud, "title":title, "member":member}, context_instance=RequestContext(request))

def bill_tag(request, tag):
    tag_instance = get_tag(tag)
    if tag_instance is None:
        raise Http404(_('No Tag found matching "%s".') % tag)

    extra_context = {'tag':tag_instance}
    extra_context['tag_url'] = reverse('bill-tag',args=[tag_instance])
    if 'member' in request.GET:
        try:
            member_id = int(request.GET['member'])
        except ValueError:
            raise Http404(_('No Member found matching "%s".') % request.GET['member'])
        extra_context['member'] = get_object_or_404(Member, pk=request.GET['member'])
        extra_context['member_url'] = reverse('member-detail',args=[extra_context['member'].id])
        extra_context['title'] = _('Bills tagged %(tag)s by %(member)s') % {'tag': tag, 'member':extra_context['member'].name}
        qs = extra_context['member'].bills.all()
    else: # only tag is given
        extra_context['title'] = _('Bills tagged %(tag)s') % {'tag': tag}
        qs = Bill

    queryset = TaggedItem.objects.get_by_model(qs, tag_instance)
    bill_proposers = [b.proposers.all() for b in TaggedItem.objects.get_by_model(Bill, tag_instance)]
    d = {}
    for bill in bill_proposers:
        for p in bill:
            d[p] = d.get(p,0)+1
    # now d is a dict: MK -> number of proposals in this tag
    mks = d.keys()
    for mk in mks:
        mk.count = d[mk]
    mks = tagging.utils.calculate_cloud(mks)
    extra_context['members'] = mks
    return object_list(request, queryset,
    #return tagged_object_list(request, queryset_or_model=qs, tag=tag,
        template_name='laws/bill_list_by_tag.html', extra_context=extra_context)

def bill_auto_complete(request):
    if request.method != 'GET':
        raise Http404

    if not 'query' in request.GET:
        raise Http404

    options = Bill.objects.filter(full_title__icontains=request.GET['query'])[:30]
    data = []
    suggestions = []
    for i in options:
        data.append(i.id)
        suggestions.append(i.full_title)

    result = { 'query': request.GET['query'], 'suggestions':suggestions, 'data':data }

    return HttpResponse(json.dumps(result), mimetype='application/json')

def vote_tags_cloud(request, min_posts_count=1):
    member = None
    if 'member' in request.GET:
        member = get_object_or_404(Member, pk=request.GET['member'])
        tags_cloud = Tag.objects.usage_for_queryset(member.votes.all(),counts=True)
        tags_cloud = tagging.utils.calculate_cloud(tags_cloud)
        title = _('Votes by %(member)s by tag') % {'member':member.name}
    else:
        title = _('Votes by tag')
        tags_cloud = Tag.objects.cloud_for_model(Vote)
    return render_to_response("laws/vote_tags_cloud.html",
        {"tags_cloud": tags_cloud, "title":title, "member":member}, context_instance=RequestContext(request))

def vote_tag(request, tag):
    tag_instance = get_tag(tag)
    if tag_instance is None:
        raise Http404(_('No Tag found matching "%s".') % tag)

    extra_context = {'tag':tag_instance}
    extra_context['tag_url'] = reverse('vote-tag',args=[tag_instance])
    if 'member' in request.GET:
        extra_context['member'] = get_object_or_404(Member, pk=request.GET['member'])
        extra_context['member_url'] = reverse('member-detail',args=[extra_context['member'].id])
        extra_context['title'] = ugettext_lazy('Votes tagged %(tag)s by %(member)s') % {'tag': tag, 'member':extra_context['member'].name}
        qs = extra_context['member'].votes.all()
    else: # only tag is given
        extra_context['title'] = ugettext_lazy('Votes tagged %(tag)s') % {'tag': tag}
        qs = Vote

    queryset = TaggedItem.objects.get_by_model(qs, tag_instance)
    vote_attendence = [v.votes.all() for v in TaggedItem.objects.get_by_model(Vote, tag_instance)]
    d = {}
    for vote in vote_attendence:
        for v in vote:
            d[v] = d.get(v,0)+1
    # now d is a dict: MK -> number of votes in this tag
    mks = d.keys()
    if mks:
        for mk in mks:
            mk.count = d[mk]
        average = float(sum([mk.count for mk in mks]))/len(mks)
        mks = [mk for mk in mks if mk.count>=average]
        mks = tagging.utils.calculate_cloud(mks)
        extra_context['members'] = mks
    if request.user.is_authenticated():
        extra_context['watched_members'] = \
            request.user.get_profile().members
    else:
        extra_context['watched_members'] = False

    return object_list(request, queryset,
    #return tagged_object_list(request, queryset_or_model=qs, tag=tag,
        template_name='laws/vote_list_by_tag.html', extra_context=extra_context)



def votes_to_bar_widths(v_count, v_for, v_against):
    """ a helper function to compute presentation widths for user votes bars.
        v_count - the total votes count
        v_for - votes for
        v_against - votes against
        returns: a tuple (width of for bar, width of against bar) in percent

    """
    m = 12 # minimal width for small bar
    T = 96 # total width for the 2 bars
    if v_count: # use votes/count, with margin m
        width_for = min(max(int(float(v_for) / v_count * T), m), 100-m)
    else: # 0 votes, use 50:50 width
        width_for = round(T/2)
    width_against = T-width_for
    return (width_for, width_against)

class BillCsvView(CsvView):
    model = Bill
    filename = 'bills.csv'
    list_display = (('full_title', _('Full Title')),
                    ('popular_name', _('Popular Name')),
                    ('get_stage_display', _('Stage')),
                    ('stage_date', _('Stage Date')),
                    ('pre_votes', _('Pre-Votes')),
                    ('first_committee_meetings', _('First Committee Meetings')),
                    ('first_vote', _('First Vote')),
                    ('second_committee_meetings', _('Second Committee Meetings')),
                    ('approval_vote', _('Approval Vote')),
                    ('proposers', _('Proposers')),
                    ('joiners', _('Joiners')))

    def get_queryset(self, **kwargs):
        try:
            return self.model.objects.select_related('law',
                                                     'first_vote',
                                                     'approval_vote')\
                                     .prefetch_related('joiners',
                                                       'proposers',
                                                       'pre_votes',
                                                       'first_committee_meetings',
                                                       'second_committee_meetings')
        except DatabaseError: # sqlite can't prefetch this query, because it has
                              # too many objects
            return self.model.objects.all()

    def community_meeting_gen(self, obj, attr):
        '''
{'fraction_non_alphanumeric': 0.11536697247706422, 'fraction_numerical': 0.006536697247706422, 'mean_word_length': 3.182494004796163, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2521841', 'n_tokens_mistral': 5456, 'n_tokens_neox': 5232, 'n_words': 1285}