import_recommendations.py 3.47 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
# coding: utf-8

import csv
import django
from django.apps import apps
import logging
import sys

from representatives_recommendations.models import Recommendation
from representatives_votes.models import Dossier, Proposal

12
from .import_data import dossier_mappings, resolutions
13

Nicolas Joyard's avatar
Nicolas Joyard committed
14
logger = logging.getLogger(__name__)
15
16
17
18
19
20
21
22
23
24


class RecommendationImporter:
    def __init__(self):
        self.dossier_cache = {}

    def get_dossier(self, title):
        dossier = self.dossier_cache.get(title, None)

        if dossier is None:
Nicolas Joyard's avatar
Nicolas Joyard committed
25
26
27
28
29
30
            ref = dossier_mappings.get(title, None)
            if ref is not None:
                query = { 'reference':ref }
            else:
                query = { 'title__iexact': title }

31
            try:
Nicolas Joyard's avatar
Nicolas Joyard committed
32
                dossier = Dossier.objects.get(**query)
33
                self.dossier_cache[title] = dossier
34
35
36
37
38
39
            except Dossier.DoesNotExist:
                dossier = None

        return dossier

    def get_proposal(self, dossier, kind):
40
41
        kinds = [kind]

42
        try:
43
44
45
46
47
48
49
50
51
52
53
54
            resolutions.index(kind.lower())
            kinds.extend(resolutions)
        except ValueError:
            pass

        for k in kinds:
            try:
                return Proposal.objects.get(dossier=dossier, kind__iexact=k)
            except Proposal.DoesNotExist:
                continue

        return None
55
56
57
58

    def import_row(self, row):
        dossier = self.get_dossier(row['title'])
        if dossier is None:
Nicolas Joyard's avatar
Nicolas Joyard committed
59
            logger.warn('No dossier "%s"' % row['title'])
60
61
62
63
            return False

        proposal = self.get_proposal(dossier, row['part'])
        if proposal is None:
Nicolas Joyard's avatar
Nicolas Joyard committed
64
65
66
            logger.warn('No proposal "%s" for dossier %s (%d): "%s"' % (
                row['part'].decode('utf-8'), dossier.reference, dossier.pk,
                row['title']))
67
68
            return False

69
70
        weight = int(row['weight']) * int(row['ponderation'])

71
72
73
74
75
76
77
        try:
            recom = Recommendation.objects.get(proposal=proposal)
        except Recommendation.DoesNotExist:
            recom = Recommendation(
                proposal=proposal,
                recommendation=row['recommendation'],
                title=row['description'],
78
                weight=weight
79
80
81
            )
            recom.save()
            logger.info('Created recommendation with weight %s for %s: %s' % (
82
                weight,
83
84
85
86
87
88
89
90
91
92
93
94
                row['title'],
                row['part']
            ))

        return True


def main(stream=None):
    """
    Imports recommendations from an old memopol instance.

    Usage:
95
        cat recommendations.csv | memopol_import_recommendations
96
97

    The input CSV file should be generated by the following query:
98
99
        SELECT CONCAT(r.description, '|', r.weight, '|', r.recommendation, '|',
            r.part, '|', p.title, '|', p.ponderation)
100
101
102
103
104
105
106
107
108
109
110
111
112
        FROM votes_recommendation r
            LEFT JOIN votes_proposal p ON r.proposal_id = p.id
        WHERE p.institution = 'EU'

    """

    if not apps.ready:
        django.setup()

    importer = RecommendationImporter()
    rejected = []
    imported = 0

113
    reader = csv.DictReader(stream or sys.stdin, delimiter='|', fieldnames=[
114
115
116
117
        'description',
        'weight',
        'recommendation',
        'part',
118
119
        'title',
        'ponderation'
120
121
122
123
124
125
126
127
128
    ], quoting=csv.QUOTE_NONE)

    for row in reader:
        if not importer.import_row(row):
            rejected.append(row)
        else:
            imported = imported + 1

    logger.info('%d rows imported, %d rows rejected', imported, len(rejected))