-

{{title}}{{domain}}

+

{{title}}{{domain}}

{{pluralize votes "Vote"}}, submitted by {{author}}, diff --git a/client/templates/posts/post_item.js b/client/templates/posts/post_item.js index cfc626bf..7cbd060d 100644 --- a/client/templates/posts/post_item.js +++ b/client/templates/posts/post_item.js @@ -14,6 +14,9 @@ Template.postItem.helpers({ } else { return 'disabled'; } + }, + postUrl: function(){ + return this.shortUrl ? this.shortUrl : this.url; } }); @@ -22,4 +25,4 @@ Template.postItem.events({ e.preventDefault(); Meteor.call('upvote', this._id); } -}); \ No newline at end of file +}); From a261e91471e1cbf74656b0f79c253a9bb15f7a2f Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Wed, 8 Jan 2014 08:30:41 +0900 Subject: [PATCH 11/17] Added getClicks method. chapter16-4 --- packages/bitly/bitly.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/bitly/bitly.js b/packages/bitly/bitly.js index 2986bbef..a737c83a 100644 --- a/packages/bitly/bitly.js +++ b/packages/bitly/bitly.js @@ -20,4 +20,29 @@ Bitly.shortenURL = function(url){ }else{ throw new Meteor.Error(500, "Bitly call failed with error: "+shortenResponse.status_txt); } -} \ No newline at end of file +} + +Bitly.getClicks = function(link){ + if(!Meteor.settings.bitly) + throw new Meteor.Error(500, 'Please provide a Bitly token in Meteor.settings'); + + var statsResponse = Meteor.http.get( + "https://api-ssl.bitly.com/v3/link/clicks?", + { + timeout: 5000, + params:{ + "format": "json", + "access_token": Meteor.settings.bitly, + "link": link + } + } + ); + if(statsResponse.data.status_code == 200) + return statsResponse.data.data.link_clicks +} + +Meteor.methods({ + 'getBitlyClicks': function(link){ + return Bitly.getClicks(link); + } +}) \ No newline at end of file From 4022e736cb3de70203e50b138adabb7bc4638dd2 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Wed, 8 Jan 2014 13:40:25 +0900 Subject: [PATCH 12/17] Distributing Bitly API calls. chapter16-5 --- client/templates/posts/post_item.html | 1 + packages/bitly/bitly.js | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/client/templates/posts/post_item.html b/client/templates/posts/post_item.html index cc2fda88..1dbc7965 100644 --- a/client/templates/posts/post_item.html +++ b/client/templates/posts/post_item.html @@ -6,6 +6,7 @@

{{title}}{{domain}}

{{pluralize votes "Vote"}}, submitted by {{author}}, + {{#if clicks}}{{pluralize clicks "click"}},{{/if}} {{pluralize commentsCount "comment"}} {{#if ownPost}}Edit{{/if}}

diff --git a/packages/bitly/bitly.js b/packages/bitly/bitly.js index a737c83a..2175ff3b 100644 --- a/packages/bitly/bitly.js +++ b/packages/bitly/bitly.js @@ -45,4 +45,27 @@ Meteor.methods({ 'getBitlyClicks': function(link){ return Bitly.getClicks(link); } -}) \ No newline at end of file +}) + +var callInterval = 10000; // 1000ms * 10 = 10s + +Meteor.setInterval(function(){ + // get all posts with the shortUrl property + var shortUrlPosts = Posts.find({shortUrl: { $exists: true }}); + var postsNumber = shortUrlPosts.count(); + + // initialize counter + var count = 0; + + shortUrlPosts.forEach(function(post){ + // calculate the right delay to distribute API calls evenly throughout the interval + var callTimeout = Math.round(callInterval/postsNumber*count); + + Meteor.setTimeout(function(){ + Posts.update(post._id, {$set: {clicks: Bitly.getClicks(post.shortUrl)}}); + }, callTimeout); + + count++; + }); + +}, callInterval); \ No newline at end of file From 4df4677c130e8c01efb8b02b712b5b15e53c0b74 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Wed, 8 Jan 2014 13:41:33 +0900 Subject: [PATCH 13/17] Adding Most Clicked view. chapter16-6 --- client/templates/includes/header.html | 3 +++ lib/router.js | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/client/templates/includes/header.html b/client/templates/includes/header.html index ddce85ef..5d6bfc43 100644 --- a/client/templates/includes/header.html +++ b/client/templates/includes/header.html @@ -17,6 +17,9 @@
  • Best
  • +
  • + Most Clicked +
  • {{#if currentUser}}
  • Submit Post diff --git a/lib/router.js b/lib/router.js index 6bf55080..7a296d4d 100644 --- a/lib/router.js +++ b/lib/router.js @@ -49,6 +49,14 @@ BestPostsController = PostsListController.extend({ } }); +ClickedPostsController = PostsListController.extend({ + sort: {clicks: -1, submitted: -1, _id: -1}, + nextPath: function() { + return Router.routes.clickedPosts.path({postsLimit: this.postsLimit() + this.increment}) + } +}); + + Router.route('/', { name: 'home', controller: NewPostsController @@ -58,6 +66,8 @@ Router.route('/new/:postsLimit?', {name: 'newPosts'}); Router.route('/best/:postsLimit?', {name: 'bestPosts'}); +Router.route('/clicked/:postsLimit?', {name: 'clickedPosts'}); + Router.route('/posts/:_id', { name: 'postPage', waitOn: function() { From cfeb935f6a0702e737bdd8e7d5c00d15d195282d Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Tue, 11 Jun 2013 07:10:13 +0900 Subject: [PATCH 14/17] Added Intercom code snippet chapter17-1 --- .meteor/packages | 1 + .meteor/versions | 1 + client/main.js | 7 +++++++ packages/bitly/versions.json | 4 ++-- packages/intercom/.gitignore | 1 + packages/intercom/intercom_loader.js | 1 + packages/intercom/package.js | 9 +++++++++ packages/intercom/versions.json | 15 +++++++++++++++ packages/rss/versions.json | 4 ++-- 9 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 packages/intercom/.gitignore create mode 100644 packages/intercom/intercom_loader.js create mode 100644 packages/intercom/package.js create mode 100644 packages/intercom/versions.json diff --git a/.meteor/packages b/.meteor/packages index 0c995fe5..6aa402aa 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -29,3 +29,4 @@ session rss http bitly +intercom diff --git a/.meteor/versions b/.meteor/versions index bc078d07..b1c48881 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -37,6 +37,7 @@ htmljs@1.0.9 http@1.1.5 ian:accounts-ui-bootstrap-3@1.2.89 id-map@1.0.7 +intercom@1.0.0 iron:controller@1.0.12 iron:core@1.0.11 iron:dynamic-template@1.0.12 diff --git a/client/main.js b/client/main.js index e69de29b..35b51b95 100644 --- a/client/main.js +++ b/client/main.js @@ -0,0 +1,7 @@ +window.intercomSettings = { + // TODO: The current logged in user's email address. + email: "john.doe@example.com", + // TODO: The current logged in user's sign-up date as a Unix timestamp. + created_at: 1234567890, + app_id: "9b593f5995da6d2bd8f418754c0411d55201258a" +}; diff --git a/packages/bitly/versions.json b/packages/bitly/versions.json index 89d32a22..fca353a7 100644 --- a/packages/bitly/versions.json +++ b/packages/bitly/versions.json @@ -2,7 +2,7 @@ "dependencies": [ [ "meteor", - "1.1.2" + "1.1.3" ], [ "underscore", @@ -10,6 +10,6 @@ ] ], "pluginDependencies": [], - "toolVersion": "meteor-tool@1.0.34", + "toolVersion": "meteor-tool@1.0.35", "format": "1.0" } \ No newline at end of file diff --git a/packages/intercom/.gitignore b/packages/intercom/.gitignore new file mode 100644 index 00000000..677a6fc2 --- /dev/null +++ b/packages/intercom/.gitignore @@ -0,0 +1 @@ +.build* diff --git a/packages/intercom/intercom_loader.js b/packages/intercom/intercom_loader.js new file mode 100644 index 00000000..7f433f34 --- /dev/null +++ b/packages/intercom/intercom_loader.js @@ -0,0 +1 @@ +(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://static.intercomcdn.com/intercom.v1.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}};})() \ No newline at end of file diff --git a/packages/intercom/package.js b/packages/intercom/package.js new file mode 100644 index 00000000..0141e481 --- /dev/null +++ b/packages/intercom/package.js @@ -0,0 +1,9 @@ +Package.describe({ + name: 'intercom', + summary: "Intercom package", + version: '1.0.0' +}); +Package.on_use(function (api) { + api.versionsFrom('0.9.4'); + api.add_files('intercom_loader.js', 'client'); +}); \ No newline at end of file diff --git a/packages/intercom/versions.json b/packages/intercom/versions.json new file mode 100644 index 00000000..fca353a7 --- /dev/null +++ b/packages/intercom/versions.json @@ -0,0 +1,15 @@ +{ + "dependencies": [ + [ + "meteor", + "1.1.3" + ], + [ + "underscore", + "1.0.1" + ] + ], + "pluginDependencies": [], + "toolVersion": "meteor-tool@1.0.35", + "format": "1.0" +} \ No newline at end of file diff --git a/packages/rss/versions.json b/packages/rss/versions.json index 89d32a22..fca353a7 100644 --- a/packages/rss/versions.json +++ b/packages/rss/versions.json @@ -2,7 +2,7 @@ "dependencies": [ [ "meteor", - "1.1.2" + "1.1.3" ], [ "underscore", @@ -10,6 +10,6 @@ ] ], "pluginDependencies": [], - "toolVersion": "meteor-tool@1.0.34", + "toolVersion": "meteor-tool@1.0.35", "format": "1.0" } \ No newline at end of file From 283e396fff9e6043e1a6f7d0edd59377bc99e784 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Tue, 11 Jun 2013 09:27:47 +0900 Subject: [PATCH 15/17] Sending custom user data. chapter17-2 --- client/helpers/config.js | 2 +- client/main.js | 19 ++++++++++++------- lib/router.js | 5 ++++- server/publications.js | 7 +++++-- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/client/helpers/config.js b/client/helpers/config.js index fa2f0d01..7d3ddacb 100644 --- a/client/helpers/config.js +++ b/client/helpers/config.js @@ -1,3 +1,3 @@ Accounts.ui.config({ - passwordSignupFields: 'USERNAME_ONLY' + passwordSignupFields: 'USERNAME_AND_EMAIL' }); \ No newline at end of file diff --git a/client/main.js b/client/main.js index 35b51b95..9ff8e636 100644 --- a/client/main.js +++ b/client/main.js @@ -1,7 +1,12 @@ -window.intercomSettings = { - // TODO: The current logged in user's email address. - email: "john.doe@example.com", - // TODO: The current logged in user's sign-up date as a Unix timestamp. - created_at: 1234567890, - app_id: "9b593f5995da6d2bd8f418754c0411d55201258a" -}; +Tracker.autorun(function(){ + if (Meteor.user() && !Meteor.loggingIn()) { + var intercomSettings = { + name: Meteor.user().username, + email: Meteor.user().emails[0].address, + created_at: Math.round(Meteor.user().createdAt/1000), + favorite_color: _.sample(['blue','red','green','yellow']), + app_id: "4na10aq1" + }; + Intercom('boot', intercomSettings); + } +}); \ No newline at end of file diff --git a/lib/router.js b/lib/router.js index 7a296d4d..c46f8984 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3,7 +3,10 @@ Router.configure({ loadingTemplate: 'loading', notFoundTemplate: 'notFound', waitOn: function() { - return [Meteor.subscribe('notifications')] + return [ + Meteor.subscribe('currentUser'), + Meteor.subscribe('notifications') + ] } }); diff --git a/server/publications.js b/server/publications.js index 2a91210f..40523b64 100644 --- a/server/publications.js +++ b/server/publications.js @@ -11,12 +11,15 @@ Meteor.publish('singlePost', function(id) { return Posts.find(id); }); - Meteor.publish('comments', function(postId) { check(postId, String); return Comments.find({postId: postId}); }); Meteor.publish('notifications', function() { - return Notifications.find({userId: this.userId, read: false}); + return Notifications.find({userId: this.userId}); +}); + +Meteor.publish('currentUser', function() { + return Meteor.users.find(this.userId, {fields: {createdAt: 1}}); }); From d727dded4350a7dab23b156a16c26bd1401c0345 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Tue, 11 Jun 2013 10:44:45 +0900 Subject: [PATCH 16/17] Enabling secure mode. chapter17-3 --- client/main.js | 2 ++ packages/intercom/intercom_server.js | 7 +++++++ packages/intercom/package.js | 4 ++++ server/accounts.js | 8 ++++++++ server/publications.js | 2 +- 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 packages/intercom/intercom_server.js create mode 100644 server/accounts.js diff --git a/client/main.js b/client/main.js index 9ff8e636..b74e0556 100644 --- a/client/main.js +++ b/client/main.js @@ -5,6 +5,8 @@ Tracker.autorun(function(){ email: Meteor.user().emails[0].address, created_at: Math.round(Meteor.user().createdAt/1000), favorite_color: _.sample(['blue','red','green','yellow']), + user_id: Meteor.user()._id, + user_hash: Meteor.user().intercomHash, app_id: "4na10aq1" }; Intercom('boot', intercomSettings); diff --git a/packages/intercom/intercom_server.js b/packages/intercom/intercom_server.js new file mode 100644 index 00000000..091fba0a --- /dev/null +++ b/packages/intercom/intercom_server.js @@ -0,0 +1,7 @@ +var crypto = Npm.require('crypto'); + +IntercomHash = function(user, secret) { + var secret = new Buffer(secret, 'utf8') + return crypto.createHmac('sha256', secret) + .update(user._id).digest('hex'); +} \ No newline at end of file diff --git a/packages/intercom/package.js b/packages/intercom/package.js index 0141e481..c5126856 100644 --- a/packages/intercom/package.js +++ b/packages/intercom/package.js @@ -3,7 +3,11 @@ Package.describe({ summary: "Intercom package", version: '1.0.0' }); + Package.on_use(function (api) { api.versionsFrom('0.9.4'); api.add_files('intercom_loader.js', 'client'); + api.add_files('intercom_server.js', 'server'); + + api.export('IntercomHash', 'server'); }); \ No newline at end of file diff --git a/server/accounts.js b/server/accounts.js new file mode 100644 index 00000000..d791c212 --- /dev/null +++ b/server/accounts.js @@ -0,0 +1,8 @@ +Accounts.onCreateUser(function(options, user) { + user.intercomHash = IntercomHash(user, '12345678'); + + if (options.profile) + user.profile = options.profile; + + return user; +}); diff --git a/server/publications.js b/server/publications.js index 40523b64..d3cf1048 100644 --- a/server/publications.js +++ b/server/publications.js @@ -21,5 +21,5 @@ Meteor.publish('notifications', function() { }); Meteor.publish('currentUser', function() { - return Meteor.users.find(this.userId, {fields: {createdAt: 1}}); + return Meteor.users.find(this.userId, {fields: {createdAt: 1, intercomHash: 1}}); }); From c35d935ad2392dbd6dcdddda35b6fac3d64e63f4 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Tue, 11 Jun 2013 10:47:05 +0900 Subject: [PATCH 17/17] Displaying the inbox link. chapter17-4 --- client/main.js | 4 ++++ client/templates/includes/header.html | 3 +++ 2 files changed, 7 insertions(+) diff --git a/client/main.js b/client/main.js index b74e0556..98d030ba 100644 --- a/client/main.js +++ b/client/main.js @@ -7,6 +7,10 @@ Tracker.autorun(function(){ favorite_color: _.sample(['blue','red','green','yellow']), user_id: Meteor.user()._id, user_hash: Meteor.user().intercomHash, + widget: { + activator: '#Intercom', + use_counter: true + }, app_id: "4na10aq1" }; Intercom('boot', intercomSettings); diff --git a/client/templates/includes/header.html b/client/templates/includes/header.html index 5d6bfc43..3728cd7c 100644 --- a/client/templates/includes/header.html +++ b/client/templates/includes/header.html @@ -27,6 +27,9 @@
  • +
  • + Support +
  • {{/if}}