def getLatestAnswers(user): #TODO Need to make display follow the same comparison algorithm # as in calculateAnswerRating latest_answers = [] l = {} questions = Question.all().\ filter("twitter_user ="******"answer_received >", None).\ order("-answer_received").fetch(10) for q in questions: original = q.lli_ref.dict_entry.meaning.split(',') if q.answer_text: answer = q.answer_text.split(',') else: answer = '' original = [x.strip() for x in original] answer = [x.strip() for x in answer] match = set(original).intersection(set(answer)) wrong = set(answer).difference(set(original)) neutral = set(original).difference(set(answer)) l = {"word": q.word, "answers": [], "rating": q.answer_rating} for i in match: l["answers"].append({"answer_text": i, "status": "match"}) for i in neutral: l["answers"].append({"answer_text": i, "status": "neutral"}) for i in wrong: l["answers"].append({"answer_text": i, "status": "wrong"}) latest_answers.append(l) return json.dumps(latest_answers)
def testDeleteDictEntry(self): today = datetime.date.today() current_time = int(time.time()) u = self.createUser("da_zbur", "enabled", 10) u.use_questions = "yes" u.put() d1 = self.createDictEntry("da_zbur", 2, "lucrative", \ u"profitable, moneymaking, remunerative", "[LOO-kruh-tiv]") d2 = self.createDictEntry("da_zbur", 2, "ferociously(en)", \ u"жестоко, яростно, свирепо, дико, неистово. Ужасно, невыносимо.") l1 = self.createLearnListItem("da_zbur", d1, today, current_time) l2 = self.createLearnListItem("da_zbur", d2, today, current_time) self.createQuestion(l1, today, "da_zbur", d1.word, "profitable, moneymaking", 1, today, 100) self.createQuestion(l2, today, "da_zbur", d2.word, u"лажа", 2, today, 0) deleteDictEntry(u, "lucrative[LOO-kruh-tiv]") self.assertEqual(None, Dictionary.all().\ filter("word =", "lucrative").get()) self.assertEqual(1, LearnList.all().count()) self.assertEqual(1, Question.all().count()) self.assertEqual(1, Dictionary.all().count())
def checkForAnswer(parsed_dict, twitter_user): # Check for answers via DirectMessage question = Question.all().\ filter("twitter_user ="******"word =", parsed_dict["word"]).\ filter("answer_received =", None).\ filter("question_message_id !=", None).get() if not question: return None return question
def sendMessagesGenerator(TwitterAPI, logging): current_time = int(time.time()) # Are there messages to send out in next SCHEDULERUN seconds? next_planned_interval = current_time + SCHEDULERUN today = datetime.date.today() for lli in LearnList.all().\ filter("next_serve_time <=", next_planned_interval): result = None # Don't send messages if user is disabled user = User.all().filter("twitter =", lli.twitter_user).\ filter("account_status =", "enabled").fetch(1) if user == []: yield result # If user has messages in todays list but is disabled now # Let's just reschedule it to tomorrow lli.next_serve_date = addDays(lli.next_serve_date, 1) lli.next_serve_time = sys.maxint lli.put() continue # If there is a question to send, prepare a different # Twitter message format question = Question.all().filter("lli_ref =", lli).\ filter("answer_received =", None).fetch(1) if question != []: message = prepareQuestionMessage(lli) else: message = prepareTwitterMessage(lli) try: #status = TwitterAPI.api.PostUpdate(message) status = TwitterAPI.api.PostDirectMessage(lli.twitter_user,\ message) result = message # For questions we do no recalculate new interval right away # We do it when answer is recieved or no received # Instead we update Question entity if question == []: answer_rating = lli.latest_answer_rating rescheduleLearnListItem(lli, answer_rating) else: question[0].question_sent = today question[0].question_message_id = status.id question[0].put() # We also need to make sure this message is not sent again automatically # Until answer is recieved or it expires lli.next_serve_time = sys.maxint lli.put() except TwitterError: print TwitterError.message logging.error("Twitter error when sending message %s" % message) yield result
def acknowledgeQuestions(day): # This is used to acknowledge any unaswered question # It sets answer rating to 0 and reschedules to today for question in Question.all().filter("answer_received =", None).\ filter("question_message_id !=", None): question.answer_received = day question.answer_rating = -POINTS_PER_GUESS question.lli_ref.latest_answer_rating = 0 question.lli_ref.next_serve_time = 0 question.lli_ref.next_serve_date = day question.lli_ref.total_served += 1 question.put() question.lli_ref.put()
def deleteDictEntry(user, word): word, _ = parseOpt(word) dict_entry = Dictionary.all().\ filter("twitter_user ="******"word =", word.strip()).get() if dict_entry: lli = LearnList.all().\ filter("dict_entry =", dict_entry.key()).get() for q in Question.all().filter("lli_ref =", lli.key()).run(): q.delete() lli.delete() dict_entry.delete() return json.dumps({})
def testQuestionAcknowledge(self): Twitter = TwitterMockup() today = datetime.date.today() current_time = int(time.time()) u = self.createUser("da_zbur","enabled",10) u.use_questions = "yes" u.put() d1 = self.createDictEntry("da_zbur",2,"lucrative",\ u"profitable, moneymaking, remunerative","[LOO-kruh-tiv]") d2 = self.createDictEntry("da_zbur",2,"ferociously(en)",\ u"жестоко, яростно, свирепо, дико, неистово. Ужасно, невыносимо.") l1 = self.createLearnListItem("da_zbur",d1,today,current_time) l2 = self.createLearnListItem("da_zbur",d2,today,current_time) # forcing question to be asked l1.total_served = 4 l2.total_served = 6 l2.put() l1.put() buildDailyList(today, logging) # Keep in mind building daily list means serve times will be # randomly distributed throighout the day! l1.next_serve_time = current_time l2.next_serve_time = current_time l2.put() l1.put() messages_generator = sendMessagesGenerator(Twitter, logging) m_list = [] while True: try: message = messages_generator.next() except StopIteration: break m_list.append(message) # Now imagine those question didn't get answers before next daily # list is build acknowledgeQuestions(today) unack_count = Question.all().filter("answer_received =", None).count() self.assertEqual(0, unack_count)
def testQuestionAdding(self): # This is testing buildDailyList method to make sure that # every second serving a Question opbject is added. today = datetime.date.today() u = self.createUser("da_zbur","enabled",10) d1 = self.createDictEntry("da_zbur",2,"dog",u"собачка") lli = self.createLearnListItem("da_zbur",d1,today) u.use_questions = "yes" u.put() lli.total_served = 6 lli.put() buildDailyList(today, logging) question_list = [] for q in Question.all().filter("lli_ref =", lli): question_list.append(q) self.assertEqual(1, len(question_list)) self.assertEqual(d1.key(), question_list[0].lli_ref.dict_entry.key())
def testSendQuestion(self): Twitter = TwitterMockup() today = datetime.date.today() current_time = int(time.time()) u = self.createUser("da_zbur","enabled",10) u.use_questions = "yes" u.put() d1 = self.createDictEntry("da_zbur",2,"lucrative",\ u"profitable, moneymaking, remunerative","[LOO-kruh-tiv]") d2 = self.createDictEntry("da_zbur",2,"ferociously(en)",\ u"жестоко, яростно, свирепо, дико, неистово. Ужасно, невыносимо.") l1 = self.createLearnListItem("da_zbur",d1,today,current_time) l2 = self.createLearnListItem("da_zbur",d2,today,current_time) # forcing question to be asked l1.total_served = 4 l1.put() buildDailyList(today, logging) # Keep in mind building daily list means serve times will be # randomly distributed throighout the day! l1.next_serve_time = current_time l2.next_serve_time = current_time l2.put() l1.put() messages_generator = sendMessagesGenerator(Twitter, logging) m_list = [] while True: try: message = messages_generator.next() except StopIteration: break m_list.append(message) # Testing that proper Question entity was created q = Question.all().fetch(1)[0] self.assertEqual(2653, q.question_message_id) self.assertEqual(today, q.question_sent) self.assertEqual(4, l1.total_served) self.assertEqual(sys.maxint, q.lli_ref.next_serve_time) self.assertEqual("lucrative[LOO-kruh-tiv]:? [4]", m_list[0])
def testCheckForAnswer(self): # I should collapse this code into something reusable Twitter = TwitterMockup() today = datetime.date.today() current_time = int(time.time()) u = self.createUser("da_zbur","enabled",10) u.use_questions = "yes" u.put() d1 = self.createDictEntry("da_zbur",2,"lucrative",\ u"profitable, moneymaking, remunerative","[LOO-kruh-tiv]") l1 = self.createLearnListItem("da_zbur",d1,today,current_time) # forcing question to be asked l1.total_served = 4 l1.put() buildDailyList(today, logging) # Keep in mind building daily list means serve times will be # randomly distributed throighout the day! l1.next_serve_time = current_time l1.put() messages_generator = sendMessagesGenerator(Twitter, logging) m_list = [] while True: try: message = messages_generator.next() except StopIteration: break m_list.append(message) q = Question.all().fetch(1)[0] # Question for word d1 was genereated and sent # Now user prepares an answer answer = "lucrative: moneymaking, profitable" m = Twitter.api.PostUpdate(answer, in_reply_to_s_id=q.question_message_id) parsed_dict = parseMessage(m.text) q2 = checkForAnswer(parsed_dict, u.twitter) self.assertEqual(q.key(), q2.key())
def testAnswersIntegration(self): # I should collapse this code into something reusable # This is a big integration test for question/answers # Idea is that there are two answers: good and bad # Need to check if messages are being properly rescheduled and send Twitter = TwitterMockup() today = datetime.date.today() current_time = int(time.time()) u = self.createUser("da_zbur","enabled",10) u.use_questions = "yes" u.put() d1 = self.createDictEntry("da_zbur",2,"lucrative",\ u"profitable, moneymaking, remunerative","[LOO-kruh-tiv]") d2 = self.createDictEntry("da_zbur",2,"ferociously(en)",\ u"жестоко, яростно, свирепо, дико, неистово. Ужасно, невыносимо.") d3 = self.createDictEntry("da_zbur",2,"confounder",\ u"искажающий результаты фактор") l1 = self.createLearnListItem("da_zbur",d1,today,current_time) l2 = self.createLearnListItem("da_zbur",d2,today,current_time) l3 = self.createLearnListItem("da_zbur",d3,today,current_time) # forcing question to be asked l1.total_served = 4 l2.total_served = 6 l3.total_served = 8 l1.interval_days = 3.2 l1.efactor = 1.3 l2.interval_days = 7.4 l2.efactor = 0.98 l3.interval_days = 17.4 l3.efactor = 1.98 l1.put() l2.put() l3.put() buildDailyList(today, logging) # Keep in mind building daily list means serve times will be # randomly distributed throighout the day! l1.next_serve_time = current_time l2.next_serve_time = current_time l3.next_serve_time = current_time l2.put() l1.put() l3.put() messages_generator = sendMessagesGenerator(Twitter, logging) m_list = [] while True: try: message = messages_generator.next() except StopIteration: break m_list.append(message) q1 = Question.all().fetch(3)[0] q2 = Question.all().fetch(3)[1] q3 = Question.all().fetch(3)[2] # This is a good answer a1 = "lucrative: moneymaking, profitable" # This is crappy answer a2 = u"ferociously(en): ---" # This is multiword answer a3 = u"Confounder: искажающий результаты фактор" m1 = Twitter.api.PostDirectMessage("LangBotStage", a1, "da_zbur") m2 = Twitter.api.PostDirectMessage("LangBotStage", a2, "da_zbur") m3 = Twitter.api.PostDirectMessage("LangBotStage", a3, "da_zbur") processMessage(m1) processMessage(m2) processMessage(m3) q1 = Question.all().fetch(3)[0] q2 = Question.all().fetch(3)[1] q3 = Question.all().fetch(3)[2] # For good question self.assertEqual(today, q1.answer_received) self.assertEqual(6, q1.answer_rating) self.assertEqual(6, q1.lli_ref.latest_answer_rating) self.assertEqual(sys.maxint, q1.lli_ref.next_serve_time) self.assertEqual(1.6, q1.lli_ref.efactor) self.assertEqual(3.2*1.3, q1.lli_ref.interval_days) self.assertEqual("moneymaking, profitable", q1.answer_text) # For bad question self.assertEqual(today, q2.answer_received) self.assertEqual(-2, q2.answer_rating) self.assertEqual(-2, q2.lli_ref.latest_answer_rating) self.assertEqual(0, q2.lli_ref.next_serve_time) self.assertEqual(today, q2.lli_ref.next_serve_date) self.assertEqual("---", q2.answer_text) # For multiword answer self.assertEqual(today, q3.answer_received) self.assertEqual(2, q3.answer_rating) self.assertEqual(2, q3.lli_ref.latest_answer_rating) self.assertEqual(sys.maxint, q3.lli_ref.next_serve_time) self.assertEqual(u"искажающий результаты фактор", q3.answer_text) # Check total user points, assuming he had 0 self.assertEqual(6 , User.all().filter("twitter =","da_zbur").\ get().total_points)