base instagram supporting;
This commit is contained in:
1 parent
17923e3730
commit
1ebfcea16b
14 files changed
+528
-103
No files matched your search
@@ -5,8 +5,10 @@
|
||||
var config = require("../config");
|
||||
var db = require("../core/db");
|
||||
var server = require("../server");
|
||||
var instagram = require("../instagram");
|
||||
|
||||
db.init(config.db.uri)
|
||||
.then(instagram)
|
||||
.then(function () {
|
||||
server(config.port);
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Created by tmshv on 06/11/14.
|
||||
*/
|
||||
|
||||
angular.module("hudozhka.instagram", [])
|
||||
.controller("InstagramController", function($scope, $http, $window){
|
||||
//$scope.auth = function() {
|
||||
// $http.get("/instagram/auth/url")
|
||||
// .success(function (data) {
|
||||
// $window.location.href = data.url;
|
||||
// });
|
||||
//};
|
||||
|
||||
$http.get("/instagram/user")
|
||||
.error(function() {
|
||||
|
||||
})
|
||||
.success(function (user) {
|
||||
$scope.user = user;
|
||||
});
|
||||
|
||||
$scope.invite = function() {
|
||||
$http.get("/instagram/invite")
|
||||
.success(function (data) {
|
||||
$scope.inviteCode = data.code;
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -23,7 +23,7 @@ var config = {
|
||||
uri: "mongodb://localhost:27017/hudozka"
|
||||
},
|
||||
|
||||
tags: ["shlb_hudozka"]
|
||||
tag: "shlb_hudozka"
|
||||
};
|
||||
|
||||
module.exports = Object.keys(privateData)
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Created by tmshv on 22/11/14.
|
||||
*/
|
||||
|
||||
var config = require("../config");
|
||||
var instagram = require("instagram-node");
|
||||
var auth_clients = {};
|
||||
|
||||
module.exports = {
|
||||
client: function(code){
|
||||
if(code && code in auth_clients) {
|
||||
return auth_clients[code].client;
|
||||
}else{
|
||||
return createClient();
|
||||
}
|
||||
},
|
||||
|
||||
user: function(code){
|
||||
if(code in auth_clients) {
|
||||
return auth_clients[code].user;
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
authorize: function(code){
|
||||
return new Promise(function(resolve, reject){
|
||||
var api = createClient();
|
||||
api.authorize_user(code, config.instagram.redirect_uri, function (err, result) {
|
||||
if (err) return reject(err);
|
||||
else {
|
||||
var user = result.user;
|
||||
var token = result.access_token;
|
||||
var client = createClient(token);
|
||||
|
||||
auth_clients[code] = {
|
||||
client: client,
|
||||
user: user
|
||||
};
|
||||
|
||||
resolve(client);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function createClient(token) {
|
||||
var client = instagram.instagram({}, {});
|
||||
if (token) {
|
||||
client.use({access_token: token});
|
||||
} else {
|
||||
client.use({
|
||||
client_id: config.instagram.client_id,
|
||||
client_secret: config.instagram.client_secret
|
||||
});
|
||||
}
|
||||
return client;
|
||||
}
|
||||
@@ -50,6 +50,13 @@ gulp.task("compile", function(){
|
||||
}))
|
||||
.pipe(uglify())
|
||||
.pipe(gulp.dest("public"));
|
||||
|
||||
gulp.src("client/instagram.js")
|
||||
.pipe(browserify({
|
||||
transform: [annotate]
|
||||
}))
|
||||
.pipe(uglify())
|
||||
.pipe(gulp.dest("public"));
|
||||
});
|
||||
|
||||
gulp.task("imagemin", function(){
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Created by tmshv on 12/03/15.
|
||||
*/
|
||||
|
||||
var db = require("../core/db");
|
||||
var co = require("co");
|
||||
var instagram = require("./instagram");
|
||||
var publish = require("./publish");
|
||||
var config = require("../config");
|
||||
|
||||
module.exports = function () {
|
||||
return loadUsers()
|
||||
.then(publish)
|
||||
.then(updateSubscription)
|
||||
};
|
||||
|
||||
function loadUsers() {
|
||||
return new Promise(function (resolve, reject) {
|
||||
db.c("users").find({provider: "instagram"})
|
||||
.toArray()
|
||||
.then(function (users) {
|
||||
users.forEach(function (u) {
|
||||
return instagram.initUser(u);
|
||||
});
|
||||
return users;
|
||||
})
|
||||
.then(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
function updateSubscription() {
|
||||
var tags = [config["tag"]];
|
||||
return tags.map(function (tag) {
|
||||
var cb = config.instagram["tag_callback"];
|
||||
return co(function *() {
|
||||
return yield instagram.api.subscribe(tag, cb);
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* Created by tmshv on 22/11/14.
|
||||
*/
|
||||
|
||||
var EventEmitter = require("events").EventEmitter;
|
||||
var thunkify = require("thunkify");
|
||||
var config = require("../config");
|
||||
var db = require("../core/db");
|
||||
var instagram = require("instagram-node");
|
||||
|
||||
function Instagram(options) {
|
||||
this.client_id = options.client_id;
|
||||
this.client_secret = options.client_secret;
|
||||
this.redirect_uri = options.redirect_uri;
|
||||
this.default_user = options.default_user;
|
||||
this.clients = {};
|
||||
this.users = {};
|
||||
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
|
||||
Instagram.prototype = Object.create(EventEmitter.prototype);
|
||||
|
||||
Instagram.prototype.authorizationURL = function (scope, state) {
|
||||
var params = {};
|
||||
params.scope = scope || ["basic"];
|
||||
if (state) {
|
||||
params.state = state;
|
||||
}
|
||||
|
||||
var client = createClient();
|
||||
return client["get_authorization_url"](this.redirect_uri, params);
|
||||
};
|
||||
|
||||
Instagram.prototype.addClient = function *(code, params) {
|
||||
var token = params.access_token;
|
||||
var item = params.user;
|
||||
item.code = code;
|
||||
item.access_token = token;
|
||||
item.provider = "instagram";
|
||||
yield db.c("users").update({provider: "instagram", id: params.user.id}, item, {upsert: true});
|
||||
|
||||
return this.initUser(item);
|
||||
};
|
||||
|
||||
Instagram.prototype.initUser = function (user) {
|
||||
var token = user.access_token;
|
||||
this.clients[user.code] = createClient(token);
|
||||
this.users[user.code] = user;
|
||||
return this;
|
||||
};
|
||||
|
||||
Instagram.prototype.getUsers = function () {
|
||||
var users = this.users;
|
||||
return Object.keys(users)
|
||||
.map(function (code) {
|
||||
return users[code];
|
||||
});
|
||||
};
|
||||
|
||||
Instagram.prototype.update = function (body) {
|
||||
this.emit("update", body);
|
||||
};
|
||||
|
||||
Instagram.prototype.client = function (code) {
|
||||
if (code && code in this.clients) {
|
||||
return this.clients[code];
|
||||
} else {
|
||||
return createClient();
|
||||
}
|
||||
};
|
||||
|
||||
Instagram.prototype.user = function (code) {
|
||||
if (code && code in this.users) {
|
||||
return this.users[code];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Instagram.prototype.authorize = function *(code) {
|
||||
var api = createClient();
|
||||
var authorize = thunkify(api["authorize_user"]);
|
||||
var result = yield authorize(code, this.redirect_uri);
|
||||
|
||||
if (result) {
|
||||
yield this.addClient(code, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Instagram.prototype.getUser = function *() {
|
||||
if (this.default_user) {
|
||||
var du = yield db.c("users").findOne({username: this.default_user});
|
||||
if (du) {
|
||||
return du;
|
||||
}
|
||||
}
|
||||
|
||||
return yield db.c("users").findOne({provider: "instagram"});
|
||||
};
|
||||
|
||||
Instagram.prototype.getUsers = function *() {
|
||||
return yield db.c("users").find({provider: "instagram"}).toArray();
|
||||
};
|
||||
|
||||
Instagram.prototype.api = {
|
||||
subscriptions: function *() {
|
||||
var ig = createClient();
|
||||
var subs = thunkify(ig["subscriptions"]);
|
||||
try {
|
||||
var s = yield subs();
|
||||
return s[0];
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
subscribe: function *(tag, callbackURL) {
|
||||
var ig = createClient();
|
||||
var sub = thunkify(ig["add_tag_subscription"]);
|
||||
try {
|
||||
var s = yield sub(tag, callbackURL);
|
||||
return s[0];
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
unsubscribe: function *(id) {
|
||||
var ig = createClient();
|
||||
var sub = thunkify(ig["del_subscription"]);
|
||||
try {
|
||||
var s = yield sub({id: id});
|
||||
return s[0];
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
tagMediaRecent: function *(client, tag, count) {
|
||||
var tag_media_recent = thunkify(client["tag_media_recent"]);
|
||||
|
||||
try{
|
||||
var result = yield tag_media_recent(tag, {count: count});
|
||||
return {
|
||||
medias: result[0],
|
||||
pagination: result[1],
|
||||
remaining: result[2],
|
||||
limit: result[3]
|
||||
}
|
||||
}catch(error){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = new Instagram(config.instagram);
|
||||
|
||||
function createClient(token) {
|
||||
var client = instagram.instagram({}, {});
|
||||
if (token) {
|
||||
client.use({access_token: token});
|
||||
} else {
|
||||
client.use({
|
||||
client_id: config.instagram.client_id,
|
||||
client_secret: config.instagram.client_secret
|
||||
});
|
||||
}
|
||||
return client;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Created by tmshv on 10/03/15.
|
||||
*/
|
||||
|
||||
var co = require("co");
|
||||
var instagram = require("./instagram");
|
||||
var config = require("../config");
|
||||
var db = require("../core/db");
|
||||
|
||||
|
||||
module.exports = function () {
|
||||
return co(function *() {
|
||||
instagram.on("update", function (data) {
|
||||
var tag = config["tag"];
|
||||
|
||||
co(function *() {
|
||||
var user = yield instagram.getUser();
|
||||
if (user) {
|
||||
var client = instagram.client(user.code);
|
||||
var permitted_users = yield instagram.getUsers();
|
||||
permitted_users = permitted_users.map(function (user) {
|
||||
return user["username"];
|
||||
});
|
||||
|
||||
var medias = yield fbt(client, tag);
|
||||
medias = medias.filter(function (gram) {
|
||||
return permitted_users.indexOf(gram.data.author) > -1;
|
||||
});
|
||||
|
||||
return medias;
|
||||
}
|
||||
})
|
||||
.then(function (posts) {
|
||||
return posts.map(function (g) {
|
||||
console.log(g);
|
||||
return db.c("posts").update({"data.id": g.data.id}, g, {upsert: true})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function *fbt(client, tag) {
|
||||
var param = yield instagram.api.tagMediaRecent(client, tag, 10);
|
||||
return param.medias.map(toInstagram);
|
||||
}
|
||||
|
||||
function toInstagram(gram) {
|
||||
var post = {};
|
||||
|
||||
post.body = gram.caption.text;
|
||||
post.type = "instagram";
|
||||
post.tags = gram.tags;
|
||||
post.date = new Date(parseInt(gram["created_time"]) * 1000);
|
||||
|
||||
post.data = {
|
||||
id: gram.id,
|
||||
author: gram.user["username"],
|
||||
image: gram.images,
|
||||
url: gram.link
|
||||
};
|
||||
|
||||
return post;
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Created by tmshv on 22/11/14.
|
||||
*/
|
||||
|
||||
var path = require("path");
|
||||
var route = require("koa-route");
|
||||
var router = require("../routes");
|
||||
var instagram = require("../instagram/instagram");
|
||||
|
||||
module.exports = function (app) {
|
||||
app.use(function *(next) {
|
||||
var code = this.cookies.get("instagram_code");
|
||||
if (code) {
|
||||
var client = instagram.client(code);
|
||||
var user = instagram.user(code);
|
||||
if (client && user) {
|
||||
this.instagram = {
|
||||
client: client,
|
||||
user: user
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
yield* next;
|
||||
});
|
||||
|
||||
app.use(
|
||||
route.get("/instagram", function *() {
|
||||
var invite = this.cookies.get("invite_code") || this.query.code;
|
||||
|
||||
if(!this.instagram) {
|
||||
if(invite == undefined){
|
||||
this.body = "invite required";
|
||||
this.status = 401;
|
||||
}else if(invite == "LOL"){
|
||||
this.cookies.set("invite_code", invite, {expires: expire()});
|
||||
|
||||
//todo: invalidate invite
|
||||
|
||||
yield router.index(
|
||||
path.join(__dirname, "../templates/instagram.html")
|
||||
);
|
||||
}else{
|
||||
this.body = "invite ist correct";
|
||||
this.status = 401;
|
||||
}
|
||||
}else{
|
||||
yield router.index(
|
||||
path.join(__dirname, "../templates/instagram.html")
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
app.use(
|
||||
route.get("/instagram/auth", function *() {
|
||||
var invite = this.cookies.get("invite_code");
|
||||
if(invite) {
|
||||
var url = instagram.authorizationURL(null, "/instagram");
|
||||
this.redirect(url);
|
||||
}else{
|
||||
this.status = 401;
|
||||
this.body = "invite required";
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
app.use(
|
||||
route.get("/instagram/user", function *() {
|
||||
var code = this.cookies.get("instagram_code");
|
||||
var user = instagram.user(code);
|
||||
|
||||
if(user) {
|
||||
this.body = user;
|
||||
}else{
|
||||
this.status = 404;
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
app.use(
|
||||
route.get("/instagram/auth/callback", function *() {
|
||||
var state = this.query.state || "/";
|
||||
var code = this.query.code;
|
||||
var client = yield instagram.authorize(code);
|
||||
|
||||
if (client) {
|
||||
this.cookies.set("instagram_code", code, {expires: expire()});
|
||||
this.redirect(state);
|
||||
} else {
|
||||
this.status = 401;
|
||||
this.redirect(state);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
app.use(route.get("/instagram/subscription/list", function *() {
|
||||
var result = yield instagram.api.subscriptions();
|
||||
if(result) {
|
||||
this.body = result;
|
||||
}else{
|
||||
this.status = 500;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(route.get("/instagram/subscription/add", function *() {
|
||||
var tag = this.query.tag;
|
||||
var cu = this.query.url;
|
||||
|
||||
var result = yield instagram.api.subscribe(tag, cu);
|
||||
if(result) {
|
||||
this.body = result;
|
||||
}else{
|
||||
this.status = 500;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(route.get("/instagram/subscription/delete", function *() {
|
||||
var id = this.query.id;
|
||||
|
||||
var result = yield instagram.api.unsubscribe(id);
|
||||
if(result) {
|
||||
this.body = result;
|
||||
}else{
|
||||
this.status = 500;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(route.get("/instagram/callback/:rnd", function *() {
|
||||
if(this.query["hub.mode"] == "subscribe"){
|
||||
this.body = this.query["hub.challenge"];
|
||||
}else{
|
||||
this.status = 400;
|
||||
}
|
||||
}));
|
||||
|
||||
app.use(route.post("/instagram/callback/:rnd", function *(rnd) {
|
||||
var sign = this.header["x-hub-signature"];
|
||||
//console.log(this.headers);
|
||||
|
||||
var body = this.request.body;
|
||||
|
||||
//var hmac = crypto.createHmac("sha1", instagram.client_secret);
|
||||
//hmac.update(body);
|
||||
//var shasum = hmac.digest("hex");
|
||||
|
||||
|
||||
//console.log("X-Hub-Signature", sign);
|
||||
//console.log("Hmac", shasum);
|
||||
//console.log();
|
||||
|
||||
//if(shasum.digest("hex") == sign) {
|
||||
instagram.update(body);
|
||||
//}
|
||||
|
||||
this.body = "";
|
||||
}));
|
||||
};
|
||||
|
||||
function expire(time){
|
||||
return time || new Date(Date.now() + 1000 * 60 * 60 * 24 * 7);
|
||||
}
|
||||
+2
-1
@@ -14,9 +14,10 @@
|
||||
"author": "Roman Timashev",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"co": "^4.4.0",
|
||||
"instagram-node": "^0.5.1",
|
||||
"koa": "^0.18.0",
|
||||
"koa-bodyparser": "^1.4.0",
|
||||
"koa-bodyparser": "^1.4.1",
|
||||
"koa-conditional-get": "^1.0.2",
|
||||
"koa-etag": "^2.0.0",
|
||||
"koa-helmet": "0.0.3",
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Created by tmshv on 22/11/14.
|
||||
*/
|
||||
|
||||
var Router = require("express").Router;
|
||||
var instagram = require("../core/instagram");
|
||||
|
||||
module.exports = function (app) {
|
||||
var router;
|
||||
router = new Router();
|
||||
router.route("/auth/instagram/callback")
|
||||
.get(function (req, res) {
|
||||
var code = req.query.code;
|
||||
instagram.authorize(code)
|
||||
.catch(function(error){
|
||||
console.log(error.body);
|
||||
res.status(500).send('');
|
||||
})
|
||||
.then(function (client) {
|
||||
res.cookie("instagram_code", code);
|
||||
res.redirect("/");
|
||||
});
|
||||
});
|
||||
app.use(router);
|
||||
|
||||
//http://your-callback.com/url/?hub.mode=subscribe&hub.challenge=15f7d1a91c1f40f8a748fd134752feb3&hub.verify_token=myVerifyToken
|
||||
router = new Router();
|
||||
router.route("/instagram/tag/:tag")
|
||||
.get(function (req, res) {
|
||||
var hub_challenge = req.query["hub.challenge"];
|
||||
//var hub_verify_token = req.query["hub.verify_token"];
|
||||
|
||||
console.log("real time get", req.param("tag"), hub_challenge);
|
||||
res.send(hub_challenge);
|
||||
})
|
||||
.post(function (req, res) {
|
||||
console.log("real time tag", req.param("tag"));
|
||||
console.log(req.body);
|
||||
res.send("");
|
||||
});
|
||||
app.use(router);
|
||||
};
|
||||
@@ -8,6 +8,7 @@ var conditional = require("koa-conditional-get");
|
||||
var etag = require("koa-etag");
|
||||
var prerender = require("koa-prerender");
|
||||
var helmet = require('koa-helmet');
|
||||
var bodyParser = require("koa-bodyparser");
|
||||
|
||||
var config = require("./config");
|
||||
var routes = require("./routes");
|
||||
@@ -15,6 +16,7 @@ var routes = require("./routes");
|
||||
var app = koa();
|
||||
app.proxy = true;
|
||||
|
||||
app.use(bodyParser());
|
||||
app.use(logger());
|
||||
app.use(conditional());
|
||||
app.use(etag());
|
||||
@@ -55,6 +57,8 @@ require("./routes/news")(app);
|
||||
|
||||
require("./routes/404")(app);
|
||||
|
||||
require("./instagram/router")(app);
|
||||
|
||||
if (process.env["NODE_ENV"] === "development") {
|
||||
app.use(route.get("/debug", function *() {
|
||||
var out = {};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html ng-app="hudozhka.instagram">
|
||||
<head>
|
||||
<base href="/">
|
||||
<meta name="fragment" content="!">
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1.0" />
|
||||
|
||||
<title ng-bind="title">ДШХ Шлиссельбурга</title>
|
||||
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/bower_components/angular/angular.min.js"></script>
|
||||
<script src="/instagram.js"></script>
|
||||
</head>
|
||||
<body ng-controller="InstagramController">
|
||||
<div class="controls">
|
||||
<a href="/instagram/auth" ng-show="!user">Instagram</a>
|
||||
<a href="//instagram.com/{{user.username}}" ng-show="user">{{user.full_name}}</a>
|
||||
<button ng-click="invite()">Invite</button>
|
||||
{{inviteCode}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Created by tmshv on 13/03/15.
|
||||
*/
|
||||
|
||||
var co = require("co");
|
||||
var should = require("should");
|
||||
var instagram = require("../instagram/instagram");
|
||||
var db = require("../core/db");
|
||||
var config = require("../config");
|
||||
|
||||
describe("Instagram", function () {
|
||||
describe("getUser()", function () {
|
||||
it("should return default user if exists", function () {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user