<commit_before>'''
Created on Aug 6, 2015

@author: theo
'''
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User

from optparse import make_option
from django.contrib.gis.geos import Point
from django.utils import timezone
from django.conf import settings
import os,pytz,datetime
import json,logging

from acacia.data.models import ProjectLocatie
from iom import util
from iom.akvo import FlowAPI, as_timestamp
from iom.models import AkvoFlow, CartoDb, Meetpunt, Waarnemer, Alias
from iom.exif import Exif

logger = logging.getLogger(__name__)

def maak_naam(parameter,diep):
    if diep and not diep.endswith('iep'):
        diep = None
    return parameter + '_' + diep if diep else parameter

def get_or_create_waarnemer(akvoname):
    try:
        # is deze alias al geregistreerd?
        alias = Alias.objects.get(alias=akvoname)
        waarnemer = alias.waarnemer
        logger.debug('Waarnemer {name} gevonden met alias {alias}'.format(name=unicode(waarnemer),alias=alias))
    except Alias.DoesNotExist:
        # Bestaat er al een waarnemer met deze naam?
        words = akvoname.split()
        if len(words) > 1:
            voornaam = words[0]
            initialen = voornaam[0]
            achternaam = words[-1]
            if len(words) > 2:
                tussenvoegsel = ' '.join(words[1:-1])
            else:
                tussenvoegsel = ''
            waarnemer, created = Waarnemer.objects.get_or_create(initialen=initialen, voornaam=voornaam, tussenvoegsel=tussenvoegsel, achternaam=achternaam)
        else:
            waarnemer, created = Waarnemer.objects.get_or_create(achternaam=akvoname)
        if created:
            logger.info('Waarnemer {} aangemaakt'.format(unicode(waarnemer)))
        # alias toevoegen aan waarnemer
        alias = waarnemer.alias_set.create(alias=akvoname)
        logger.info('alias {alias} toegevoegd aan waarnemer {name}'.format(alias=unicode(alias),name=unicode(waarnemer)))
    return waarnemer

def download_photo(url):
    # copy photo to local storage and rotate if necessary
    try:
        filename = os.path.basename(url)
        Exif.copyImage(url, os.path.join(settings.PHOTO_DIR,filename))
        return os.path.join(settings.PHOTO_URL,filename)
    except:
        return url
                
def importAkvoRegistration(api,akvo,projectlocatie,user):
    surveyId = akvo.regform
    meetpunten=set()
    num_meetpunten = 0
    
    beginDate=as_timestamp(akvo.last_update)
#    instances = api.get_registration_instances(surveyId,beginDate=beginDate).items()
    instances = api.get_registration_instances(surveyId).items()
    for key,instance in instances:
        identifier=instance['surveyedLocaleIdentifier']
        displayName = instance['surveyedLocaleDisplayName']
        submitter = instance['submitterName']
        device = instance['deviceIdentifier']
        date=instance['collectionDate']
        date=datetime.datetime.utcfromtimestamp(date/1000.0).replace(tzinfo=pytz.utc)
        answers = api.get_answers(instance['keyId'])
        akvowaarnemer = api.get_answer(answers,questionText='Waarnemer')
        try:
            obj = json.loads(akvowaarnemer)
            if isinstance(obj, list):
                akvowaarnemer = obj[0]['text']
        except Exception as e:
            logger.Exception('Probleem met naam van waarnemer {}'.format(akvowaarnemer),e)
            akvowaarnemer = None
        meetid = api.get_answer(answers,questionText='Meetpunt ID')
        foto = api.get_answer(answers,questionText='Maak een foto van het meetgebied')
        geoloc = api.get_answer(answers,questionText='Geolocatie')
        omschrijving = api.get_answer(answers,questionText='Meetpunt omschrijving')
        num_meetpunten += 1
        try:
            lat,lon,elev,code = geoloc.split('|')
            location = Point(float(lon),float(lat),srid=4326)
            location.transform(28992)
        except:
            logger.error('Probleem met coordinaten {loc}'.format(loc=geoloc))
            continue

        akvoname = akvowaarnemer or submitter
        waarnemer = get_or_create_waarnemer(akvoname)

        # change reference to photo from smartphone storage to amazon storage and download to this server
        if foto:
            foto = download_photo(os.path.join(akvo.storage,os.path.basename(foto)))

        if meetid:
            # Gebuik waarnemer naam + meetid
            meetName = '{name} - {id}'. format(name=akvoname, id=meetid)
        else:
            meetName = displayName
        try:
            meetpunt, created = waarnemer.meetpunt_set.get_or_create(identifier=identifier, defaults={
                'name': meetName, 
                'projectlocatie': projectlocatie, 
                'location': location, 
                'displayname': displayName, 
                'device': device,
                'photo_url': foto,
                'description': omschrijving})
        except Exception as e:
            # acacia.data.models.meetlocatie probably exists
            try:
                meetpunt = Meetpunt.objects.get(name=meetName, projectlocatie=projectlocatie)
                meetpunt.identifier = identifier
                meetpunt.displayname = displayName
                meetpunt.device = device
                meetpunt.identifier = identifier
                meetpunt.photo_url = foto
                meetpunt.save()
                meetpunten.add(meetpunt)
                created = True
            except:
                logger.exception('Probleem bij toevoegen meetpunt {mname} aan waarnemer {wname}'.format(mname=meetName, wname=unicode(waarnemer)))
                continue

        if created:
            logger.info('Meetpunt {id} aangemaakt voor waarnemer {name}'.format(id=meetName,name=unicode(waarnemer)))
            meetpunten.add(meetpunt)

        if device != 'IMPORTER':
            ec = api.get_answer(answers,questionText='Meet EC waarde - ECOND') 
            diep = api.get_answer(answers,questionText='Diep of ondiep gemeten?')
            waarneming_naam = maak_naam('EC',diep)
    
            try:
                waarneming, created = meetpunt.waarneming_set.get_or_create(naam=waarneming_naam, waarnemer=waarnemer, datum=date, 
                                                  defaults = {'waarde': ec, 'device': device, 'opmerking': '', 'foto_url': foto, 'eenheid': 'uS/cm'})
            except Exception as e:
                logger.exception('Probleem bij toevoegen waarneming {wname} aan meetpunt {mname}'.format(wname=waarneming_naam, mname=unicode(meetpunt)))
                continue
    
            if created:
                logger.debug('{id}, {date}, EC={ec}'.format(id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                meetpunten.add(meetpunt)
    
            elif int(waarneming.waarde) != int(ec):
                waarneming.waarde = ec
                waarneming.save()
                meetpunten.add(meetpunt)
        
    logger.info('Aantal nieuwe meetpunten: {punt}'.format(punt=num_meetpunten))

    return meetpunten
   
def importAkvoMonitoring(api,akvo):
    meetpunten = set()
    num_waarnemingen = 0
    num_replaced = 0

    beginDate = as_timestamp(akvo.last_update)
    for surveyId in [f.strip() for f in akvo.monforms.split(',')]:
        survey = api.get_survey(surveyId)
        instances,meta = api.get_survey_instances(surveyId=surveyId,beginDate=beginDate)
        while instances:
            for instance in instances:
                submitter = instance['submitterName']
                waarnemer = get_or_create_waarnemer(submitter)
                
                #find related registration form (meetpunt)
                localeId = instance['surveyedLocaleIdentifier']
                try:
                    meetpunt = Meetpunt.objects.get(identifier=localeId)
                except Meetpunt.DoesNotExist:
                    logger.error('Meetpunt {locale} niet gevonden voor {submitter}'.format(locale=localeId, submitter=submitter))
                    continue
                
                device = instance['deviceIdentifier']
                date=instance['collectionDate']
                date=datetime.datetime.utcfromtimestamp(date/1000.0).replace(tzinfo=pytz.utc)

                answers = api.get_answers(instance['keyId'])
                ec=api.get_answer(answers,questionID='2060924')
                foto=api.get_answer(answers,questionID='5040929')
                diep=api.get_answer(answers,questionID='7080929')
                waarneming_naam = maak_naam('EC',diep)
                
                if foto:
                    foto = download_photo(os.path.join(akvo.storage,os.path.basename(foto)))
        
                if foto and not meetpunt.photo_url:
                    # update meetpunt along the way..
                    meetpunt.photo_url = foto
                    meetpunt.save(update_fields=['photo_url'])
                     
                waarneming, created = meetpunt.waarneming_set.get_or_create(naam=waarneming_naam, waarnemer=waarnemer, datum=date, 
                                              defaults = {'waarde': ec, 'device': device, 'opmerking': '', 'foto_url': foto, 'eenheid': 'uS/cm'})
                if created:
                    logger.info('{locale}={mp}, {id}({date})={ec}'.format(locale=localeId, mp=unicode(meetpunt), id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                    num_waarnemingen += 1
                    meetpunten.add(meetpunt)
                elif int(waarneming.waarde) != int(ec):
                    waarneming.waarde = ec
                    waarneming.save()
                    logger.info('{locale}={mp}, {id}({date})={ec}'.format(locale=localeId, mp=unicode(meetpunt), id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                    num_replaced += 1
                    meetpunten.add(meetpunt)
            instances,meta = api.get_survey_instances(surveyId=surveyId, beginDate=beginDate, since=meta['since'])
    logger.info('Aantal nieuwe metingen: {meet}, bijgewerkt: {repl}'.format(meet=num_waarnemingen,repl=num_replaced))
    return meetpunten

class Command(BaseCommand):
    args = ''
    help = 'Importeer metingen vanuit akvo flow'
    option_list = BaseCommand.option_list + (
            make_option('--akvo',
                action='store',
                dest = 'akvo',
                default = 1,
                help = 'id van Akvoflow configuratie'),
            make_option('--cartodb',
                action='store',
                dest = 'cartodb',
                default = 1,
                help = 'id van Cartodb configuratie'),
            make_option('--project',
                action='store',
                dest = 'proj',
                default = 1,
                help = 'id van project locatie'),
            make_option('--user',
                action='store',
                dest = 'user',
                default = 'akvo',
                help = 'user name'),
        )

    def handle(self, *args, **options):
        
        akvo = AkvoFlow.objects.get(pk=options.get('akvo'))
        api = FlowAPI(instance=akvo.instance, key=akvo.key, secret=akvo.secret)
        cartodb = CartoDb.objects.get(pk=options.get('cartodb'))
    
        project = ProjectLocatie.objects.get(pk=options.get('proj'))
        user = User.objects.get(username=options.get('user'))

        try:
            logger.debug('Meetpuntgegevens ophalen')
            mp = importAkvoRegistration(api, akvo, projectlocatie=project,user=user)
            logger.debug('Waarnemingen ophalen')
            mp.update(importAkvoMonitoring(api, akvo))
            
            if mp:
                logger.debug('Grafieken aanpassen')
                util.updateSeries(mp, user)
                logger.debug('Cartodb actualiseren')
                util.updateCartodb(cartodb, mp)
            
            akvo.last_update = timezone.now()
            akvo.save()        
        except Exception as e:
            logger.exception('Probleem met verwerken nieuwe EC metingen: %s',e)
        finally:
            pass
<commit_msg>monitoring questionIDS replaced with questionText<commit_after>'''
Created on Aug 6, 2015

@author: theo
'''
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User

from optparse import make_option
from django.contrib.gis.geos import Point
from django.utils import timezone
from django.conf import settings
import os,pytz,datetime
import json,logging

from acacia.data.models import ProjectLocatie
from iom import util
from iom.akvo import FlowAPI, as_timestamp
from iom.models import AkvoFlow, CartoDb, Meetpunt, Waarnemer, Alias
from iom.exif import Exif

logger = logging.getLogger(__name__)

def maak_naam(parameter,diep):
    if diep and not diep.endswith('iep'):
        diep = None
    return parameter + '_' + diep if diep else parameter

def get_or_create_waarnemer(akvoname):
    try:
        # is deze alias al geregistreerd?
        alias = Alias.objects.get(alias=akvoname)
        waarnemer = alias.waarnemer
        logger.debug('Waarnemer {name} gevonden met alias {alias}'.format(name=unicode(waarnemer),alias=alias))
    except Alias.DoesNotExist:
        # Bestaat er al een waarnemer met deze naam?
        words = akvoname.split()
        if len(words) > 1:
            voornaam = words[0]
            initialen = voornaam[0]
            achternaam = words[-1]
            if len(words) > 2:
                tussenvoegsel = ' '.join(words[1:-1])
            else:
                tussenvoegsel = ''
            waarnemer, created = Waarnemer.objects.get_or_create(initialen=initialen, voornaam=voornaam, tussenvoegsel=tussenvoegsel, achternaam=achternaam)
        else:
            waarnemer, created = Waarnemer.objects.get_or_create(achternaam=akvoname)
        if created:
            logger.info('Waarnemer {} aangemaakt'.format(unicode(waarnemer)))
        # alias toevoegen aan waarnemer
        alias = waarnemer.alias_set.create(alias=akvoname)
        logger.info('alias {alias} toegevoegd aan waarnemer {name}'.format(alias=unicode(alias),name=unicode(waarnemer)))
    return waarnemer

def download_photo(url):
    # copy photo to local storage and rotate if necessary
    try:
        filename = os.path.basename(url)
        Exif.copyImage(url, os.path.join(settings.PHOTO_DIR,filename))
        return os.path.join(settings.PHOTO_URL,filename)
    except:
        return url
                
def importAkvoRegistration(api,akvo,projectlocatie,user):
    surveyId = akvo.regform
    meetpunten=set()
    num_meetpunten = 0
    
    beginDate=as_timestamp(akvo.last_update)
    instances = api.get_registration_instances(surveyId,beginDate=beginDate).items()
#    instances = api.get_registration_instances(surveyId).items()
    for key,instance in instances:
        identifier=instance['surveyedLocaleIdentifier']
        displayName = instance['surveyedLocaleDisplayName']
        submitter = instance['submitterName']
        device = instance['deviceIdentifier']
        date=instance['collectionDate']
        date=datetime.datetime.utcfromtimestamp(date/1000.0).replace(tzinfo=pytz.utc)
        answers = api.get_answers(instance['keyId'])
        akvowaarnemer = api.get_answer(answers,questionText='Waarnemer')
        try:
            obj = json.loads(akvowaarnemer)
            if isinstance(obj, list):
                akvowaarnemer = obj[0]['text']
        except Exception as e:
            logger.Exception('Probleem met naam van waarnemer {}'.format(akvowaarnemer),e)
            akvowaarnemer = None
        meetid = api.get_answer(answers,questionText='Meetpunt ID')
        foto = api.get_answer(answers,questionText='Maak een foto van het meetgebied')
        geoloc = api.get_answer(answers,questionText='Geolocatie')
        omschrijving = api.get_answer(answers,questionText='Meetpunt omschrijving')
        num_meetpunten += 1
        try:
            lat,lon,elev,code = geoloc.split('|')
            location = Point(float(lon),float(lat),srid=4326)
            location.transform(28992)
        except:
            logger.error('Probleem met coordinaten {loc}. waarnemer = {waar}, meetpunt = {mp}'.format(loc=geoloc, waar = akvowaarnemer or submitter, mp=meetid))
            continue

        akvoname = akvowaarnemer or submitter
        waarnemer = get_or_create_waarnemer(akvoname)

        # change reference to photo from smartphone storage to amazon storage and download to this server
        if foto:
            foto = download_photo(os.path.join(akvo.storage,os.path.basename(foto)))

        if meetid:
            # Gebuik waarnemer naam + meetid
            meetName = '{name} - {id}'. format(name=akvoname, id=meetid)
        else:
            meetName = displayName
        try:
            meetpunt, created = waarnemer.meetpunt_set.get_or_create(identifier=identifier, defaults={
                'name': meetName, 
                'projectlocatie': projectlocatie, 
                'location': location, 
                'displayname': displayName, 
                'device': device,
                'photo_url': foto,
                'description': omschrijving})
        except Exception as e:
            # acacia.data.models.meetlocatie probably exists
            try:
                meetpunt = Meetpunt.objects.get(name=meetName, projectlocatie=projectlocatie)
                meetpunt.identifier = identifier
                meetpunt.displayname = displayName
                meetpunt.device = device
                meetpunt.identifier = identifier
                meetpunt.photo_url = foto
                meetpunt.save()
                meetpunten.add(meetpunt)
                created = True
            except:
                logger.exception('Probleem bij toevoegen meetpunt {mname} aan waarnemer {wname}'.format(mname=meetName, wname=unicode(waarnemer)))
                continue

        if created:
            logger.info('Meetpunt {id} aangemaakt voor waarnemer {name}'.format(id=meetName,name=unicode(waarnemer)))
            meetpunten.add(meetpunt)

        if device != 'IMPORTER':
            ec = api.get_answer(answers,questionText='Meet EC waarde - ECOND') 
            diep = api.get_answer(answers,questionText='Diep of ondiep gemeten?')
            waarneming_naam = maak_naam('EC',diep)
    
            try:
                waarneming, created = meetpunt.waarneming_set.get_or_create(naam=waarneming_naam, waarnemer=waarnemer, datum=date, 
                                                  defaults = {'waarde': ec, 'device': device, 'opmerking': '', 'foto_url': foto, 'eenheid': 'uS/cm'})
            except Exception as e:
                logger.exception('Probleem bij toevoegen waarneming {wname} aan meetpunt {mname}'.format(wname=waarneming_naam, mname=unicode(meetpunt)))
                continue
    
            if created:
                logger.debug('{id}, {date}, EC={ec}'.format(id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                meetpunten.add(meetpunt)
    
            elif int(waarneming.waarde) != int(ec):
                waarneming.waarde = ec
                waarneming.save()
                meetpunten.add(meetpunt)
        
    logger.info('Aantal meetpunten: {aantal}, nieuwe meetpunten: {new}'.format(aantal=num_meetpunten, new=len(meetpunten)))

    return meetpunten
   
def importAkvoMonitoring(api,akvo):
    meetpunten = set()
    num_waarnemingen = 0
    num_replaced = 0

    beginDate = as_timestamp(akvo.last_update)
    for surveyId in [f.strip() for f in akvo.monforms.split(',')]:
        survey = api.get_survey(surveyId)
        instances,meta = api.get_survey_instances(surveyId=surveyId,beginDate=beginDate)
        while instances:
            for instance in instances:
                submitter = instance['submitterName']
                waarnemer = get_or_create_waarnemer(submitter)
                
                #find related registration form (meetpunt)
                localeId = instance['surveyedLocaleIdentifier']
                try:
                    meetpunt = Meetpunt.objects.get(identifier=localeId)
                except Meetpunt.DoesNotExist:
                    logger.error('Meetpunt {locale} niet gevonden voor {submitter}'.format(locale=localeId, submitter=submitter))
                    continue
                
                device = instance['deviceIdentifier']
                date=instance['collectionDate']
                date=datetime.datetime.utcfromtimestamp(date/1000.0).replace(tzinfo=pytz.utc)

                answers = api.get_answers(instance['keyId'])
                ec=api.get_answer(answers,questionText='EC waarde - ECOND')
                foto=api.get_answer(answers,questionID='Maak een foto van het meetgebied')
                diep=api.get_answer(answers,questionText='Diep of ondiep')
                waarneming_naam = maak_naam('EC',diep)
                
                if foto:
                    foto = download_photo(os.path.join(akvo.storage,os.path.basename(foto)))
        
                if foto and not meetpunt.photo_url:
                    # update meetpunt along the way..
                    meetpunt.photo_url = foto
                    meetpunt.save(update_fields=['photo_url'])
                     
                waarneming, created = meetpunt.waarneming_set.get_or_create(naam=waarneming_naam, waarnemer=waarnemer, datum=date, 
                                              defaults = {'waarde': ec, 'device': device, 'opmerking': '', 'foto_url': foto, 'eenheid': 'uS/cm'})
                if created:
                    logger.info('{locale}={mp}, {id}({date})={ec}'.format(locale=localeId, mp=unicode(meetpunt), id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                    num_waarnemingen += 1
                    meetpunten.add(meetpunt)
                elif int(waarneming.waarde) != int(ec):
                    waarneming.waarde = ec
                    waarneming.save()
                    logger.info('{locale}={mp}, {id}({date})={ec}'.format(locale=localeId, mp=unicode(meetpunt), id=waarneming.naam, date=waarneming.datum, ec=waarneming.waarde))
                    num_replaced += 1
                    meetpunten.add(meetpunt)
            instances,meta = api.get_survey_instances(surveyId=surveyId, beginDate=beginDate, since=meta['since'])
    logger.info('Aantal nieuwe metingen: {meet}, bijgewerkt: {repl}'.format(meet=num_waarnemingen,repl=num_replaced))
    return meetpunten

class Command(BaseCommand):
    args = ''
    help = 'Importeer metingen vanuit akvo flow'
    option_list = BaseCommand.option_list + (
            make_option('--akvo',
                action='store',
                dest = 'akvo',
                default = 1,
                help = 'id van Akvoflow configuratie'),
            make_option('--cartodb',
                action='store',
                dest = 'cartodb',
                default = 1,
                help = 'id van Cartodb configuratie'),
            make_option('--project',
                action='store',
                dest = 'proj',
                default = 1,
                help = 'id van project locatie'),
            make_option('--user',
                action='store',
                dest = 'user',
                default = 'akvo',
                help = 'user name'),
        )

    def handle(self, *args, **options):
        
        akvo = AkvoFlow.objects.get(pk=options.get('akvo'))
        api = FlowAPI(instance=akvo.instance, key=akvo.key, secret=akvo.secret)
        cartodb = CartoDb.objects.get(pk=options.get('cartodb'))
    
        project = ProjectLocatie.objects.get(pk=options.get('proj'))
        user = User.objects.get(username=options.get('user'))

        try:
            logger.debug('Meetpuntgegevens ophalen')
            mp = importAkvoRegistration(api, akvo, projectlocatie=project,user=user)
            logger.debug('Waarnemingen ophalen')
            mp.update(importAkvoMonitoring(api, akvo))
            
            if mp:
                logger.debug('Grafieken aanpassen')
                util.updateSeries(mp, user)
                logger.debug('Cartodb actualiseren')
                util.updateCartodb(cartodb, mp)
            
            akvo.last_update = timezone.now()
            akvo.save()        
        except Exception as e:
            logger.exception('Probleem met verwerken nieuwe EC metingen: %s',e)
        finally:
            pass

{'fraction_non_alphanumeric': 0.1027672802633183, 'fraction_numerical': 0.0041854606038441225, 'mean_word_length': 2.202758979698074, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1352270', 'n_tokens_mistral': 7765, 'n_tokens_neox': 7261, 'n_words': 1345}