diff --git a/bridges/python/Pipfile b/bridges/python/Pipfile index 6568a43d8..daf0a0ef1 100644 --- a/bridges/python/Pipfile +++ b/bridges/python/Pipfile @@ -7,6 +7,7 @@ name = "pypi" requests = "==2.21.0" pytube = "==9.2.2" tinydb = "==3.9.0" +parsedatetime = "*" [dev-packages] diff --git a/package-lock.json b/package-lock.json index 896a73f17..81cae5539 100644 --- a/package-lock.json +++ b/package-lock.json @@ -914,7 +914,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "dev": true, + "optional": true }, "is-glob": { "version": "2.0.1", @@ -3172,13 +3173,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "dev": true, + "optional": true }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -5331,7 +5334,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5352,12 +5356,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5372,17 +5378,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5499,7 +5508,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5511,6 +5521,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5525,6 +5536,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5532,12 +5544,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5556,6 +5570,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5636,7 +5651,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5648,6 +5664,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5733,7 +5750,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5769,6 +5787,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5788,6 +5807,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5831,12 +5851,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/packages/dateandtime/README.md b/packages/dateandtime/README.md new file mode 100644 index 000000000..9f68283bf --- /dev/null +++ b/packages/dateandtime/README.md @@ -0,0 +1,51 @@ +# Date Time Package + +The Date Time package contains multiple functions to deal with date and time. + +## Modules + +### Guess Date + +ask for future, current or past date + +#### Usage + +``` +(en-US) "What day is it?" +(en-US) "What day is today?" +(en-US) "What day is tomorrow?" +(en-US) "What day was yesterday?" +(en-US) "What day it will be 2 days from tomorrow?" +(en-US) "What day it will be 5 days from yesterday?" +... +``` + +### Say Current Time + +ask for current time + +#### Usage + +``` +(en-US) "Could you tell me the time, please?" +(en-US) "can I get the time?" +(en-US) "Do you have the time?" +(en-US) "Do you know what time it is?" +(en-US) "Have you got time?" +(en-US) "Have you got the time on you?" +(en-US) "may I know what time it is right now?" +(en-US) "What time do you have?" +(en-US) "What time do you make it?" +(en-US) "What time is it now?" +(en-US) "what time is it, please?" +(en-US) "What time is it?" +(en-US) "What’s the time?" +(en-US) "What time have we got?" +(en-US) "You got the time?" +... +``` + +## Todo + +- translate to as many languages as possible +- answer date/time for different timezone diff --git a/packages/dateandtime/__init__.py b/packages/dateandtime/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/config/.gitkeep b/packages/dateandtime/config/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/data/.gitkeep b/packages/dateandtime/data/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/data/answers/.gitkeep b/packages/dateandtime/data/answers/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/data/answers/en.json b/packages/dateandtime/data/answers/en.json new file mode 100644 index 000000000..1d0bdb717 --- /dev/null +++ b/packages/dateandtime/data/answers/en.json @@ -0,0 +1,20 @@ +{ + "saycurrenttime": { + "time": [ + "It's %time%." + ], + "error": [ + "Couldn't get the current time, maybe you should try again.", + "I am having a hard time getting the current time, try again..." + ] + }, + "guessdate": { + "guess": [ + "%guess%." + ], + "error": [ + "Couldn't guess the date, maybe you should try again.", + "I am having a hard time guessing the date, try again..." + ] + } +} diff --git a/packages/dateandtime/data/db/.gitkeep b/packages/dateandtime/data/db/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/data/expressions/.gitkeep b/packages/dateandtime/data/expressions/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dateandtime/data/expressions/en.json b/packages/dateandtime/data/expressions/en.json new file mode 100644 index 000000000..e368e1201 --- /dev/null +++ b/packages/dateandtime/data/expressions/en.json @@ -0,0 +1,27 @@ +{ + "saycurrenttime": [ + "Could you tell me the time, please?", + "can I get the time?", + "Do you have the time?", + "Do you know what time it is?", + "Have you got time?", + "Have you got the time on you?", + "may I know what time it is right now?", + "What time do you have?", + "What time do you make it?", + "What time is it now?", + "what time is it, please?", + "What time is it?", + "What’s the time?", + "What time have we got?", + "You got the time?" + ] + ,"guessdate": [ + "What day was yesterday", + "What day is it?", + "What day is it today?", + "What’s the date today?", + "What date is it?", + "What’s today’s date?" + ] +} diff --git a/packages/dateandtime/guessdate.py b/packages/dateandtime/guessdate.py new file mode 100644 index 000000000..69d454beb --- /dev/null +++ b/packages/dateandtime/guessdate.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- + +import requests +import utils +import datetime +import parsedatetime +# import dateparser +from random import randint + +def guessdate(word): + + word = word.lstrip() + if word.startswith('the'): + word = word.replace('the', 'one', 1) + + cal = parsedatetime.Calendar() + time_struct, parse_status = cal.parse(word) + guess = datetime.datetime(*time_struct[:6]) + day = guess.day + time = datetime.datetime.time(guess) + random = randint(0, 2) + + # https://stackoverflow.com/questions/9647202/ordinal-numbers-replacement + suf = lambda n: "%d%s"%(n,{1:"st",2:"nd",3:"rd"}.get(n if n<20 else n%10,"th")) + + if random == 0: + return utils.output('end', 'guess', utils.translate('guess', { 'guess': "The " + suf(day) + ' of ' + '{:%B}'.format(guess) + ', {:%Y}'.format(guess)})) + elif random == 1: + return utils.output('end', 'guess', utils.translate('guess', { 'guess': '{:%B}'.format(guess) + ' the ' + suf(day) + ', {:%Y}'.format(guess)})) + else: + return utils.output('end', 'guess', utils.translate('guess', { 'guess': suf(day) + ' of ' '{:%B}'.format(guess) + ', {:%Y}'.format(guess)})) + + + #trying to use dateparser lib + # return utils.output('end', 'guess', utils.translate('guess', { 'guess': dateparser.parse(word) })) diff --git a/packages/dateandtime/saycurrenttime.py b/packages/dateandtime/saycurrenttime.py new file mode 100644 index 000000000..72335196f --- /dev/null +++ b/packages/dateandtime/saycurrenttime.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- + +import requests +import utils +import datetime +from random import randint + +def saycurrenttime(string): + + # https://sukhbinder.wordpress.com/2013/12/29/time-in-words-with-python/ + time = datetime.datetime.now() + + if randint(0, 1) != 0: + words = [ + "one", "two", "three", "four", "five", "six", "seven", "eight","nine", + "ten", "eleven", "twelve", "thirteen", "fourteen", "quarter", "sixteen", + "seventeen", "eighteen", "nineteen", "twenty", "twenty one", + "twenty two", "twenty three", "twenty four", "twenty five", + "twenty six", "twenty seven", "twenty eight", "twenty nine", "half" + ] + + hrs = time.hour + mins = time.minute + msg = "" + + if (hrs > 12): + hrs = hrs-12 + if (mins == 0): + hr = words[hrs-1] + msg = hr + " o'clock." + elif (mins < 31): + hr = words[hrs-1] + mn = words[mins-1] + msg = mn + " past " + hr + "." + else: + hr = words[hrs] + mn = words[(60 - mins-1)] + msg = mn + " to " + hr + "." + return utils.output('end', 'time', utils.translate('time', { 'time': msg })) + + return utils.output('end', 'time', utils.translate('time', { 'time': 'exactly ' + '{:%H:%M:%S}'.format(time) })) + + diff --git a/packages/dateandtime/test/guessdate.spec.js b/packages/dateandtime/test/guessdate.spec.js new file mode 100644 index 000000000..d35776082 --- /dev/null +++ b/packages/dateandtime/test/guessdate.spec.js @@ -0,0 +1,13 @@ +'use strict' + +describe('dateandtime:guessdate', async () => { + test('detects valid date guess', async () => { + global.nlu.brain.execute = jest.fn() + global.nlu.process('what day is today?') + + const [obj] = global.nlu.brain.execute.mock.calls + await global.brain.execute(obj[0]) + + expect(global.brain.finalOutput.code).toBe('guess') + }) +}) diff --git a/packages/dateandtime/test/saycurrenttime.spec.js b/packages/dateandtime/test/saycurrenttime.spec.js new file mode 100644 index 000000000..f0fbae07d --- /dev/null +++ b/packages/dateandtime/test/saycurrenttime.spec.js @@ -0,0 +1,13 @@ +'use strict' + +describe('dateandtime:saycurrenttime', async () => { + test('detects valid date', async () => { + global.nlu.brain.execute = jest.fn() + global.nlu.process('what time is it?') + + const [obj] = global.nlu.brain.execute.mock.calls + await global.brain.execute(obj[0]) + + expect(global.brain.finalOutput.code).toBe('time') + }) +}) diff --git a/packages/dateandtime/version.txt b/packages/dateandtime/version.txt new file mode 100644 index 000000000..afaf360d3 --- /dev/null +++ b/packages/dateandtime/version.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file