-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathembedUI.py
157 lines (119 loc) · 4.4 KB
/
embedUI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""Insert feedback UI in feed entry."""
import bs4 as bs
from colour import Color
from content_extraction import get_text, get_url
from feature_extraction import text2sentences
from flask import request
from fuzzywuzzy import fuzz
import logging as log
import numpy as np
from scipy.stats import rankdata
from traceback import format_exc
def _feedbackurl(link, well_spent):
return (
u"http://"
+ request.host
+ u"/feedback/"
+ (u"l" if well_spent else u"d")
+ u"/"
+ link
)
def _is_long(text):
return len(text) > 1000
def _p(style, text):
return u'<p style="{style}">{text}</p>'.format(style=style, text=text)
def _a(href, target, text):
return u'<a href="{href}" target="{target}">{text}</a>'.format(
href=href, target=target, text=text
)
def _font(color, text):
return u'<font color="{color}">{text}</font>'.format(color=color, text=text)
def _span(text, color):
# style = u'"border-bottom: 3px solid {color}"'
# style = u'"text-decoration: underline; text-decoration-color: {color}"'
style = u'"background-color: {color}; line-height: 1"'.format(color=color)
return u"<span style={style}>{text}</span>".format(text=text, style=style)
def _feedback_link(is_good, content_link):
return _a(
href=_feedbackurl(link=content_link, well_spent=is_good),
target=u"_top",
text=_font(
color=u"green" if is_good else u"red",
text=u"Time Well Spent" if is_good else u"Time Wasted",
),
)
def _conditional_bar(mean_score, content_link):
return _p(
style=u"BACKGROUND-COLOR: #DBDBDB",
text=(_feedback_link(True, content_link) if mean_score <= 0.5 else u"")
+ (u" or " if mean_score == 0.5 else u"")
+ (_feedback_link(False, content_link) if mean_score >= 0.5 else u""),
)
def _add_bar(text, mean_score, content_link):
bar = _conditional_bar(mean_score, content_link)
return bar + text + (bar if _is_long(text) else u"")
def _embedUI_entry(entry, score):
if score is not None:
mean_score = score.mean()
# body = entry2text(entry)
body = _highlight_text(get_text(entry=entry), score)
# body = get_html(entry=entry)
# body = _highlight_html(html, text, score) #broken
url = get_url(entry)
if u"description" in entry:
entry[u"description"] = _add_bar(body, mean_score, url)
if u"content" in entry:
entry[u"content"][0].value = _add_bar(body, mean_score, url)
if u"title" in entry:
entry[u"title"] = u"{mean_score:} | {title}".format(
mean_score=int(mean_score * 100), title=entry[u"title"]
)
return entry
def embedUI(parsed_feed, score):
"""Insert a UI element in each entry of a feed.
Parameters
----------
parsed_feed : feedparser.
Description of parameter `parsed_feed`.
score : type
Description of parameter `score`.
Returns
-------
type
Description of returned object.
"""
parsed_feed.entries = [
_embedUI_entry(e, s) for e, s in zip(parsed_feed.entries, score)
]
return parsed_feed
_colors = list(Color(hsl=(0.8, 1, 1)).range_to(Color(hsl=(0.8, 1, 0.8)), 256))
def _score2color(score):
return _colors[min(int(score * 256), 255)].get_hex_l()
def _highlight_text(text, score):
try:
sentences = text2sentences(text)
rank = (rankdata(score) - 1) / (len(score) - 1.0) if len(score) > 1 else [0.5]
return u"".join(
[_highlight_sentence(x, s, r) for x, s, r in zip(sentences, score, rank)]
)
except Exception:
log.error(format_exc())
return text
def _highlight_sentence(sentence, score, rank):
return _span(
u"<small>{s:.2f}</small> {x}".format(x=sentence, s=score), _score2color(rank)
)
def _best_match_score(x, sentences, score):
assert len(sentences) == len(score), (len(sentences), len(score))
return score[np.array([fuzz.ratio(x, s) for s in sentences]).argmax()]
def _highlight_html(html, text, score):
# this doesn't work yet for paragraphs of multiple sentences
sentences = text2sentences(text)
soup = bs.BeautifulSoup(html)
for x in soup.findAll(text=True):
x.replaceWith(
bs.BeautifulSoup(
_highlight_sentence(x, _best_match_score(x, sentences, score))
)
)
return soup