1
1
mirror of https://github.com/leon-ai/leon.git synced 2024-12-01 03:15:58 +03:00

Merge branch 'trend-package' into develop

This commit is contained in:
Louistiti 2019-04-07 16:43:52 +08:00
commit 99b4d838e4
8 changed files with 197 additions and 25 deletions

View File

@ -14,13 +14,28 @@ Grab the GitHub trends repositories according to several options.
(en-US) "What's trending on GitHub?"
(en-US) "Give me the 4 GitHub trends of this week for the JavaScript language"
(en-US) "What's the three GitHub trends of this month?"
(fr-FR) "Quelles sont les tendances sur GitHub ?"
(fr-FR) "Donne-moi les 4 tendances GitHub de cette semaine pour le langage JavaScript"
(fr-FR) "Donne-moi les trois tendances GitHub de ce mois"
...
```
### Product Hunt
WIP...
Grab the Product Hunt trends.
#### Usage
WIP...
1. Log in to your [Product Hunt](https://www.producthunt.com/) account.
2. Add a [new application](https://www.producthunt.com/v1/oauth/applications) (E.g. name: Leon; Redirect URI: https://localhost).
3. Once your application is created, click `Create Token`.
4. Copy the `Developer Token` and paste it in `packages/trend/config/config.json` at the `producthunt.developer_token` key.
```
(en-US) "What's trending on Product Hunt?"
(en-US) "What were the four first Product Hunt trends on the 7th of October 2018?"
(en-US) "What were the Product Hunt trends of yesterday?"
(fr-FR) "Quelles sont les tendances sur Product Hunt ?"
(fr-FR) "Donne-moi les 4 tendances Product Hunt du 7 octobre 2018"
...
```

View File

@ -3,6 +3,7 @@
"options": {}
},
"producthunt": {
"developer_token": "YOUR_DEVELOPER_TOKEN",
"options": {}
}
}

View File

@ -9,22 +9,22 @@
"Let me reach GitHub..."
],
"today": [
"Here are the %limit% latest GitHub trends of today:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the day:<br><br><ul>%result%</ul>"
],
"week": [
"Here are the %limit% latest GitHub trends of this week:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the week:<br><br><ul>%result%</ul>"
],
"month": [
"Here are the %limit% latest GitHub trends of this month:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the month:<br><br><ul>%result%</ul>"
],
"today_with_tech": [
"Here are the %limit% latest GitHub trends of today for the %tech% technology:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the day for the %tech% technology:<br><br><ul>%result%</ul>"
],
"week_with_tech": [
"Here are the %limit% latest GitHub trends of this week for the %tech% technology:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the week for the %tech% technology:<br><br><ul>%result%</ul>"
],
"month_with_tech": [
"Here are the %limit% latest GitHub trends of this month for the %tech% technology:<br><br><ul>%result%</ul>"
"Here are the %limit% GitHub trends of the month for the %tech% technology:<br><br><ul>%result%</ul>"
],
"unreachable": [
"GitHub is unreachable for the moment, please retry later.",
@ -36,5 +36,39 @@
]
},
"producthunt": {
"limit_max": [
"You've asked for too many Product Hunt trends, I'll give you %new_limit% trends instead.",
"%limit% Product Hunt trends is a lot, let me tell you the %new_limit% trends instead."
],
"reaching": [
"I'm reaching Product Hunt, please wait a second...",
"Let me reach Product Hunt..."
],
"today": [
"Here are the %limit% Product Hunt trends of the day:<br><br><ul>%result%</ul>"
],
"specific_day": [
"Here are the %limit% Product Hunt trends for the %date%:<br><br><ul>%result%</ul>"
],
"unreachable": [
"Product Hunt is unreachable for the moment, please retry later.",
"I'm having difficulties to reach Product Hunt, please retry later.",
"Product Hunt seems to be down, please try again later."
],
"list_element": [
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> created by <a href=\"%author_url%\" target=\"_blank\">%author_name%</a> with %votes_nb% votes.</li>"
],
"list_element_with_unknown_maker": [
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> with %votes_nb% votes. There is no information about the maker.</li>",
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> with %votes_nb% votes. I did not find any information about the maker.</li>"
],
"not_found": [
"There is no product on that date.",
"I did not find any product on that date."
],
"invalid_developer_token": [
"Your Product Hunt developer token is invalid. Please provide a valid one by <a href=\"https://github.com/leon-ai/leon/blob/develop/packages/trend/README.md#product-hunt\" target=\"_blank\">reading this</a>.",
"You did not set a valid Product Hunt developer token. Please set a valid one by <a href=\"https://github.com/leon-ai/leon/blob/develop/packages/trend/README.md#product-hunt\" target=\"_blank\">reading this</a>."
]
}
}

View File

@ -36,5 +36,39 @@
]
},
"producthunt": {
"limit_max": [
"Vous demandez beaucoup trop de tendances, laissez moi plutôt vous donner les %new_limit% tendances.",
"%limit% tendances Product Hunt c'est beaucoup, permettez moi de vous donner les %new_limit% tendances à la place."
],
"reaching": [
"Je suis en train d'atteindre Product Hunt, veuille patienter une seconde...",
"Laissez moi atteindre Product Hunt..."
],
"today": [
"Voici les %limit% dernières tendances Product Hunt du jour :<br><br><ul>%result%</ul>"
],
"specific_day": [
"Voici les %limit% dernières tendances Product Hunt du %date% :<br><br><ul>%result%</ul>"
],
"unreachable": [
"Product Hunt est inaccessible pour le moment, merci de réessayer plus tard.",
"Je rencontre des difficultés pour atteindre Product Hunt, merci de réessayer plus tard.",
"Product Hunt semble ne pas fonctionner correctement, veuillez retenter plus tard."
],
"list_element": [
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> créé par <a href=\"%author_url%\" target=\"_blank\">%author_name%</a> avec %votes_nb% votes.</li>"
],
"list_element_with_unknown_maker": [
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> avec %votes_nb% votes. Il n'y a pas d'information à propos du créateur.</li>",
"<li>#%rank%. <a href=\"%post_url%\" target=\"_blank\">%product_name%</a> avec %votes_nb% votes. Je n'ai trouvé aucune information à propos du créateur.</li>"
],
"not_found": [
"Il n'y a pas de produit à cette date.",
"Je n'ai trouvé aucun produit à cette date."
],
"invalid_developer_token": [
"Votre jeton de développeur Product Hunt est invalide. Merci d'en fournir un valide en <a href=\"https://github.com/leon-ai/leon/blob/develop/packages/trend/README.md#product-hunt\" target=\"_blank\">lisant ceci</a>.",
"Vous n'avez pas bien configuré votre jeton de développeur Product Hunt. Veuillez en installer un valide en <a href=\"https://github.com/leon-ai/leon/blob/develop/packages/trend/README.md#product-hunt\" target=\"_blank\">lisant ceci</a>."
]
}
}

View File

@ -5,6 +5,90 @@ import requests
import utils
def producthunt(string, entities):
"""WIP..."""
"""Grab the Product Hunt trends"""
return utils.output('end', 'done')
# Developer token
developertoken = utils.config('developer_token')
# Number of products
limit = 5
# Answer key
answerkey = 'today'
# Day date
daydate = ''
for item in entities:
if item['entity'] == 'number':
limit = item['resolution']['value']
if item['entity'] == 'date':
answerkey = 'specific_day'
if 'strPastValue' in item['resolution']:
daydate = item['resolution']['strPastValue']
else:
daydate = item['resolution']['strValue']
utils.output('inter', 'reaching', utils.translate('reaching'))
try:
url = 'https://api.producthunt.com/v1/posts'
if (daydate != ''):
url = url + '?day=' + daydate
r = utils.http('GET', url, { 'Authorization': 'Bearer ' + developertoken })
response = r.json()
if 'error' in response and response['error'] == 'unauthorized_oauth':
return utils.output('end', 'invalid_developer_token', utils.translate('invalid_developer_token'))
posts = list(enumerate(response['posts']))
result = ''
if len(posts) == 0:
return utils.output('end', 'not_found', utils.translate('not_found'))
if limit > len(posts):
utils.output('inter', 'limit_max', utils.translate('limit_max', {
'limit': limit,
'new_limit': len(posts)
}))
limit = len(posts)
elif limit == 0:
limit = 5
for i, post in posts:
# If the product maker is known
if post['maker_inside']:
author = list(reversed(post['makers']))[0]
result += utils.translate('list_element', {
'rank': i + 1,
'post_url': post['discussion_url'],
'product_name': post['name'],
'author_url': author['profile_url'],
'author_name': author['name'],
'votes_nb': post['votes_count']
}
)
else:
result += utils.translate('list_element_with_unknown_maker', {
'rank': i + 1,
'post_url': post['discussion_url'],
'product_name': post['name'],
'votes_nb': post['votes_count']
}
)
if (i + 1) == limit:
break
return utils.output('end', answerkey, utils.translate(answerkey, {
'limit': limit,
'result': result,
'date': daydate
}
)
)
except requests.exceptions.RequestException as e:
return utils.output('end', 'unreachable', utils.translate('unreachable'))

View File

@ -8,8 +8,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(25)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
'limit_max',
@ -25,8 +23,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(16)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
'reaching',
@ -41,8 +37,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(5)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
'reaching',
@ -57,8 +51,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(5)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
'reaching',
@ -73,8 +65,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(7)
expect(global.brain.finalOutput.speech.indexOf('Python')).not.toBe(-1)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
@ -90,8 +80,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(14)
expect(global.brain.finalOutput.speech.indexOf('JavaScript')).not.toBe(-1)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
@ -107,8 +95,6 @@ describe('trend:github', async () => {
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
console.log(global.brain.finalOutput)
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(5)
expect(global.brain.finalOutput.speech.indexOf('CSS')).not.toBe(-1)
expect(global.brain.finalOutput.codes).toIncludeSameMembers([

View File

@ -0,0 +1,18 @@
'use strict'
describe('trend:producthunt', async () => {
test('requests Product Hunt', async () => {
global.nlu.brain.execute = jest.fn()
await global.nlu.process('What\'s trending on Product Hunt?')
const [obj] = global.nlu.brain.execute.mock.calls
await global.brain.execute(obj[0])
expect([
'reaching',
'today',
'unreachable',
'invalid_developer_token'
]).toIncludeAnyMembers(global.brain.finalOutput.codes)
})
})

View File

@ -165,7 +165,7 @@ class Brain {
this.socket.emit('is-typing', false)
log.title(packageName)
reject({ type: 'error', obj: data })
reject({ type: 'error', obj: new Error(data) })
})
// Catch the end of the module execution