in src/plugins/utils/tone.py [0:0]
def picoTone(KibbleBit, bodies):
""" Sentiment analysis using picoAPI Text Analysis """
if 'picoapi' in KibbleBit.config:
headers = {
'Content-Type': 'application/json',
'PicoAPI-Key': KibbleBit.config['picoapi']['key']
}
js = {
"texts": []
}
# For each body...
a = 0
moods = []
for body in bodies:
# Crop out quotes
lines = body.split("\n")
body = "\n".join([x for x in lines if not x.startswith(">")])
doc = {
"id": str(a),
"body": body
}
js['texts'].append(doc)
moods.append({}) # placeholder for each doc, to be replaced
a += 1
try:
rv = requests.post(
"https://v1.picoapi.com/api/text/sentiment",
headers = headers,
data = json.dumps(js)
)
jsout = rv.json()
except:
jsout = {} # borked sentiment analysis?
if 'results' in jsout and len(jsout['results']) > 0:
for doc in jsout['results']:
mood = {}
# Sentiment is the overall score, and we use that for the neutrality of a text
val = (1 + doc['sentiment']) / 2
mood['negative'] = doc['negativity'] # Use the direct Bayesian score from picoAPI
mood['positive'] = doc['positivity'] # Use the direct Bayesian score from picoAPI
mood['neutral'] = doc['neutrality'] # Calc neutrality to favor a middle sentiment score, ignore high/low
# Additional (optional) emotion weighting
if 'emotions' in doc:
for k, v in doc['emotions'].items():
mood[k] = v / 100 # Value is betwen 0 and 100.
moods[int(doc['id'])] = mood # Replace moods[X] with the actual mood
else:
KibbleBit.pprint("Failed to analyze email body.")
print(jsout)
# 403 returned on invalid key, 429 on rate exceeded.
# If we see a code return, let's just stop for now.
# Later scans can pick up the slack.
if 'code' in jsout:
KibbleBit.pprint("Possible rate limiting in place, stopping for now.")
return False
return moods