예제 #1
0
class TwitterListener(StreamListener):
    def __init__(self):
        self.cache = LFUCache(maxsize=50)
        self.cache2 = LFUCache(maxsize=50)
        Timer(interval=60, function=self.print_keys)
        Timer(interval=30, function=self.check_cached_words)

    def on_data(self, data):
        data_lst = json.loads(data)
        data_lst = data_lst.get('text', '').split()

        if self.cache.currsize == self.cache.maxsize:
            for key in list(self.cache.keys()):
                if self.cache[key] == 0:
                    del self.cache[key]

        for word in data_lst:
            if word in self.cache.keys():
                self.cache[word] += 1
            else:
                self.cache[word] = 1
            if self.cache[word] < 0:
                del self.cache[word]

        return True

    def print_keys(self):
        """
        print recent words and update the second cache every 60 seconds
        """
        print(list(self.cache.items()))
        self.cache2.update(self.cache)
        return True

    def check_cached_words(self):
        """
        Decrease score of word by 1 if the score does not change within
        60 seconds
        """
        for word in list(self.cache.keys()):
            if self.cache.get(word) == self.cache2.get(word):
                self.cache[word] -= 1
        return True
예제 #2
0
파일: WordBot.py 프로젝트: ashrovy/Wordbot
class WordBot():
	def __init__(self):
		self.dictionaryCache = LFUCache(maxsize = 200)
		self.urbandictionaryCache = LFUCache(maxsize = 200)
		self.wordOfTheDayCache = {}
		self.bot = telebot.TeleBot(bot_token)
		self.session = requests.Session()
		self.session.mount('http://', requests.adapters.HTTPAdapter(max_retries=5))
		self.session.mount('https://', requests.adapters.HTTPAdapter(max_retries=5))

	def handle_inline(self, query):
		try:
			query_word = query.get('query')
			default_word = self.getWordOfTheDay()
			inline_answers = []
			if default_word:
				default_result = types.InlineQueryResultArticle(
					'1', 
					'Word of the day', 
					types.InputTextMessageContent(
						'*' + default_word['word'] + '*\n' + default_word['definitions'],
						parse_mode='markdown'
					),
					description=default_word['word']
				)
				inline_answers = [default_result]
			if query_word or query_word != '':
				reply = self.make_reply('/define ' + query_word)
				desc = reply if reply == 'Word not found.' else None
				query_result = types.InlineQueryResultArticle('2', 
					query_word, 
					types.InputTextMessageContent(
						reply,
						parse_mode='markdown'
					),
					description=desc
				)
				inline_answers = [query_result]
			self.bot.answer_inline_query(query.get('id'), inline_answers)
		except Exception as e:
			pass
			#sprint(e)

	def handle_message(self, message):
		if 'new_chat_participant' in message:
			return
		query = message.get('text')
		if not query:
			return
		if '@LexicoBot' in query:
			query = query.replace('@LexicoBot', '')
		reply = self.make_reply(query)
		if reply != '':
			self.bot.send_chat_action(message['chat']['id'], 'typing')
			self.bot.send_message(message['chat']['id'], reply, parse_mode='markdown')
	   
	def make_reply(self, query):
		if query in ['/start', '/help']:
			return start_message		
		reply_message = ''
		if query == '/today':
			wordData = self.getWordOfTheDay()
			if wordData is None:
				return 'Server error.'
			query = '/define ' + wordData['word']
		query = query.split()
		if len(query) > 1:
			if query[0] in ['/define', '/synonyms', '/antonyms', '/use', '/all', '/ud']:
				word = ' '.join(query[1::])
				reply_message = '*' +  word + '*\n'
				if query[0] != '/ud':
					wordData = self.dictionaryCache.get(word)
					if wordData is None:
						wordData = self.getWord(word)
					else:
						pass
						#print 'Cache hit ' + word 
					if wordData is None:
						return 'Word not found.'
					if query[0] in ['/define','/all']:
						reply_message += wordData['definitions'] + '\n'
					if query[0] in ['/synonyms','/all']:
						reply_message += wordData['synonyms'] + '\n'
					if query[0] in ['/antonyms','/all']:
						reply_message += wordData['antonyms'] + '\n'
					if query[0] in ['/use','/all']:
						reply_message += wordData['examples'] + '\n'
				else:
					wordData = self.urbandictionaryCache.get(word)
					if wordData is None:
						wordData = self.getUrbandictionaryWord(word)
					if wordData is None:
						return 'Word not found'
					reply_message += wordData['definition'] + '\n'
					reply_message += wordData['example']	
		return reply_message
	
	def updateCache(self, word, wordData):
		dataDict = {}
		definitionText = '*Definitions*' +'\n'
		synonymsText = '*Synonyms*' + '\n'
		antonymsText = '*Antonyms*' + '\n'
		examplesText = '*Examples*' + '\n'
		definitions = self.getDefinitions(wordData)
		synonyms = self.getSynonyms(wordData)
		antonyms = self.getAntonyms(wordData)
		examples = self.getExamples(wordData)
		if not definitions:
			definitionText += 'No definitions found.\n'
		if not synonyms:
			synonymsText += 'No synonyms found.\n'
		if not antonyms:
			antonymsText += 'No antonyms found.\n'
		if not examples:
			examplesText += 'No examples found.\n'		
		for definition in self.getDefinitions(wordData):
			if definition[0]:
				definitionText += definition[0] + ': '
			definitionText += definition[1] + '\n\n'	
		definitionText = definitionText[:-1]	
		for synonym in synonyms[:3]:
			synonymsText += synonym + '\n'
		for antonym in antonyms[:3]:
			antonymsText += antonym + '\n'
		for index, example in enumerate(examples[:3]):
			examplesText += str(index+1) + '. ' + example + '\n\n'
		examplesText = examplesText[:-1]
		dataDict['word'] = word
		dataDict['definitions'] = definitionText
		dataDict['synonyms'] = synonymsText
		dataDict['antonyms'] = antonymsText
		dataDict['examples'] = examplesText
		self.dictionaryCache.update({word:dataDict})
		return dataDict
			
	def getDefinitions(self, wordData):
		partCounter = Counter()
		definitions = []
		for definition in wordData:
			if 'partOfSpeech' in definition.keys() and partCounter[definition['partOfSpeech']] < 2:
				definitions.append( 
					('_' + definition['partOfSpeech'] + '_ ', 
					definition['text'])
				)
				partCounter[definition['partOfSpeech']] += 1
			else:
				definitions.append(('',definition['text']))
		return definitions

	def getSynonyms(self, wordData):
		synonyms = []
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType'] == 'synonym':
				for synonym in relatedWords['words']:
					synonyms.append(synonym)
		
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType']	 == 'cross-reference':
				for synonym in relatedWords['words']:
					synonyms.append(synonym)	
		return synonyms

	def getAntonyms(self, wordData):
		antonyms = []
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType']	 == 'antonym':
				for antonym in relatedWords['words']:
					antonyms.append(antonym)
		return antonyms

	def getExamples(self, wordData):
		examples = []
		for index,example in enumerate(wordData[0]['examples']):
			examples.append(example['text'].replace('\n',''))
		return examples
		
	def getEtymology(self, wordData):
		etymologies = []
		for etymology in wordData[0]['etymologies']:
			etymologies.append(etymology)
		return etymology

	def getWord(self, word):
		def_url = wordnik_url + word + '/definitions?limit=15&api_key=' + wordnik_api_key
		example_url = wordnik_url + word + '/examples?api_key=' + wordnik_api_key
		related_url = wordnik_url + word + '/relatedWords?api_key=' + wordnik_api_key
		urls = [def_url, example_url, related_url]
		data = []
		for url in urls:
			try:
				response = self.session.get(url, verify=False)
				if response.status_code != 200:
					return None
				data.append(json.loads(response.text.encode('utf-8')))
			except ValueError:
				return None
		if not data[0]:
			return None
		wordData = data[0]
		try:
			wordData[0]['examples'] = data[1]['examples']
		except KeyError:
			wordData[0]['examples'] = []
		try:
			wordData[0]['relatedWords'] = data[2]
		except KeyError:
			wordData[0]['relatedWords'] = []
		return self.updateCache(word,wordData)
	
	def getUrbandictionaryWord(self, word):
		api_url = 'http://api.urbandictionary.com/v0/define?term='
		#response = requests.get(api_url+word, verify=False)
		response = urllib2.urlopen(api_url + word)
		data = json.loads(response.read().decode('utf-8'))
		if data['result_type'] == 'no_results' or not data['list']:
			return None
		wordData = {}
		wordData['definition'] = '*Definition*' + '\n'
		wordData['example'] = '*Example*'  + '\n'
		try:
			if data['list'][0]['definition']:
				wordData['definition'] += data['list'][0]['definition'].strip() + '\n'
			else:
				return None
		except KeyError:
			return None
		try:
			if data['list'][0]['example']:
				wordData['example'] += data['list'][0]['example'].strip() + '\n'
			else:
				wordData['example'] += 'No example found.'
		except KeyError:
			wordData['example'] += 'No example found.'			
		self.urbandictionaryCache.update({word:wordData})
		return wordData
	
	def getWordOfTheDay(self):
		wordOfTheDay = self.wordOfTheDayCache.get(datetime.now().day, None)
		if wordOfTheDay is None:
			today = datetime.strftime(datetime.now(), '%Y-%m-%d')
			url = wordnik_url[:-10] + 'words.json/wordOfTheDay?api_key=' + wordnik_api_key + '&date=' + today
			data = []
			response = self.session.get(url, verify=False)
			try:
				data.append(json.loads(response.text.encode('utf-8')))
			except ValueError:
				return None
			wordOfTheDay = data[0]['word']
			self.wordOfTheDayCache.clear()
			self.wordOfTheDayCache[datetime.now().day] = wordOfTheDay
		else:
			pass
			#print 'Today Cache Hit ' + wordOfTheDay
		wordData = self.dictionaryCache.get(wordOfTheDay)
		if not wordData:
			url = wordnik_url + wordOfTheDay + '/relatedWords?api_key=' + wordnik_api_key
			wordData = [definition for definition in data[0]['definitions']]
			for definition in wordData:
				definition['attributionText'] = ''
			wordData[0]['examples'] = data[0]['examples']
			response = self.session.get(url, verify = False)
			relatedWords = json.loads(response.text)
			wordData[0]['relatedWords'] = relatedWords
			wordData[0]['word'] = wordOfTheDay
			return self.updateCache(wordOfTheDay, wordData)	
		else:
			#print 'Cache hit ' + wordOfTheDay
			return wordData	
예제 #3
0
class PoolMetrics(object):
    def __init__(self, food_size, history_size):
        self.reaction_graph = ReactionGraph()
        self.food_size = food_size
        self.history = Counter()
        self.substrate_count = Counter()
        self.recent_history = LFUCache(history_size)
        self.pool_str_hist = deque(maxlen=1000)
        self.n_reactions = Counter()
        self.emergent_substrates = set()

    def on_reaction_computed(self, pool, reaction):
        #FIXME: move to arguments
        self.expressions = pool.expressions
        self.pool = pool
        self.reaction_graph.add_reaction(reaction)
        substrate = reaction.get_substrate()
        if substrate is not None:
            self.substrate_count[substrate] += 1

        for product in reaction.products:
            self.history[product] = self.history.get(product, 0) + 1
            self.recent_history[product] = self.recent_history.get(product,
                                                                   0) + 1
        self.n_reactions[reaction.type] += 1

    def get_current_p_reduce(self):
        Z = sum(self.n_reactions.values())
        return self.n_reactions['reduce'] / Z if Z > 0 else 0

    def get_current_p_break(self):
        Z = sum(self.n_reactions.values())
        return self.n_reactions['break'] / Z if Z > 0 else 0

    def get_current_p_combine(self):
        Z = sum(self.n_reactions.values())
        return self.n_reactions['combine'] / Z if Z > 0 else 0

    def get_current_n_combine(self):
        return self.n_reactions['combine']

    def get_current_n_reduce(self):
        return self.n_reactions['reduce']

    def get_current_n_break(self):
        return self.n_reactions['break']

    @lazy
    def raf(self):
        food_set = set(
            x for x in self.reaction_graph.remove_selfloop().get_expressions()
            if len(x) <= self.food_size)
        raf = self.reaction_graph.get_raf(food_set)
        for r in raf:
            count = self.reaction_graph.get_occurrences(r)
            logger.info(f'{count} x {r} ')  #(' +
            #'; '.join(f'{x} = {self.expressions[x]}'
            #    for x in r.reactives) +
            #')')
        return raf

    def is_valid_raf(self, raf, food_set):
        for r in raf:
            if any(p not in food_set and not any(p not in r2.products
                                                 for r2 in raf)
                   for p in r.reactives):
                return False
        return True

    @lazy
    def reduction_sg(self):
        return self.reaction_graph.get_reduction_subgraph().remove_selfloop()
        # for reactives, product in raf:
        #     if term.size(product) > 3:
        #         print(" + ".join(map(term.to_str, reactives)), '->', term.to_str(product))

    def reset_perishable_history(self):
        #self.reaction_graph.reset()
        lazy.invalidate(self, 'raf')
        lazy.invalidate(self, 'reduction_sg')
        self.n_reactions.clear()

    def get_substrate_count(self):
        return self.substrate_count

    def get_current_total_size(self):
        return self.pool.get_total_size()

    def get_current_expressions_top10_length(self):
        sizes = list(map(len, self.expressions))
        sizes.sort()
        return np.mean(sizes[-10:])

    def get_current_expressions_reducible_count(self):
        reducibles = sum(v for ex, v in self.expressions.items()
                         if ex.is_reducible(self.pool))
        return reducibles

    def get_recent_largest_scc_size(self):
        if len(self.reaction_graph) > 0:
            return len(self.get_largest_strongly_connected_component())
        else:
            return -1

    def get_largest_strongly_connected_component(self):
        graph = self.reaction_graph.get_reduction_subgraph()
        graph.trim_short_formulae(4)
        largest = max(graph.get_all_strongly_connected_components(), key=len)
        node_types = nx.get_node_attributes(graph.graph, 'node_type')
        sg = self.reaction_graph.graph.subgraph(largest)
        #for n in largest:
        #    if node_types[n] == 'formula':
        #        print(term.to_str(n))
        #        self.print_preceding_graph(sg, n)
        return largest

    def get_current_expressions_count(self):
        return sum(v for ex, v in self.expressions.items())

    def get_current_expressions_distinct_count(self):
        return sum(1 for _ in self.expressions.unique())

    def get_current_expressions_recurrence_count(self, threshold=4):
        c, n = 0, 0
        for f in self.history:
            if len(f) > threshold:
                c += self.history[f]
                n += 1
        return c / n if n > 0 else 0
        # try:
        #     m = max((x for x in self.pool.pool if term.size(x) > threshold),
        #             key=lambda k: self.history.get(k, 0))
        #     #if self.history[m] > 0:
        #     #    print (term.to_str(m), self.history[m])
        #     #    g = self.reaction_graph.graph
        #     #    if m in g:
        #     #        self.print_preceding_graph(g, m, 1)
        #     #    print('-'*30)
        # except ValueError:
        #     pass

    def get_recent_reactions_count(self):
        return len(self.reaction_graph.get_all_reducing_reactions())

    def get_recent_expressions_recurrence_count(self, threshold=4):
        c, n = 0, 0
        for f in self.recent_history:
            if len(f) > threshold:
                c += self.recent_history[f]
                n += 1
        return c / n if n > 0 else 0

    def get_pool_compressed_length(self):
        sorted_pool = sorted(self.expressions, key=len)
        pool_str = " | ".join(map(str, sorted_pool))
        self.pool_str_hist.append(pool_str)
        hist_str = "\n".join(self.pool_str_hist)
        compressed_hist_str = zlib.compress(hist_str.encode())
        return len(compressed_hist_str)

    def get_recent_scc_count(self):
        n = 0
        for scc in self.reduction_sg.get_without_substrates_subgraph(
        ).get_all_strongly_connected_components():
            if len(scc) > 1:
                # print("="*20)
                # console_tools.print_scc(scc)
                for r in sorted((r for r in scc if isinstance(r, Reaction)),
                                reverse=True):
                    logger.debug(f'{r} in scc')
                # import pickle
                # sg_scc = self.reduction_sg.get_subgraph(scc)
                # print(len(sg_scc))
                # if len(scc)>100:
                #     pickle.dump(sg_scc.graph,  open('scc.pkl', 'wb'))
                n += 1
        return n

    def get_recent_raf_length(self):
        return len(self.raf)

    def get_recent_raf_cycle_length(self):
        raf_graph = ReactionGraph()
        for reaction in self.raf:
            raf_graph.add_reaction(reaction)
        return raf_graph.get_maximal_cycle_length()

    def get_recent_raf_substrate_count(self):
        raf_graph = ReactionGraph()
        for reaction in self.raf:
            substrate = reaction.get_substrate()
            if substrate is not None:
                self.emergent_substrates.add(substrate)
        if self.emergent_substrates:
            logger.info('Emergent substrates: {}'.format(
                self.emergent_substrates))
        return len(self.emergent_substrates)

    def get_recent_raf_scc_count(self):
        raf_subgraph = self.reduction_sg.get_subgraph_from_reactions(self.raf)
        n = 0
        raf_subgraph.remove_food_edges()
        for scc in raf_subgraph.get_all_strongly_connected_components():
            if len(scc) > 1:
                n += 1
        return 1

    def get_current_expressions_max_length(self):
        return max(map(len, self.expressions.unique()))

    def get_current_expressions_max_depth(self):
        return max(map(lambda e: e.get_depth(), self.expressions.unique()))

    def get_current_expressions_reduction_count(self):
        return np.mean(
            list(
                map(lambda e: len(e.all_reductions()),
                    self.expressions.unique())))

    def get_current_expressions_percent_at_1(self):
        return self.get_current_expressions_percent_at(1)

    def get_current_expressions_percent_at_2(self):
        return self.get_current_expressions_percent_at(2)

    def get_current_expressions_percent_at(self, k):
        total = 0
        at_k = 0
        for expr in self.expressions.unique():
            n = self.expressions[expr]
            total += n
            if len(expr) <= k:
                at_k += n
        return at_k * 100 / total

    def get_current_expressions_mean_length(self):
        return np.mean(list(map(len, self.expressions.unique())))

    def get_recent_raf_product_max_length(self):
        return max(map(lambda r: max(len(p) for p in r.products), self.raf),
                   default=0)

    def get_recent_raf_products_count(self):
        return sum(
            list(self.expressions[p]
                 for p in set.union(set(), *(set(r.products)
                                             for r in self.raf))))

    def get_current_expressions_max_multiplicity(self):
        return max(list(v for k, v in self.expressions.items()
                        if len(k) > self.food_size),
                   default=0)

    def get_current_expressions_mean_multiplicity(self):
        current_expressions_multiplicity = list(
            v for k, v in self.expressions.items() if len(k) > self.food_size)
        return np.mean(current_expressions_multiplicity
                       ) if current_expressions_multiplicity else 0

    def get_current_expressions_max_multiplicity_length(self):
        multiplicity = self.get_current_expressions_max_multiplicity()
        if multiplicity == 1:
            return 0  # no trivial solutions
        max_multiplicity_lengths = list(
            len(k) for k, v in self.expressions.items() if v == multiplicity)
        return np.mean(
            max_multiplicity_lengths) if max_multiplicity_lengths else 0

    def get_recent_raf_products_max_multiplicity(self):
        #print(term.to_str(max(set(r.product for r in self.raf if term.size(r.product) > self.food_size), key=lambda k:self.pool.terms_set[k])))
        return max(list(self.expressions[p] for p in set.union(
            set(),
            *(set(r.products) for r in self.raf if any(
                len(p) > self.food_size for p in r.products)))),
                   default=0)

    def get_recent_raf_complement_products_max_multiplicity(self):
        #print(term.to_str(max(set(r.product for r in self.raf if term.size(r.product) > self.food_size), key=lambda k:self.pool.terms_set[k])))
        return max(list(self.expressions[p] for p in self.expressions
                        if p not in set.union(
                            set(),
                            *(set(r.products) for r in self.raf if any(
                                len(p) > self.food_size
                                for p in r.products)))),
                   default=0)

    def get_recent_raf_scc_expressions_multiplicity(self):
        raf_subgraph = self.reaction_graph.get_subgraph_from_reactions(
            self.raf)
        all_sccs = list(
            scc
            for scc in raf_subgraph.get_all_strongly_connected_components()
            if len(scc) > 1)
        largest_expr_in_sccs = list(max(scc, key=len) for scc in all_sccs)
        if all_sccs:
            m = max((expr for expr in largest_expr_in_sccs),
                    key=self.expressions.get_multiplicity)
            return self.expressions.get_multiplicity(m)
        else:
            return 0

    def get_recent_recurrent_expression_length(self):
        try:
            f = max((expr for expr in self.recent_history
                     if len(expr) > self.food_size),
                    key=self.recent_history.get)
            return len(f)
        except ValueError:
            return 0

    def get_longest_non_trivial_recurring_formula(self):
        non_trivial_recurring_formulae = self.get_non_trivial_recurring_formulae(
        )
        if non_trivial_recurring_formulae:
            return max(non_trivial_recurring_formulae, key=len)
        else:
            return None

    def get_non_trivial_recurring_formulae(self):
        m = -mode(-np.array(list(self.history.values()))).mode
        return [f for f, n_occ in self.history.items() if n_occ > m]
예제 #4
0
class WordBot():

	def __init__(self):
		self.offset = ''
		self.URL = 'https://api.telegram.org/bot' + bot_token
		self.session = requests.Session()
		self.session.mount("http://", requests.adapters.HTTPAdapter(max_retries=2))
		self.session.mount("https://", requests.adapters.HTTPAdapter(max_retries=2))
		self.cache = LFUCache(maxsize = 200)
		self.startMessage = start_message
		self.keyboard = {"keyboard":[["/define"],["/synonyms"],["/antonyms"],["/examples"],["/all"]]}

	def processUpdates(self):
		response = self.session.get(self.URL + '/getUpdates?offset=' + str(self.offset),verify=False)
		print "Got update"
		status = False
		updates = json.loads(response.text)
		if updates['result']:
			self.offset = updates['result'][0]['update_id'] + 1
			query = updates['result'][0]['message']['text']
			chat_id = updates['result'][0]['message']['chat']['id']
			self.session.get(self.URL + '/sendChatAction?chat_id=' + str(chat_id) +'&action=typing',verify=False)
			message = self.makeMessage(query)			
			status = self.sendMessage(message,chat_id)
		return status
	
	def makeMessage(self,query):
		message = self.startMessage
		if query == '/stop':
			message = 'Bot disabled.'
		elif query == '/today':
			wordData = self.getWordOfTheDay()
			query = '/define ' + wordData['word']
		query = query.split()
		if len(query) > 1:
			if query[0] not in ['/define','/synonyms','/antonyms','/use','/all']:
				return self.startMessage
			word = ' '.join(query[1::]).lower()
			message = 'Word: ' +  word + '\n'
			message += '=' * (len(word) + 7) + '\n'
			if self.cache.get(word):
				print "Fetching from cache"
				wordData = self.cache.get(word)
			else:
				wordData = self.getWord(word)
				if wordData is None:
					return 'Word not found.'
			if query[0] in ['/define','/all']:
				message += wordData['definitions'] + '\n'
			if query[0] in ['/synonyms','/all']:
				message += wordData['synonyms'] + '\n'
			if query[0] in ['/antonyms','/all']:
				message += wordData['antonyms'] + '\n'
			if query[0] in ['/use','/all']:
				message += wordData['examples'] + '\n'	
		return message
	
	def updateCache(self,word,wordData):
		dataDict = {}
		definitionText = 'Definitions :-' + '\n'
		definitionText += '-' * 20 + '\n'
		synonymsText = 'Synonyms :-' + '\n'
		synonymsText += '-' * 20 + '\n'
		antonymsText = 'Antonyms :-' + '\n'
		antonymsText += '-' * 20 + '\n'
		examplesText = 'Exmaples :-' + '\n'
		examplesText += '-' * 20 + '\n'
		definitions = self.getDefinitions(wordData)
		synonyms = self.getSynonyms(wordData)
		antonyms = self.getAntonyms(wordData)
		examples = self.getExamples(wordData)
		if not definitions:
			definitionText += 'No definitions found.\n'
		if not synonyms:
			synonymsText += 'No synonyms found.\n'
		if not antonyms:
			antonymsText += 'No antonyms found.\n'
		if not examples:
			examplesText += 'No examples found.\n'
			
		for definition in self.getDefinitions(wordData):
			definitionText += definition[0] + '\n' + definition[1] + ': ' +  definition[2] + '\n\n'
		for synonym in synonyms[:5]:
			synonymsText += synonym + '\n'
		for antonym in antonyms[:5]:
			antonymsText += antonym + '\n'
		for index,example in enumerate(examples[:5]):
			examplesText += str(index+1) + ". " + example + '\n\n'
		
		dataDict['word'] = word
		dataDict['definitions'] = definitionText
		dataDict['synonyms'] = synonymsText
		dataDict['antonyms'] = antonymsText
		dataDict['examples'] = examplesText
		self.cache.update({word:dataDict})
		return dataDict 
			
	def getDefinitions(self,wordData):
		partCounter = Counter()
		definitions = []
		for definition in wordData:
			if partCounter[definition['partOfSpeech']] < 2:
				definitions.append((definition['attributionText'],definition['partOfSpeech'],definition['text']))
				partCounter[definition['partOfSpeech']] += 1
		return definitions


	def getSynonyms(self,wordData):
		synonyms = []
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType'] == 'synonym':
				for synonym in relatedWords['words']:
					synonyms.append(synonym)
		
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType']  == 'cross-reference':
				for synonym in relatedWords['words']:
					synonyms.append(synonym)
		
		return synonyms

	def getAntonyms(self,wordData):
		antonyms = []
		for relatedWords in wordData[0]['relatedWords']:
			if relatedWords['relationshipType']  == 'antonym':
				for antonym in relatedWords['words']:
					antonyms.append(antonym)
		return antonyms

	def getExamples(self,wordData):
		examples = []
		for index,example in enumerate(wordData[0]['examples']):
			examples.append(example['text'].replace('\n',''))
		return examples
		
	def getEtymology(self,wordData):
		etymologies = []
		for etymology in wordData[0]['etymologies']:
			etymologies.append(etymology)
		return etymology

	def getWord(self,word):
		url1 = wordnik_url + word + '/definitions?api_key=' + wordnik_api_key
		url2 = wordnik_url + word + '/examples?api_key=' + wordnik_api_key
		url3 = wordnik_url + word + '/relatedWords?api_key=' + wordnik_api_key
		urls = [url1,url2,url3]
		data = []
		for url in urls:
			try:
				response = self.session.get(url,verify=False)
				data.append(json.loads(response.text.encode('utf-8')))
			except ValueError:
				return None
		if not data[0]:
			return None
		wordData = data[0]
		try:
			wordData[0]['examples'] = data[1]['examples']
		except KeyError:
			wordData[0]['examples'] = []
		try:
			wordData[0]['relatedWords'] = data[2]
		except KeyError:
			wordData[0]['relatedWords'] = []
		return self.updateCache(word,wordData)
	
	def getWordOfTheDay(self):
		today = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d')
		url = wordnik_url[:-10] + 'words.json/wordOfTheDay?api_key=' + wordnik_api_key + '&date=' + today
		wordData = []
		data = []
		response = self.session.get(url,verify = False)
		data.append(json.loads(response.text.encode('utf-8')))
		word = data[0]['word']
		if self.cache.get(word):
			wordData = self.cache.get(word)
			return wordData
		url = wordnik_url + word + '/relatedWords?api_key=' + wordnik_api_key
		wordData = [definition for definition in data[0]['definitions']]
		for definition in wordData:
			definition['attributionText'] = ''
		wordData[0]['examples'] = data[0]['examples']
		response = self.session.get(url,verify = False)
		relatedWords = json.loads(response.text)
		wordData[0]['relatedWords'] = relatedWords
		wordData[0]['word'] = word
		return self.updateCache(word,wordData)		
			
	def sendMessage(self,message,chat_id):
		dataDict = {'chat_id':str(chat_id),
				'text':message.encode('utf-8'),
				'reply_markup':self.keyboard}
		response = self.session.post(self.URL + '/sendMessage',data = dataDict)
		if response.status_code == 200:
			return True
		else:
			return False
예제 #5
0
class Dictionary(object):
    def __init__(self):
        self.dictionaryCache = LFUCache(maxsize=1000)
        self.urbandictionaryCache = LFUCache(maxsize=1000)
        self.wordOfTheDayCache = {}
        self.session = requests.Session()
        self.session.mount('http://',
                           requests.adapters.HTTPAdapter(max_retries=5))
        self.session.mount('https://',
                           requests.adapters.HTTPAdapter(max_retries=5))

    def updateCache(self, word, wordData):
        dataDict = {}
        definitionText = '*Definitions*' + '\n'
        synonymsText = '*Synonyms*' + '\n'
        antonymsText = '*Antonyms*' + '\n'
        examplesText = '*Examples*' + '\n'
        definitions = self.getDefinitions(wordData)
        synonyms = self.getSynonyms(wordData)
        antonyms = self.getAntonyms(wordData)
        examples = self.getExamples(wordData)
        if not definitions:
            definitionText += 'No definitions found.\n'
        if not synonyms:
            synonymsText += 'No synonyms found.\n'
        if not antonyms:
            antonymsText += 'No antonyms found.\n'
        if not examples:
            examplesText += 'No examples found.\n'
        for definition in definitions:
            if definition[0]:
                definitionText += definition[0] + ': '
            definitionText += definition[1] + '\n\n'
        definitionText = definitionText[:-1]
        for synonym in synonyms[:3]:
            synonymsText += synonym + '\n'
        for antonym in antonyms[:3]:
            antonymsText += antonym + '\n'
        for index, example in enumerate(examples[:3]):
            examplesText += str(index + 1) + '. ' + example + '\n\n'
        examplesText = examplesText[:-1]
        dataDict['word'] = word
        dataDict['definitions'] = definitionText
        dataDict['synonyms'] = synonymsText
        dataDict['antonyms'] = antonymsText
        dataDict['examples'] = examplesText
        self.dictionaryCache.update({word: dataDict})
        return dataDict

    def getDefinitions(self, wordData):
        partCounter = Counter()
        definitions = []
        for definition in wordData:
            if 'partOfSpeech' in definition.keys(
            ) and partCounter[definition['partOfSpeech']] < 2:
                definitions.append(('_' + definition['partOfSpeech'] + '_ ',
                                    definition['text']))
                partCounter[definition['partOfSpeech']] += 1
            else:
                definitions.append(('', definition['text']))
        return definitions

    def getSynonyms(self, wordData):
        synonyms = []
        for relatedWords in wordData[0]['relatedWords']:
            if relatedWords['relationshipType'] == 'synonym':
                for synonym in relatedWords['words']:
                    synonyms.append(synonym)

        for relatedWords in wordData[0]['relatedWords']:
            if relatedWords['relationshipType'] == 'cross-reference':
                for synonym in relatedWords['words']:
                    synonyms.append(synonym)
        return synonyms

    def getAntonyms(self, wordData):
        antonyms = []
        for relatedWords in wordData[0]['relatedWords']:
            if relatedWords['relationshipType'] == 'antonym':
                for antonym in relatedWords['words']:
                    antonyms.append(antonym)
        return antonyms

    def getExamples(self, wordData):
        examples = []
        for index, example in enumerate(wordData[0]['examples']):
            examples.append(example['text'].replace('\n', ''))
        return examples

    def getEtymology(self, wordData):
        etymologies = []
        for etymology in wordData[0]['etymologies']:
            etymologies.append(etymology)
        return etymology

    def getWord(self, word):
        if '#' in word:
            return None
        def_url = wordnik_url + word + '/definitions?limit=15&api_key=' + wordnik_api_key
        example_url = wordnik_url + word + '/examples?api_key=' + wordnik_api_key
        related_url = wordnik_url + word + '/relatedWords?api_key=' + wordnik_api_key
        urls = [def_url, example_url, related_url]
        data = []
        for url in urls:
            try:
                response = self.session.get(url, verify=False)
                if response.status_code != 200:
                    return None
                data.append(json.loads(response.text.encode('utf-8')))
            except ValueError:
                return None
        if not data[0]:
            return None
        wordData = data[0]
        try:
            wordData[0]['examples'] = data[1]['examples']
        except KeyError:
            wordData[0]['examples'] = []
        try:
            wordData[0]['relatedWords'] = data[2]
        except KeyError:
            wordData[0]['relatedWords'] = []
        return self.updateCache(word, wordData)

    def getUrbandictionaryWord(self, word):
        api_url = 'http://api.urbandictionary.com/v0/define?term='
        #response = requests.get(api_url+word, verify=False)
        response = urllib2.urlopen(api_url + word)
        data = json.loads(response.read().decode('utf-8'))
        if data['result_type'] == 'no_results' or not data['list']:
            return None
        wordData = {}
        wordData['definition'] = '*Definition*' + '\n'
        wordData['example'] = '*Example*' + '\n'
        try:
            if data['list'][0]['definition']:
                wordData['definition'] += data['list'][0]['definition'].strip(
                ) + '\n'
            else:
                return None
        except KeyError:
            return None
        try:
            if data['list'][0]['example']:
                wordData['example'] += data['list'][0]['example'].strip(
                ) + '\n'
            else:
                wordData['example'] += 'No example found.'
        except KeyError:
            wordData['example'] += 'No example found.'
        self.urbandictionaryCache.update({word: wordData})
        return wordData

    def getWordOfTheDay(self):
        wordOfTheDay = self.wordOfTheDayCache.get(datetime.now().day, None)
        if wordOfTheDay is None:
            today = datetime.strftime(datetime.now(), '%Y-%m-%d')
            url = wordnik_url[:
                              -10] + 'words.json/wordOfTheDay?api_key=' + wordnik_api_key + '&date=' + today
            data = []
            response = self.session.get(url, verify=False)
            try:
                data.append(json.loads(response.text.encode('utf-8')))
            except ValueError:
                return None
            wordOfTheDay = data[0]['word']
            self.wordOfTheDayCache.clear()
            self.wordOfTheDayCache[datetime.now().day] = wordOfTheDay
        else:
            pass
        wordData = self.dictionaryCache.get(wordOfTheDay)
        if not wordData:
            url = wordnik_url + wordOfTheDay + '/relatedWords?api_key=' + wordnik_api_key
            wordData = [definition for definition in data[0]['definitions']]
            for definition in wordData:
                definition['attributionText'] = ''
            wordData[0]['examples'] = data[0]['examples']
            response = self.session.get(url, verify=False)
            relatedWords = json.loads(response.text)
            wordData[0]['relatedWords'] = relatedWords
            wordData[0]['word'] = wordOfTheDay
            return self.updateCache(wordOfTheDay, wordData)
        else:
            return wordData