diff --git a/gov_track_hk_web/api/models.py b/gov_track_hk_web/api/models.py index 0cf077a..86db8a8 100644 --- a/gov_track_hk_web/api/models.py +++ b/gov_track_hk_web/api/models.py @@ -1,5 +1,5 @@ from django.db import models -from datetime import datetime + class Consultation(models.Model): lang = models.CharField(max_length=128) @@ -7,9 +7,9 @@ class Consultation(models.Model): link = models.CharField(max_length=1024) key = models.CharField(max_length=128) title = models.CharField(max_length=1024) + class Meta: unique_together = ('lang', 'key') + def __unicode__(self): return self.link + "-" + self.title.encode("utf-8") + "-" + self.lang - - diff --git a/gov_track_hk_web/api/urls.py b/gov_track_hk_web/api/urls.py index 573f083..3cb4f01 100644 --- a/gov_track_hk_web/api/urls.py +++ b/gov_track_hk_web/api/urls.py @@ -1,32 +1,77 @@ -from django.conf.urls import url, include +from django.conf.urls import include, url from rest_framework import routers + from api import views + router = routers.DefaultRouter() -router.register(r'latest_bills', views.LatestBillsViewSet, base_name='latest_bills') -router.register(r'latest_votes', views.LatestVotesViewSet, base_name='latest_votes') -router.register(r'votes_search/(?P.*)', views.VotesSearchViewSet, base_name='votes_search') -router.register(r'parties', views.PartiesViewSet) -router.register(r'meetings', views.MeetingsViewSet, base_name='meetings') -router.register(r'meetings/(?P[0-9]+)', views.MeetingsViewSet, base_name='meetings') -router.register(r'questions', views.LatestQuestionsViewSet, base_name='questions') -router.register(r'questions/(?P\w*)', views.LatestQuestionsViewSet, base_name='questions') -router.register(r'questions/(?P\w*)/(?P[0-9]+)', views.LatestQuestionsViewSet, base_name='questions') -router.register(r'most_present', views.MostPresentIndividualsViewSet, base_name='most_present') -router.register(r'most_absent', views.MostAbsentIndividualsViewSet, base_name='most_absent') -router.register(r'most_speech', views.MostSpeechIndividualsViewSet, base_name='most_speech') -router.register(r'subscribe', views.SubscribeViewSet, base_name='subscribe') -router.register(r'consultations', views.ConsultationsViewSet, base_name='consultations') -router.register(r'weather', views.WeatherViewSet, base_name='weather') -router.register(r'party/(?P.+)', views.PartyDetailViewSet, base_name='party') -router.register(r'bills', views.AllBillsViewSet, base_name='bills') -router.register(r'news', views.NewsViewSet, base_name='news') -router.register(r'bills/(?P\w*)', views.AllBillsViewSet, base_name='bills') -router.register(r'bills/(?P\w*)/(?P[0-9]+)', views.AllBillsViewSet, base_name='bills') -router.register(r'important_motion', views.ImportantMotionViewSet, base_name='important_motion') -router.register(r'speeches/(?P\w*)', views.MeetingSpeechSearchViewSet, base_name='speeches') -router.register(r'speeches', views.MeetingSpeechSearchViewSet, base_name='speeches') +router.register(r'latest_bills', + views.LatestBillsViewSet, + base_name='latest_bills') +router.register(r'latest_votes', + views.LatestVotesViewSet, + base_name='latest_votes') +router.register(r'votes_search/(?P.*)', + views.VotesSearchViewSet, + base_name='votes_search') +router.register(r'parties', + views.PartiesViewSet) +router.register(r'meetings', + views.MeetingsViewSet, + base_name='meetings') +router.register(r'meetings/(?P[0-9]+)', + views.MeetingsViewSet, + base_name='meetings') +router.register(r'questions', + views.LatestQuestionsViewSet, + base_name='questions') +router.register(r'questions/(?P\w*)', + views.LatestQuestionsViewSet, + base_name='questions') +router.register(r'questions/(?P\w*)/(?P[0-9]+)', + views.LatestQuestionsViewSet, + base_name='questions') +router.register(r'most_present', + views.MostPresentIndividualsViewSet, + base_name='most_present') +router.register(r'most_absent', + views.MostAbsentIndividualsViewSet, + base_name='most_absent') +router.register(r'most_speech', + views.MostSpeechIndividualsViewSet, + base_name='most_speech') +router.register(r'subscribe', + views.SubscribeViewSet, + base_name='subscribe') +router.register(r'consultations', + views.ConsultationsViewSet, + base_name='consultations') +router.register(r'weather', + views.WeatherViewSet, + base_name='weather') +router.register(r'party/(?P.+)', + views.PartyDetailViewSet, + base_name='party') +router.register(r'bills', + views.AllBillsViewSet, + base_name='bills') +router.register(r'news', + views.NewsViewSet, + base_name='news') +router.register(r'bills/(?P\w*)', + views.AllBillsViewSet, + base_name='bills') +router.register(r'bills/(?P\w*)/(?P[0-9]+)', + views.AllBillsViewSet, + base_name='bills') +router.register(r'important_motion', + views.ImportantMotionViewSet, + base_name='important_motion') +router.register(r'speeches/(?P\w*)', + views.MeetingSpeechSearchViewSet, + base_name='speeches') +router.register(r'speeches', + views.MeetingSpeechSearchViewSet, + base_name='speeches') urlpatterns = [ url(r'', include(router.urls)) ] - - diff --git a/gov_track_hk_web/api/views.py b/gov_track_hk_web/api/views.py index 096fa37..4f7ba68 100644 --- a/gov_track_hk_web/api/views.py +++ b/gov_track_hk_web/api/views.py @@ -1,22 +1,24 @@ # -*- coding: utf-8 -*- -from django.db import IntegrityError -from django.db.models import Q -from django.core.cache import cache -from rest_framework import viewsets -from django.db.models import Count -from legco.models import Vote, Motion, Party, Individual, IndividualVote, VoteSummary, Bill, Question, MeetingHansard, MeetingSpeech, ImportantMotion, ImportantMotion -from rest_framework import serializers -from rest_framework.response import Response -from rest_framework.decorators import detail_route, list_route -from datetime import datetime, timedelta, date -from subscriber.models import Subscriber, News +import re +from datetime import date, datetime, timedelta from hashlib import md5 + import requests +from django.core.cache import cache +from django.db import IntegrityError +from django.db.models import Count, Q from lxml import etree, html -import re -from rest_framework.authentication import SessionAuthentication, BasicAuthentication -from api.models import Consultation +from rest_framework import serializers, viewsets +from rest_framework.authentication import (BasicAuthentication, + SessionAuthentication) +from rest_framework.decorators import detail_route, list_route +from rest_framework.response import Response +from api.models import Consultation +from legco.models import (Bill, ImportantMotion, Individual, IndividualVote, + MeetingHansard, MeetingSpeech, Motion, Party, + Question, Vote, VoteSummary) +from subscriber.models import News, Subscriber class CsrfExemptSessionAuthentication(SessionAuthentication): diff --git a/gov_track_hk_web/district/admin.py b/gov_track_hk_web/district/admin.py index 8c38f3f..e69de29 100644 --- a/gov_track_hk_web/district/admin.py +++ b/gov_track_hk_web/district/admin.py @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/gov_track_hk_web/district/models.py b/gov_track_hk_web/district/models.py index bd4b2ab..e69de29 100644 --- a/gov_track_hk_web/district/models.py +++ b/gov_track_hk_web/district/models.py @@ -1,5 +0,0 @@ -from __future__ import unicode_literals - -from django.db import models - -# Create your models here. diff --git a/gov_track_hk_web/district/tests.py b/gov_track_hk_web/district/tests.py index 7ce503c..e69de29 100644 --- a/gov_track_hk_web/district/tests.py +++ b/gov_track_hk_web/district/tests.py @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/gov_track_hk_web/district/urls.py b/gov_track_hk_web/district/urls.py index 56fb307..edf6d42 100644 --- a/gov_track_hk_web/district/urls.py +++ b/gov_track_hk_web/district/urls.py @@ -1,5 +1,7 @@ -from django.conf.urls import url, include -from district.views import * +from django.conf.urls import url + +from district.views import index_view + urlpatterns = [ url(r'^$', index_view) ] diff --git a/gov_track_hk_web/district/views.py b/gov_track_hk_web/district/views.py index d0a0df1..567abdd 100644 --- a/gov_track_hk_web/district/views.py +++ b/gov_track_hk_web/district/views.py @@ -1,5 +1,7 @@ from django.shortcuts import render -from django.db.models import Count -def index_view(request): - return render(request, 'district/index.html', {'nbar': 'home', 'tbar':'dc'}) + +def index_view(request): + return render(request, + 'district/index.html', + {'nbar': 'home', 'tbar': 'dc'}) diff --git a/gov_track_hk_web/gov_track_hk_web/urls.py b/gov_track_hk_web/gov_track_hk_web/urls.py index 430a67a..e606d07 100644 --- a/gov_track_hk_web/gov_track_hk_web/urls.py +++ b/gov_track_hk_web/gov_track_hk_web/urls.py @@ -13,9 +13,11 @@ 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.conf.urls import url, include +from django.conf.urls import include, url from django.contrib import admin + from gov_track_hk_web import views + urlpatterns = [ url(r'^$', views.index_view), url(r'^projects/', views.other_projects_view), diff --git a/gov_track_hk_web/gov_track_hk_web/views.py b/gov_track_hk_web/gov_track_hk_web/views.py index 59f0672..0fed3eb 100644 --- a/gov_track_hk_web/gov_track_hk_web/views.py +++ b/gov_track_hk_web/gov_track_hk_web/views.py @@ -1,4 +1,5 @@ from django.shortcuts import render + # Create your views here. @@ -6,6 +7,7 @@ def index_view(request): return render(request, 'index.html', {'tbar': 'home', 'nbar':'home'}) def other_projects_view(request): - return render(request, 'other_projects.html', {'tbar': 'home', 'nbar':'projects'}) - - + return render(request, + 'other_projects.html', + {'tbar': 'home', 'nbar':'projects'} + ) diff --git a/gov_track_hk_web/legco/admin.py b/gov_track_hk_web/legco/admin.py index 7a8a797..e61e852 100644 --- a/gov_track_hk_web/legco/admin.py +++ b/gov_track_hk_web/legco/admin.py @@ -1,11 +1,15 @@ -from django.contrib import admin from django import forms +from django.contrib import admin from django.db import models from django.utils.html import mark_safe -from legco.models import Party, Individual, Council, Constituency, Meeting, Motion, VoteSummary, IndividualVote, Vote, CouncilMember, CouncilMembershipType -from legco.models import Bill, BillCommittee, BillThirdReading, BillFirstReading, BillSecondReading -from legco.models import MeetingSpeech, MeetingHansard -from legco.models import Question + +from legco.models import (Bill, BillCommittee, BillFirstReading, + BillSecondReading, BillThirdReading, Constituency, + Council, CouncilMember, CouncilMembershipType, + Individual, IndividualVote, Meeting, MeetingHansard, + MeetingSpeech, Motion, Party, Question, Vote, + VoteSummary) + class CouncilAdmin(admin.ModelAdmin): formfield_overrides = { @@ -43,4 +47,3 @@ class CouncilMemberAdmin(admin.ModelAdmin): admin.site.register(MeetingHansard) admin.site.register(CouncilMember, CouncilMemberAdmin) admin.site.register(CouncilMembershipType) - diff --git a/gov_track_hk_web/legco/bill_model.py b/gov_track_hk_web/legco/bill_model.py index d456dcb..131352d 100644 --- a/gov_track_hk_web/legco/bill_model.py +++ b/gov_track_hk_web/legco/bill_model.py @@ -1,7 +1,10 @@ -from django.db import models from datetime import datetime + from dirtyfields import DirtyFieldsMixin +from django.db import models + from .common_models import * + # class BillThirdReading(DirtyFieldsMixin, models.Model): diff --git a/gov_track_hk_web/legco/common_models.py b/gov_track_hk_web/legco/common_models.py index 8ba5db3..6960563 100644 --- a/gov_track_hk_web/legco/common_models.py +++ b/gov_track_hk_web/legco/common_models.py @@ -1,6 +1,8 @@ -from django.db import models from datetime import datetime +from django.db import models + + class Keyword(models.Model): keyword = models.CharField(max_length=128, unique=True) def __unicode__(self): @@ -21,5 +23,3 @@ class Individual(models.Model): image = models.CharField(max_length=512, blank=True, null=True, default=None) def __unicode__(self): return self.name_en + "-" + self.name_ch - - diff --git a/gov_track_hk_web/legco/models.py b/gov_track_hk_web/legco/models.py index 128d159..fda663c 100644 --- a/gov_track_hk_web/legco/models.py +++ b/gov_track_hk_web/legco/models.py @@ -1,7 +1,10 @@ -from django.db import models from datetime import datetime + +from django.db import models + from .bill_model import * from .common_models import * + # Create your models here. class Motion(models.Model): diff --git a/gov_track_hk_web/legco/templatetags/legco_extras.py b/gov_track_hk_web/legco/templatetags/legco_extras.py index d0af49e..e872d47 100644 --- a/gov_track_hk_web/legco/templatetags/legco_extras.py +++ b/gov_track_hk_web/legco/templatetags/legco_extras.py @@ -1,16 +1,17 @@ # -*- coding: utf-8 -* from django import template -from django.template.defaultfilters import stringfilter -from datetime import datetime, date -from legco.models import * -register = template.Library() import random +from datetime import datetime +register = template.Library() + + @register.filter def parse_date_chinese(d): if d is datetime and d.replace(tzinfo=None) == datetime.min: return "未知" return "%d年%d月%d日" % (d.year, d.month, d.day) + @register.filter def article_source_chinese(s): if s == "mingpao": @@ -19,20 +20,33 @@ def article_source_chinese(s): return "蘋果日報" return "" + @register.filter def is_date_min(d): - return d.replace(tzinfo=None) == datetime.min + return d.replace(tzinfo=None) == datetime.min + @register.simple_tag def random_label(): - labels = ["label-default", "label-primary", "label-success", "label-info" ,"label-warning" ,"label-danger"] - return labels[random.randint(0,len(labels) - 1)] + labels = ["label-default", + "label-primary", + "label-success", + "label-info", + "label-warning", + "label-danger"] + return labels[random.randint(0, len(labels) - 1)] + @register.simple_tag def random_panel(i=-1): - labels = ["default", "primary", "success", "info" ,"warning" ,"danger"] + labels = ["default", + "primary", + "success", + "info", + "warning", + "danger"] if i == -1: - i = random.randint(0,len(labels) - 1) + i = random.randint(0, len(labels) - 1) return "panel-" + labels[i] @@ -40,6 +54,7 @@ def random_panel(i=-1): def vote_result_chinese(result): return "通過" if result.lower() == "passed" else "否決" + @register.filter def vote_result_color(result): return "#00ff00" if result.lower() == "passed" else "#ff0000" @@ -47,5 +62,9 @@ def vote_result_color(result): @register.filter def vote_chinese(v): - d = {'YES': '贊成', 'NO': '反對' , 'ABSTAIN': '棄權', 'PRESENT': '出席', 'ABSENT': '缺席'} + d = {'YES': '贊成', + 'NO': '反對', + 'ABSTAIN': '棄權', + 'PRESENT': '出席', + 'ABSENT': '缺席'} return d[v] diff --git a/gov_track_hk_web/legco/urls.py b/gov_track_hk_web/legco/urls.py index 13ae312..33aeb64 100644 --- a/gov_track_hk_web/legco/urls.py +++ b/gov_track_hk_web/legco/urls.py @@ -1,6 +1,8 @@ -from django.conf.urls import url, include +from django.conf.urls import include, url + from legco.views import * + urlpatterns = [ url(r'^$', index_view), url(r'^vote/$', all_votes_view), @@ -25,5 +27,3 @@ url(r'^councils/$', councils_view), url(r'^members/(?P[0-9]+)/$', members_view), ] - - diff --git a/gov_track_hk_web/legco/views.py b/gov_track_hk_web/legco/views.py index d220f3b..5ccd886 100644 --- a/gov_track_hk_web/legco/views.py +++ b/gov_track_hk_web/legco/views.py @@ -1,18 +1,23 @@ # -*- coding: utf-8 -*- -from django.shortcuts import render -from django.db.models import Count -from legco.models import Individual, Party, IndividualVote, Vote, VoteSummary, Bill, MeetingSpeech, MeetingHansard, FinanceMeetingItem, FinanceMeetingItemEvent, FinanceMeetingResult, Question, BillCommittee, Council, CouncilMember, CouncilMembershipType -from legco.models import ImportantMotion -from datetime import date, datetime -from django.db.models import Q -from legco.models import MeetingSpeech, MeetingPersonel, MeetingHansard +import textwrap +import time from collections import defaultdict +from datetime import date, datetime +from math import cos, pi, sin +from urllib.parse import urljoin + +from django.db.models import Count, Q from django.http import HttpResponse +from django.shortcuts import render + +from legco.models import (Bill, BillCommittee, Council, CouncilMember, + CouncilMembershipType, FinanceMeetingItem, + FinanceMeetingItemEvent, FinanceMeetingResult, + ImportantMotion, Individual, IndividualVote, + MeetingHansard, MeetingPersonel, MeetingSpeech, + Party, Question, Vote, VoteSummary) from legco.templatetags import legco_extras -from urllib.parse import urljoin -from math import cos, sin, pi -import textwrap -import time + # Create your views here. @@ -184,6 +189,3 @@ def open_data_view(request): def meeting_view(request): return render(request, 'legco/meetings.html', {'nbar': 'meeting', 'tbar': 'legco'}) - - - diff --git a/gov_track_hk_web/requirements.txt b/gov_track_hk_web/requirements.txt index 1c79147..45231f9 100644 --- a/gov_track_hk_web/requirements.txt +++ b/gov_track_hk_web/requirements.txt @@ -30,3 +30,5 @@ wordcloud==1.2.1 PyExecJS==1.4.0 django-webpack-loader==0.6.0 django-letsencrypt==3.0.0 +pylama==7.4.3 +isort==4.3.4 diff --git a/gov_track_hk_web/rss/urls.py b/gov_track_hk_web/rss/urls.py index cd97b81..3eaec1b 100644 --- a/gov_track_hk_web/rss/urls.py +++ b/gov_track_hk_web/rss/urls.py @@ -1,4 +1,5 @@ from django.conf.urls import url + from .views import ConsultationsFeed, NewsFeed urlpatterns = [ @@ -7,4 +8,3 @@ url(r'^news.xml$', NewsFeed()), # ... ] - diff --git a/gov_track_hk_web/rss/views.py b/gov_track_hk_web/rss/views.py index 6e8329f..01bd08b 100644 --- a/gov_track_hk_web/rss/views.py +++ b/gov_track_hk_web/rss/views.py @@ -1,15 +1,18 @@ # -*- coding: utf-8 -*- -from django.shortcuts import render -from django.core.cache import cache -import requests +from datetime import datetime, time, timedelta +from hashlib import md5 + import dateutil.parser +import requests from django.contrib.syndication.views import Feed -from subscriber.models import News +from django.core.cache import cache +from django.db.models import Q +from django.shortcuts import render from django.utils import feedgenerator -from hashlib import md5 -from datetime import datetime, timedelta, time + from api.models import Consultation -from django.db.models import Q +from subscriber.models import News + # Create your views here. class ConsultationsFeed(Feed): diff --git a/gov_track_hk_web/subscriber/admin.py b/gov_track_hk_web/subscriber/admin.py index 940630f..cbfb4b0 100644 --- a/gov_track_hk_web/subscriber/admin.py +++ b/gov_track_hk_web/subscriber/admin.py @@ -1,5 +1,7 @@ from django.contrib import admin -from subscriber.models import Subscriber, News + +from subscriber.models import News, Subscriber + # Register your models here. admin.site.register(Subscriber) diff --git a/gov_track_hk_web/subscriber/models.py b/gov_track_hk_web/subscriber/models.py index 2aa5855..78f2089 100644 --- a/gov_track_hk_web/subscriber/models.py +++ b/gov_track_hk_web/subscriber/models.py @@ -1,13 +1,14 @@ from __future__ import unicode_literals from django.db import models -from django import forms # Create your models here. + class Subscriber(models.Model): email = models.EmailField(max_length=1024) key = models.CharField(unique=True, max_length=128) + def __unicode__(self): return self.email @@ -18,5 +19,6 @@ class News(models.Model): title_ch = models.CharField(max_length=4096) title_en = models.CharField(max_length=4096) date = models.DateField() + def __unicode__(self): return self.title_ch + " " + self.date.strftime('%Y-%m-%d') diff --git a/gov_track_hk_web/subscriber/tests.py b/gov_track_hk_web/subscriber/tests.py index 7ce503c..e69de29 100644 --- a/gov_track_hk_web/subscriber/tests.py +++ b/gov_track_hk_web/subscriber/tests.py @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/gov_track_hk_web/subscriber/views.py b/gov_track_hk_web/subscriber/views.py index 91ea44a..e69de29 100644 --- a/gov_track_hk_web/subscriber/views.py +++ b/gov_track_hk_web/subscriber/views.py @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/gov_track_hk_web/xmls/download.py b/gov_track_hk_web/xmls/download.py index c0ce6c2..6aaacf3 100644 --- a/gov_track_hk_web/xmls/download.py +++ b/gov_track_hk_web/xmls/download.py @@ -1,9 +1,17 @@ # -*- coding: utf-8 -*- import requests + year_range = ["12-13", "13-14", "14-15", "15-16", "16-17"] meeting_types = ["cm", "esc", "pwsc", "hc", "fc"] -url_format = {"cm": "http://www.legco.gov.hk/yr%s/chinese/counmtg/voting/cm_vote_", "esc": "http://www.legco.gov.hk/yr%s/chinese/fc/esc/results/esc_vote_", "pwsc": "http://www.legco.gov.hk/yr%s/chinese/fc/pwsc/results/pwsc_vote_", "hc": "http://www.legco.gov.hk/yr%s/chinese/hc/voting/hc_vote_", "fc": "http://www.legco.gov.hk/yr%s/chinese/fc/fc/results/fc_vote_"} -detect_url_format = "http://www.legco.gov.hk/php/detect-votes.php?term=yr%s&meeting=%s" +url_format = { + "cm": "http://www.legco.gov.hk/yr%s/chinese/counmtg/voting/cm_vote_", + "esc": "http://www.legco.gov.hk/yr%s/chinese/fc/esc/results/esc_vote_", + "pwsc": "http://www.legco.gov.hk/yr%s/chinese/fc/pwsc/results/pwsc_vote_", + "hc": "http://www.legco.gov.hk/yr%s/chinese/hc/voting/hc_vote_", + "fc": "http://www.legco.gov.hk/yr%s/chinese/fc/fc/results/fc_vote_" +} +detect_url_format = \ + "http://www.legco.gov.hk/php/detect-votes.php?term=yr%s&meeting=%s" for yr in ["16-17"]: for mc in meeting_types: detect_url = detect_url_format % (yr, mc)