Commit 63e4b241 authored by Arnaud Fabre's avatar Arnaud Fabre

Merge branch 'dev'

Conflicts:
	.gitignore
	manage.py
	requirements.txt
parents 99874e35 648c9a49
{
"directory": "core/static/libs"
}
*~
build
develop-eggs
dist
*.egg
*.egg-info
eggs
.installed.cfg
nosetests.xml
pip-log.txt
*.py[co]
pylint.out
.tox
env
settings_local.py
*.swp
*.swo
*.index
*.sqlite3
celerybeat-schedule
memopol/config.json
# SASS Cache
.sass-cache
CACHE/*
# Emacs backup
# From https://github.com/github/gitignore/blob/master/Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
venv/
ve/
db.sqlite
COFFEESCRIPT_CACHE
build/
var/
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
How to install memopol
1. Create a directory containing the whole project (say ~memopol)
2. Create a python virtualenv in ~memopol : ~memopol/ve
3. Clone memopol main repository (http://git.laquadrature.net/memopol/memopol_political_memory) in ~memopol/memopol_political_memory
4. Clone django-representative directory (http://git.laquadrature.net/memopol/compotista_django-representatives) in ~memopol/django-representatives
5. Clone the last version of django-chronograph (https://bitbucket.org/wnielson/django-chronograph) in ~memopol/django-chronograph
(It seems that the version in pip is not up to date…)
6. Symlink ~memopol/memopol_political_memory/representatives -> ~memopol/django-representatives/representatives
7. Symlink ~memopol/memopol_political_memory/chronograph -> ~memopol/django-chronograph/chronograph
8. Install requierements in the virtualenv with pip install -r ~memopol//memopol_political_memory/requierements
9. Config your database in ~memopol/memopol_political_memory/settings.py
10. Sync the database python manage.py syncdb
11. Import mep from a compotista instance : python manage.py update update_eu_mps
12. Run the server
{
"name": "Memopol",
"version": "0.0.0",
"dependencies": {
"jquery": "~2.1.3",
"foundation": "~5.5.1"
}
}
from django.contrib import admin
# Register your models here.
from django.db import models
# Create your models here.
@font-face{
font-family: 'propagandaregular';
src: url('../font/propagan-webfont.eot');
src: url('../font/propagan-webfont.eot?#iefix') format('embedded-opentype'), url('../font/propagan-webfont.woff') format('woff'), url('../font/propagan-webfont.ttf') format('truetype'), url('../font/propagan-webfont.svg#propagandaregular') format('svg');
font-weight: normal;
font-style: normal;
}
@font-face{
font-family: 'sansus_webissimoitalic';
src: url('../font/sansus_webissimo-italic-webfont-webfont.eot');
src: url('../font/sansus_webissimo-italic-webfont-webfont.eot?#iefix') format('embedded-opentype'), url('../font/sansus_webissimo-italic-webfont-webfont.woff') format('woff'), url('../font/sansus_webissimo-italic-webfont-webfont.ttf') format('truetype'), url('../font/sansus_webissimo-italic-webfont-webfont.svg#sansus_webissimoitalic') format('svg');
font-weight: normal;
font-style: normal;
}
@font-face{
font-family: 'sansus_webissimoregular';
src: url('../font/sansus_webissimo-regular-webfont-webfont.eot');
src: url('../font/sansus_webissimo-regular-webfont-webfont.eot?#iefix') format('embedded-opentype'), url('../font/sansus_webissimo-regular-webfont-webfont.woff') format('woff'), url('../font/sansus_webissimo-regular-webfont-webfont.ttf') format('truetype'), url('../font/sansus_webissimo-regular-webfont-webfont.svg#sansus_webissimoregular') format('svg');
font-weight: normal;
font-style: normal;
}
td {
vertical-align: middle;
}
body {
background-color: #E5E5E5;
font-family: "Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1;
}
#header {
padding: 0px 20px;
height: 78px;
line-height: 45px;
}
.row {
width: 940px;
max-width: 100%;
min-width: 768px;
margin: 0px auto;
}
#header, #footer {
background: none repeat scroll 0px 0px #5B8EDC;
color: #FFF;
vertical-align: middle;
}
#header img {
float: left;
width: 74px;
}
#header h1 {
margin: 0px;
}
h1 {
font-size: 44px;
}
#header h1 a {
line-height: 10px;
font-family: propagandaregular;
font-size: 26px;
}
#header a {
color: #FFF;
text-decoration: none;
}
#header p {
font-style: italic;
padding-left: 20px;
margin-bottom: 17px;
}
p {
font-family: "Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;
font-weight: normal;
font-size: 14px;
line-height: 1.6;
margin-bottom: 17px;
}
.nav-bar {
margin-top: 0px;
background-color: #FFF;
border-bottom: 1px solid #EEE;
height: 30px;
line-height: 30px;
height: 40px;
padding: 0px;
}
.nav-bar > li {
float: left;
display: block;
position: relative;
padding: 0px;
margin: 0px;
line-height: 38px;
}
.nav-bar > li > a {
padding: 0px 20px;
font-size: 14px;
text-decoration: none;
color: #000;
}
li {
text-decoration: none;
list-style: outside none none;
}
.panel.callout {
background: none repeat scroll 0% 0% #5B8EDC;
color: #FFF;
border-color: #2284A1;
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.5) inset;
}
.panel {
background: none repeat scroll 0% 0% #F2F2F2;
border: 1px solid #E6E6E6;
margin: 0px 20px 22px;
padding: 20px;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;
font-weight: bold;
color: #222;
text-rendering: optimizelegibility;
line-height: 1.1;
margin-bottom: 14px;
margin-top: 14px;
}
h2, h3, h4 {
font-family: sansus_webissimoregular;
}
h2 { font-size: 2em; }
h3 { font-size: 1.5em; }
h3 small { font-size: 0.6em; }
.column, .columns {
float: left;
min-height: 1px;
padding: 0px 0px;
position: relative;
}
.large-12.main {
background: white;
padding: 10px;
width: 920px;
}
.large-8 {
width: 66.6667%;
} .large-4 {
width: 33.3333%;
}
#footer {
padding: 20px 0px;
text-align: center;
line-height: 20px;
font-size: 14px;
}
#footer ul {
margin-bottom: 11px;
}
#footer li {
display: inline;
}
#footer a {
color: #FFF;
text-decoration: underline;
}
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
{% extends "contrib/admin/templates/admin/index.html" %}
{% block branding %}
<h1 id="site-name">Administration for Memopol</h1>
{% endblock %}
{% block content %}
{{ block.super }}
{% endblock %}
<!DOCTYPE html>
<html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="{{ STATIC_URL }}img/favicon.ico" />
<!-- Set the viewport width to device width for mobile -->
<meta name="viewport" content="width=device-width" />
{% block head %}{% endblock %}
<title>{% block title %}Home{% endblock %} - The Political Memory of {{ organization_name }}</title>
<link rel="stylesheet" href="{{ STATIC_URL }}css/reset.css" type="text/css" />
<link rel="stylesheet" href="{{ STATIC_URL }}css/base.css" type="text/css" />
</head>
<body {% block bodyattrs %}{% endblock %}>
{% include "core/blocks/header.html" %}
<div class="row main">
<div class="large-12 main columns">
{% block content %}
{% endblock %}
</div>
</div>
{% include "core/blocks/footer.html" %}
</body>
</html>
- load i18n
#footer.row
%ul
%li
- blocktrans
Memopol is free software
<a href="https://gitorious.org/memopol2-0">released</a>
under the terms of the
<a href="http://www.gnu.org/licenses/agpl.html">GNU aGPLV3+</a>
%li
-# %a{href: "{% url about %}"}
-# - trans "About"
%li
%a{href: "https://projets.lqdn.fr/projects/mempol"}
- trans "Bug tracking system"
%li
%a{href: "https://projets.lqdn.fr/projects/mempol/issues/new"}
- trans "Report a bug"
%ul
%li
-# %a{href: "{% url api_doc %}"}
-# API
%li
-# %a{href: "{% url contact_form %}"}
-# Contact
-# - if user.is_staff
-# %li
-# %a{href: "{% url admin:index %}"}
-# - trans "Administration"
-# %li
-# %a{href: "{% url admin:comments_comment_changelist %}"}
-# - trans "Comments moderation"
-# %li
-# %a{href: "{% url admin:logout %}"}
-# - trans "Logout"
-# -if user.is_anonymous
-# %li
-# %a{href: "{% url admin:index %}"}
-# - trans "Login"
%ul
%li
{% trans "Provided by" %} <a href="http://www.laquadrature.net/">La Quadrature du Net</a>
/ -load memopol_tags cache
- load i18n
- load cache
.row.large-12.head
#header
%a{href: "/"}
%img{src: "https://memopol.lqdn.fr/static/img/logo.png"}/
%h1
%a#header_banner{href: "/"}
-trans "Political Memory"
%p
=organization_name
-include "core/blocks/navigation.html"
%ul.nav-bar
%li
%a{href: "{% url 'legislature:representatives_index' %}"}
Representatives
%li
%em By :
%li
%a{href: "{% url 'legislature:groups_by_kind' 'country' %}"}
Countries
%li
%a{href: "{% url 'legislature:groups_by_kind' 'group' %}"}
Parties
%li
%a{href: "{% url 'legislature:groups_by_kind' 'delegation' %}"}
Delegations
%li
%a{href: "{% url 'legislature:groups_by_kind' 'committee' %}"}
Committees
%ul.nav-bar
%li
%a{href: "{% url 'votes:votes_index' %}"}
Votes
%li
%em By :
.panel.callout
%h3
What is memopol?
%p
Political Memory is a tool designed by La Quadrature du Net to help
European citizens to reach members of European Parliament (MEPs) and
track their voting records on issues related to fundamental
freedoms online. <em><a href="">More...</a></em>
- extends "base.html"
- block content
.row
.large-8.columns
%p
Actually Memopol is actually reachable only in <b>reduced functionality mode</b>. By the way, you could access to <a href="/representatives">the actual list of MEPs</a>.
%p
You can help on building the new Memopol by <a href="https://wiki.laquadrature.net/Projects/Memopol/Roadmap">coding, translating, de signing, funding, etc...</a>.
%p
<a href="http://memopol.org">Memopol Blog</a> is available as well as the new <a href="http://git.laquadrature.net/memopol/memopol_political_memory/issues">bugtracking system</a>
.large-4.columns
- include "core/blocks/what_is_memopol.html"
from django.test import TestCase
# Create your tests here.
# coding: utf-8
# This file is part of memopol.
#
# memopol is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or any later version.
#
# memopol is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU General Affero Public
# License along with django-representatives.
# If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2015 Arnaud Fabre <af@laquadrature.net>
from __future__ import absolute_import
from django.core.exceptions import ObjectDoesNotExist
def create_child_instance_from_parent(child_cls, parent_instance):
parent_cls = parent_instance.__class__
field = child_cls._meta.get_ancestor_link(parent_cls).column
# We could specify a parent_identifier which is a unique field in
# the parent class that link child to parent
if hasattr(child_cls, 'parent_identifier'):
try:
child_instance = child_cls.objects.get(
**{child_cls.child_parent_identifier:
getattr(parent_instance, child_cls.parent_identifier)}
)
setattr(child_instance, field, parent_instance.pk)
except ObjectDoesNotExist:
child_instance = child_cls(**{
field: parent_instance.pk,
child_cls.child_parent_identifier:
getattr(parent_instance, child_cls.parent_identifier)
})
else:
child_instance = child_cls(**{
field: parent_instance.pk
})
child_instance.__dict__.update(parent_instance.__dict__)
child_instance.save()
return child_instance
from django.shortcuts import render
from django.views.generic.base import TemplateView
class HomeView(TemplateView):
template_name = "core/home.html"
def get_context_data(self, **kwargs):
return {
'organization_name': 'La Quadrature du Net'
}
from __future__ import absolute_import
from django.contrib import admin
from representatives.models import Email, WebSite, Address, Phone, Country
from .models import MemopolRepresentative
class EmailInline(admin.TabularInline):
model = Email
extra = 0
class WebsiteInline(admin.TabularInline):
model = WebSite
extra = 0
class AdressInline(admin.StackedInline):
model = Address
extra = 0
class PhoneInline(admin.TabularInline):
model = Phone
extra = 0
class CountryInline(admin.TabularInline):
model = Country
extra = 0
class MemopolRepresentativeAdmin(admin.ModelAdmin):
list_display = ('full_name', 'country', 'score')
search_fields = ('first_name', 'last_name', 'birth_place')
list_filter = ('gender', 'active')
inlines = [
PhoneInline,
EmailInline,
WebsiteInline,
AdressInline,
]
# class MandateAdmin(admin.ModelAdmin):
# list_display = ('representative', 'group', 'role', 'constituency', 'begin_date', 'end_date', 'active')
# search_fields = ('representative', 'group', 'constituency')
# list_filter = ('role',)
# admin.site.register(Representative, RepresentativeAdmin)
admin.site.register(MemopolRepresentative, MemopolRepresentativeAdmin)
# admin.site.register(Country)
# admin.site.register(MemopolMandate, MandateAdmin)
# admin.site.register(MemopolGroup)
# admin.site.register(Constituency)
from __future__ import absolute_import
from django.db import transaction
from django.core.management.base import BaseCommand
import pyprind
import representatives.models
import legislature.models
class Command(BaseCommand):
@transaction.atomic
def handle(self, *args, **options):
bar = pyprind.ProgBar(representatives.models.Representative.objects.all().count())
for i, representative in enumerate(representatives.models.Representative.objects.all()):
try:
memopol_representative = legislature.models.MemopolRepresentative.objects.get(
representative_remote_id = representative.remote_id
)
except legislature.models.MemopolRepresentative.DoesNotExist:
memopol_representative = legislature.models.MemopolRepresentative(
representative_remote_id = representative.remote_id
)
memopol_representative.representative_ptr_id = representative.pk
memopol_representative.__dict__.update(representative.__dict__)
memopol_representative.save()
memopol_representative.update_country()
bar.update()
for i, group_item in enumerate(representatives.models.Group.objects.all()):
memopol_group, _ = legislature.models.MemopolGroup.objects.get_or_create(
group = group_item
)
memopol_group.__dict__.update(group_item.__dict__)
memopol_group.update_active()
memopol_group.save()
import pyprind
from django.core.management.base import BaseCommand
from legislature.models import MemopolRepresentative
class Command(BaseCommand):
def handle(self, *args, **options):
bar = pyprind.ProgBar(MemopolRepresentative.objects.all().count())
for representative in MemopolRepresentative.objects.all():
representative.update_score()
bar.update(item_id = str(representative))