diff --git a/api/feed.js b/api/feed.js new file mode 100644 index 00000000..3e56bc9d --- /dev/null +++ b/api/feed.js @@ -0,0 +1,22 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var Router = require("express").Router; +var Post = require("../schema/post"); + +module.exports = function (app) { + var router; + router = new Router(); + router.route("/api/feed") + .get(function (req, res) { + Post.find({}).exec(function (error, list) { + if (error) return res.error(error); + + res.json(list.map(function (post) { + return post.toObject(); + })); + }); + }); + app.use(router); +}; \ No newline at end of file diff --git a/assets/graphics/rawline.png b/assets/graphics/rawline.png index 4dfe6fdd..a40c95fe 100644 Binary files a/assets/graphics/rawline.png and b/assets/graphics/rawline.png differ diff --git a/assets/style/feed.scss b/assets/style/feed.scss new file mode 100644 index 00000000..d46f50b2 --- /dev/null +++ b/assets/style/feed.scss @@ -0,0 +1,30 @@ +.feed { + width: 50%; + margin: 30px auto 0; + + ul{ + margin: 0; + padding: 0; + + list-style: none; + } + + .post { + margin-bottom: 30px; + + .user img { + width: 60px; + border-radius: 50%; + } + + .body img { + display: block; + width: 100%; + max-width: 640px; + box-sizing: border-box; + border-radius: 5px; + border: 8px solid white; + box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.35); + } + } +} \ No newline at end of file diff --git a/bin/insta.js b/bin/insta.js new file mode 100644 index 00000000..7f57f78e --- /dev/null +++ b/bin/insta.js @@ -0,0 +1,140 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var config = require("../config"); +var db = require("../core/db"); +var instagram = require("../core/instagram"); +var express = require("express"); +var Promise = require("promise"); +var methodOverride = require("method-override"); +var logger = require("morgan"); +var cookieParser = require("cookie-parser"); +var bodyParser = require("body-parser"); + +var Post = require("../schema/post"); + +db.init(config.db) + .then(function () { + server(config.port); + }); + +function server(port) { + var app = express(); + app.use(logger("dev")); + app.use(cookieParser()); + app.use(bodyParser.json()); + app.use(bodyParser.urlencoded({extended: true})); + app.use(methodOverride()); + + require("../routers/instagram")(app); + + var Router = express.Router; + var instagram = require("../core/instagram"); + var router = new Router(); + router.route("/").get(function (req, res) { + if ("instagram_code" in req.cookies) { + var client = instagram.client(req.cookies["instagram_code"]); + instagramSandbox(client, res); + } else { + var ig = instagram.client(); + var url = ig.get_authorization_url(config.instagram.redirect_uri, {scope: ["basic"], state: "hello"}); + res.redirect(url); + } + }); + app.use(router); + app.listen(port); +} + +function instagramSandbox(ig, res) { +// //{"username":"mlazareffa","bio":"","website":"","profile_picture":"http://images.ak.instagram.com/profiles/anonymousUser.jpg","full_name":"","id":"1549382451"} +// //ig.user_search("mlazareffa", [], function(err, users, remaining, limit) { +// // console.log(err, users, remaining, limit); +// // res.json(users); +// //}); +// +// // ig.user_media_recent("1549382451", [], function (err, medias, pagination, remaining, limit) { +// // console.log(err, medias, pagination, remaining, limit); +// // res.json(users); +// // }); +// +// //ig.subscriptions(function(err, result, remaining, limit){ +// // console.log(err, result, remaining, limit); +// // res.json(result); +// //}); +// +// //ig.del_subscription({id: 14180526}, function (err, subscriptions, limit) { +// // console.log(err, subscriptions, limit); +// // res.json(subscriptions); +// //}); +// +// ///* OPTIONS: { [verify_token] } +// // ig.add_tag_subscription("hello", "http://home.tmshv.ru:1337/instagram/tag/hello", [], function(err, result, remaining, limit){ +// // console.log(err, result, remaining, limit); +// // res.json(result); +// //}); + + findByTag(ig, "shlb_hudozka", 10) + .catch(function (error) { + console.log(error); + }) + .then(function (params) { + var list = params.medias; + var pagination = params.pagination; + var remaining = params.remaining; + var limit = params.limit; + + var posts = list.map(function (gram) { + //var post = new Post(); + var post = {}; + post.id = gram.id; + post.author = gram.user["username"]; + post.publishDate = new Date(parseInt(gram["created_time"]) * 1000); + post.data = gram; + post.body = ""; + post.type = "instagram"; + + return post; + }); + + Promise.all(posts.map(function (post) { + return new Promise(function (resolve, reject) { + console.log('updating', post.id); + Post.update({id: post.id}, post, {upsert: true}, function (error, num) { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + })) + .catch(function (error) { + console.log(error); + }) + .then(function () { + res.send("LOL"); + }); + + //if (pagination.next) { + // pagination.next(mtr); // Will get second page results + //} + }); +} + +function findByTag(ig, tag, count) { + return new Promise(function (resolve, reject) { + ig.tag_media_recent(tag, {count: count}, function (err, medias, pagination, remaining, limit) { + if (err) { + reject(err); + } else { + resolve({ + medias: medias, + pagination: pagination, + remaining: remaining, + limit: limit + }); + } + }); + }); +} \ No newline at end of file diff --git a/bin/www.js b/bin/www.js new file mode 100644 index 00000000..b39eefe3 --- /dev/null +++ b/bin/www.js @@ -0,0 +1,12 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var config = require("../config"); +var db = require("../core/db"); +var server = require("../server"); + +db.init(config.db) + .then(function () { + server(config.port); + }); \ No newline at end of file diff --git a/client/api/api.js b/client/api/api.js new file mode 100644 index 00000000..06677e4b --- /dev/null +++ b/client/api/api.js @@ -0,0 +1,13 @@ +/** + * Created by tmshv on 22/11/14. + */ + +module.exports = function(app) { + app.factory("api", function ($http) { + var api = {}; + var Endpoint = require("./feed"); + api.feed = new Endpoint($http); + + return api; + }); +}; \ No newline at end of file diff --git a/client/api/feed.js b/client/api/feed.js new file mode 100644 index 00000000..d9e563e9 --- /dev/null +++ b/client/api/feed.js @@ -0,0 +1,13 @@ +/** + * Created by tmshv on 22/11/14. + */ + +function APIFeed(http){ + this.request = http; +} + +APIFeed.prototype.post = function() { + return this.request.get("/api/feed"); +}; + +module.exports = APIFeed; \ No newline at end of file diff --git a/client/app.js b/client/app.js index 415de296..e3ab1a3f 100644 --- a/client/app.js +++ b/client/app.js @@ -39,16 +39,14 @@ app.config(function ($locationProvider, $routeProvider) { }); }); +require("./api/api")(app); require("./ui/menu")(app); require("./filters/uppercase-first")(app); +require("./pages/home")(app); require("./pages/schedule")(app); require("./pages/team")(app); require("./pages/docs")(app); -app.controller("HomePageController", function ($scope) { - $scope.pageClass = "page-home"; -}); - app.controller("SchedulePageController", function ($scope) { $scope.pageClass = "page-schedule"; }); diff --git a/client/pages/home.js b/client/pages/home.js new file mode 100644 index 00000000..b7329432 --- /dev/null +++ b/client/pages/home.js @@ -0,0 +1,25 @@ +/** + * Created by tmshv on 22/11/14. + */ + +module.exports = function (app) { + app.controller("HomePageController", function ($scope) { + $scope.pageClass = "page-home"; + }); + + app.controller("FeedController", function ($scope, api) { + api.feed.post() + .success(function (list) { + $scope.feed = list.map(function (post) { + return { + date: post.publishDate, + image: post.data.images.standard_resolution.url, + url: post.data.link, + username: post.data.user.username, + userpic: post.data.user.profile_picture, + text: post.data.caption.text + } + }); + }); + }); +}; \ No newline at end of file diff --git a/config.js b/config.js index db67aec6..cf222eda 100644 --- a/config.js +++ b/config.js @@ -6,13 +6,25 @@ const document = require("./models/document"); const schedule = require("./models/schedule"); module.exports = { - port: 18010, + port: process.env["PORT"] || 3000, pub: "./", data: { menu: MENU, documents: document.docs, team: team.team, courses: course.courses - } + }, + + db: { + uri: "mongodb://localhost:27017/hudozka" + }, + + instagram:{ + client_id: "f17901a26a5e4a5ca4544dd0eebe2a15", + client_secret: "ecce08509871427ab9f8f383318315fc", + redirect_uri: "http://72.tmshv.ru:1337/auth/instagram/callback" + }, + + tags: ["shlb_hudozka"] }; \ No newline at end of file diff --git a/core/db.js b/core/db.js new file mode 100644 index 00000000..55044e2e --- /dev/null +++ b/core/db.js @@ -0,0 +1,18 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var mongoose = require("mongoose"); +var Promise = require("promise"); + +module.exports = { + init: function (options) { + return new Promise(function (resolve, reject) { + mongoose.connect(options.uri, function (error) { + if (error) return reject(error); + resolve(); + }); + }); + + } +}; \ No newline at end of file diff --git a/core/instagram.js b/core/instagram.js new file mode 100644 index 00000000..a035be4c --- /dev/null +++ b/core/instagram.js @@ -0,0 +1,46 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var config = require("../config"); +var Promise = require("promise"); + +var auth_clients = {}; + +module.exports = { + client: function(param){ + if(param in auth_clients) { + return auth_clients[param]; + }else{ + return createClient(); + } + }, + + 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 token = result.access_token; + var c = createClient(token); + auth_clients[code] = c; + resolve(c); + } + }); + }); + } +}; + +function createClient(token) { + var api = require('instagram-node').instagram(); + if (token) { + api.use({access_token: token}); + } else { + api.use({ + client_id: config.instagram.client_id, + client_secret: config.instagram.client_secret + }); + } + return api; +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index c9ac2588..0d6aab34 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -49,4 +49,4 @@ gulp.task("imagemin", function(){ }); gulp.task("default", ["sass", "compile"]); -gulp.task("deploy", ["default", "copy", "imagemin"]); \ No newline at end of file +gulp.task("deploy", ["default", "copy", "imagemin"]); diff --git a/package.json b/package.json index d429c48b..86e50701 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,14 @@ "author": "Roman Timashev", "license": "ISC", "dependencies": { - "express": "^4.10.1" + "body-parser": "^1.9.3", + "cookie-parser": "^1.3.3", + "express": "^4.10.1", + "instagram-node": "^0.5.1", + "method-override": "^2.3.0", + "mongoose": "^3.8.19", + "morgan": "^1.5.0", + "promise": "^6.0.1" }, "devDependencies": { "gulp": "^3.8.10", diff --git a/routers/instagram.js b/routers/instagram.js new file mode 100644 index 00000000..2b6c6862 --- /dev/null +++ b/routers/instagram.js @@ -0,0 +1,44 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var Router = require("express").Router; +var instagram = require("./instagram"); + +module.exports = function (app) { + var router; + router = new Router(); + router.route("/auth/instagram/callback") + .get(function (req, res) { + var api = instagram.client(); + + 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); +}; \ No newline at end of file diff --git a/schema/post.js b/schema/post.js new file mode 100644 index 00000000..c485045a --- /dev/null +++ b/schema/post.js @@ -0,0 +1,20 @@ +/** + * Created by tmshv on 22/11/14. + */ + +var mongoose = require("mongoose"); +var Schema = mongoose.Schema; +var ObjectId = Schema.Types.ObjectId; + +var schema = new Schema({ + id: {type: String, required: true, index: {unique: true}}, + author: {type: String, default: []}, + type: {type: String, enum: ["post", "instagram"]}, + publishDate: Date, + body: String, + data: Object + } +); + +var Post = mongoose.model("Post", schema, "posts"); +module.exports = Post; \ No newline at end of file diff --git a/server.js b/server.js index 0e839f04..3b4a63b4 100644 --- a/server.js +++ b/server.js @@ -1,18 +1,35 @@ var express = require("express"); var path = require("path"); -var config = require("./config"); +var Post = require("./schema/post"); -var server = express(); -server.use("/bower_components", express.static(path.join(__dirname, "bower_components"))); -server.use("/views", express.static(path.join(__dirname, "views"))); -server.use(express.static(path.join(__dirname, "public"))); +var Promise = require("promise"); +var methodOverride = require("method-override"); +var logger = require("morgan"); +var cookieParser = require("cookie-parser"); +var bodyParser = require("body-parser"); -server.get("/document/*", function (req, res) { +var app = express(); +app.use("/bower_components", express.static(path.join(__dirname, "bower_components"))); +app.use("/views", express.static(path.join(__dirname, "views"))); +app.use(express.static(path.join(__dirname, "public"))); + +app.use(logger("dev")); +app.use(cookieParser()); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({extended: true})); +app.use(methodOverride()); + +require("./api/feed")(app); +require("./routers/instagram")(app); + +app.get("/document/*", function (req, res) { res.sendFile(path.join(__dirname, "views/document.html")); }); -server.get("*", function (req, res) { +app.get("*", function (req, res) { res.sendFile(path.join(__dirname, "views/index.html")); }); -server.listen(config.port); +module.exports = function (port) { + app.listen(port); +}; diff --git a/views/home.html b/views/home.html index 10e9c129..9134c886 100644 --- a/views/home.html +++ b/views/home.html @@ -1 +1,16 @@ -
{{post.text}}
+