diff --git a/.gitignore b/.gitignore index 8318267..0a343b7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,93 @@ node_modules Dockerfile docker-compose.yml .DS_Store -/*.env \ No newline at end of file +/*.env + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask instance folder +instance/ + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject \ No newline at end of file diff --git a/Procfile b/Procfile index df040e9..c15ecbe 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ -web: node src/web/index.js \ No newline at end of file +web: node src/web/index.js +clock: python src/clock/clock.py \ No newline at end of file diff --git a/assets/create_accesstokens b/assets/create_accesstokens new file mode 100644 index 0000000..239b74b --- /dev/null +++ b/assets/create_accesstokens @@ -0,0 +1,6 @@ +CREATE TABLE accesstokens ( + id bigserial primary key, + token varchar(100) NOT NULL, + uid varchar(100) NOT NULL, + date_added timestamp default current_timestamp +) \ No newline at end of file diff --git a/package.json b/package.json index 11dee82..efa21bb 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ }, "dependencies": { "ejs": "2.4.1", - "express": "4.13.4" + "express": "4.13.4", + "requestify": "0.1.17", + "pg": "4.5.3" }, "keywords": [], "author": "Wade Wegner", diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..10ecf2d --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +APScheduler==3.0.0 \ No newline at end of file diff --git a/src/clock/clock.py b/src/clock/clock.py new file mode 100644 index 0000000..b4a4ec6 --- /dev/null +++ b/src/clock/clock.py @@ -0,0 +1,20 @@ +from datetime import datetime + +from apscheduler.schedulers.blocking import BlockingScheduler + +from urllib2 import Request, urlopen, URLError + +def job_function(): + print("Hello World") + + request = Request('http://localhost:5000/trigger') + response = urlopen(request) + kittens = response.read() + print(kittens) + +sched = BlockingScheduler() + +# Schedule job_function to be called every two hours +sched.add_job(job_function, 'interval', seconds=2) + +sched.start() \ No newline at end of file diff --git a/src/web/index.js b/src/web/index.js index ea0ab74..7b76aa6 100644 --- a/src/web/index.js +++ b/src/web/index.js @@ -1,20 +1,172 @@ var express = require('express'); var app = express(); +var pg = require('pg'); + + +// First, checks if it isn't implemented yet. +if (!String.prototype.format) { + String.prototype.format = function() { + var args = arguments; + return this.replace(/{(\d+)}/g, function(match, number) { + return typeof args[number] != 'undefined' + ? args[number] + : match + ; + }); + }; +} app.set('port', (process.env.PORT || 5000)); - app.use(express.static(__dirname + '/public')); - -// views is directory for all template files app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); +var clientId = process.env.CLIENT_ID; +var clientSecret = process.env.CLIENT_SECRET; +var redirectUrl = process.env.REDIRECT_URL; + +var code = ''; +var accessToken = ''; +var signinUrl = 'https://untappd.com/oauth/authenticate/?client_id={0}&response_type=code&redirect_url={1}'.format(clientId, redirectUrl); +var firstName = ''; +var lastName = ''; +var userName = ''; + +// index.ejs app.get('/', function(request, response) { - response.render('pages/index'); + response.render('pages/index', { + signinUrl: signinUrl, + accessToken: accessToken + }); +}); + +// profile.ejs +app.get('/profile', function(request, response) { + response.render('pages/profile', { + signinUrl: signinUrl, + accessToken: accessToken + }); +}); + +// logout +app.get('/logout', function(request, response) { + accessToken = ''; + userName = ''; + response.redirect('/'); +}); + +// trigger +app.get('/trigger', function(request, response) { + response.send('trigger') +}); + + +// oauth callback +app.get('/callback', function(request, response) { + + code = request.query.code; + + var url = 'https://untappd.com/oauth/authorize/?client_id={0}&client_secret={1}&response_type=code&redirect_url={2}&code={3}'.format(clientId, clientSecret, redirectUrl, code); + + var requestify = require('requestify'); + + requestify.get(url).then(function(response2) { + + accessToken = response2.getBody().response.access_token; + + console.log(accessToken); + + var userInfoUrl = 'https://api.untappd.com/v4/user/info?access_token={0}'.format(accessToken); + + requestify.get(userInfoUrl).then(function(response3) { + + var uid = response3.getBody().response.user.user_name; + var id = response3.getBody().response.user.id; + var user_name = response3.getBody().response.user.user_name; + var first_name = response3.getBody().response.user.first_name; + var last_name = response3.getBody().response.user.last_name; + var user_avatar = response3.getBody().response.user.user_avatar; + var user_avatar_hd = response3.getBody().response.user.user_avatar_hd; + var user_cover_photo = response3.getBody().response.user.user_cover_photo; + var user_cover_photo_offset = response3.getBody().response.user.user_cover_photo_offset; + var location = response3.getBody().response.user.location; + var bio = response3.getBody().response.user.bio; + var url = response3.getBody().response.user.url; + var untappd_url = response3.getBody().response.user.untappd_url; + var twitter = response3.getBody().response.user.contact.twitter; + var foursquare = response3.getBody().response.user.contact.foursquare; + var facebook = response3.getBody().response.user.contact.facebook; + var email_address = response3.getBody().response.user.settings.email_address; + + firstName = first_name; + lastName = last_name; + userName = user_name; + + console.log(process.env.DATABASE_URL); + + pg.defaults.ssl = true; + pg.connect(process.env.DATABASE_URL, function(err, client) { + if (err) throw err; + + var query = "INSERT INTO salesforce.untappduser__c (" + + "uid__c," + + "user_name__c," + + "facebook__c," + + "bio__c," + + "location__c," + + "email_address__c," + + "user_avatar_hd__c," + + "user_avatar__c," + + "first_name__c," + + "foursquare__c," + + "untappd_url__c," + + "last_name__c," + + "twitter__c," + + "url__c," + + "user_cover_photo__c," + + "id__c," + + "name) " + + "SELECT '" + + uid + "','" + + user_name + "','" + + facebook + "','" + + bio + "','" + + location + "','" + + email_address + "','" + + user_avatar_hd + "','" + + user_avatar + "','" + + first_name + "','" + + foursquare + "','" + + untappd_url + "','" + + last_name + "','" + + twitter + "','" + + url + "','" + + user_cover_photo + "','" + + id + "','" + + id + "' WHERE NOT EXISTS ( SELECT id__c FROM salesforce.untappduser__c WHERE id__c = '" + id + "' )"; + + console.log(query); + + client.query(query, function(err, result) { + if (err) throw err; + + console.log(result); + }); + + var query = "INSERT INTO accesstokens (token, uid) VALUES ('" + accessToken + "','" + uid + "')"; + + client.query(query, function(err, result) { + if (err) throw err; + + console.log(result); + }); + + response.redirect('/profile'); + }); + }); + }); }); app.listen(app.get('port'), function() { console.log('Node app is running on port', app.get('port')); -}); - - +}); \ No newline at end of file diff --git a/src/web/views/pages/index.ejs b/src/web/views/pages/index.ejs index 5210357..12a07d6 100644 --- a/src/web/views/pages/index.ejs +++ b/src/web/views/pages/index.ejs @@ -1,45 +1,72 @@ - - <% include ../partials/header.ejs %> - - - - - <% include ../partials/nav.ejs %> - -
-
-

An Internet of Beers

-

Learn your estimated blood alcohol content (BAC) when you check into Untappd.

- Getting Started - Source on GitHub -
-
-
- -
-
-
-

How it works

-
    -
  • TBD
  • -
+ + <% include ../partials/header.ejs %> + + + <% include ../partials/nav.ejs %> +
+
+

+ An Internet of Beers +

+

+ Learn your estimated blood alcohol content (BAC) when you check into Untappd. +

+ + + + Getting Started + + + + + Source on GitHub + +
-
-

Learn More

- +
+ +
+
+
+

+ + + How it works +

+
    +
  • + TBD +
  • +
+
+
+

+ + + Learn More +

+ +
+
+ + +
-
- -
- - - + diff --git a/src/web/views/pages/profile.ejs b/src/web/views/pages/profile.ejs new file mode 100644 index 0000000..fa55c27 --- /dev/null +++ b/src/web/views/pages/profile.ejs @@ -0,0 +1,13 @@ + + + + <% include ../partials/header.ejs %> + + + <% include ../partials/nav.ejs %> +
+
+
+
+ + diff --git a/src/web/views/partials/nav.ejs b/src/web/views/partials/nav.ejs index d5abb9c..165f0ec 100644 --- a/src/web/views/partials/nav.ejs +++ b/src/web/views/partials/nav.ejs @@ -4,14 +4,21 @@
  • Home
  • + <% if (accessToken) { %>
  • - Sign In + Profile
  • + < + <% } %>
    - + \ No newline at end of file