<commit_before># -*- coding: utf-8 -*-
"""
@author: Daniel Antunes & Cédric Hubert

"""

import vrep
import sys
import numpy as np
import random

# declaration des constantes
DELAY = 150
NB_ITERATIONS = 1500
NB_ACTIONS_ECHANTILLONAGE = 50
NS = 250
K = 5
# declaration des variables
LE = []         #liste erreur à chaque pas de temps
LEm= []         #liste erreur moyenne à chaque pas de temps
data_MP = []	#de la forme [param1,param2,param3,ecart]
data_P = []	#de la forme [param1,param2,param3,distance]

vrep.simxFinish(-1) # fermeture de toutes les connexions ouvertes
clientID = vrep.simxStart('127.0.0.1',19999,True,True,5000,5) #etablissement de la connexion avec V-REP

if clientID == -1:
    print("La connexion a échouée")
    sys.exit("Connexion échouée")
else:
    print("Connexion au seveur remote API établie")

# recuperation des "handlers" dans la scene
returnCode, robotHandle = vrep.simxGetObjectHandle(clientID,"Robot", vrep.simx_opmode_oneshot_wait)
returnCode, leftMotor = vrep.simxGetObjectHandle(clientID,"leftMotor", vrep.simx_opmode_oneshot_wait)
returnCode, rightMotor = vrep.simxGetObjectHandle(clientID,"rightMotor", vrep.simx_opmode_oneshot_wait)
returnCode, balle = vrep.simxGetObjectHandle(clientID,"balle", vrep.simx_opmode_oneshot_wait)

returnVal = vrep.simxCallScriptFunction(clientID,"",)

def execute_action(cID, leftHandle, rightHandle, (speed_left,speed_right,frequency), botHandle, ballHandle):
    vrep.simxSetJointTargetVelocity(cID,leftHandle,speed_left,vrep.simx_opmode_oneshot)
    vrep.simxSetJointTargetVelocity(cID,rightHandle,speed_right,vrep.simx_opmode_oneshot)
    if frequency > 0.66 and frequency <= 1:
        # ball jumps to robot
        returnCode1, pos1 = vrep.simxGetObjectPosition(cID,botHandle,-1,vrep.simx_opmode_oneshot_wait)
        returnCode2, pos2 = vrep.simxGetObjectPosition(cID,ballHandle,-1,vrep.simx_opmode_oneshot_wait)
        vrep.simxSetObjectPosition(cID,ballHandle,-1,[pos1[0],pos1[1],pos2[2]],vrep.simx_opmode_oneshot)
#        signeX = -1 if (pos2[0]-pos1[0] < 0) else 1
#        signeY = -1 if (pos2[1]-pos1[1] < 0) else 1
#        if np.abs(pos1[0]-pos2[0]) < np.abs(pos1[1]-pos2[1]): # balle plus loin dans l'axe y
#            ratio = np.abs(pos1[0]-pos2[0])/np.abs(pos1[1]-pos2[1])
#            vrep.simxSetObjectPosition(cID,ballHandle,botHandle,[largeurRobot*signeX*ratio,largeurRobot*signeY,0],vrep.simx_opmode_oneshot)
#        else: # balle plus loin sur l'axe x
#            ratio = np.abs(pos1[1]-pos2[1])/np.abs(pos1[0]-pos2[0]) if np.abs(pos1[0]-pos2[0]) != 0 else 1
#            vrep.simxSetObjectPosition(cID,ballHandle,botHandle,[largeurRobot*signeX,largeurRobot*signeY*ratio,0],vrep.simx_opmode_oneshot)
    if frequency >= 0 and frequency <= 0.33:
        # ball goes to random position
        returnCode1, pos1 = vrep.simxGetObjectPosition(cID,botHandle,-1,vrep.simx_opmode_oneshot_wait)
        returnCode2, pos2 = vrep.simxGetObjectPosition(cID,ballHandle,-1,vrep.simx_opmode_oneshot_wait)
        vrep.simxSetObjectPosition(cID,ballHandle,-1,[random.uniform(-2.3,2.3),random.uniform(-2.3,2.3),pos2[2]],vrep.simx_opmode_oneshot)

def distance(cID):
#    returnCode1, position1 = vrep.simxGetObjectPosition(cID,handle1,-1,vrep.simx_opmode_oneshot_wait)
#    returnCode2, position2 = vrep.simxGetObjectPosition(cID,handle2,-1,vrep.simx_opmode_oneshot_wait)
#    if(returnCode1 or returnCode2):
#        print("Erreur dans requête de position")
#        sys.exit("simxGetObjectionPosition error")
#    else:
#        return np.sqrt((position1[0]-position2[0])**2+(position1[1]-position2[1])**2)
    retCode, dist = vrep.simxGetDistanceHandle(cID,"distance",vrep.simx_opmode_oneshot)
    retCode, distance = vrep.simxReadDistance(cID,dist,vrep.simx_opmode_oneshot)
    return distance

def bouclePrincipale():
	t=0
	possibleActions = []	#liste d'actions possibles à ce step
	LPActions= []		#learning progress calculé pour chaque action

	while t < NB_ITERATIONS:
		'''
			Génération liste d'actions possibles
		'''
		for i in range(NB_ACTIONS_ECHANTILLONAGE):
			possibleActions.append( [random.uniform(-1,1) , random.uniform(-1,1) , random.uniform(0,1)] )
		'''
			Selection de l'action
		'''
		for i in range(len(possibleActions)):

			Ep = MetaPredictionMP(possibleActions[i]) #calcul de la prediction de l'erreur
			tempLE = list(LE) #on clone LE
			tempLE.append(Ep) #on rajoute à la liste clonée l'erreur prédite
			Emp= np.mean(tempLE[-DELAY:]) #TODO calculer la moyenne des exemples existants s'il n'y en a pas encore DELAY
			LP= -(-Emp-LEm[t+1-DELAY])
			LPActions.append(LP)

		if(random.random() > 0.1):			#exploitation
			indiceActionChoisie = np.argmax(LPActions)
		else:								#exploration
			indiceActionChoisie = 0

		'''
			Prediction de la machine P
		'''
		S = PredictionP(possibleActions[indiceActionChoisie])
		'''
			Réalisation de l'action dans le simulateur
		'''
		#TODO executer l'action dans le simulateur

		#On stoppe le robot
#		vrep.simxSetJointTargetVelocity(clientID,leftMotor,0,vrep.simx_opmode_oneshot_wait)
#		vrep.simxSetJointTargetVelocity(clientID,rightMotor,0,vrep.simx_opmode_oneshot_wait)
		t += 1
		'''
			Vérification résultat action
		'''
		# calcul de la distance, ce serait bien de faire avec senseurs, sinon directement avec les fonctions de VREP
		Sa = distance(clientID)
		#sauvegarde dans data_P
		ajoutData=list(possibleActions[indiceActionChoisie])
		ajoutData.append(Sa)
		data_P.append(ajoutData)
		#calcul de l'erreur
		E = abs(S-Sa)
		#sauvegarde dans data_MP
		ajoutData=list(possibleActions[indiceActionChoisie])
		ajoutData.append(E) #a verfifier
		data_MP.append(ajoutData)
		#maj listes
		LE.append(E)
		Em = np.mean(LE[-DELAY:]) #TODO que si t > DELAY
		LEm.append(Em)
	return 0

#TODO pour les deux algos k-moyenne, renvoyer la moyenne des existants au lieu de 0 dans le cas ou len(data) < K ???
def MetaPredictionMP(action):
	d=[]	#on va ranger dans cette liste l'écart entre notre action et chaque exemple de la bdd
	res=0	#valeur moyenne des K plus proches voisins, à retourner
	for i in range(len(data_MP)):
		d1=abs(data_MP[i][0]-action[0])
		d2=abs(data_MP[i][1]-action[1])
		d3=abs(data_MP[i][2]-action[2])
		dtot=d1+d2+d3
		d.append([dtot,i])
	d.sort()	#on trie dans l'ordre croissant des écarts
	if K <= len(data_MP):
		for i in range(K):
			res += data_MP[i][3]
		res = res / K
	return res

def PredictionP(action):
	d=[]	#on va ranger dans cette liste l'écart entre notre action et chaque exemple de la bdd
	res=0	#valeur moyenne des K plus proches voisins, à retourner
	for i in range(len(data_P)):
		d1=abs(data_P[i][0]-action[0])
		d2=abs(data_P[i][1]-action[1])
		d3=abs(data_P[i][2]-action[2])
		dtot=d1+d2+d3
		d.append([dtot,i])
	d.sort()	#on trie dans l'ordre croissant des écarts
	if K <= len(data_P):
		for i in range(K):
			res += data_P[i][3]
		res = res / K

	return res

<commit_msg>corrections et TODOs<commit_after># -*- coding: utf-8 -*-
"""
@author: Daniel Antunes & Cédric Hubert

"""

import vrep
import sys
import numpy as np
import random

# declaration des constantes
DELAY = 150
NB_ITERATIONS = 1500
NB_ACTIONS_ECHANTILLONAGE = 50
NS = 250
K = 5
# declaration des variables
LE = []         #liste erreur à chaque pas de temps
LEm= []         #liste erreur moyenne à chaque pas de temps
data_MP = []    #de la forme [param1,param2,param3,ecart]
data_P = [] #de la forme [param1,param2,param3,distance]

vrep.simxFinish(-1) # fermeture de toutes les connexions ouvertes
clientID = vrep.simxStart('127.0.0.1',19999,True,True,5000,5) #etablissement de la connexion avec V-REP

if clientID == -1:
    print("La connexion a échouée")
    sys.exit("Connexion échouée")
else:
    print("Connexion au seveur remote API établie")

# recuperation des "handlers" dans la scene
returnCode, robotHandle = vrep.simxGetObjectHandle(clientID,"Robot", vrep.simx_opmode_oneshot_wait)
returnCode, leftMotor = vrep.simxGetObjectHandle(clientID,"leftMotor", vrep.simx_opmode_oneshot_wait)
returnCode, rightMotor = vrep.simxGetObjectHandle(clientID,"rightMotor", vrep.simx_opmode_oneshot_wait)
returnCode, balle = vrep.simxGetObjectHandle(clientID,"balle", vrep.simx_opmode_oneshot_wait)

returnVal = vrep.simxCallScriptFunction(clientID,"",)

def execute_action(cID, leftHandle, rightHandle, action, botHandle, ballHandle):
    vrep.simxSetJointTargetVelocity(cID,leftHandle,action[0],vrep.simx_opmode_oneshot)
    vrep.simxSetJointTargetVelocity(cID,rightHandle,action[1],vrep.simx_opmode_oneshot)
    if action[2] > 0.66 and action[2] <= 1:
        # ball jumps to robot
        returnCode1, pos1 = vrep.simxGetObjectPosition(cID,botHandle,-1,vrep.simx_opmode_oneshot_wait)
        returnCode2, pos2 = vrep.simxGetObjectPosition(cID,ballHandle,-1,vrep.simx_opmode_oneshot_wait)
        vrep.simxSetObjectPosition(cID,ballHandle,-1,[pos1[0],pos1[1],pos2[2]],vrep.simx_opmode_oneshot)
#        signeX = -1 if (pos2[0]-pos1[0] < 0) else 1
#        signeY = -1 if (pos2[1]-pos1[1] < 0) else 1
#        if np.abs(pos1[0]-pos2[0]) < np.abs(pos1[1]-pos2[1]): # balle plus loin dans l'axe y
#            ratio = np.abs(pos1[0]-pos2[0])/np.abs(pos1[1]-pos2[1])
#            vrep.simxSetObjectPosition(cID,ballHandle,botHandle,[largeurRobot*signeX*ratio,largeurRobot*signeY,0],vrep.simx_opmode_oneshot)
#        else: # balle plus loin sur l'axe x
#            ratio = np.abs(pos1[1]-pos2[1])/np.abs(pos1[0]-pos2[0]) if np.abs(pos1[0]-pos2[0]) != 0 else 1
#            vrep.simxSetObjectPosition(cID,ballHandle,botHandle,[largeurRobot*signeX,largeurRobot*signeY*ratio,0],vrep.simx_opmode_oneshot)
    if action[2] >= 0 and action[2] <= 0.33:
        # ball goes to random position
        returnCode1, pos1 = vrep.simxGetObjectPosition(cID,botHandle,-1,vrep.simx_opmode_oneshot_wait)
        returnCode2, pos2 = vrep.simxGetObjectPosition(cID,ballHandle,-1,vrep.simx_opmode_oneshot_wait)
        vrep.simxSetObjectPosition(cID,ballHandle,-1,[random.uniform(-2.3,2.3),random.uniform(-2.3,2.3),pos2[2]],vrep.simx_opmode_oneshot)

def distance(cID):
#    returnCode1, position1 = vrep.simxGetObjectPosition(cID,handle1,-1,vrep.simx_opmode_oneshot_wait)
#    returnCode2, position2 = vrep.simxGetObjectPosition(cID,handle2,-1,vrep.simx_opmode_oneshot_wait)
#    if(returnCode1 or returnCode2):
#        print("Erreur dans requête de position")
#        sys.exit("simxGetObjectionPosition error")
#    else:
#        return np.sqrt((position1[0]-position2[0])**2+(position1[1]-position2[1])**2)
    retCode, dist = vrep.simxGetDistanceHandle(cID,"distance",vrep.simx_opmode_oneshot)
    retCode, distance = vrep.simxReadDistance(cID,dist,vrep.simx_opmode_oneshot)
    return distance

def bouclePrincipale():
    t=0

    while t < NB_ITERATIONS:
        possibleActions = []    #liste d'actions possibles à ce step
        LPActions= []           #learning progress calculé pour chaque action
        '''
            Génération liste d'actions possibles
        '''
        for i in range(NB_ACTIONS_ECHANTILLONAGE):
            possibleActions.append( [random.uniform(-1,1) , random.uniform(-1,1) , random.uniform(0,1)] )
        '''
            Selection de l'action
        '''
        for i in range(len(possibleActions)):

            Ep = MetaPredictionMP(possibleActions[i]) #calcul de la prediction de l'erreur
            tempLE = list(LE) #on clone LE
            tempLE.append(Ep) #on rajoute à la liste clonée l'erreur prédite
            if t == 0:
                LP = Ep
            if t != 0 and t < DELAY:
                Emp = np.mean(tempLE)
                LP = -(Emp-LEm[0])
            else:
                Emp= np.mean(tempLE[-DELAY:])
                LP = -(Emp-LEm[t+1-DELAY])
            LPActions.append(LP)

        if(random.random() > 0.1):          #exploitation
            indiceActionChoisie = np.argmax(LPActions)
        else:                               #exploration
            indiceActionChoisie = 0

        '''
            Prediction de la machine P
        '''
        S = PredictionP(possibleActions[indiceActionChoisie])

        '''
            Réalisation de l'action dans le simulateur
        '''
        execute_action(clientID,leftMotor,rightMotor,possibleActions[indiceActionChoisie],robotHandle,balle)

        #On stoppe le robot
#       vrep.simxSetJointTargetVelocity(clientID,leftMotor,0,vrep.simx_opmode_oneshot_wait)
#       vrep.simxSetJointTargetVelocity(clientID,rightMotor,0,vrep.simx_opmode_oneshot_wait)
        t += 1
        '''
            Vérification résultat action
        '''
        # calcul de la distance, ce serait bien de faire avec senseurs, sinon directement avec les fonctions de VREP
        Sa = distance(clientID)
        #sauvegarde dans data_P
        ajoutData=list(possibleActions[indiceActionChoisie])
        ajoutData.append(Sa)
        data_P.append(ajoutData)
        #calcul de l'erreur
        E = abs(S-Sa)
        #sauvegarde dans data_MP
        ajoutData=list(possibleActions[indiceActionChoisie])
        ajoutData.append(E) #a verfifier
        data_MP.append(ajoutData)
        #maj listes
        LE.append(E)
        if len(LE) < DELAY:
            Em = np.mean(LE)
        else:
            Em = np.mean(LE[-DELAY:])
        LEm.append(Em)

    return 0

def MetaPredictionMP(action):
    d=[]    #on va ranger dans cette liste l'écart entre notre action et chaque exemple de la bdd
    res=0   #valeur moyenne des K plus proches voisins, à retourner
    if len(data_MP) == 0:
        return res
    if len(data_MP) < K:
        for i in range(len(data_MP)):
            res += data_MP[i][3]
        res = res / len(data_MP)
    else:
        for i in range(len(data_MP)):
            d1=abs(data_MP[i][0]-action[0])
            d2=abs(data_MP[i][1]-action[1])
            d3=abs(data_MP[i][2]-action[2])
            dtot=d1+d2+d3
            d.append([dtot,i])
        d.sort()    #on trie dans l'ordre croissant des écarts
        for i in range(K):
            res += data_MP[i][3]
        res = res / K
    return res

def PredictionP(action):
    d=[]    #on va ranger dans cette liste l'écart entre notre action et chaque exemple de la bdd
    res=0   #valeur moyenne des K plus proches voisins, à retourner
    if len(data_P) == 0:
        return res
    if len(data_P) < K:
        for i in range(len(data_P)):
            res += data_P[i][3]
        res = res / len(data_P)
    else:
        for i in range(len(data_P)):
            d1=abs(data_P[i][0]-action[0])
            d2=abs(data_P[i][1]-action[1])
            d3=abs(data_P[i][2]-action[2])
            dtot=d1+d2+d3
            d.append([dtot,i])
        d.sort()    #on trie dans l'ordre croissant des écarts
        if K <= len(data_P):
            for i in range(K):
                res += data_P[i][3]
            res = res / K

    return res

bouclePrincipale()

            <|endoftext|>


<commit_before>"""Where player runs the game"""

import random
import time

import board
import conversion
import games
from settings import (NUMBER_OF_TRIALS,
                      RECORD_FILE,
                      SAVE_PROGRESS)

class Game(object):
    def __init__(self,
                 record_file=RECORD_FILE,
                 save_progress=SAVE_PROGRESS,
                 test_mode=False):

        self.record_total_time = 0.0
        self.record_total_trials = 0
        self.trial_duration = 0.0

        self.record_file = record_file
        self.save_progress = save_progress
        self.test_mode = test_mode

        self.x_loc_chess, self.y_loc_chess = board.identify_random_square()
        self.location = conversion.coordinate_to_alg(self.x_loc_chess,
                                                     self.y_loc_chess)

    def main(self):
        self.display_board()
        self.display_status_information()
        quit = self.get_user_input()
        if not quit:
            # check to see if user quit game so we don't save
            self.record_progress()
        return quit

    def write_record_to_file(self, a_string, file_name):
        with open(file_name, 'w') as f:
            f.write(a_string)

    def get_record_from_file(self, file_name):
        with open(file_name, 'r') as f:
            result = f.readline()
        return result

    def get_user_input(self, test_string=None):
        """ Ask for input from the user """
        start = time.time()
        attempt = input('Enter highlighted square, or \'quit\': ')
        end = time.time()
        if attempt == self.location:
            print("CORRECT!!")
        elif attempt == "quit" or attempt == "q":
            print("Exiting, current trial will not be saved.")
            return True
        else:
            print("Wrong, the answer was {0}".format(self.location))
        self.trial_duration = end - start
        print("Attempt took {0:.03f} seconds".format(self.trial_duration))
        return False

    def display_board(self):
        games_source = games.GamePositions()
        current_board = board.Board(games_source.random_game(),
                                    orientation=random.choice((True, False)))
        current_board.highlight_square(self.x_loc_chess,
                                       self.y_loc_chess)
        current_board.update_board_string()
        print(current_board)

    def display_status_information(self):
        if self.save_progress:
            try:
                # Try to retrieve data from record file
                record = self.get_record_from_file(self.record_file).split(',')
                self.record_total_time = float(record[0])
                self.record_total_trials = int(record[1])
                template = "Average time: {0:.2f}\nTotal seconds: {1:.2f}, \
Total trials: {2}"
                record_total_float = float(self.record_total_trials)
                trial_avg = self.record_total_time/record_total_float
                print(template.format(trial_avg,
                                      self.record_total_time,
                                      self.record_total_trials))
            except FileNotFoundError:
                print("No record file found.\n\
Creating a new one after this trial: {0}".format(self.record_file))

    def record_progress(self):
        if self.save_progress:
            self.record_total_time += self.trial_duration
            self.record_total_trials = self.record_total_trials + 1
            record = "{0},{1}".format(self.record_total_time,
                                      self.record_total_trials)
            self.write_record_to_file(record, self.record_file)

if __name__ == '__main__':
    for trial_num in range(NUMBER_OF_TRIALS):
        game_trial = Game()
        if game_trial.main():
            # if main() returns True at any time, it means the user quit
            break
<commit_msg>Move static file functions, update docstrings, and make some variables more configurable<commit_after>"""Where player runs the game"""

import random
import time

import board
import conversion
import games
from settings import (NUMBER_OF_TRIALS,
                      RECORD_FILE,
                      SAVE_PROGRESS)

# Static helper functions
def write_record_to_file(a_string, file_name):
    """Write one line string to file_name. Always overwrites"""
    with open(file_name, 'w') as record_file:
        record_file.write(a_string)

def get_record_from_file(file_name):
    """Get first (and only) line back from file_name and return it"""
    with open(file_name, 'r') as record_file:
        result = record_file.readline()
    return result

class Game(object):
    """Class which represents a single trial of the game"""

    # pylint: disable=too-many-instance-attributes
    # This is where we integrate other classes, so having a lot of
    # configuration attributes is necessary

    def __init__(self,
                 record_file=RECORD_FILE,
                 save_progress=SAVE_PROGRESS,
                 test_mode=False):

        self.record_total_time = 0.0
        self.record_total_trials = 0
        self.trial_duration = 0.0

        self.record_file = record_file
        self.save_progress = save_progress
        self.test_mode = test_mode

        self.orientation = random.choice((True, False))
        self.player_color = random.choice(("white", "black"))
        self.x_loc_chess, self.y_loc_chess = board.identify_random_square()
        self.location = conversion.convert_notation(self.x_loc_chess,
                                                    self.y_loc_chess,
                                                    "alg",
                                                    self.player_color)

    def main(self):
        """Primary entry point where a single game/trial is played.
        Returns True if user quit the game otherwise false"""
        self.display_board()
        self.display_status_information()
        quit_game = self.get_user_input()
        if not quit_game:
            # check to see if user quit game so we don't save
            self.record_progress()
        return quit_game

    def get_user_input(self):
        """ Ask for input from the user """
        start = time.time()
        attempt = input('Enter highlighted square, or \'quit\': ')
        end = time.time()
        if attempt == self.location:
            print("CORRECT!!")
        elif attempt == "quit" or attempt == "q":
            print("Exiting, current trial will not be saved.")
            return True
        else:
            print("{0} is wrong, the answer was {1}".format(attempt,
                                                            self.location))
        self.trial_duration = end - start
        print("Attempt took {0:.03f} seconds".format(self.trial_duration))
        return False

    def display_board(self):
        """Display the updated board with highlighted square"""
        games_source = games.GamePositions()
        current_board = board.Board(games_source.random_game(),
                                    orientation=self.orientation)
        current_board.highlight_square(self.x_loc_chess,
                                       self.y_loc_chess)
        current_board.update_board_string()
        print(current_board)

    def display_status_information(self):
        """Shows game status to the player"""
        if self.save_progress:
            try:
                # Try to retrieve data from record file
                record = get_record_from_file(self.record_file).split(',')
                self.record_total_time = float(record[0])
                self.record_total_trials = int(record[1])
                template = ("Average time: {0:.2f}, Playing as: {1}\n"
                            "Total seconds: {2:.2f}, Total trials: {3}")
                record_total_float = float(self.record_total_trials)
                trial_avg = self.record_total_time/record_total_float
                print(template.format(trial_avg,
                                      self.player_color.capitalize(),
                                      self.record_total_time,
                                      self.record_total_trials))
            except FileNotFoundError:
                print("No record file found.\n\
Creating a new one after this trial: {0}".format(self.record_file))

    def record_progress(self):
        """Saves string representing game progress, if save_progress is True"""
        if self.save_progress:
            self.record_total_time += self.trial_duration
            self.record_total_trials = self.record_total_trials + 1
            record = "{0},{1}".format(self.record_total_time,
                                      self.record_total_trials)
            write_record_to_file(record, self.record_file)

if __name__ == '__main__':
    for trial_num in range(NUMBER_OF_TRIALS):
        game_trial = Game()
        if game_trial.main():
            # if main() returns True at any time, it means the user quit
            break
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Main recognizer loop: wait for a trigger then perform and handle
recognition."""

import logging
import os
import sys
import threading
import time

import configargparse
from googlesamples.assistant import auth_helpers

import audio
import action
import i18n
import speech
import tts

# =============================================================================
#
# Hey, Makers!
#
# Are you looking for actor.add_keyword? Do you want to add a new command?
# You need to edit src/action.py. Check out the instructions at:
# https://aiyprojects.withgoogle.com/voice/#makers-guide-3-3--create-a-new-voice-command-or-action
#
# =============================================================================

logging.basicConfig(
    level=logging.INFO,
    format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
)
logger = logging.getLogger('main')

CACHE_DIR = os.getenv('XDG_CACHE_HOME') or os.path.expanduser('~/.cache')
VR_CACHE_DIR = os.path.join(CACHE_DIR, 'voice-recognizer')

CONFIG_DIR = os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')
CONFIG_FILES = [
    '/etc/voice-recognizer.ini',
    os.path.join(CONFIG_DIR, 'voice-recognizer.ini')
]

# Legacy fallback: old locations of secrets/credentials.
OLD_CLIENT_SECRETS = os.path.expanduser('~/client_secrets.json')
OLD_SERVICE_CREDENTIALS = os.path.expanduser('~/credentials.json')

ASSISTANT_CREDENTIALS = os.path.join(VR_CACHE_DIR, 'assistant_credentials.json')
ASSISTANT_OAUTH_SCOPE = 'https://www.googleapis.com/auth/assistant-sdk-prototype'

PID_FILE = '/run/user/%d/voice-recognizer.pid' % os.getuid()

def try_to_get_credentials(client_secrets):
    """Try to get credentials, or print an error and quit on failure."""

    if os.path.exists(ASSISTANT_CREDENTIALS):
        return auth_helpers.load_credentials(
            ASSISTANT_CREDENTIALS, scopes=[ASSISTANT_OAUTH_SCOPE])

    if not os.path.exists(VR_CACHE_DIR):
        os.mkdir(VR_CACHE_DIR)

    if not os.path.exists(client_secrets) and os.path.exists(OLD_CLIENT_SECRETS):
        client_secrets = OLD_CLIENT_SECRETS

    if not os.path.exists(client_secrets):
        print('You need client secrets to use the Assistant API.')
        print('Follow these instructions:')
        print('    https://developers.google.com/api-client-library/python/auth/installed-app'
              '#creatingcred')
        print('and put the file at', client_secrets)
        sys.exit(1)

    if not os.getenv('DISPLAY') and not sys.stdout.isatty():
        print("""
To use the Assistant API, manually start the application from the dev terminal.
See the "Turn on the Assistant API" section of the Voice Recognizer
User's Guide for more info.""")
        sys.exit(1)

    credentials = auth_helpers.credentials_flow_interactive(
        client_secrets, scopes=[ASSISTANT_OAUTH_SCOPE])
    auth_helpers.save_credentials(ASSISTANT_CREDENTIALS, credentials)
    logging.info('OAuth credentials initialized: %s', ASSISTANT_CREDENTIALS)
    return credentials

def create_pid_file(file_name):
    with open(file_name, 'w') as pid_file:
        pid_file.write("%d" % os.getpid())

def main():
    parser = configargparse.ArgParser(
        default_config_files=CONFIG_FILES,
        description="Act on voice commands using Google's speech recognition")
    parser.add_argument('-I', '--input-device', default='default',
                        help='Name of the audio input device')
    parser.add_argument('-O', '--output-device', default='default',
                        help='Name of the audio output device')
    parser.add_argument('-T', '--trigger', default='gpio',
                        help='Trigger to use {\'clap\', \'gpio\'}')
    parser.add_argument('--cloud-speech', action='store_true',
                        help='Use the Cloud Speech API instead of the Assistant API')
    parser.add_argument('-L', '--language', default='en-US',
                        help='Language code to use for speech (default: en-US)')
    parser.add_argument('-l', '--led-fifo', default='/tmp/status-led',
                        help='Status led control fifo')
    parser.add_argument('-p', '--pid-file', default=PID_FILE,
                        help='File containing our process id for monitoring')
    parser.add_argument('--audio-logging', action='store_true',
                        help='Log all requests and responses to WAV files in /tmp')
    parser.add_argument('--assistant-secrets',
                        help='Path to client secrets for the Assistant API')
    parser.add_argument('--cloud-speech-secrets',
                        help='Path to service account credentials for the '
                        'Cloud Speech API')

    args = parser.parse_args()

    create_pid_file(args.pid_file)
    i18n.set_language_code(args.language, gettext_install=True)

    player = audio.Player(args.output_device)

    if args.cloud_speech:
        credentials_file = os.path.expanduser(args.cloud_speech_secrets)
        if not os.path.exists(credentials_file) and os.path.exists(OLD_SERVICE_CREDENTIALS):
            credentials_file = OLD_SERVICE_CREDENTIALS
        recognizer = speech.CloudSpeechRequest(credentials_file)
    else:
        credentials = try_to_get_credentials(
            os.path.expanduser(args.assistant_secrets))
        recognizer = speech.AssistantSpeechRequest(credentials)

    recorder = audio.Recorder(
        input_device=args.input_device, channels=1,
        bytes_per_sample=speech.AUDIO_SAMPLE_SIZE,
        sample_rate_hz=speech.AUDIO_SAMPLE_RATE_HZ)
    with recorder:
        do_recognition(args, recorder, recognizer, player)

def do_recognition(args, recorder, recognizer, player):
    """Configure and run the recognizer."""
    say = tts.create_say(player)

    actor = action.make_actor(say)

    if args.cloud_speech:
        action.add_commands_just_for_cloud_speech_api(actor, say)

    recognizer.add_phrases(actor)
    recognizer.set_audio_logging_enabled(args.audio_logging)

    if args.trigger == 'gpio':
        import triggers.gpio
        triggerer = triggers.gpio.GpioTrigger(channel=23)
        msg = 'Press the button on GPIO 23'
    elif args.trigger == 'clap':
        import triggers.clap
        triggerer = triggers.clap.ClapTrigger(recorder)
        msg = 'Clap your hands'
    else:
        logger.error("Unknown trigger '%s'", args.trigger)
        return

    mic_recognizer = SyncMicRecognizer(
        actor, recognizer, recorder, player, say, triggerer, led_fifo=args.led_fifo)

    with mic_recognizer:
        if sys.stdout.isatty():
            print(msg + ' then speak, or press Ctrl+C to quit...')

        # wait for KeyboardInterrupt
        while True:
            time.sleep(1)

class SyncMicRecognizer(object):

    """Detects triggers and runs recognition in a background thread.

    This is a context manager, so it will clean up the background thread if the
    main program is interrupted.
    """

    # pylint: disable=too-many-instance-attributes

    def __init__(self, actor, recognizer, recorder, player, say, triggerer, led_fifo):
        self.actor = actor
        self.player = player
        self.recognizer = recognizer
        self.recognizer.set_endpointer_cb(self.endpointer_cb)
        self.recorder = recorder
        self.say = say
        self.triggerer = triggerer
        self.triggerer.set_callback(self.recognize)

        self.running = False

        if led_fifo and os.path.exists(led_fifo):
            self.led_fifo = led_fifo
        else:
            if led_fifo:
                logger.warning(
                    'File %s specified for --led-fifo does not exist.',
                    led_fifo)
            self.led_fifo = None
        self.recognizer_event = threading.Event()

    def __enter__(self):
        self.running = True
        threading.Thread(target=self._recognize).start()
        self.triggerer.start()
        self._status('ready')

    def __exit__(self, *args):
        self.running = False
        self.recognizer_event.set()

        self.recognizer.end_audio()

    def _status(self, status):
        if self.led_fifo:
            with open(self.led_fifo, 'w') as led:
                led.write(status + '\n')
        logger.info('%s...', status)

    def recognize(self):
        if self.recognizer_event.is_set():
            # Duplicate trigger (eg multiple button presses)
            return

        self.recognizer.reset()
        self.recorder.add_processor(self.recognizer)
        self._status('listening')
        # Tell recognizer to run
        self.recognizer_event.set()

    def endpointer_cb(self):
        self.recorder.del_processor(self.recognizer)
        self._status('thinking')

    def _recognize(self):
        while self.running:
            self.recognizer_event.wait()
            if not self.running:
                break

            logger.info('recognizing...')
            try:
                self._handle_result(self.recognizer.do_request())
            except speech.Error:
                logger.exception('Unexpected error')
                self.say(_('Unexpected error. Try again or check the logs.'))

            self.recognizer_event.clear()
            self.triggerer.start()
            self._status('ready')

    def _handle_result(self, result):
        if result.transcript and self.actor.handle(result.transcript):
            logger.info('handled local command: %s', result.transcript)
        elif result.response_audio:
            self._play_assistant_response(result.response_audio)
        elif result.transcript:
            logger.warning('%r was not handled', result.transcript)
            self.say(_("I don’t know how to answer that."))
        else:
            logger.warning('no command recognized')
            self.say(_("Could you try that again?"))

    def _play_assistant_response(self, audio_bytes):
        bytes_per_sample = speech.AUDIO_SAMPLE_SIZE
        sample_rate_hz = speech.AUDIO_SAMPLE_RATE_HZ
        logger.info('Playing %.4f seconds of audio...',
                    len(audio_bytes) / (bytes_per_sample * sample_rate_hz))
        self.player.play_bytes(audio_bytes, sample_width=bytes_per_sample,
                               sample_rate=sample_rate_hz)

if __name__ == '__main__':
    main()
<commit_msg>commit<commit_after>#!/usr/bin/env python3
# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Main recognizer loop: wait for a trigger then perform and handle
recognition."""

import logging
import os
import sys
import threading
import time

import configargparse
from googlesamples.assistant import auth_helpers

import audio
import action
import i18n
import speech
import tts

# =============================================================================
#
# Hey, Makers!
#
# Are you looking for actor.add_keyword? Do you want to add a new command?
# You need to edit src/action.py. Check out the instructions at:
# https://aiyprojects.withgoogle.com/voice/#makers-guide-3-3--create-a-new-voice-command-or-action
#
# =============================================================================

logging.basicConfig(
    level=logging.INFO,
    format="[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
)
logger = logging.getLogger('main')

CACHE_DIR = os.getenv('XDG_CACHE_HOME') or os.path.expanduser('~/.cache')
VR_CACHE_DIR = os.path.join(CACHE_DIR, 'voice-recognizer')

CONFIG_DIR = os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')
CONFIG_FILES = [
    '/etc/voice-recognizer.ini',
    os.path.join(CONFIG_DIR, 'voice-recognizer.ini')
]

# Legacy fallback: old locations of secrets/credentials.
OLD_CLIENT_SECRETS = os.path.expanduser('~/client_secrets.json')
OLD_SERVICE_CREDENTIALS = os.path.expanduser('~/credentials.json')

ASSISTANT_CREDENTIALS = os.path.join(VR_CACHE_DIR, 'assistant_credentials.json')
ASSISTANT_OAUTH_SCOPE = 'https://www.googleapis.com/auth/assistant-sdk-prototype'

PID_FILE = '/run/user/%d/voice-recognizer.pid' % os.getuid()

def try_to_get_credentials(client_secrets):
    """Try to get credentials, or print an error and quit on failure."""

    if os.path.exists(ASSISTANT_CREDENTIALS):
        return auth_helpers.load_credentials(
            ASSISTANT_CREDENTIALS, scopes=[ASSISTANT_OAUTH_SCOPE])

    if not os.path.exists(VR_CACHE_DIR):
        os.mkdir(VR_CACHE_DIR)

    if not os.path.exists(client_secrets) and os.path.exists(OLD_CLIENT_SECRETS):
        client_secrets = OLD_CLIENT_SECRETS

    if not os.path.exists(client_secrets):
        print('You need client secrets to use the Assistant API.')
        print('Follow these instructions:')
        print('    https://developers.google.com/api-client-library/python/auth/installed-app'
              '#creatingcred')
        print('and put the file at', client_secrets)
        sys.exit(1)

    if not os.getenv('DISPLAY') and not sys.stdout.isatty():
        print("""
To use the Assistant API, manually start the application from the dev terminal.
See the "Turn on the Assistant API" section of the Voice Recognizer
User's Guide for more info.""")
        sys.exit(1)

    credentials = auth_helpers.credentials_flow_interactive(
        client_secrets, scopes=[ASSISTANT_OAUTH_SCOPE])
    auth_helpers.save_credentials(ASSISTANT_CREDENTIALS, credentials)
    logging.info('OAuth credentials initialized: %s', ASSISTANT_CREDENTIALS)
    return credentials

def create_pid_file(file_name):
    with open(file_name, 'w') as pid_file:
        pid_file.write("%d" % os.getpid())

def main():
    parser = configargparse.ArgParser(
        default_config_files=CONFIG_FILES,
        description="Act on voice commands using Google's speech recognition")
    parser.add_argument('-I', '--input-device', default='default',
                        help='Name of the audio input device')
    parser.add_argument('-O', '--output-device', default='default',
                        help='Name of the audio output device')
    parser.add_argument('-T', '--trigger', default='gpio',
                        help='Trigger to use {\'clap\', \'gpio\'}')
    parser.add_argument('--cloud-speech', action='store_true',
                        help='Use the Cloud Speech API instead of the Assistant API')
    parser.add_argument('-L', '--language', default='en-US',
                        help='Language code to use for speech (default: en-US)')
    parser.add_argument('-l', '--led-fifo', default='/tmp/status-led',
                        help='Status led control fifo')
    parser.add_argument('-p', '--pid-file', default=PID_FILE,
                        help='File containing our process id for monitoring')
    parser.add_argument('--audio-logging', action='store_true',
                        help='Log all requests and responses to WAV files in /tmp')
    parser.add_argument('--assistant-secrets',
                        help='Path to client secrets for the Assistant API')
    parser.add_argument('--cloud-speech-secrets',
                        help='Path to service account credentials for the '
                        'Cloud Speech API')

    args = parser.parse_args()

    create_pid_file(args.pid_file)
    i18n.set_language_code(args.language, gettext_install=True)

    player = audio.Player(args.output_device)

    if args.cloud_speech:
        credentials_file = os.path.expanduser(args.cloud_speech_secrets)
        if not os.path.exists(credentials_file) and os.path.exists(OLD_SERVICE_CREDENTIALS):
            credentials_file = OLD_SERVICE_CREDENTIALS
        recognizer = speech.CloudSpeechRequest(credentials_file)
    else:
        credentials = try_to_get_credentials(
            os.path.expanduser(args.assistant_secrets))
        recognizer = speech.AssistantSpeechRequest(credentials)

    recorder = audio.Recorder(
        input_device=args.input_device, channels=1,
        bytes_per_sample=speech.AUDIO_SAMPLE_SIZE,
        sample_rate_hz=speech.AUDIO_SAMPLE_RATE_HZ)
    with recorder:
        do_recognition(args, recorder, recognizer, player, credentials)

def do_recognition(args, recorder, recognizer, player, credentials):
    """Configure and run the recognizer."""
    say = tts.create_say(player)

    actor = action.make_actor(say)

    if args.cloud_speech:
        action.add_commands_just_for_cloud_speech_api(actor, say)

    recognizer.add_phrases(actor)
    recognizer.set_audio_logging_enabled(args.audio_logging)

    if args.trigger == 'gpio':
        import triggers.gpio
        triggerer = triggers.gpio.GpioTrigger(channel=23)
        msg = 'Press the button on GPIO 23'
    elif args.trigger == 'clap':
        import triggers.clap
        triggerer = triggers.clap.ClapTrigger(recorder)
        msg = 'Clap your hands'
    elif args.trigger == 'hotword':
        import triggers.hotword
        triggerer = triggers.hotword.HotwordTrigger(credentials)
        msg = 'Say "Ok Google"'
    else:
        logger.error("Unknown trigger '%s'", args.trigger)
        return

    mic_recognizer = SyncMicRecognizer(
        actor, recognizer, recorder, player, say, triggerer, led_fifo=args.led_fifo)

    with mic_recognizer:
        if sys.stdout.isatty():
            print(msg + ' then speak, or press Ctrl+C to quit...')

        # wait for KeyboardInterrupt
        while True:
            time.sleep(1)

class SyncMicRecognizer(object):

    """Detects triggers and runs recognition in a background thread.

    This is a context manager, so it will clean up the background thread if the
    main program is interrupted.
    """

    # pylint: disable=too-many-instance-attributes

    def __init__(self, actor, recognizer, recorder, player, say, triggerer, led_fifo):
        self.actor = actor
        self.player = player
        self.recognizer = recognizer
        self.recognizer.set_endpointer_cb(self.endpointer_cb)
        self.recorder = recorder
        self.say = say
        self.triggerer = triggerer
        self.triggerer.set_callback(self.recognize)

        self.running = False

        if led_fifo and os.path.exists(led_fifo):
            self.led_fifo = led_fifo
        else:
            if led_fifo:
                logger.warning(
                    'File %s specified for --led-fifo does not exist.',
                    led_fifo)
            self.led_fifo = None
        self.recognizer_event = threading.Event()

    def __enter__(self):
        self.running = True
        threading.Thread(target=self._recognize).start()
        self.triggerer.start()
        self._status('ready')

    def __exit__(self, *args):
        self.running = False
        self.recognizer_event.set()

        self.recognizer.end_audio()

    def _status(self, status):
        if self.led_fifo:
            with open(self.led_fifo, 'w') as led:
                led.write(status + '\n')
        logger.info('%s...', status)

    def recognize(self):
        if self.recognizer_event.is_set():
            # Duplicate trigger (eg multiple button presses)
            return

        self.recognizer.reset()
        self.recorder.add_processor(self.recognizer)
        self._status('listening')
        # Tell recognizer to run
        self.recognizer_event.set()

    def endpointer_cb(self):
        self.recorder.del_processor(self.recognizer)
        self._status('thinking')

    def _recognize(self):
        while self.running:
            self.recognizer_event.wait()
            if not self.running:
                break

            logger.info('recognizing...')
            try:
                self._handle_result(self.recognizer.do_request())
            except speech.Error:
                logger.exception('Unexpected error')
                self.say(_('Unexpected error. Try again or check the logs.'))

            self.recognizer_event.clear()
            self.triggerer.start()
            self._status('ready')

    def _handle_result(self, result):
        if result.transcript and self.actor.handle(result.transcript):
            logger.info('handled local command: %s', result.transcript)
        elif result.response_audio:
            self._play_assistant_response(result.response_audio)
        elif result.transcript:
            logger.warning('%r was not handled', result.transcript)
            self.say(_("I don’t know how to answer that."))
        else:
            logger.warning('no command recognized')
            self.say(_("Could you try that again?"))

    def _play_assistant_response(self, audio_bytes):
        bytes_per_sample = speech.AUDIO_SAMPLE_SIZE
        sample_rate_hz = speech.AUDIO_SAMPLE_RATE_HZ
        logger.info('Playing %.4f seconds of audio...',
                    len(audio_bytes) / (bytes_per_sample * sample_rate_hz))
        self.player.play_bytes(audio_bytes, sample_width=bytes_per_sample,
                               sample_rate=sample_rate_hz)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/python
# coding: utf-8
from flask import Flask
import threading
import time
from datetime import datetime
import os
import sys
from socket import *
import json

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from Adafruit_IO import Client

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

from AM2322 import AM2322

# temperatureReading = 0
# humidityReading = 0
ADAFRUIT_IO_KEY = os.environ.get('AIO_KEY')
ADAFRUIT_IO_BASENAME = os.environ.get('AIO_BASENAME')
ROOM_NAME = os.environ.get('ROOM_NAME', 'Room')
ROOM_PBM_64 = os.environ.get('ROOM_PBM_64')
UDP_PORT = 51231
DISP_RST = 24

app = Flask(__name__)

@app.route('/')
def web_index():
    global temperatureReading
    global humidityReading
    return '{} currently: {}°F, {}% Humidity'.format(ROOM_NAME, temperatureReading, humidityReading)

def server():
    app.run(host='0.0.0.0', port=80)

def call_at_interval(period, callback, args):
    while True:
        time.sleep(period)
        callback(*args)

def setInterval(period, callback, *args):
    threading.Thread(target=call_at_interval, args=(period, callback, args)).start()

def broadcast_to_network():
    global temperatureReading
    global humidityReading
    global aio
    global udpSocket
    try:
        # sent_data = {'temperature': temperatureReading, 'humidity': humidityReading}
        # print("Sending {}, data {}".format(os.environ.get('AIO_BASENAME'), sent_data))
        # returned_data = aio.send_group(os.environ.get('AIO_BASENAME'), sent_data)
        returned_data = aio.send("{}-{}".format(ADAFRUIT_IO_BASENAME, "temperature"), temperatureReading)
        returned_data = aio.send("{}-{}".format(ADAFRUIT_IO_BASENAME, "humidity"), humidityReading)
        # print("Update returned {}".format(returned_data))
    except:
        print("Unexpected error:", sys.exc_info()[0])
        # print "Name error: {}".format(e.message)
        pass
    data = {
        "time": datetime.utcnow().isoformat(),
        "name": ROOM_NAME,
        "identifier": ADAFRUIT_IO_BASENAME,
        "room_pbm64": ROOM_PBM_64,
        "temperature": temperatureReading,
        "humidity": humidityReading
    }#repr(time.time()) + '\n'
    dataJSON = json.dumps(data, separators=(',',':'))
    udpSocket.sendto(dataJSON, ('<broadcast>', UDP_PORT))

def i2c_read_temperature():
    am2322.read()
    print am2322.temperature, am2322.humidity
    temperatureReading = (am2322.temperature*9/5)+32
    humidityReading = am2322.humidity
    return (temperatureReading, humidityReading)

def i2c_display_setup(rst=DISP_RST):
    disp = Adafruit_SSD1306.SSD1306_128_64(rst)
    disp.begin()
    disp.clear()
    disp.display()
    width = disp.width
    height = disp.height
    image = Image.new('1', (width, height))
    draw = ImageDraw.Draw(image)
    draw.rectangle((0,0,width,height), outline=0, fill=0)
    padding = 2
    shape_width = 20
    top = padding
    bottom = height-padding
    x = 2
    x += 22
    x += 22
    x += 22
    x += 22
    font = ImageFont.load_default()
    # Some other nice fonts to try: http://www.dafont.com/bitmap.php
    #font = ImageFont.truetype('Minecraftia.ttf', 8)
    draw.text((x, top),    'Hello',  font=font, fill=255)
    draw.text((x, top+20), 'World!', font=font, fill=255)
    disp.image(image)
    disp.display()
    return (disp, draw, image)

if __name__ == '__main__':
    global temperatureReading
    global humidityReading
    global aio
    global udpSocket
    udpSocket = socket(AF_INET, SOCK_DGRAM)
    udpSocket.bind(('', 0))
    udpSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

    temperatureReading = 0
    humidityReading = 0
    aio = Client(ADAFRUIT_IO_KEY)

    serverThread = threading.Thread(target=server)
    serverThread.start()

    am2322 = AM2322(0, synchronous=True)

    # display init
    (disp, draw, image) = i2c_display_setup()
    padding = top = 2
    font = ImageFont.load_default()
    setInterval(60, broadcast_to_network)

    while True:
        (temperatureReading, humidityReading) = i2c_read_temperature()
        draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
        draw.text((4, top),    u'Temp: {}°F'.format(temperatureReading), font=font, fill=255)
        draw.text((4, top+16), u'Humi: {}%'.format(humidityReading)    , font=font, fill=255)
        disp.image(image)
        disp.display()
        time.sleep(5)
<commit_msg>support for both old and new pis<commit_after>#!/usr/bin/python
# coding: utf-8
from flask import Flask
import threading
import time
from datetime import datetime
import os
import sys
from socket import *
import json

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from Adafruit_IO import Client
import RPi.GPIO as GPIO

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

from AM2322 import AM2322

# temperatureReading = 0
# humidityReading = 0
ADAFRUIT_IO_KEY = os.environ.get('AIO_KEY')
ADAFRUIT_IO_BASENAME = os.environ.get('AIO_BASENAME')
ROOM_NAME = os.environ.get('ROOM_NAME', 'Room')
ROOM_PBM_64 = os.environ.get('ROOM_PBM_64')
UDP_PORT = 51231
DISP_RST = 24

app = Flask(__name__)

@app.route('/')
def web_index():
    global temperatureReading
    global humidityReading
    return '{} currently: {}°F, {}% Humidity'.format(ROOM_NAME, temperatureReading, humidityReading)

def server():
    app.run(host='0.0.0.0', port=80)

def call_at_interval(period, callback, args):
    while True:
        time.sleep(period)
        callback(*args)

def setInterval(period, callback, *args):
    threading.Thread(target=call_at_interval, args=(period, callback, args)).start()

def broadcast_to_network():
    global temperatureReading
    global humidityReading
    global aio
    global udpSocket
    try:
        # sent_data = {'temperature': temperatureReading, 'humidity': humidityReading}
        # print("Sending {}, data {}".format(os.environ.get('AIO_BASENAME'), sent_data))
        # returned_data = aio.send_group(os.environ.get('AIO_BASENAME'), sent_data)
        returned_data = aio.send("{}-{}".format(ADAFRUIT_IO_BASENAME, "temperature"), temperatureReading)
        returned_data = aio.send("{}-{}".format(ADAFRUIT_IO_BASENAME, "humidity"), humidityReading)
        # print("Update returned {}".format(returned_data))
    except:
        print("Unexpected error:", sys.exc_info()[0])
        # print "Name error: {}".format(e.message)
        pass
    data = {
        "time": datetime.utcnow().isoformat(),
        "name": ROOM_NAME,
        "identifier": ADAFRUIT_IO_BASENAME,
        "room_pbm64": ROOM_PBM_64,
        "temperature": temperatureReading,
        "humidity": humidityReading
    }#repr(time.time()) + '\n'
    dataJSON = json.dumps(data, separators=(',',':'))
    udpSocket.sendto(dataJSON, ('<broadcast>', UDP_PORT))

def i2c_read_temperature():
    am2322.read()
    print am2322.temperature, am2322.humidity
    temperatureReading = (am2322.temperature*9/5)+32
    humidityReading = am2322.humidity
    return (temperatureReading, humidityReading)

def i2c_display_setup(rst=DISP_RST):
    disp = Adafruit_SSD1306.SSD1306_128_64(rst)
    disp.begin()
    disp.clear()
    disp.display()
    width = disp.width
    height = disp.height
    image = Image.new('1', (width, height))
    draw = ImageDraw.Draw(image)
    draw.rectangle((0,0,width,height), outline=0, fill=0)
    padding = 2
    shape_width = 20
    top = padding
    bottom = height-padding
    x = 2
    x += 22
    x += 22
    x += 22
    x += 22
    font = ImageFont.load_default()
    # Some other nice fonts to try: http://www.dafont.com/bitmap.php
    #font = ImageFont.truetype('Minecraftia.ttf', 8)
    draw.text((x, top),    'Hello',  font=font, fill=255)
    draw.text((x, top+20), 'World!', font=font, fill=255)
    disp.image(image)
    disp.display()
    return (disp, draw, image)

if __name__ == '__main__':
    global temperatureReading
    global humidityReading
    global aio
    global udpSocket
    udpSocket = socket(AF_INET, SOCK_DGRAM)
    udpSocket.bind(('', 0))
    udpSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

    temperatureReading = 0
    humidityReading = 0
    aio = Client(ADAFRUIT_IO_KEY)

    serverThread = threading.Thread(target=server)
    serverThread.start()
    i2c_interface = 1
    if GPIO.RPI_INFO['P1_REVISION'] == 1: #old RPi have user i2c on bus 0
        i2c_interface = 0

    am2322 = AM2322(i2c_interface, synchronous=True)

    # display init
    (disp, draw, image) = i2c_display_setup()
    padding = top = 2
    font = ImageFont.load_default()
    setInterval(60, broadcast_to_network)

    while True:
        (temperatureReading, humidityReading) = i2c_read_temperature()
        draw.rectangle((0,0,disp.width,disp.height), outline=0, fill=0)
        draw.text((4, top),    u'Temp: {}°F'.format(temperatureReading), font=font, fill=255)
        draw.text((4, top+16), u'Humi: {}%'.format(humidityReading)    , font=font, fill=255)
        disp.image(image)
        disp.display()
        time.sleep(5)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from andip import AnDiP
from andip.provider import FileProvider, DatabaseProvider, PlWikiProvider

ad1 = AnDiP(FileProvider("../data/polish"))
ad2 = AnDiP(DatabaseProvider("../data/polish"), ad1)
ad3 = AnDiP(PlWikiProvider("../data/polish"), ad2)

print ad3.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas teraźniejszy', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
print ad3.get_word(('przymiotnik', 'żółty', {'przypadek' : 'dopełniacz', 'stopień' : 'wyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad3.get_word(('rzeczownik', 'pies', {'przypadek':'wołacz', 'liczba': 'mnoga'}));

ad3.save() # save new items to database

print ad2.get_word(('rzeczownik', 'pies', {'przypadek':'wołacz', 'liczba': 'pojedyncza'}));
print ad2.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas teraźniejszy', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'celownik', 'stopień' : 'wyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'dopełniacz', 'stopień' : 'najwyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'celownik', 'stopień' : 'najwyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))

#print ad.get_conf('najżółtszych')
#print ad.get_conf('najżółtszym')
#print ad.get_conf('żółtszych')
#print ad.get_conf('żółtszym')
#print 'opisany', ad.get_word(('przymiotnik', 'opis', {'liczba': 'pojedyncza', 'rodzaj': 'm'}))
#print 'opisane', ad.get_word(('przymiotnik', 'opis', {'liczba': 'mnoga', 'rodzaj': 'm'}))
#print 'opisana', ad.get_word(('przymiotnik', 'opis', {'liczba': 'pojedyncza', 'rodzaj': 'ż'}))
#print 'opisane', ad.get_word(('przymiotnik', 'opis', {'liczba': 'mnoga', 'rodzaj': 'ż'}))
#
#print ad.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas przeszły', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
#
#print ad.get_word("występować")

#db = DatabaseProvider.DatabaseProvider('Data')
#print db.get_verb({'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}, 'występować')
#print db.get_verb({'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}, 'zabierać')

#print ad.get_conf('występować')

#print ad.get_word(('przymiotnik', 'zachodni', {'stopień': 'podstawowy', 'przypadek' : 'dopełniacz', 'liczba': 'mnoga', 'rodzaj': 'm'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'pojedyncza', 'osoba': 'trzecia'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'pierwsza'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'druga'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'pojedyncza', 'osoba': 'druga'}))

#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}))
#print ad.get_conf("występować")
#print ad.get_conf("piękny")
#print ad.get_conf("zdrowy")
#print ad.get_conf("zachodni")
#print ad.get_conf("zdrów")
#print ad.get_conf('kot')

#
#print ad.get_word(('czasownik', 'być', {'forma': 'czas przesz\xc5\x82y', 'osoba': 'trzecia', 'aspekt': 'dokonane', 'liczba': 'pojedyncza'}))
<commit_msg>fix execution of PlWikiProvider()<commit_after># -*- coding: utf-8 -*-

from andip import AnDiP
from andip.provider import FileProvider, DatabaseProvider, PlWikiProvider

ad1 = AnDiP(FileProvider("../data/polish"))
ad2 = AnDiP(DatabaseProvider("../data/polish"), backoff=ad1)
ad3 = AnDiP(PlWikiProvider(), backoff=ad2)

print ad3.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas teraźniejszy', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
print ad3.get_word(('przymiotnik', 'żółty', {'przypadek' : 'dopełniacz', 'stopień' : 'wyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad3.get_word(('rzeczownik', 'pies', {'przypadek':'wołacz', 'liczba': 'mnoga'}));

ad3.save() # save new items to database

print ad2.get_word(('rzeczownik', 'pies', {'przypadek':'wołacz', 'liczba': 'pojedyncza'}));
print ad2.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas teraźniejszy', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'celownik', 'stopień' : 'wyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'dopełniacz', 'stopień' : 'najwyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))
print ad2.get_word(('przymiotnik', 'żółty', {'przypadek' : 'celownik', 'stopień' : 'najwyższy', 'liczba': 'mnoga', 'rodzaj': 'm'}))

#print ad.get_conf('najżółtszych')
#print ad.get_conf('najżółtszym')
#print ad.get_conf('żółtszych')
#print ad.get_conf('żółtszym')
#print 'opisany', ad.get_word(('przymiotnik', 'opis', {'liczba': 'pojedyncza', 'rodzaj': 'm'}))
#print 'opisane', ad.get_word(('przymiotnik', 'opis', {'liczba': 'mnoga', 'rodzaj': 'm'}))
#print 'opisana', ad.get_word(('przymiotnik', 'opis', {'liczba': 'pojedyncza', 'rodzaj': 'ż'}))
#print 'opisane', ad.get_word(('przymiotnik', 'opis', {'liczba': 'mnoga', 'rodzaj': 'ż'}))
#
#print ad.get_word(("czasownik", "występować", {'aspekt': 'dokonane', 'forma': 'czas przeszły', 'liczba': 'mnoga', 'osoba': 'trzecia'}))
#
#print ad.get_word("występować")

#db = DatabaseProvider.DatabaseProvider('Data')
#print db.get_verb({'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}, 'występować')
#print db.get_verb({'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}, 'zabierać')

#print ad.get_conf('występować')

#print ad.get_word(('przymiotnik', 'zachodni', {'stopień': 'podstawowy', 'przypadek' : 'dopełniacz', 'liczba': 'mnoga', 'rodzaj': 'm'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'pojedyncza', 'osoba': 'trzecia'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'pierwsza'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'druga'}))
#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'pojedyncza', 'osoba': 'druga'}))

#print ad.get_word(('czasownik', 'występować', {'aspekt' : 'niedokonane', 'forma' : 'czas terazniejszy', 'liczba' : 'mnoga', 'osoba': 'trzecia'}))
#print ad.get_conf("występować")
#print ad.get_conf("piękny")
#print ad.get_conf("zdrowy")
#print ad.get_conf("zachodni")
#print ad.get_conf("zdrów")
#print ad.get_conf('kot')

#
#print ad.get_word(('czasownik', 'być', {'forma': 'czas przesz\xc5\x82y', 'osoba': 'trzecia', 'aspekt': 'dokonane', 'liczba': 'pojedyncza'}))
<|endoftext|>


<commit_before>from __future__ import print_function
from lambda_client import upload
from api_gateway import ApiGatewayConnection
import os
from argparse import ArgumentParser
from util import zipdir
from config import get_config

def get_path_segments(path):
    """splits a path into its segments

    Args:
        path (str): the path to explode

    Returns:
        list(str): list of path segments, in order
    """
    parts = filter(None, path.split(os.sep))
    return parts

def get_resource_by_path(path, resources):
    return next(
        (x for x in resources if x['path'] == path),
        None)

def get_resources_to_create(path, resources):
    """gets the resources to create for this path

    Args:
        path (str): path to create
        resources (list(str)): list of resources that have already been created

    Returns:
        (str, list(str)): the first item is a parent_id of the path to create,
                          the second is a list of path segments to create, in
                          order
    """
    cur_path = "/"
    segments = get_path_segments(path)
    parent_id = get_resource_by_path("/", resources)['id']

    resources_to_create = []

    for segment in segments:
        cur_path += segment

        previous_created_resource = get_resource_by_path(cur_path, resources)

        if not previous_created_resource:
            resources_to_create.append(segment)
        else:
            parent_id = previous_created_resource["id"]
        cur_path += "/"

    return parent_id, resources_to_create

def create_resource_path(api_connection, api_id, path, resources):
    """creates all resources necessary for a path

    Args:
        api_connection (ApiGatewayConnection): api gateway client
        api_id (str): id of the api to operate on
        path (str): path to create

    Returns:
        str: id of the resource that was created
    """

    parent_id, resources_to_create = get_resources_to_create(
        path, resources)

    cur_path = "/"
    for segment in resources_to_create:
        cur_path += segment

        response = api_connection.create_resource(
            api_id, parent_id, segment)
        resources.append(response)

        parent_id = response["id"]
        cur_path += "/"

    return parent_id, resources

def is_substring_of_path(needle, haystack):
    """returns true if the needle is a substring
       of anything in the haystack

    Args:
        needle (str): String to find in haystack
        haystack (list(str)): Collection to search through

    Returns:
        bool: Description
    """
    for x in haystack:
        if x.find(needle) == 0:
            return False
    return True

def get_resources_to_delete(resources, paths):
    """returns a list of all resources to delete

    Args:
        resources (list(dict)): resources to compare to the paths
        paths (list(str)): paths from the config file

    Returns:
        list(str): list of ids of resources to remove
    """
    sorted_resources = reversed(sorted(resources,
                                       key=lambda x: x["path"].count("/")))
    resources_to_delete = [resource['id']
                           for resource
                           in sorted_resources
                           # is substring of path determines if the
                           # current path is a substring of any of the other
                           # paths passed in
                           if is_substring_of_path(resource["path"], paths)]
    return resources_to_delete

def prune_nonexistent_paths(api_connection, api_id, paths, resources):
    """Deletes all paths that don't exist in paths from given api

    Args:
        api_connection (ApiGatewayConnection): api gateway client
        api_id (str): id of api to work on
        paths (list(str)): list of paths from config
    """
    resources_to_delete = get_resources_to_delete(resources, paths)
    for resource_to_delete in resources_to_delete:
        api_connection.delete_resource(api_id, resource_to_delete)

def create_request_mapping_template():
    mapping_template = """
#set($params = $input.params())
#set($path = $params.path)
#set($querystring = $params.querystring)
#set($headers = $params.header)
#set($body = $input.json('$'))

{
"path" : {
    #foreach ($mapEntry in $path.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $path.size()),#end
    #end
    },
"querystring" : {
    #foreach ($mapEntry in $querystring.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $querystring.size()),#end
    #end
    },
"headers" : {
    #foreach ($mapEntry in $headers.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $headers.size()),#end
    #end
    }

#if(!$body),
"body": $body
#end
}
"""

    return mapping_template

def create_integration_request(api_id, parent_id, method,
                               gateway_function_arn, creds_arn, content_type,
                               parameters):
    mapping_templates = {}
    mapping_templates[content_type] = create_request_mapping_template()

    api_connection.create_integration(
        api_id, parent_id, method, gateway_function_arn,
        creds_arn, mapping_templates)

parser = ArgumentParser(description=str('deploy an api to AWS lambda '
                                        'and API Gateway'))
parser.add_argument(
    "--conf", type=str, default=None, required=True,
    help="YAML or JSON swagger config describing your API")

parser.add_argument("--publish", type=str, default=None,
                    help="name of the stage to publish to (default:dev)")

api_group = parser.add_mutually_exclusive_group(required=True)
api_group.add_argument(
    "--api_id", type=str, help="the api you wish to update")
api_group.add_argument("--api_name", type=str,
                       help="name of the new api to create")

args = parser.parse_args()

load_str = args.conf
script_directory = os.path.dirname(__file__)
stage_name = args.publish or "dev"
api_name = args.api_name
api_id = args.api_id

access_key = os.environ.get('AWS_ACCESS_KEY_ID')
secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')

if not access_key or not secret_key:
    raise Exception("Critical information is missing")

path_infos, config = get_config(load_str, script_directory)
application_root = config["x-application-root"]

api_connection = ApiGatewayConnection()

# shouldn't need a third case here, parser should catch it
if api_name:
    api_resp = api_connection.get_api_by_name(api_name)
    if not api_resp:
        api_resp = api_connection.create_api(api_name)
elif api_id:
    api_resp = api_connection.get_api(api_id)
    api_name = api_resp["name"]

api_id = api_resp["id"]

resources = api_connection.get_resources(api_id)['items']
prune_nonexistent_paths(
    api_connection, api_id, [x[0] for x in path_infos], resources)

for path_info in path_infos:
    path = path_info[0]
    zip_path = path_info[1]
    function_name = path_info[2]
    handler_name = path_info[3]
    creds_arn = path_info[4]
    method = path_info[5]
    parameters = path_info[6]
    status_code = 200
    content_type = "application/json"
    app_root = None

    # package source code if we have it
    if not zip_path:
        app_root = application_root
        if app_root[-1] != "/":
            app_root += "/"
        zipdir(app_root, "main.zip")
        zip_path = "main.zip"

    with open(zip_path) as zip_file:
        function_arn = upload("PAWS-{0}-{1}".format(api_name, function_name),
                              zip_file,
                              creds_arn,
                              handler_name,
                              stage_name)

    if app_root:
        os.remove(zip_path)

    # todo:rebuild this string concat so that respects region
    gateway_function_arn = str('arn:aws:apigateway:us-east-1:lambda:path'
                               '/2015-03-31/functions/{0}/invocations').format(
        function_arn)

    parent_id, resources = create_resource_path(
        api_connection, api_id, path, resources)

    api_connection.create_method(
        api_id, parent_id, method)

    create_integration_request(api_id, parent_id, method,
                               gateway_function_arn, creds_arn, content_type,
                               parameters)

    api_connection.create_integration_response(
        api_id, parent_id, method, status_code)
    api_connection.create_method_response(
        api_id, parent_id, method, status_code)
    api_connection.create_deployment(api_id, stage_name)

print("We worked on {0}".format(api_id))
<commit_msg>changed name of function to reflect behavior<commit_after>from __future__ import print_function
from lambda_client import upload
from api_gateway import ApiGatewayConnection
import os
from argparse import ArgumentParser
from util import zipdir
from config import get_config

def get_path_segments(path):
    """splits a path into its segments

    Args:
        path (str): the path to explode

    Returns:
        list(str): list of path segments, in order
    """
    parts = filter(None, path.split(os.sep))
    return parts

def get_resource_by_path(path, resources):
    return next(
        (x for x in resources if x['path'] == path),
        None)

def get_resources_to_create(path, resources):
    """gets the resources to create for this path

    Args:
        path (str): path to create
        resources (list(str)): list of resources that have already been created

    Returns:
        (str, list(str)): the first item is a parent_id of the path to create,
                          the second is a list of path segments to create, in
                          order
    """
    cur_path = "/"
    segments = get_path_segments(path)
    parent_id = get_resource_by_path("/", resources)['id']

    resources_to_create = []

    for segment in segments:
        cur_path += segment

        previous_created_resource = get_resource_by_path(cur_path, resources)

        if not previous_created_resource:
            resources_to_create.append(segment)
        else:
            parent_id = previous_created_resource["id"]
        cur_path += "/"

    return parent_id, resources_to_create

def create_resource_path(api_connection, api_id, path, resources):
    """creates all resources necessary for a path

    Args:
        api_connection (ApiGatewayConnection): api gateway client
        api_id (str): id of the api to operate on
        path (str): path to create

    Returns:
        str: id of the resource that was created
    """

    parent_id, resources_to_create = get_resources_to_create(
        path, resources)

    cur_path = "/"
    for segment in resources_to_create:
        cur_path += segment

        response = api_connection.create_resource(
            api_id, parent_id, segment)
        resources.append(response)

        parent_id = response["id"]
        cur_path += "/"

    return parent_id, resources

def is_not_substring_of_path(needle, haystack):
    """returns false if the needle is a substring
       of anything in the haystack

    Args:
        needle (str): String to find in haystack
        haystack (list(str)): Collection to search through

    Returns:
        bool: Description
    """
    for x in haystack:
        if x.find(needle) == 0:
            return False
    return True

def get_resources_to_delete(resources, paths):
    """returns a list of all resources to delete

    Args:
        resources (list(dict)): resources to compare to the paths
        paths (list(str)): paths from the config file

    Returns:
        list(str): list of ids of resources to remove
    """
    sorted_resources = reversed(sorted(resources,
                                       key=lambda x: x["path"].count("/")))
    resources_to_delete = [resource['id']
                           for resource
                           in sorted_resources
                           # is substring of path determines if the
                           # current path is a substring of any of the other
                           # paths passed in
                           if is_not_substring_of_path(resource["path"],
                                                       paths)]
    return resources_to_delete

def prune_nonexistent_paths(api_connection, api_id, paths, resources):
    """Deletes all paths that don't exist in paths from given api

    Args:
        api_connection (ApiGatewayConnection): api gateway client
        api_id (str): id of api to work on
        paths (list(str)): list of paths from config
    """
    resources_to_delete = get_resources_to_delete(resources, paths)
    for resource_to_delete in resources_to_delete:
        api_connection.delete_resource(api_id, resource_to_delete)

def create_request_mapping_template():
    mapping_template = """
#set($params = $input.params())
#set($path = $params.path)
#set($querystring = $params.querystring)
#set($headers = $params.header)
#set($body = $input.json('$'))

{
"path" : {
    #foreach ($mapEntry in $path.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $path.size()),#end
    #end
    },
"querystring" : {
    #foreach ($mapEntry in $querystring.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $querystring.size()),#end
    #end
    },
"headers" : {
    #foreach ($mapEntry in $headers.entrySet())
        "$mapEntry.key":"$mapEntry.value"
        #if($velocityCount < $headers.size()),#end
    #end
    }

#if(!$body),
"body": $body
#end
}
"""

    return mapping_template

def create_integration_request(api_id, parent_id, method,
                               gateway_function_arn, creds_arn, content_type,
                               parameters):
    mapping_templates = {}
    mapping_templates[content_type] = create_request_mapping_template()

    api_connection.create_integration(
        api_id, parent_id, method, gateway_function_arn,
        creds_arn, mapping_templates)

parser = ArgumentParser(description=str('deploy an api to AWS lambda '
                                        'and API Gateway'))
parser.add_argument(
    "--conf", type=str, default=None, required=True,
    help="YAML or JSON swagger config describing your API")

parser.add_argument("--publish", type=str, default=None,
                    help="name of the stage to publish to (default:dev)")

api_group = parser.add_mutually_exclusive_group(required=True)
api_group.add_argument(
    "--api_id", type=str, help="the api you wish to update")
api_group.add_argument("--api_name", type=str,
                       help="name of the new api to create")

args = parser.parse_args()

load_str = args.conf
script_directory = os.path.dirname(__file__)
stage_name = args.publish or "dev"
api_name = args.api_name
api_id = args.api_id

access_key = os.environ.get('AWS_ACCESS_KEY_ID')
secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')

if not access_key or not secret_key:
    raise Exception("Critical information is missing")

path_infos, config = get_config(load_str, script_directory)
application_root = config["x-application-root"]

api_connection = ApiGatewayConnection()

# shouldn't need a third case here, parser should catch it
if api_name:
    api_resp = api_connection.get_api_by_name(api_name)
    if not api_resp:
        api_resp = api_connection.create_api(api_name)
elif api_id:
    api_resp = api_connection.get_api(api_id)
    api_name = api_resp["name"]

api_id = api_resp["id"]

resources = api_connection.get_resources(api_id)['items']
prune_nonexistent_paths(
    api_connection, api_id, [x[0] for x in path_infos], resources)

for path_info in path_infos:
    path = path_info[0]
    zip_path = path_info[1]
    function_name = path_info[2]
    handler_name = path_info[3]
    creds_arn = path_info[4]
    method = path_info[5]
    parameters = path_info[6]
    status_code = 200
    content_type = "application/json"
    app_root = None

    # package source code if we have it
    if not zip_path:
        app_root = application_root
        if app_root[-1] != "/":
            app_root += "/"
        zipdir(app_root, "main.zip")
        zip_path = "main.zip"

    with open(zip_path) as zip_file:
        function_arn = upload("PAWS-{0}-{1}".format(api_name, function_name),
                              zip_file,
                              creds_arn,
                              handler_name,
                              stage_name)

    if app_root:
        os.remove(zip_path)

    # todo:rebuild this string concat so that respects region
    gateway_function_arn = str('arn:aws:apigateway:us-east-1:lambda:path'
                               '/2015-03-31/functions/{0}/invocations').format(
        function_arn)

    parent_id, resources = create_resource_path(
        api_connection, api_id, path, resources)

    api_connection.create_method(
        api_id, parent_id, method)

    create_integration_request(api_id, parent_id, method,
                               gateway_function_arn, creds_arn, content_type,
                               parameters)

    api_connection.create_integration_response(
        api_id, parent_id, method, status_code)
    api_connection.create_method_response(
        api_id, parent_id, method, status_code)
    api_connection.create_deployment(api_id, stage_name)

print("We worked on {0}".format(api_id))
<|endoftext|>


<commit_before># coding=utf-8
import tornado.ioloop
import tornado.web
from tornado import gen
import bangumi_bot
import difflib
import datetime
import os
import time

__author__ = 'fengyuyao'

WEEKDAY_NAME = [u"星期日", u"星期一", u"星期二", u"星期三", u"星期四", u"星期五", u"星期六"]

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        print 1
        res = yield self.get_data()

        # print res
        # self.write(str(res))
        cur_weekday = datetime.datetime.now().weekday() + 1
        # for Sunday, in database Sunday is 0
        if cur_weekday == 7:
            cur_weekday = 0
        self.render("../templates/index.html",
                    bangumi_info=res,
                    cur_weekday=cur_weekday,
                    WEEKDAY_NAME=WEEKDAY_NAME)

    @gen.coroutine
    def get_data(self):
        bangumi_info = {}

        for i in range(7):
            bangumi_info[i] = []
        bangumi_info[-1] = []

        bots = [bangumi_bot.TudouBot(), bangumi_bot.BilibiliBot(), bangumi_bot.YoukuBot(), bangumi_bot.IQiyiBot()]
        for bot in bots:
            data = yield bot.get_data()
            for cur_record in data:
                info_in_day = bangumi_info[cur_record['weekday']]

                for iRecord in info_in_day:
                    if self._bangumi_similar(iRecord, cur_record) > 0.5:
                        iRecord['url'][bot.name] = cur_record['url']
                        iRecord['update_time'][bot.name] = cur_record['update_time']
                        break
                else:
                    cur_record['url'] = {bot.name: cur_record['url']}
                    cur_record['update_time'] = {bot.name: cur_record['update_time']}
                    info_in_day.append(cur_record)

        def _cmp(x, y):
            x_utime = x['update_time']
            y_utime = y['update_time']

            # only use not None val
            for k in x_utime:
                if x_utime[k]:
                    x_utime = x_utime[k]
                    break
            else:
                return 1

            for k in y_utime:
                if y_utime[k]:
                    y_utime = y_utime[k]
                    break
            else:
                return 1

            print x_utime, y_utime
            # x_utime = x_utime[x_utime.keys()[0]]
            # y_utime = y_utime[y_utime.keys()[0]]

            if x_utime > y_utime:
                return 1
            elif x_utime < y_utime:
                return -1
            else:
                return 0

        for key in bangumi_info:
            bangumi_info[key].sort(cmp=_cmp)

        raise gen.Return(bangumi_info)

    @staticmethod
    def _bangumi_similar(a, b):
        return difflib.SequenceMatcher(a=a['title'], b=b['title']).ratio()

def make_app():
    settings = {
        "static_path": os.path.join(os.path.dirname(__file__), '..', "static"),
        "debug": True
    }

    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/(.*)", tornado.web.StaticFileHandler,
         dict(path=settings['static_path'])),
    ], **settings)

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
<commit_msg>remove debug code<commit_after># coding=utf-8
import tornado.ioloop
import tornado.web
from tornado import gen
import bangumi_bot
import difflib
import datetime
import os
import time

__author__ = 'fengyuyao'

WEEKDAY_NAME = [u"星期日", u"星期一", u"星期二", u"星期三", u"星期四", u"星期五", u"星期六"]

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        print 1
        res = yield self.get_data()

        # print res
        # self.write(str(res))
        cur_weekday = datetime.datetime.now().weekday() + 1
        # for Sunday, in database Sunday is 0
        if cur_weekday == 7:
            cur_weekday = 0
        self.render("../templates/index.html",
                    bangumi_info=res,
                    cur_weekday=cur_weekday,
                    WEEKDAY_NAME=WEEKDAY_NAME)

    @gen.coroutine
    def get_data(self):
        bangumi_info = {}

        for i in range(7):
            bangumi_info[i] = []
        bangumi_info[-1] = []

        bots = [bangumi_bot.TudouBot(), bangumi_bot.BilibiliBot(), bangumi_bot.YoukuBot(), bangumi_bot.IQiyiBot()]
        for bot in bots:
            data = yield bot.get_data()
            for cur_record in data:
                info_in_day = bangumi_info[cur_record['weekday']]

                for iRecord in info_in_day:
                    if self._bangumi_similar(iRecord, cur_record) > 0.5:
                        iRecord['url'][bot.name] = cur_record['url']
                        iRecord['update_time'][bot.name] = cur_record['update_time']
                        break
                else:
                    cur_record['url'] = {bot.name: cur_record['url']}
                    cur_record['update_time'] = {bot.name: cur_record['update_time']}
                    info_in_day.append(cur_record)

        def _cmp(x, y):
            x_utime = x['update_time']
            y_utime = y['update_time']

            # only use not None val
            for k in x_utime:
                if x_utime[k]:
                    x_utime = x_utime[k]
                    break
            else:
                return 1

            for k in y_utime:
                if y_utime[k]:
                    y_utime = y_utime[k]
                    break
            else:
                return 1

            # x_utime = x_utime[x_utime.keys()[0]]
            # y_utime = y_utime[y_utime.keys()[0]]

            if x_utime > y_utime:
                return 1
            elif x_utime < y_utime:
                return -1
            else:
                return 0

        for key in bangumi_info:
            bangumi_info[key].sort(cmp=_cmp)

        raise gen.Return(bangumi_info)

    @staticmethod
    def _bangumi_similar(a, b):
        return difflib.SequenceMatcher(a=a['title'], b=b['title']).ratio()

def make_app():
    settings = {
        "static_path": os.path.join(os.path.dirname(__file__), '..', "static"),
        "debug": True
    }

    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/(.*)", tornado.web.StaticFileHandler,
         dict(path=settings['static_path'])),
    ], **settings)

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
<|endoftext|>