#!/usr/bin/env python3
#coding: utf-8

###############################MODULES###############################
###DIVERS###
import json, random, re, datetime, urllib

###SCRAPING###
import mechanize
import urllib.parse as urlP

###IMAGE###
from PIL import ImageFile

###TWITTER API###
import tweepy

###############################CREDENTIALS##############################
consumer_key = 'o4btJ3ffmKbkIOSeYd8uczGyn'
consumer_secret = 'aEiWz1VWekWwLArRmJmM9Z3RGj98x3DuZwMd359Lv2DM1e52Jd'

access_token = '1225365225068728320-mLZXueeQmDBOnLc4JJpseznaCy58LY'
access_token_secret = 'buHu9NI9dCHpwHkupS8OXfvTxsf3i8sn52DTIQoRRC8Rp'

tomtom_api_key = 'GYNAQ6sx8c98oqXqGGOmvqvgOYn0FARQ'

##################VÉRIFIER QUE LE PROGRAMME PEUT S'ÉXÉCUTER#################
with open('balade_dépendences/h_arriv.txt', 'r', encoding='utf8') as h:
    h_arriv = h.read()
    if len(h_arriv) == 0:
        print('Pas d\'heure d\'arrivée prévue, on passe à la suite')
    else:
        h_arriv = datetime.datetime.strptime(''.join(h_arriv.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
        maintenant = datetime.datetime.now(h_arriv.tzinfo)

        print('Heure d\'arrivée prévue : %s ' % h_arriv)
        print('Heure d\'exécution du programme : %s' % maintenant)

        if h_arriv > maintenant:
            print('quitter le programme')
            quit()

#######FONCTION POUR TROUVER LA TAILLE DE L'IMAGE SANS À TÉLÉCHARGER######
def getsizes(uri):
    # get file size *and* image size (None if not known)
    file = urllib.request.urlopen(uri)
    uri_size = file.headers.get("content-length")
    if uri_size:
        uri_size = int(uri_size)
    p = ImageFile.Parser()
    while True:
        uri_data = file.read(1024)
        if not uri_data:
            break
        p.feed(uri_data)
        if p.image:
            return uri_size, p.image.size
    file.close()
    return(uri_size, None)

##########################LATITUDE/LONGITUDE##########################
###fonction qui checke si la latitude est comprise dans le rayon voulu
def check_lat(val):
    if lat_base - r <= val <= lat_base + r:
        return True
    return False

###fonction qui checke si la longitude est comprise dans le rayon voulu
def check_long(val):
    if long_base-r <= val <= long_base+r:
        return True
    return False

##########################LISTE COMMUNES#######################
with open('balade_dépendences/liste_communes_clean.json', 'r', encoding="utf8") as f:
    data = f.read()
    d = json.loads(data)

##################RÉCUPÉRER LES COMMUNES DÉJÀ VISITÉES##################
###ouvre le log, récupère les communes et prend la derniere
with open('balade_dépendences/communes_visitées', 'r', encoding='utf8') as f:
    comm_visit = f.read()
    comm_visit = comm_visit.splitlines()
    ###pour avoir le dernier élément de la liste
    comm_visit.reverse()

index_derniere_commune = d['nom_commune'].index(comm_visit[0])

###remplace la latitude et la longitude de départ avec les valeurs de la commune précédente
lat_base = float(d['latitude'][index_derniere_commune])
long_base = float(d['longitude'][index_derniere_commune])

#1 km +- = à km_lat degrés
km_lat = 0.0090437173295
#r correspond environ à un rayon de 30 km
r = 15*km_lat

foirages = 0

compteur = 0

###on crée 2 listes pour ra+nger les valeurs correspondant au rayon souhaité
lat_good = []
long_good = []

###affiche seulement les communes qui correspondent et leur nom
for index in range(len(d['latitude'])):
    try:
        if check_lat(float(d['latitude'][index])):
            tuplo = (index, d['nom_commune'][index])
            lat_good.append(tuplo)
    except IndexError:
        foirages += 1
        print('oupsi')

###range dans long_good les villages dans le rayon souhaité
for i in lat_good:
    try:
        if check_long(float(d['longitude'][i[0]])):
            long_good.append(i)
            compteur += 1
    except IndexError:
        foirages +=1
        print('oupsi')

###checker si le village est déjà dans la liste des communes visitées
compte = 0
long_goodok = []

for index, village in long_good:
    # print("checking if %s is in comm_visit" % (village))
    if village not in comm_visit:
        # print("not in comm_visit. valid.")
        long_goodok.append(long_good[compte])
    compte += 1

long_good = long_goodok

### ajouter la commune visitée dans un fichier
with open('balade_dépendences/communes_visitées', 'a', encoding='utf8') as f:
    try:
        commune_selec = random.choice(long_good)[1]
        f.write(commune_selec+'\n')
    except IndexError:
        print('Pas de village dans le rayon. :(')

###récupérer la latitude/longitude de la commune_selec
index_commune_selec = d['nom_commune'].index(commune_selec)

###remplace la latitude et la longitude de départ avec les valeurs de la commune précédente
lat_fin = d['latitude'][index_commune_selec]
long_fin = d['longitude'][index_commune_selec]

###########RÉCUPÉRER LE TEMPS DE TRAJET+LONGUEUR DU TRAJET############
###les clés d'accès à l'API de TomTom sont dans accès.py (pour l'instant)
###il faut récupérer le temps de trajet et faire la partie qui checke le temps entre chaque post en fonction du temps de trajet
tomtom_url = 'https://api.tomtom.com/routing/1/calculateRoute/{0}%2C{1}%3A{2}%2C{3}/json?avoid=unpavedRoads&travelMode=pedestrian&key={4}'.format(lat_base, long_base, lat_fin, long_fin, tomtom_api_key)

getData = urllib.request.urlopen(tomtom_url).read()
result = json.loads(getData.decode('utf-8'))

longueur_trajet = result['routes'][0]['summary']['lengthInMeters']
temps_trajet = result['routes'][0]['summary']['travelTimeInSeconds']
heure_arrivée = result['routes'][0]['summary']['arrivalTime']

with open('balade_dépendences/h_arriv.txt', 'w', encoding='utf8') as h:
    h.write(heure_arrivée)

temps_trajet = str(datetime.timedelta(seconds=temps_trajet))
tps_vars = re.split(':', temps_trajet)

temps_trajet = '%sh%s' % (tps_vars[0], tps_vars[1])

##############################ENJOLIVER LE STATUT################################
###IMAGE VILLLAGE###
##maintenant il faut récupérer la première image de Google Image quand on tape le nom de la ville
br = mechanize.Browser()
br.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36')]
br.set_handle_robots(False)

commune_selec = commune_selec.encode('utf-8')
url = 'https://www.google.com/search?hl=en&tbm=isch&q=' + urlP.quote(commune_selec) + '&source=lnms'
data = br.open(url, timeout=50)
source = data.read()

###regex pour récupérer l'URL de l'image dans le code source, parce qu'elle n'est pas dans une balise donc on peut pas la trouver avec un sélecteur css
img = re.findall(r'\["([^"]+\.jpg)",[0-9]+,[0-9]+\]', str(source))

###téléchargement de la première image
###si la première ne correspond pas on essaie la suivante jusqu'à ce que ça marche
n = 0
while True:
    try:
        ###pour ne pas avoir d'images trop grandes pour Twitter
        size = getsizes(img[n])[0]
        if size >= 3000072:
            print('trop grand')
            n += 1
            continue
        file_img = 'balade_dépendences/image.jpg'
        br.retrieve(img[n], file_img)
        print('image n°%s téléchargée' % (n+1))
        break
    except:
        print('image corrompue')
        n += 1
	break
###PHRASE###
##on choisit une tournure de phrase au hasard et on inclut le nom de la commune sélectionnée
phr = ["Direction %s", "C'est parti pour %s !", "Aujourd'hui je vais à %s", "Objectif : %s !", "Cap sur %s", "Allons à %s", "En route pour %s", "Départ pour %s", "Prochaine étape : %s", "Et la prochaine commune est %s", "Maintenant je me dirige vers %s", "Aujourd'hui j'ai décidé d'aller à %s", "En déplacement à %s", "Bonjour %s !", "%s,  me voilà !", "%s est la prochaine étape sur ma route", "%s en vue !"]
phrase = random.choice(phr) % commune_selec.decode('utf-8')
print(phrase)

#longueur du trajet
longueur_trajet = str(longueur_trajet)
longueur_trajet = '%s,%s km' % (longueur_trajet[:len(longueur_trajet)-3], longueur_trajet[len(longueur_trajet)-3:])

phrase_tps = '%s de route, arrivée prévue dans %s' % (longueur_trajet, temps_trajet)
print(phrase_tps)

######################################TWEET########################################
###identification à l'API de Twitter
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)

###post en lui-même, en 2 parties (texte et image)
photo_path = 'balade_dépendences/image.jpg'
api.update_with_media(photo_path, status=phrase+'\n'+phrase_tps)
print('Post envoyé !')

######################################INTERACTION########################################
phrases = ['Je suis déjà passé par %s !', 'Je suis déjà allé à %s :)', 'Je la trouve sympa la commune de %s.', 'Tiens, %s me dit quelque chose.']

###on prend la 30e commune en partant de la fin (sachant que l'array comm_visit est inversée)
ancienne_commune = comm_visit[120]
print(ancienne_commune.upper())
try:
    for status in tweepy.Cursor(api.search, q=ancienne_commune, lang='fr', tweet_mode='extended').items(2):
        tweet_id = status.id
        tweet_username = status.user.screen_name
        ###pour ne pas se répondre à soi-même
        if tweet_username == 'baladecampagne':
            print('On ne se répond pas à soi-même enfin')
        else:
            ###si le tweet est retweeté, afficher le texte du retweet. Sinon, afficher le texte du tweet
            if hasattr(status, 'retweeted_status'):
                tweetText = status.retweeted_status.full_text
            else:
                tweetText = status.full_text
            ###si le tweet ne contient pas le nom de la commune (ça peut arriver), ne pas répondre au tweet
            if ancienne_commune.lower() in tweetText.lower():
                tweet = tweetText
                message = random.choice(phrases)
                print(ancienne_commune.upper(), tweet)
                print('@{0} {1}'.format(tweet_username, message) % ancienne_commune, tweet_id)
                api.update_status('@{0} {1}'.format(tweet_username, message) % ancienne_commune, tweet_id)
                break
            else:
                print('Le nom de la commune n\'est pas dans le tweet, on continue')
                print('   '+tweetText)
except NameError:
    print('Pas de tweet trouvé pour '+ancienne_commune+', on continue')
