def goToState0(p, **kwargs): input = kwargs['input'] if 'input' in kwargs.keys() else None giveInstruction = input is None if giveInstruction: reply_txt = 'Hi {}, press *{}* or *{}* if you want to play!'.format( p.getName(), BUTTON_SYNONIM_GAME, BUTTON_INTRUDER_GAME) kb = [[BUTTON_SYNONIM_GAME], [BUTTON_INTRUDER_GAME], [BUTTON_INFO]] tell(p.chat_id, reply_txt, kb) else: if input == '': tell(p.chat_id, "Not a valid input.") elif input == BUTTON_SYNONIM_GAME: first_time_instructions = utility.unindent(""" Let’s train your vocabulary! Can you find a word with the same meaning? You will see a series of sentences with certain words highlighted. Which words describe the highlighted parts best? """) tell(p.chat_id, first_time_instructions) sendWaitingAction(p.chat_id, sleep_time=1) redirectToState(p, 1) elif input == BUTTON_INTRUDER_GAME: first_time_instructions = utility.unindent(""" Let’s find the intruder! 🐸 """) tell(p.chat_id, first_time_instructions) sendWaitingAction(p.chat_id, sleep_time=1) redirectToState(p, 2) elif input == BUTTON_INFO: tell(p.chat_id, INFO_TEXT) else: tell( p.chat_id, FROWNING_FACE + " Sorry, I don't understand what you have input")
def getMonthlyMessage(): people_count = person.getPeopleCount() contr_count, contr_namesString, recCommandsString = getLastContibutors(31) msg = "Siamo ora " + str( people_count) + " persone iscritte a @DialettiBot!\n\n" if contr_count > 0: if contr_count == 1: msg += utility.unindent(""" Nell'ultimo mese abbiamo ricevuto una registrazione! Un grande ringraziamento a *{}*! {}\n Se vuoi ascoltarla premi su questo comando:\n{} """.format(contr_namesString, CLAPPING_HANDS, recCommandsString)) else: msg += utility.unindent(""" Nell'ultimo mese abbiamo ricevuto {} registrazioni! Un grande ringraziamento a *{}*! {}\n Se vuoi ascoltarle premi su questi comandi:\n{} """.format(contr_count, contr_namesString, CLAPPING_HANDS * contr_count, recCommandsString)) else: msg += "Purtroppo questo mese non abbiamo ricevuto nessuna nuova registrazione " + FROWNING_FACE msg += "\n\nSul sito http://dialectbot.appspot.com potrai " \ "*visualizzare* (e *ascoltare*) tutte le registrazioni sulla *mappa* 🗺 !" msg += "\n\n*Aiutaci a crescere*: aggiungi nuove registrazioni del tuo dialetto tramite il bot " \ "e invita altre persone ad unirsi! " + SMILY return msg
def goToState22(p, input=None, **kwargs): BUTTON_SKIP_PHOTO = "Skip Photo" ASK_PICTURE_TEXT = unindent("""\ We encourage our contributors to send a *photo of the new location*.\ A link to the picture will be attached to the new location created in OpenStreetMap\ and will serve as supporting evidence for OpenStreetMap validators. Could you send me a photo of the {} location?\ If so please send me the photo using the paper clip below (📎).""") THANKS_TEXT = unindent("""\ 🙏 Thanks for your contribution! The location has been submitted to OpenStreetMap.\ It will be stortily available in the\ [online map](http://www.openstreetmap.org/#map=18/{}/{})\ and in SearchAroundBot.""") photo = kwargs['photo'] if 'photo' in kwargs else None giveInstruction = input is None and photo == None type = p.getSearchType() if giveInstruction: reply_txt = ASK_PICTURE_TEXT.format(type) tell(p.chat_id, reply_txt, kb=[[BUTTON_SKIP_PHOTO]], one_time_keyboard=True) else: if input == BUTTON_SKIP_PHOTO: file_id = None elif photo: logging.debug("Photo field: " + str(photo)) file_id = photo[-1]['file_id'] else: tell( p.chat_id, "Not a valid type of input. " "Please send me a photo or press the \\'{0}\\' button.".format( BUTTON_SKIP_PHOTO)) return # both with and without picture lat = p.location.lat lon = p.location.lon tell(p.chat_id, THANKS_TEXT.format(lat, lon)) restart(p) photo_url = parameters.PHOTO_BASE_URL + file_id if file_id else None node_id = osmEdit.insertNewLocation(lat, lon, p.getSearchType(), p.chat_id, photo_url) contribution.addContribution(p, node_id, file_id) msg = "User {} has inserted the following new {}: {}, {}. ".format( p.getUserInfoString(), type, lat, lon) if photo_url: msg += "\nPicure [url]({})".format(photo_url) msg += "\n[online map](http://www.openstreetmap.org/#map=18/{}/{}".format( lat, lon) tell(key.FEDE_CHAT_ID, msg)
def goToState21(p, input=None, **kwargs): CONFIRM_TEXT = unindent("""\ I am about to insert a new *{}* location\ into [OpenStreetMap](http://www.openstreetmap.org/).\ Please make sure you have sent a *correct* and *accurate* location. Are you sure you want to proceed?""") giveInstruction = input is None type = p.getSearchType() if giveInstruction: reply_txt = CONFIRM_TEXT.format(type) tell(p.chat_id, reply_txt, kb=[[BUTTON_YES, BUTTON_NO]], one_time_keyboard=True) else: if input == '': tell(p.chat_id, "Not a valid input.") elif input == BUTTON_YES: redirectToState(p, 22) #picture elif input == BUTTON_NO: restart(p) else: tell( p.chat_id, FROWNING_FACE + " Sorry, I don't understand your request. Please use the buttons." )
def broadcast(sender, msg, restart_user=False, curs=None, enabledCount=0): #return BROADCAST_COUNT_REPORT = utility.unindent(""" Mesage sent to {} people Enabled: {} Disabled: {} """) users, next_curs, more = Person.query().fetch_page(50, start_cursor=curs) try: for p in users: if p.enabled: enabledCount += 1 if restart_user: restart(p) tell(p.chat_id, msg, sleepDelay=True) except datastore_errors.Timeout: sleep(1) deferred.defer(broadcast, sender, msg, restart_user, curs, enabledCount) return if more: deferred.defer(broadcast, sender, msg, restart_user, next_curs, enabledCount) else: total = Person.query().count() disabled = total - enabledCount msg_debug = BROADCAST_COUNT_REPORT.format(str(total), str(enabledCount), str(disabled)) tell(sender.chat_id, msg_debug)
def goToState1(p, **kwargs): input = kwargs['input'] if 'input' in kwargs.keys() else None giveInstruction = input is None if giveInstruction: exerciseId, sentence, wordIndexToReplace, wordsToReplace, falseSynonymes, trueSynonymes = exercise_synonim.getRandomExercise( ) sentenceWithBoldWord = getSentenceWithBoldedWord( sentence, wordIndexToReplace, wordsToReplace) plural = 's' if len(wordsToReplace.split()) > 1 else '' instructions = utility.unindent(""" I've chosen the following sentence for you:\n {0}\n Select an option from the following list which is a synonym of the word{1} in bold text ({2}). """.format(sentenceWithBoldWord, plural, wordsToReplace)) options = falseSynonymes + trueSynonymes random.shuffle(options) options_text = [ BULLET_POINT + ' /' + str(n) + ': ' + x for n, x in enumerate(options, 1) ] instructions += '\n'.join(options_text) number_buttons = [str(x) for x in range(1, len(options) + 1)] kb = utility.distributeElementMaxSize(number_buttons) kb.append([BUTTON_EXIT]) tell(p.chat_id, instructions, kb, one_time_keyboard=False) p.setLastExerciseNumberAndOptions(exerciseId, options) else: if input == '': tell(p.chat_id, "Not a valid input.") elif input == BUTTON_EXIT: restart(p) #elif input == BUTTON_NEXT_SENTENCE: # repeatState(p) else: exerciseId, exerciseOptions = p.getLastExerciseIdAndOptions() exerciseId, sentence, wordIndexToReplace, wordsToReplace, falseSynonymes, trueSynonymes = exercise_synonim.getExercizeId( exerciseId) if input.startswith('/'): input = input[1:] if utility.representsIntBetween(input, 1, len(exerciseOptions) + 1): number = int(input) chosenWord = exerciseOptions[number - 1] else: #tell(p.chat_id, FROWNING_FACE + " Sorry, I don't understand what you have input") chosenWord = input msg = "You have chosen *{0}*.\n".format(chosenWord) sendWaitingAction(p.chat_id, sleep_time=0.5) if chosenWord in trueSynonymes: msg += "😄 Great, your answer is correct!" #kb = [[BUTTON_NEXT_SENTENCE], [BUTTON_EXIT]] kb = [[BUTTON_EXIT]] tell(p.chat_id, msg, kb) sendWaitingAction(p.chat_id, sleep_time=1) repeatState(p) else: msg += "🙁 I'm sorry, your answer is NOT correct, try again" tell(p.chat_id, msg)
else: pass # ================================ # GENERAL FUNCTIONS # ================================ # --------- # BROADCAST # --------- BROADCAST_COUNT_REPORT = utility.unindent( """ Messaggio inviato a {} persone Ricevuto da: {} Non rivevuto da : {} (hanno disattivato il bot) """ ) #NOTIFICATION_WARNING_MSG = '🔔 Per modificare le notifiche vai su {} → {}.'.format( # BOTTONE_IMPOSTAZIONI, BOTTONE_NOTIFICHE) def broadcast(sender, msg, qry = None, restart_user=False, blackList_sender=False, sendNotification=True, notificationWarning = False): from google.appengine.ext.db import datastore_errors from google.appengine.api.urlfetch_errors import InternalTransientError if qry is None:
import utility if __name__ == "__main__": test_unindent = utility.unindent(""" Let’s find the intruder! 🐸 """) print(test_unindent)
def post(self): body = jsonUtil.json_loads_byteified(self.request.body) logging.info('request body:') logging.info(body) self.response.write(json.dumps(body)) # update_id = body['update_id'] if 'message' not in body: return message = body['message'] #message_id = message.get('message_id') # date = message.get('date') if "chat" not in message: return # fr = message.get('from') chat = message['chat'] chat_id = chat['id'] if "first_name" not in chat: return text = message.get('text', "") name = chat["first_name"] last_name = chat.get("last_name", "-") username = chat.get("username", "-") location = message.get("location", None) voice = message.get("voice", None) #audio = message.get("audio", None) #document = message.get("document", None) logging.debug("Received input from {}. Text={} Location={}".format( chat_id, text, location)) def reply(msg=None, kb=None, markdown=True, inline_keyboard=False): send_message(chat_id, msg, kb=kb, markdown=markdown, inline_keyboard=inline_keyboard) p = person.getPersonByChatId(chat_id) if p is None: # new user logging.info("Text: " + text) if text == '/help': reply(ISTRUZIONI) if text.startswith("/start"): p = person.addPerson(chat_id, name) reply("Ciao " + p.getFirstName() + ", " + "benvenuta/o!") init_user(p, name, last_name, username) restart(p) # state = -1 or -2 tell_masters("New user: "******"Premi su /start se vuoi iniziare. " "Se hai qualche domanda o suggerimento non esitare di contattarmi cliccando su @kercos" ) else: # known user person.updateUsername(p, username) if text.startswith("/start"): reply("Ciao " + p.getFirstName() + ", " + "ben ritrovata/o!") init_user(p, name, last_name, username) restart(p) # state = -1 or -2 elif text == '/state': if p.state in STATES: reply("You are in state " + str(p.state) + ": " + STATES[p.state]) else: reply("You are in state " + str(p.state)) elif WORK_IN_PROGRESS and not p.isAdmin(): reply(UNDER_CONSTRUCTION + " Il sistema è in aggiornamento, riprova più tardi.") elif text.startswith('/rec_'): send_voiceLocationTranslationFromCommand(p, text, userInfo=p.isAdmin()) elif text.startswith('/sendText') and p.isAdmin(): dealWithsendTextCommand(p, text, markdown=False) elif p.state == -1: # INITIAL STATE if text in ['/help', BOTTONE_INFO]: redirectToState(p, 8) elif text == BOTTONE_REGISTRA: if p.location: dealWithPlaceAndMicInstructions(p) else: reply( "Questa è la tua prima registrazione: " "è necessario che tu inserisca il luogo del dialetto che vuoi registrare.\n" + ISTRUZIONI_POSIZIONE, kb=[[BOTTONE_ANNULLA]]) person.setState(p, -2) elif text == BOTTONE_ASCOLTA: goToAscolta(p) # state 30 elif p.isAdmin(): if text == BOTTONE_ADMIN: redirectToState(p, 9) elif text == '/test': reply('test') #reply(geoUtils.getLocationTest()) #taskqueue.add(url='/worker', params={'key': key}) #geoUtils.test_Google_Map_Api() elif text == '/infoCounts': c = person.getPeopleCount() reply("Number of users: " + str(c)) elif text == '/restartUsers': text = "Nuova interfaccia e nuove funzionalità :)\n" \ "Ora puoi inserire le località digitando il nome del posto (e.g, Perugia).\n" \ "Inoltre puoi cercare registrazioni in prossimità di un luogo.\n" \ "Buon ascolto e buona registrazione!" deferred.defer(restartAllUsers, text) #'New interface :)') #deferred.defer(restartTest, text) #'New interface :)') logging.debug('restarted users') elif text == '/importVivaldi': #logging.debug('nothing') recording.importVivaldi() elif text == '/countVivaldi': c = recording.countVivaldi() reply('Vivaldi recs: ' + str(c)) elif text == '/deleteVivaldi': recording.deleteVivaldi() reply('Deleted Vivaldi recs.') elif text == '/remFormatVoice': c = recording.removeFormatVoice() reply("removed rec format voice: " + str(c)) elif text == '/stats': msg = recording.getRecodingsStats() send_message(p.chat_id, msg, markdown=False) msg = "People count: {}".format( person.getPeopleCount()) send_message(p.chat_id, msg, markdown=False) elif text.startswith('/echo ') and len(text) > 6: msg = text[6:] reply(msg) elif text.startswith('/broadcast ') and len(text) > 11: msg = text[11:] deferred.defer(broadcast, p.chat_id, msg, restart_user=False) elif text.startswith( '/restartBroadcast ') and len(text) > 18: msg = text[18:] deferred.defer(broadcast, p.chat_id, msg, restart_user=True) elif text.startswith('/self ') and len(text) > 6: msg = text[6:] reply(msg) elif text == '/lastContributors': count, namesString, recCommandsString = getLastContibutors( 300) msg = "Contributors: " + str( count) + "\nNames: " + namesString reply(msg) elif text == '/testMonthlyMessage': msg = getMonthlyMessage() reply(msg) else: reply('Scusa, capisco solo /help /start ' 'e altri comandi segreti...') #setLanguage(d.language) else: reply( "Scusa non capisco quello che hai detto.\n" "Usa i pulsanti sotto o premi {} per avere informazioni." .format(BOTTONE_INFO)) elif p.state == -2: # POSIZIONE if text == BOTTONE_ANNULLA: restart(p, "Operazione annullata.") elif location != None: logging.debug('User sending location: {}, {}'.format( location['latitude'], location['longitude'])) luogo = geoUtils.getComuneProvinciaFromCoordinates( location['latitude'], location['longitude']) logging.debug('Detected luogo: {}'.format(luogo)) if luogo: person.setLocation(p, location['latitude'], location['longitude']) dealWithPlaceAndMicInstructions(p) else: reply( "Non conosco la località inserita, prova ad essere più precisa/o.\n" + ISTRUZIONI_POSIZIONE, kb=[[BOTTONE_INVIA_LOCATION], [BOTTONE_ANNULLA]]) logging.debug( 'Problem finding comune and provincia from coordinates {} {}' .format(location['latitude'], location['longitude'])) #state 20 elif text.startswith('('): text_split = text[1:-1].split(",") latitude = float(text_split[0]) longitude = float(text_split[1]) person.setLocation(p, latitude, longitude) send_location(p.chat_id, latitude, longitude) dealWithPlaceAndMicInstructions(p) #state 20 else: place = geoUtils.getLocationFromName(text) if place: person.setLocation(p, place.latitude, place.longitude) dealWithPlaceAndMicInstructions(p) #state 20 else: reply( "Non conosco la località inserita, prova ad essere più precisa/o.\n" + ISTRUZIONI_POSIZIONE, kb=[[BOTTONE_INVIA_LOCATION], [BOTTONE_ANNULLA]]) elif p.state == 20: # REGISTRA if text == BOTTONE_INDIETRO: restart(p, "Operazione annullata.") # state = -1 elif text == BOTTONE_CAMBIA_LUOGO: reply("Ok, cambiamo il luogo.\n" + ISTRUZIONI_POSIZIONE, kb=[[BOTTONE_INVIA_LOCATION], [BOTTONE_ANNULLA]]) person.setState(p, -2) # state -2 elif voice != None: reply( "Bene! 😉\n" "Ora riascolta la registrazione e conferma su ✅ OK " "se la registrazione è ben riuscita o premi su 🎙 REGISTRA DI NUOVO per" "effettuare un'altra registrazione.", kb=[['✅ OK'], ['🎙 REGISTRA DI NUOVO'], [BOTTONE_ANNULLA]]) file_id = voice['file_id'] #send_voice(p.chat_id, file_id) rec = recording.addRecording(p, file_id) person.setLastRecording(p, rec) person.setState(p, 21) else: reply( FROWNING_FACE + " Scusa non capisco quello che hai detto, devi inserire la registrazione tenendo premuto il microfono." ) elif p.state == 21: # CONFIRM RECORDING if text == BOTTONE_ANNULLA: person.removeLastRecording(p) restart(p, "Operazione annullata.") # state = -1 elif text == '✅ OK': msg = utility.unindent(''' Riteniamo utile avere una traduzione in italiano delle registrazione \ in modo da essere comprensibili da tutti gli utenti.\n *Scrivi qua sotto* la traduzione della registrazione \ (in aggiunta puoi inserire la trascrizione in dialetto e il significato in caso si tratti di un proverbio) ''') reply(msg, kb=[['Salta Traduzione']]) person.setState(p, 22) elif text == '🎙 REGISTRA DI NUOVO': person.removeLastRecording(p) reply(MIC_INSTRUCTIONS, kb=[[BOTTONE_CAMBIA_LUOGO], [BOTTONE_ANNULLA]]) person.setState(p, 20) else: reply( FROWNING_FACE + "Scusa non capisco quello che hai detto, premi *OK* per confermare la registrazione." ) elif p.state == 22: # CHECK IF AVAILABLE FOR TRANSLATION if text == 'Salta Traduzione': msg = "👍😀 Grazie per il tuo contributo!\n" \ "La registrazione è in attesa di approvazione, riceverai un messaggio a breve." reply(msg) sendNewRecordingNotice(p) restart(p) elif text == '': msg = "Input non valido. *Scrivi* qua sotto la traduzione in italiano della registrazione" reply(msg, kb=[['Salta Traduzione']]) return else: recording.addTranslation(p.last_recording_file_id, text) msg = "👍😀 Grazie per il tuo contributo!\n" \ "La registrazione è in attesa di approvazione, riceverai un messaggio a breve." reply(msg) sendNewRecordingNotice(p) restart(p) elif p.state == 30: if text == BOTTONE_INDIETRO: restart(p) # state = -1 elif text == BOTTONE_INDOVINA_LUOGO: dealWithRandomRecording(p) # state 31 elif text == BOTTONE_CERCA_LUOGO: reply(ISTRUZIONI_POSIZIONE_SEARCH, kb=[[BOTTONE_INDIETRO]]) person.setState(p, 32) # state 32 elif text == BOTTONE_RECENTI: getRecentRecordings(p) person.setState(p, 33) # state 33 elif text == BOTTONE_TUTTE: getAllRecordings(p) person.setState(p, 33) # state 33 else: msg = "Input non valido. Usa i pulsanti qua sotto." reply(msg) return elif p.state == 31: # ASCOLTA - INDOVINA LUOGO if text in [BOTTONE_INDIETRO, BOTTONE_ANNULLA]: restart(p) # state = -1 elif text == "ASCOLTA NUOVA REGISTRAZIONE": dealWithRandomRecording(p) # state 31 elif location != None: dealWithGuessedLocation(p, location) else: place = geoUtils.getLocationFromName(text) if place: guessed_loc = { 'latitude': place.latitude, 'longitude': place.longitude } dealWithGuessedLocation(p, guessed_loc) else: reply( "Non conosco la località inserita, prova ad essere più precisa/o.\n" + ISTRUZIONI_POSIZIONE_GUESS, kb=[[BOTTONE_ANNULLA]]) elif p.state == 32: #ASCOLTA - RICERCA LUOGO sendWaitingAction(p.chat_id) if location != None: dealWithFindClosestRecording(p, location) elif text == BOTTONE_INDIETRO: restart(p) else: place = geoUtils.getLocationFromName(text) if place: loc = { 'latitude': place.latitude, 'longitude': place.longitude } dealWithFindClosestRecording(p, loc) else: reply( "Non conosco la località inserita, prova ad essere più precisa/o.\n" + ISTRUZIONI_POSIZIONE_SEARCH, kb=[[BOTTONE_INDIETRO]]) elif p.state == 33: # REGISTRAZIONI RECENTI if text == BOTTONE_INDIETRO: goToAscolta(p) else: reply(FROWNING_FACE + "Scusa non capisco quello che hai detto.") else: logging.debug("Sending {0} to state {1}".format( p.getFirstName(), str(p.state))) repeatState(p, input=text)