Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • la-quadrature-du-net/memopol/memopol
  • lnclt/political_memory
  • arthur/political_memory
  • agrausem/political_memory
  • periode/memopol
  • Anthony/memopol
  • Porkepix/memopol
  • jaster/memopol
  • luxcem/memopol
  • TAlone/memopol
10 résultats
Afficher les modifications
Affichage de
avec 370 ajouts et 260 suppressions
#!/bin/bash
#
# Quick-start script for new developers
# Usage: from repo root, `source bin/quickstart.sh`
#
REPOROOT=$(dirname $(dirname $0))
# Ensure we're at the root of the memopol repository
pushd $REPOROOT >/dev/null
# Create & activate python virtual environment
virtualenv memopol_env
source memopol_env/bin/activate
# Install python dependencies
pip install -U pip setuptools
pip install -e .[testing]
# Install client dependencies
src/memopol/bin/install_client_deps.sh
# Create pg user and database
if [ $(psql -c "select 'CNT=' || count(1) from pg_catalog.pg_user where usename='memopol';" -U postgres | grep CNT=1 | wc -l) -lt 1 ]; then
psql -c "create user memopol with password 'memopol';" -U postgres
fi
psql -c "alter role memopol with createdb;" -U postgres
if [ $(psql -l -U postgres | egrep "^ memopol\W" | wc -l) -lt 1 ]; then
psql -c "create database memopol with owner memopol;" -U postgres
fi
# Setup environment
export DJANGO_DEBUG=True
export DJANGO_SETTINGS_MODULE=memopol.settings
# Run django migration to create database
memopol migrate
# Import sample data
memopol loaddata data_sample.json
memopol refresh_scores
# Build index for Whoosh
memopol rebuild_index
echo
echo "You're all set!"
echo "To start the application run the following from the repository root ($REPOROOT):"
echo " source memopol_env/bin/activate"
echo " export DJANGO_DEBUG=True DJANGO_SETTINGS_MODULE=memopol.settings"
echo " memopol runserver"
echo
echo "If you make changes, don't forget to run tests using:"
echo " flake8 . --exclude '*/migrations,docs,static' --ignore E128"
echo " py.test memopol representatives_positions representatives_recommendations"
echo
echo "Happy hacking ;)"
echo
popd >/dev/null
......@@ -2,15 +2,14 @@
bin/update_representatives
# grace time for pg
sleep 120
sleep 10
bin/update_dossiers
sleep 120
sleep 10
bin/update_votes
bin/update_proposals
sleep 120
sleep 10
bin/update_scores
bin/update_votes
#!/bin/bash
set -ex
set -x
source ${OPENSHIFT_REPO_DIR}bin/lib.sh
source bin/lib.sh
pipe_download_to_command ep_dossiers.json.xz parltrack_import_dossiers
parltrack_download_pipe ep_dossiers.json.xz parltrack_import_dossiers
sleep 10
francedata_download_pipe dossiers.json.gz francedata_import_dossiers
#!/bin/bash
set -x
source bin/lib.sh
# Nothing for parltrack - proposals imported with votes
francedata_download_pipe scrutins.json.gz francedata_import_scrutins
#!/bin/bash
set -ex
set -x
source ${OPENSHIFT_REPO_DIR}bin/lib.sh
source bin/lib.sh
pipe_download_to_command ep_meps_current.json.xz parltrack_import_representatives
parltrack_download_pipe ep_meps_current.json.xz parltrack_import_representatives
sleep 10
francedata_download_pipe parlementaires.json.gz francedata_import_representatives
#!/bin/bash
set -ex
source ${OPENSHIFT_REPO_DIR}bin/lib.sh
[ -n "$OPENSHIFT_REPO_DIR" ] && cd $OPENSHIFT_REPO_DIR
./manage.py update_score
#!/bin/bash
set -ex
set -x
source ${OPENSHIFT_REPO_DIR}bin/lib.sh
source bin/lib.sh
pipe_download_to_command ep_votes.json.xz parltrack_import_votes
parltrack_download_pipe ep_votes.json.xz parltrack_import_votes
sleep 10
parltrack_download_pipe ep_com_votes.json.xz parltrack_import_votes
sleep 10
francedata_download_pipe votes.json.gz francedata_import_votes
if [ "x$1" != "xnoscores" ]; then
sleep 10
refresh_scores
fi
{
"name": "Memopol",
"version": "3.0.0",
"dependencies": {
"bootstrap": "~3.3.5",
"flag-icon-css": "~0.7.1"
},
"devDependencies": {
"fontawesome": "~4.3.0"
}
}
<!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" />
<title>
{% block title %}Home{% endblock %}
- The Political Memory of {{ config.ORGANIZATION_NAME }}</title>
{% load compress %}
{% load staticfiles %}
{% compress css %}
<link rel="stylesheet" href="{% static 'stylesheets/libs.min.css' %}" type="text/css" />
<link rel="stylesheet" href="{% static 'stylesheets/base.min.css' %}" type="text/css" />
<link rel="stylesheet" href="{% static 'libs/fontawesome/css/font-awesome.min.css' %}" type="text/css" />
{% endcompress %}
{% compress js %}
<script type="text/javascript" src="{% static 'libs/jquery/dist/jquery.js' %}"></script>
<script type="text/javascript" src="{% static 'libs/bootstrap/dist/js/bootstrap.js' %}"></script>
{% endcompress %}
{% block head %}{% endblock %}
</head>
<body {% block bodyattrs %}{% endblock %}>
{% include "core/blocks/header.html" %}
<div class="container-fluid main-container">
{% block content %}
{% endblock %}
</div>
{% include "core/blocks/footer.html" %}
</body>
</html>
- load i18n
#footer.container-fluid
- 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>
%a{href: "https://projets.lqdn.fr/projects/mempol"}
- trans "Bug tracking system"
%a{href: "https://projets.lqdn.fr/projects/mempol/issues/new"}
- trans "Report a bug"
%br
{% trans "Provided by" %} <a href="http://www.laquadrature.net/">La Quadrature du Net</a>
/ -load memopol_tags cache
- load i18n
- load cache
- load staticfiles
#header.container-fluid
%a{href: "/", id: 'logo'}
%img{src: '{% static "images/logo.png" %}'}
%h1
%a#header_banner{href: "/"}
-trans "Political Memory"
%p.organization
=config.ORGANIZATION_NAME
#nav.container-fluid
-include "core/blocks/navigation.html"
%ul.nav
%li
%a{href: "{% url 'legislature:representative-index' %}"}
Representatives
%li
%a{href: "{% url 'legislature:group-index' kind='country' %}"}
Countries
%li
%a{href: "{% url 'legislature:group-index' kind='group' %}"}
Parties
%li
%a{href: "{% url 'legislature:group-index' kind='delegation' %}"}
Delegations
%li
%a{href: "{% url 'legislature:group-index' kind='committee' %}"}
Committees
%ul.nav
%li
%a{href: "{% url 'votes:dossier-index' %}"}
Votes
.pagination-block
%nav
%ul.pagination.pagination-sm
- if page.has_previous
%li
%a{'href': '?={queries.urlencode}&page=={page.previous_page_number}',
'aria-label': 'Previous'}
<i aria-hidden="true" class="fa fa-chevron-left"></i>
- for p in page.pages
- if p
- if p == page.number
%li.active
%a{'href': ''}
{{ p }}
- else
%li
%a{'href': '?={queries.urlencode}&page=={p}'}
{{ p }}
- else
%li.disabled
%a{'href': ''}
- if page.has_next
%li
%a{'href': '?={queries.urlencode}&page=={page.next_page_number}',
'aria-label': 'Next'}
<i aria-hidden="true" class="fa fa-chevron-right"></i>
%div.count
Number of results : {{ paginator.count }}
%br
Number of displayed results :
{{ paginator.per_page }}
(
- for limit in pagination_limits
%a{'href': '?limit={{ limit }}'}
{{ limit }}
- if not forloop.last
\/
)
- include 'core/blocks/grid-list.html'
- extends "base.html"
- block content
.row
.col-md-8
%p
Memopol is reachable only in <b>reduced functionality mode</b>.
By the way, you could access to
<a href="{% url 'legislature:representative-index' %}">the 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>.
.col-md-4
.panel.panel-default
.panel-body
%p
<a href="http://memopol.org">Memopol Blog</a> is available as well as the new
<a href="http://git.laquadrature.net/memopol/memopol/issues">
bugtracking system</a>
%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>
from __future__ import absolute_import
from pure_pagination import EmptyPage
from pure_pagination import Paginator
from django.shortcuts import render
def create_child_instance_from_parent(child_cls, parent_instance):
"""
Create a child model instance from a parent instance
"""
parent_cls = parent_instance.__class__
field = child_cls._meta.get_ancestor_link(parent_cls).column
child_instance = child_cls(**{
field: parent_instance.pk
})
child_instance.__dict__.update(parent_instance.__dict__)
child_instance.save()
return child_instance
def render_paginate_list(request, object_list, template_name):
"""
Render a paginated list of representatives
"""
pagination_limits = (10, 20, 50, 100)
num_by_page = request.GET.get('limit', 30)
paginator = Paginator(object_list, num_by_page)
number = request.GET.get('page', '1')
number = int(number) if number.isdigit() else 1
try:
page = paginator.page(number)
except EmptyPage:
page = paginator.page(paginator.num_pages)
context = {}
context['paginator'] = paginator
context['page'] = page
context['object_list'] = context['page'].object_list
context['pagination_limits'] = pagination_limits
return render(
request,
template_name,
context
)
# 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 django.views.generic.base import TemplateView
class HomeView(TemplateView):
template_name = "core/home.html"
......@@ -10,7 +10,7 @@ Authentication in the admin backend
If you haven't already, create a super-administrator
account with command::
./manage.py createsuperuser
memopol createsuperuser
Then use this account to authenticate in the
administration backend located in ``/admin``.
......
API Documentation
~~~~~~~~~~~~~~~~~
Memopol publishes its data with a read-only REST API using `Django REST
Framework <http://www.django-rest-framework.org/>`_. The API is browseable and
partially self-documented, from the ``/api`` URL.
The goal of this documentation is to plug the holes in the
automatically-generated documentation.
Overview
========
The API homepage resides at the ``/api/`` URL. Each model is accessible from two
URLs:
* ``/api/<model>/`` for a (filterable) list of objects
* ``/api/<model>/<pk>/`` to get a detailed view of a specific object
When accessing the API from a web browser, data should be displayed in a
user-friendly paginated interface, and relation fields are links to the
corresponding API URLs (if that's not the case, you can force it by appending
``format=api`` to the querystring). To get raw JSON data instead, either pass
an ``Accept: application/json`` request header or append ``format=json`` to the
querystring.
Object lists may be filtered using ``field=value`` in the querystring ; related
fields may be used in filters with double underscores (for example
``representative__name=John``). Alternative operators may be available for
some fields (for example ``score__gte=100``), amongst which:
* ``lte``: matches values that are lower than or equal to the specified value
* ``gte``: matches values greater than equal to or the specified value
* ``icontains``: matches values that contain the specified value, ignoring case
Note that fields that are made available for filtering depend on each model;
the same goes for alternative operators (by default only exact match is
available).
Finally, note that this documentation does not show the data schema. Feel free
to browse the API yourself to find out how data is published.
Representatives API
===================
This API provides views on representatives and mandates.
Representatives
---------------
The ``/api/representatives/[<pk>/]`` endpoints give access to representatives.
The following fields are available for filtering:
* ``active``: True or False
* ``slug`` (alt.: icontains)
* ``id``
* ``remote_id``
* ``first_name``
* ``last_name`` (alt.: icontains)
* ``gender``: M or F
* ``birth_place``
* ``birth_date`` (alt.: gte, lte)
* ``search``: searches in the ``first_name``, ``last_name`` and ``slug`` fields
Mandates
--------
The ``/api/mandates/[<pk>/]`` endpoints give access to mandates. The following
fields are available for filtering:
* ``id``
* ``group__name`` (alt.: icontains)
* ``group__abbreviation``
* ``search``: searches in the ``group__name`` and ``group_abbreviation`` fields
Constituency
------------
The ``/api/constituencies/[<pk>/]`` endpoints give access to constituencies.
Groups
------
The ``/api/groups/[<pk>/]`` endpoints give access to groups.
Representatives-votes API
=========================
This API provides views on dossiers, proposals and votes.
Dossiers
--------
The ``/api/dossiers/[<pk>/]`` endpoints give access to dossiers. The following
fields are available for filtering:
* ``fingerprint``
* ``title`` (alt.: icontains)
* ``reference`` (alt.: icontains)
* ``search``: searches in the ``fingerprint``, ``title``, ``reference``,
``text`` and ``proposals__title`` fields
Proposals
---------
The ``/api/proposals/[<pk>/]`` endpoints give access to proposals. The following
fields are available for filtering:
* ``fingerprint``
* ``dossier__fingerprint``
* ``title`` (alt.: icontains)
* ``description`` (alt.: icontains)
* ``reference`` (alt.: icontains)
* ``datetime`` (alt.: gte, lte)
* ``kind``
* ``search``: searches in the ``fingerprint``, ``title``,
``dossier__fingerprint``, ``dossier__title`` and ``dossier__reference`` fields
Votes
-----
The ``/api/votes/[<pk>/]`` endpoints give access to votes. The following fields
are available for filtering:
* ``proposal__fingerprint``
* ``position``
* ``representative_name`` (alt.: icontains)
* ``representative``
Memopol API
===========
This API provides views on recommendations and representative scores.
Recommendations
---------------
The ``/api/recommendations/[<pk>/]`` endpoints give access to recommendations.
The following fields are available for filtering:
* ``id``
* ``recommendation``
* ``title`` (alt.: icontains)
* ``description`` (alt.: icontains)
* ``weight`` (alt.: gte, lte)
* ``search``: searches in the ``title`` and ``description`` fields
Vote Scores
-----------
The ``/api/vote_scores/[<pk>/]`` endpoints give access to scored votes; that is,
representative votes with their contribution to the representative score. Only
votes that match a recommendation are visible using this endpoint. The
following fields are available for filtering:
* ``representative``
* ``proposal``
* ``proposal__dossier``
Dossier Scores
--------------
The ``/api/dossier_scores/[<pk>/]`` endpoints give access to dossier scores;
that is, the contribution of each dossier on a representative score. Only
dossiers with recommendations are visible using this endpoint. The following
fields are available for filtering:
* ``dossier``
* ``representative``
* ``score`` (alt.: gte, lte)
Representative scores
---------------------
The ``/api/scores/[<pk>/]`` endpoints give access to total scores for each
representative. The following fields are available for filtering:
* ``representative``
* ``score`` (alt.: gte, lte)
......@@ -113,7 +113,7 @@ html_theme = 'alabaster'
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
html_theme_path = ['../memopol_env/local/lib/python2.7/site-packages']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
......
Deployment on a custom machine
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prerequisites
=============
You will need the following:
* A clone of the git repository at ``https://git.laquadrature.net/memopol/memopol.git``
* A dedicated python virtualenv
* a PostgreSQL>=9.2 database (not necessarily on the same machine)
* a WSGI-capable web server
Setup environment
=================
Set the following environment variables::
DJANGO_SETTINGS_MODULE=memopol.settings
Customize settings
==================
Create a copy of the example local settings file::
$ cp src/memopol/local_settings.py.example src/memopol/local_settings.py
Edit ``src/memopol/local_settings.py`` to set directories, database settings and
allowed hosts. Setup your WSGI server to serve:
* Static files from the directory specified in the ``PUBLIC_DIR`` setting to the
``/static`` URL
* The ``src/memopol/wsgi.py`` WSGI application
Initial memopol setup
=====================
From the repository root, install python dependencies (you may want to do that
in a virtualenv)::
$ pip install -U pip setuptools
$ pip install -Ue .
Install client libraries::
$ src/memopol/bin/install_client_deps.sh
Setup the database schema::
$ memopol migrate --noinput
Collect static files::
$ memopol collectstatic --noinput
Memopol should be ready to go.
Updating
========
To update simply pull the repository and run setup commands again::
$ git pull
$ pip install -Ue .
$ src/memopol/bin/install_client_deps.sh
$ memopol migrate --noinput
$ memopol collectstatic --noinput
Data provisionning
==================
Set up two cron jobs:
* One to update data from parliaments, that runs ``bin/update_all``. This
script takes quite some time to run, so you should schedule it once every
night for example
* One to refresh scores, that runs ``memopol refresh_scores``. This one
runs quite quickly (a few seconds), you may want to run it after the update
job has completed (but you can run it more often).
Ensure that cron jobs get the same environment as the application.
Continue to :doc:`administration`.