Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 47ff2e2
Showing
434 changed files
with
425,202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directory | ||
node_modules | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# OS | ||
.DS_Store | ||
|
||
env | ||
|
||
app/public/js/bundle.js | ||
app/public/js/app.js | ||
|
||
# idea | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# 7 Step - React/Redux tutorial series | ||
|
||
This example application created by [getstream.io](https://getstream.io/?ref=github_stream_react_example) teaches you how to to build an Instagram style application with activity streams and newsfeeds. | ||
|
||
Visit [cabin.getstream.io](http://cabin.getstream.io/) for an overview of all 7 tutorials and a live demo. If you enjoy this tutorial please star this repo. | ||
|
||
<p align="center"> | ||
<img src="https://stream-cabin.s3.amazonaws.com/defaults/Cabin_Github@2x.png" alt="Examples of what you can build" title="What you can build"/> | ||
</p> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Config | ||
*/ | ||
module.exports = { | ||
name: 'GetStream.io - React Example App', | ||
version: '1.0.0', | ||
env: process.env.NODE_ENV || 'DEVELOPMENT', | ||
port: process.env.PORT || 8000, | ||
jwt: { | ||
secret: process.env.JWT_SECRET, | ||
}, | ||
db: { | ||
name: 'cabin', | ||
username: process.env.DB_USERNAME, | ||
password: process.env.DB_PASSWORD, | ||
host: process.env.DB_HOST, | ||
port: process.env.DB_PORT, | ||
}, | ||
mapbox: { | ||
accessToken: process.env.MAPBOX_ACCESS_TOKEN, | ||
}, | ||
s3: { | ||
key: process.env.S3_KEY, | ||
secret: process.env.S3_SECRET, | ||
bucket: process.env.S3_BUCKET, | ||
}, | ||
stream: { | ||
appId: process.env.STREAM_APP_ID, | ||
key: process.env.STREAM_KEY, | ||
secret: process.env.STREAM_SECRET, | ||
}, | ||
algolia: { | ||
appId: process.env.ALGOLIA_APP_ID, | ||
searchOnlyKey: process.env.ALGOLIA_SEARCH_ONLY_KEY, | ||
apiKey: process.env.ALGOLIA_API_KEY, | ||
}, | ||
keen: { | ||
projectId: process.env.KEEN_PROJECT_ID, | ||
writeKey: process.env.KEEN_WRITE_KEY, | ||
readKey: process.env.KEEN_READ_KEY, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Env Configuration | ||
*/ | ||
require('dotenv').config({ path: 'env' }); | ||
|
||
/** | ||
* Module Dependencies | ||
*/ | ||
var config = require('./config'), | ||
bunyan = require('bunyan'), | ||
winston = require('winston'), | ||
bunyanWinston = require('bunyan-winston-adapter'), | ||
mysql = require('mysql'), | ||
jwt = require('restify-jwt'); | ||
|
||
/** | ||
* Global Dependencies | ||
*/ | ||
global.__base = __dirname + '/'; | ||
global.config = require('./config.js'); | ||
global.restify = require('restify'); | ||
|
||
/** | ||
* Logging | ||
*/ | ||
global.log = new winston.Logger({ | ||
transports: [ | ||
new winston.transports.Console({ | ||
level: 'info', | ||
timestamp: function() { | ||
return new Date().toString(); | ||
}, | ||
json: true | ||
}) | ||
] | ||
}); | ||
|
||
/** | ||
* Initialize Server | ||
*/ | ||
global.server = restify.createServer({ | ||
name : config.name, | ||
version : config.version, | ||
log : bunyanWinston.createAdapter(log), | ||
}); | ||
|
||
/** | ||
* Middleware | ||
*/ | ||
server.use(restify.bodyParser()); | ||
server.use(restify.acceptParser(server.acceptable)); | ||
server.use(restify.authorizationParser()); | ||
server.use(restify.queryParser({ mapParams: true })); | ||
server.pre(require('./lib/cors')()); | ||
server.use(restify.fullResponse()); | ||
server.use(jwt({ secret: config.jwt.secret }).unless({ | ||
path: ['/users'] | ||
})); | ||
|
||
/** | ||
* Initialize MySQL Connection | ||
*/ | ||
global.db = mysql.createConnection({ | ||
host : config.db.host, | ||
user : config.db.username, | ||
password : config.db.password, | ||
database : config.db.name, | ||
timezone: 'UTC' | ||
}); | ||
db.connect(); | ||
|
||
db.query(` | ||
SET sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" | ||
`) | ||
|
||
/** | ||
* Boot | ||
*/ | ||
server.listen(config.port, function () { | ||
require('./routes'); | ||
log.info( | ||
'%s v%s ready to accept connections on port listening on port %s in %s environment', | ||
server.name, | ||
config.version, | ||
config.port, | ||
config.env | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
'use strict'; | ||
|
||
function cors(options) { | ||
|
||
const defaultAllowHeaders = ['Authorization', 'Content-Type']; | ||
const defaultAllowMethods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD"]; | ||
|
||
const opts = Object.assign({}, { | ||
allowHeaders: defaultAllowHeaders, | ||
allowMethods: defaultAllowMethods, | ||
allowOrigins: null, | ||
allowCreds: true, | ||
}, options || {}); | ||
|
||
const setHeader = (req, res, methods) => { | ||
const origin = req.headers.origin; | ||
const requestMethod = req.headers['access-control-request-method']; | ||
const requestHeaders = req.headers['access-control-request-headers']; | ||
|
||
res.once('header', () => { | ||
if (opts.allowCreds) res.header('Access-Control-Allow-Credentials', 'true'); | ||
|
||
if (opts.allowOrigins) { | ||
res.header('Access-Control-Allow-Origin', | ||
(Array.isArray(opts.allowOrigins)) ? opts.allowOrigins.join(', ') : opts.allowOrigins); | ||
} else { | ||
res.header('Access-Control-Allow-Origin', origin); | ||
} | ||
|
||
res.header('Access-Control-Allow-Methods', opts.allowMethods.join(', ')); | ||
res.header('Access-Control-Allow-Headers', opts.allowHeaders.map(h => h.toUpperCase()).join(', ')); | ||
}); | ||
}; | ||
|
||
return (req, res, next) => { | ||
setHeader(req, res); | ||
if (req.method == 'OPTIONS') return res.send(200); | ||
return next(); | ||
}; | ||
}; | ||
|
||
module.exports = cors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
'use strict'; | ||
var async = require('async'); | ||
|
||
function referencesFromActivities(activitiesOrNotifications) { | ||
/* | ||
Returns the references from a list of activities | ||
*/ | ||
var references = {} | ||
activitiesOrNotifications.forEach(function(item) { | ||
var activities = (item.activities) ? item.activities : [ | ||
item | ||
]; | ||
activities.forEach(function(activity) { | ||
Object.keys(activity).forEach(function(key) { | ||
if (activity[key] && activity[key].indexOf && activity[key].indexOf(':') != -1) { | ||
var parts = activity[key].split(':'); | ||
var reference = parts[0]; | ||
var referenceId = parts[1]; | ||
if (!(reference in references)) { | ||
references[reference] = {}; | ||
} | ||
references[reference][ | ||
referenceId | ||
] = 1; | ||
} | ||
}); | ||
}); | ||
}); | ||
return references; | ||
}; | ||
|
||
function loadReferencedObjects(references, userId, callback) { | ||
// TODO: subqueries are inneficient. Handle do i like and do i follow | ||
// in 2 separate queries | ||
var queries = []; | ||
if (references.upload) { | ||
let sql = ` | ||
SELECT | ||
uploads.id AS id, | ||
users.id AS user_id, | ||
users.first_name AS first_name, | ||
users.last_name AS last_name, | ||
MD5(users.email) AS email_md5, | ||
uploads.id AS upload_id, | ||
uploads.filename AS filename, | ||
uploads.hashtags AS hashtags, | ||
uploads.caption AS caption, | ||
uploads.location AS location, | ||
IF((SELECT 1 AS liked FROM likes WHERE user_id = ? AND upload_id = uploads.id), true, false) AS liked | ||
FROM uploads | ||
LEFT JOIN users ON (uploads.user_id = users.id) | ||
WHERE uploads.id IN (?) | ||
`; | ||
queries.push({ | ||
'name': 'upload', | ||
'sql': sql | ||
}); | ||
} | ||
if (references.user) { | ||
// do the same thing for users | ||
let sql = ` | ||
SELECT | ||
users.id AS id, | ||
users.id AS user_id, | ||
users.first_name AS first_name, | ||
users.last_name AS last_name, | ||
MD5(users.email) AS email_md5, | ||
IF( | ||
( | ||
SELECT | ||
1 AS following | ||
FROM followers AS f | ||
WHERE f.follower_id = users.id | ||
AND f.user_id = ? | ||
), | ||
true, | ||
false | ||
) AS following | ||
FROM users | ||
WHERE users.id IN (?) | ||
`; | ||
queries.push({ | ||
'name': 'user', | ||
'sql': sql | ||
}); | ||
} | ||
var referencedObject = {}; | ||
// run all the queries | ||
async.eachSeries(queries, function iteratee(query, cb) { | ||
db.query(query.sql, [userId, Object.keys(references[query.name])], function(err, results) { | ||
if (err) { | ||
cb(err); | ||
} | ||
referencedObject[query.name] = {}; | ||
results.forEach(function(result) { | ||
referencedObject[query.name][result.id] = result; | ||
}); | ||
cb(); | ||
}); | ||
}, function done() { | ||
callback(referencedObject); | ||
}); | ||
} | ||
|
||
function enrichActivities(activitiesOrNotifications, refencedObjects) { | ||
/* | ||
* Enriches the activities by replacing references with the actual objects | ||
*/ | ||
activitiesOrNotifications.forEach(function(item) { | ||
var activities = (item.activities) ? item.activities : [item]; | ||
activities.forEach(function(activity) { | ||
Object.keys(activity).forEach(function(key) { | ||
if (activity[key] && activity[key].indexOf && activity[key].indexOf(':') != -1) { | ||
var parts = activity[key].split(':'); | ||
var reference = parts[0]; | ||
var referenceId = parts[1]; | ||
if (reference in refencedObjects && refencedObjects[reference][referenceId]) { | ||
activity[key] = refencedObjects[reference][referenceId]; | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
'referencesFromActivities': referencesFromActivities, | ||
'loadReferencedObjects': loadReferencedObjects, | ||
'enrichActivities': enrichActivities | ||
}; |
Oops, something went wrong.