This commit is contained in:
Wade Wegner 2016-04-13 21:37:53 -07:00
Родитель 0c5e3de4f2
Коммит ccbbd274f8
10 изменённых файлов: 371 добавлений и 53 удалений

91
.gitignore поставляемый
Просмотреть файл

@ -37,4 +37,93 @@ node_modules
Dockerfile
docker-compose.yml
.DS_Store
/*.env
/*.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

Просмотреть файл

@ -1 +1,2 @@
web: node src/web/index.js
web: node src/web/index.js
clock: python src/clock/clock.py

Просмотреть файл

@ -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
)

Просмотреть файл

@ -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",

1
requirements.txt Normal file
Просмотреть файл

@ -0,0 +1 @@
APScheduler==3.0.0

20
src/clock/clock.py Normal file
Просмотреть файл

@ -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()

Просмотреть файл

@ -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'));
});
});

Просмотреть файл

@ -1,45 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<% include ../partials/header.ejs %>
</head>
<body>
<% include ../partials/nav.ejs %>
<div class="jumbotron text-center">
<div class="container">
<h1>An Internet of Beers</h1>
<p>Learn your estimated blood alcohol content (BAC) when you check into Untappd.</p>
<a type="button" class="btn btn-lg btn-default" href="#"><span class="glyphicon glyphicon-flash"></span> Getting Started</a>
<a type="button" class="btn btn-lg btn-primary" href="https://github.com/wadewegner/internet-of-beers"><span class="glyphicon glyphicon-download"></span> Source on GitHub</a>
</div>
</div>
<div class="container">
<div class="alert alert-info text-center" role="alert">
This app and service is based on the talk <a href="https://www.thatconference.com/sessions/session/10592" class="alert-link">An Internet of Beers</a> given at ThatConference on Tuesday, August 9, 2016.
</div>
<hr>
<div class="row">
<div class="col-md-6">
<h3><span class="glyphicon glyphicon-info-sign"></span> How it works</h3>
<ul>
<li>TBD</li>
</ul>
<head>
<% include ../partials/header.ejs %>
</head>
<body>
<% include ../partials/nav.ejs %>
<div class="jumbotron text-center">
<div class="container">
<h1>
An Internet of Beers
</h1>
<p>
Learn your estimated blood alcohol content (BAC) when you check into Untappd.
</p>
<a class="btn btn-lg btn-default" href="#" type="button">
<span class="glyphicon glyphicon-flash">
</span>
Getting Started
</a>
<a class="btn btn-lg btn-primary" href="https://github.com/wadewegner/internet-of-beers" type="button">
<span class="glyphicon glyphicon-download">
</span>
Source on GitHub
</a>
</div>
</div>
<div class="col-md-6">
<h3><span class="glyphicon glyphicon-link"></span> Learn More</h3>
<ul>
<li><a href="https://www.wadewegner.com/home">www.wadewegner.com</a></li>
</ul>
<div class="container">
<div class="alert alert-info text-center" role="alert">
This app and service is based on the talk
<a class="alert-link" href="https://www.thatconference.com/sessions/session/10592">
An Internet of Beers
</a>
given at ThatConference on Tuesday, August 9, 2016.
</div>
<hr>
<div class="row">
<div class="col-md-6">
<h3>
<span class="glyphicon glyphicon-info-sign">
</span>
How it works
</h3>
<ul>
<li>
TBD
</li>
</ul>
</div>
<div class="col-md-6">
<h3>
<span class="glyphicon glyphicon-link">
</span>
Learn More
</h3>
<ul>
<li>
<a href="https://www.wadewegner.com/home">
www.wadewegner.com
</a>
</li>
</ul>
</div>
</div>
<!-- row -->
<div class="alert alert-info text-center" role="alert">
Your actual blood alcohol concentration depends on a variety of additional factors, like genetic makeup, personal health, and recent food consumption. These results are rough estimates and for your personaly enjoyment only. Do not rely on these results to drive or work. Never drink and drive.
</div>
</hr>
</div>
</div> <!-- row -->
<div class="alert alert-info text-center" role="alert">
Your actual blood alcohol concentration depends on a variety of additional factors, like genetic makeup, personal health, and recent food consumption. These results are rough estimates and for your personaly enjoyment only. Do not rely on these results to drive or work. Never drink and drive.
</div>
</div>
</body>
</body>
</html>

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<% include ../partials/header.ejs %>
</head>
<body>
<% include ../partials/nav.ejs %>
<div class="jumbotron text-center">
<div class="container">
</div>
</div>
</body>
</html>

Просмотреть файл

@ -4,14 +4,21 @@
<li class="active">
<a href="/"><span class="glyphicon glyphicon-home"></span> Home</a>
</li>
<% if (accessToken) { %>
<li>
<a href="#"><span class="glyphicon glyphicon-user"></span> Sign In</a>
<a href="/profile"><span class="glyphicon glyphicon-book"></span> Profile</a>
</li>
<
<% } %>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="navbar-right">
<a href="http://www.wadewegner.com"><span class="glyphicon glyphicon-book"></span> Wade Wegner</a>
<% if (accessToken) { %>
<a href="/logout"><span class="glyphicon glyphicon-user"></span> Sign Out</a>
<% } else { %>
<a href="<%= signinUrl %>"><span class="glyphicon glyphicon-user"></span> Sign In</a>
<% } %>
</li>
</ul>
</div>
</nav>
</nav>