Completed
Pull Request — master (#326)
by James
02:15
created

ArticleSearch   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 36
Duplicated Lines 0 %
Metric Value
dl 0
loc 36
rs 10
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A _extract_article_data() 0 11 2
A run() 0 12 2
A _rank_article() 0 3 1
1
from lib.actions import BaseAction
2
from dotted.utils import dot
3
from fuzzywuzzy import fuzz
4
from functools import partial
5
import json
6
import pprint
7
8
9
class ArticleSearch(BaseAction):
10
    def run(self, query, include_body=False, limit=5):
11
        response = self._api_get('/articles')
12
        articles = response['articles']
13
14
        ranks_fun = partial(self._rank_article, query=query)
15
        ranks = map(ranks_fun, articles)
16
17
        results = sorted(ranks, key=lambda rank: rank[0], reverse=True)[:limit]
18
        response_fun = partial(self._extract_article_data,
19
                               include_body=include_body)
20
        response = map(response_fun, results)
21
        return json.dumps(response)
22
23
    # Takes an incoming query and an article, and runs a fuzzy token
24
    # search to get data from an article.
25
    #
26
    # Returns a tuple of (rank, article)
27
    def _rank_article(self, article, query):
28
        rank = fuzz.token_set_ratio(query, article['body'].encode('utf-8'))
29
        return (rank, article)
30
31
    # Takes a tuple of (rank, article), and extracts data from the
32
    # object based on whether the user asks for additional body data
33
    # or not.
34
    def _extract_article_data(self, result, include_body=False):
35
        article = result[1]
36
37
        article_data = {
38
            'title': article['title'],
39
            'url': article['url'],
40
        }
41
        if include_body:
42
            article_data['body'] = article['body']
43
44
        return article_data
45
46