class LocalParty(Party):
    country = models.ForeignKey(Country, null=True)

    @property
    def _q_objects(self):
        return Q(mep__partyrepresentative__party=self), Q(representative__partyrepresentative__party=self)

    @classmethod
    def with_meps_count(cls):
        return cls.objects.distinct().filter(partyrepresentative__representative__mep__active=True).annotate(meps_count=Count('partyrepresentative__representative__mep', distinct=True)) class MEP(Representative):
    active = models.BooleanField()
    ep_id = models.IntegerField(unique=True)
    ep_opinions = models.URLField()
    ep_debates = models.URLField()
    ep_questions = models.URLField()
    ep_declarations = models.URLField()
    ep_reports = models.URLField()
    ep_motions = models.URLField()
    ep_webpage = models.URLField()
    bxl_building = models.ForeignKey(Building, related_name="bxl_building", null=True)
    bxl_floor = models.CharField(max_length=255, null=True)
    bxl_office_number = models.CharField(max_length=255, null=True)
    bxl_fax = models.CharField(max_length=255, null=True)
    bxl_phone1 = models.CharField(max_length=255, null=True)
    bxl_phone2 = models.CharField(max_length=255, null=True)
    stg_building = models.ForeignKey(Building, related_name="stg_building", null=True)
    stg_floor = models.CharField(max_length=255, null=True)
    stg_office_number = models.CharField(max_length=255, null=True)
    stg_fax = models.CharField(max_length=255, null=True)
    stg_phone1 = models.CharField(max_length=255, null=True)
    stg_phone2 = models.CharField(max_length=255, null=True)
    groups = models.ManyToManyField(Group, through='GroupMEP')
    countries = models.ManyToManyField(Country, through='CountryMEP')
    delegations = models.ManyToManyField(Delegation, through='DelegationRole')
    committees = models.ManyToManyField(Committee, through='CommitteeRole')
    organizations = models.ManyToManyField(Organization, through='OrganizationMEP')
    position = models.IntegerField(default=None, null=True)
    total_score = models.FloatField(default=None, null=True)

    def age(self):
        if date.today().month > self.birth_date.month:
            return date.today().year - self.birth_date.year
        elif date.today().month == self.birth_date.month and date.today().day > self.birth_date.day:
            return date.today().year - self.birth_date.year
        else:
            return date.today().year - self.birth_date.year + 1

    @reify
    def get_ep_webpage(self):
        if self.active and self.ep_webpage:
            return self.ep_webpage
        return None

    def get_absolute_url(self):
        return reverse('meps:mep', args=(self.id,))

    @reify
    def bxl_office(self):
        return self.bxl_floor + self.bxl_office_number

    @reify
    def stg_office(self):
        return self.stg_floor + self.stg_office_number

    @reify
    def groups_mep(self):
        return self.groupmep_set.select_related('group')

    @reify
    def group(self):
        try:
            return self.groups_mep.latest('end').group
        except GroupMEP.DoesNotExist:
            return None

    @reify
    def country(self):
        return self.countries_mep.latest('end').country

    @reify
    def party(self):
        return self.countries_mep.latest('end').party

    @reify
    def countries_mep(self):
        return self.countrymep_set.select_related('country', 'party')

    @reify
    def delegations_roles(self):
        return self.delegationrole_set.select_related('delegation')

    @reify
    def committees_roles(self):
        return self.committeerole_set.select_related('committee')

    @reify
    def organizations_mep(self):
        return self.organizationmep_set.select_related('organization')

    @reify
    def assistants_mep(self):
        return self.assistantmep_set.select_related('assistant')

    @property
    def score_color(self):
        return "rgb(%s, %s, %s)" % color(self.total_score)

    @snippet(template='meps/snippets/country.html')
    def country_tag(self):
        return dict(country=self.country)

    @snippet(template='meps/snippets/party.html')
    def party_tag(self):
        return dict(party=self.party)

    @reify
    def important_posts(self):
        all_roles = list(self.organizations_mep.only_current())
        for i in (self.groups_mep.only_current().exclude(role="").exclude(role="Member").exclude(role="Substitute"),
                  self.committees_roles.only_current()):
            roles = i.filter(mep=self)
            if roles:
                all_roles += list(roles)
        return all_roles

    class Meta:
        ordering = ['last_name'] class Delegation(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __unicode__(self):
        return self.name
    content = __unicode__

    def get_absolute_url(self):
        return reverse('meps:index_by_delegation', args=(self.id,))

    @property
    def meps(self):
        return self.mep_set.filter(active=True).distinct()
        #return self.mep_set.filter(active=True, delegationrole__end=date(9999, 12, 31)).distinct()

    @property
    def _q_objects(self):
        return Q(mep__delegationrole__delegation=self), Q(representative__mep__delegationrole__delegation=self)

    @classmethod
    def with_meps_count(cls):
        return (cls.objects.distinct().filter(delegationrole__mep__active=True, delegationrole__end=CURRENT_MAGIC_VAL)
                           .annotate(meps_count=Count('delegationrole__mep', distinct=True))) class DelegationRole(TimePeriod):
    mep = models.ForeignKey(MEP)
    delegation = models.ForeignKey(Delegation)
    role = models.CharField(max_length=255)

    @reify
    def instance(self):
        return self.delegation

    def __unicode__(self):
        return u"%s : %s" % (self.mep.full_name, self.delegation) class PostalAddress(models.Model):
    addr = models.CharField(max_length=255)
    mep = models.ForeignKey(MEP) class Country(models.Model):
    code = models.CharField(max_length=2, unique=True)
    name = models.CharField(max_length=30, unique=True)

    def __unicode__(self):
        return u"%s - %s" % (self.code, self.name)

    @property
    def meps(self):
        return self.mep_set.filter(active=True).distinct()
        #return self.mep_set.filter(active=True, countrymep__end=date(9999, 12, 31)).distinct()

    def meps_on_date(self, date):
        return self.mep_set.filter(groupmep__end__gte=date, groupmep__begin__lte=date).distinct()

    @classmethod
    def with_meps_count(cls):
        return cls.objects.distinct().filter(countrymep__mep__active=True).annotate(meps_count=Count('countrymep__mep', distinct=True))

    @property
    def _q_objects(self):
        return Q(mep__countrymep__country=self), Q(representative__mep__countrymep__country=self)

    class Meta:
        ordering = ["code"] class CountryMEP(TimePeriod):
    mep = models.ForeignKey(MEP)
    country = models.ForeignKey(Country)
    party = models.ForeignKey(LocalParty) class Organization(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __unicode__(self):
        return self.name
    content = __unicode__

    def get_absolute_url(self):
        return reverse('meps:index_by_organization', args=(self.id,))

    @property
    def meps(self):
        return self.mep_set.filter(active=True).distinct()
        #return self.mep_set.filter(active=True, organizationmep__end=date(9999, 12, 31)).distinct()

    @property
    def _q_objects(self):
        return Q(mep__organizationmep__organization=self), Q(representative__mep__organizationmep__organization=self)

    @classmethod
    def with_meps_count(cls):
        return cls.objects.distinct().filter(organizationmep__mep__active=True).annotate(meps_count=Count('organizationmep__mep', distinct=True)) class OrganizationMEP(TimePeriod):
    mep = models.ForeignKey(MEP)
    organization = models.ForeignKey(Organization)
    role = models.CharField(max_length=255)

    @reify
    def instance(self):
        return self.organization class Committee(models.Model):
    name = models.CharField(max_length=255, unique=True)
    abbreviation = models.CharField(max_length=30, unique=True)

    def __unicode__(self):
        return u"%s: %s" % (self.abbreviation, self.name)
    content = __unicode__

    def get_absolute_url(self):
        return reverse('meps:index_by_committee', args=(self.abbreviation,))

    @property
    def meps(self):
        return self.mep_set.filter(active=True).distinct()

    @property
    def _q_objects(self):
        return Q(mep__committeerole__committee=self), Q(representative__mep__committeerole__committee=self)

    @classmethod
    def ordered_by_meps_count(cls):
        return (cls.objects.distinct().filter(committeerole__mep__active=True, committeerole__end=CURRENT_MAGIC_VAL)
                           .annotate(meps_count=Count('committeerole__mep', distinct=True)).order_by('-meps_count')) class CommitteeRole(TimePeriod):
    mep = models.ForeignKey(MEP)
    committee = models.ForeignKey(Committee)
    role = models.CharField(max_length=255)

    @reify
    def instance(self):
        return self.committee

    def __unicode__(self):
        return u"%s : %s" % (self.committee.abbreviation, self.mep.full_name) class Group(models.Model):
    abbreviation = models.CharField(max_length=10, unique=True)
    name = models.CharField(max_length=100, unique=True)

    def __unicode__(self):
        return u"%s - %s" % (self.abbreviation, self.name)
    content = __unicode__

    def get_absolute_url(self):
        return reverse('meps:index_by_group', args=(self.abbreviation,))

    @property
    def meps(self):
        return self.mep_set.filter(active=True).distinct()
        #return self.mep_set.filter(active=True, groupmep__end=date(9999, 12, 31)).distinct()

    def meps_on_date(self, date):
        return self.mep_set.filter(groupmep__end__gte=date, groupmep__begin__lte=date).distinct()

    @property
    def _q_objects(self):
        return Q(mep__groupmep__group=self), Q(representative__mep__groupmep__group=self)

    @classmethod
    def ordered_by_meps_count(cls):
        return (cls.objects.distinct().filter(groupmep__mep__active=True, groupmep__end=CURRENT_MAGIC_VAL)
                           .annotate(meps_count=Count('groupmep__mep', distinct=True)).order_by('-meps_count')) class GroupMEP(TimePeriod):
    mep = models.ForeignKey(MEP)
    group = models.ForeignKey(Group)
    role = models.CharField(max_length=255)

    @reify
    def instance(self):
        return self.group class Building(models.Model):
    """ A building of the European Parliament"""
    name = models.CharField(max_length=255)
    id = models.CharField('Abbreviation', max_length=255, primary_key=True)
    street = models.CharField(max_length=255)
    postcode = models.CharField(max_length=255)

    class Meta:
        ordering = ('postcode', 'pk',)

    @reify
    def _town(self):
        return "bxl" if self.postcode == "1047" else "stg"

    @reify
    def floors(self):
        floors = []
        def add(x):
            if getattr(x, "%s_floor" % self._town) not in floors:
                floors.append(getattr(x, "%s_floor" % self._town))
        map(add, self.meps.order_by("%s_floor" % self._town))
        return floors

    @reify
    def meps(self):
        return getattr(self, "%s_building" % self._town).filter(active=True)

    def __unicode__(self):
        return u"%s - %s - %s - %s" % (self.id, self.name, self.street, self.postcode) class Assistant(models.Model):
    full_name = models.CharField(max_length=255)

    def __unicode__(self):
        return self.full_name class AssistantMEP(models.Model):
    mep = models.ForeignKey(MEP)
    assistant = models.ForeignKey(Assistant)
    type = models.CharField(max_length=255)
    # active = models.BooleanField()
import os
import json
import re
import unidecode
from os.path import join
from datetime import datetime
from django.core.management.base import BaseCommand
from django.db.models import Count
from django.db import transaction
from django.conf import settings
from memopol.meps.utils import update_meps_positions
from memopol.base.utils import update_search_index, get_or_create
from memopol.reps.models import PartyRepresentative, Email, WebSite, CV
from memopol.meps.models import LocalParty, MEP, Delegation, DelegationRole, PostalAddress, Country, CountryMEP, Organization, OrganizationMEP, Committee, CommitteeRole, Group, GroupMEP, Building, Assistant, AssistantMEP

JSON_DUMP_ARCHIVE_LOCALIZATION = join(settings.MEMOPOL_TMP_DIR, "ep_meps_current.json.xz")
JSON_DUMP_LOCALIZATION = join(settings.MEMOPOL_TMP_DIR, "ep_meps_current.json")
_parse_date = lambda date: datetime.strptime(date, "%Y-%m-%dT00:%H:00")


class Command(BaseCommand):
    help = 'Update the eurodeputies data by pulling it from parltrack'

    def handle(self, *args, **options):
        print "clean old downloaded files"
        if os.path.exists(JSON_DUMP_ARCHIVE_LOCALIZATION):
            os.system("rm %s" % (JSON_DUMP_ARCHIVE_LOCALIZATION))
        if os.path.exists(JSON_DUMP_LOCALIZATION):
            os.system("rm %s" % (JSON_DUMP_LOCALIZATION))
        print "download lastest data dump of meps from parltrack"
        os.system("wget http://parltrack.euwiki.org/dumps/ep_meps_current.json.xz -O %s" % JSON_DUMP_ARCHIVE_LOCALIZATION)
        print "unxz dump"
        os.system("unxz %s" % JSON_DUMP_ARCHIVE_LOCALIZATION)
        print "load json"
        meps = json.load(open(JSON_DUMP_LOCALIZATION, "r"))
        print "Set all current active mep to unactive before importing"
        with transaction.commit_on_success():
            MEP.objects.filter(active=True).update(active=False)
            a = 0
            for mep_json in meps:
                a += 1
                print a, "-", mep_json["Name"]["full"].encode("Utf-8")
                in_db_mep = MEP.objects.filter(ep_id=int(mep_json["UserID"]))
                if in_db_mep:
                    mep = in_db_mep[0]
                    mep.active = bool(mep_json['active'])
                    manage_mep(mep, mep_json)
                else:
                    mep = create_mep(mep_json)
            clean()
        print
        update_meps_positions(verbose=True)
        update_search_index()


def create_uniq_id(mep_json):
    id = mep_json["Name"]["sur"].capitalize().replace(" ", "") + mep_json["Name"]["family"].capitalize().replace(" ", "")
    return re.sub("\W", "", unidecode.unidecode(id))

def add_committees(mep, committees):
    CommitteeRole.objects.filter(mep=mep).delete()
    for committee in committees:
        if committee.get("committee_id"):
            try:
                    in_db_committe = Committee.objects.get(abbreviation=committee["committee_id"])
            except Committee.DoesNotExist:
                print "     create new commitee:", committee["committee_id"], committee["Organization"]
                in_db_committe = Committee.objects.create(name=committee["Organization"],
                                                          abbreviation=committee["committee_id"])
            print "     link mep to commmitte:", committee["Organization"]
            params={}
            if committee.get("start"):
                params['begin']=_parse_date(committee.get("start"))
            if committee.get("end"):
                params['end']=_parse_date(committee.get("end"))
            CommitteeRole.objects.create(mep=mep, committee=in_db_committe,
                                         role=committee["role"], **params)
                                         #begin=_parse_date(committee.get("start")),
                                         #end=_parse_date(committee.get("end")))
        else:
            # FIXME create or how abbreviations ? Or are they really important ? or create a new class ?
            print "WARNING: committe without abbreviation:", committee["Organization"]

def add_delegations(mep, delegations):
    DelegationRole.objects.filter(mep=mep).delete()
    for delegation in delegations:
        db_delegation = get_or_create(Delegation, name=delegation["Organization"])
        print "     create DelegationRole to link mep to delegation"
        params={}
        if delegation.get("start"):
            params['begin']=_parse_date(delegation["start"])
        if delegation.get("end"):
            params['end']=_parse_date(delegation["end"])
        DelegationRole.objects.create(mep=mep, delegation=db_delegation,
                                      role=delegation["role"], **params)
                                      #begin=_parse_date(delegation["start"]),
                                      #end=_parse_date(delegation["end"]))

def add_addrs(mep, addrs):
    if addrs.get("Brussels"):
        print "     add Brussels infos"
        bxl = addrs["Brussels"]
        if bxl["Address"].get("building_code"):
            mep.bxl_building = get_or_create(Building, _id="id",
                                         id=bxl["Address"]["building_code"],
                                         name=bxl["Address"]["Building"],
                                         street=bxl["Address"]["Street"],
                                         postcode=bxl["Address"]["Zip"])
        mep.bxl_floor = bxl["Address"]["Office"][:2]
        mep.bxl_office_number = bxl["Address"]["Office"][2:]
        mep.bxl_fax = bxl.get("Fax")
        if "Phone" in bxl:
            mep.bxl_phone1 = bxl["Phone"]
            mep.bxl_phone2 = bxl["Phone"][:-4] + "7" + bxl["Phone"][-3:]
    print "     add Strasbourg infos"
    if addrs.get("Strasbourg"):
        stg = addrs["Strasbourg"]
        if stg["Address"].get("building_code"):
            mep.stg_building = get_or_create(Building, _id="id",
                                         id=stg["Address"]["building_code"],
                                         name=stg["Address"]["Building"],
                                         street=stg["Address"]["Street"],
                                         postcode=stg["Address"].get("Zip", stg["Address"]["Zip1"]))
        mep.stg_floor = stg["Address"]["Office"][:3]
        mep.stg_office_number = stg["Address"]["Office"][3:]
        mep.stg_fax = stg.get("Fax")
        if "Phone" in stg:
            mep.stg_phone1 = stg["Phone"]
            mep.stg_phone2 = stg["Phone"][:-4] + "7" + stg["Phone"][-3:]
        print "     adding mep's postal addresses:"
    mep.save()
    PostalAddress.objects.filter(mep=mep).delete()
    for addr in addrs.get("Postal", []):
        print "       *", addr.encode("Utf-8")

        PostalAddress.objects.create(addr=addr, mep=mep)