Permalink
Browse files

tweet counts!

  • Loading branch information...
1 parent 6f7e050 commit 2a18ef951ecf4698f2e3a5ebb03385173734b4e1 @rvagg rvagg committed Apr 24, 2012
View
17 index.html
@@ -382,26 +382,29 @@
line-height: 56px;
font-size: 40px;
}
- .title .gh {
+ .title .stat {
margin-top: -14px;
text-align: left;
font-size: 11px;
font-weight: bold;
height: 19px;
opacity: 0.5;
}
- .title .gh span {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAABECAYAAACI7LWAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlVJREFUeNrsls9LVFEUx9/zd+b4q5hFpmMYiCCI+0ChVbsWIQNC0m5WQaJEgrtauhVajTtdOaL/gLgzBJ9Ku8QfUJAQM+WiiPT5Pfq9cbpz38ygCS7egY+8e98533vfOXfu0Q/D0LuKVTnm0iAAolwgIefSRd6yA5IAOVAAGZBS71KcK9AnYd5pAXmxCtJWsBYZok/OFpCgQypnwwsTx0Ah9pY+h4z5KxBwi54ScFmWPhnGeD6rIH+amZYfZRI/CHbp122qsAeOQU8FlWuh754WMLZbgcC+q4yhKk26ghwkOE6ZHWyBUZDluBu8U+ssgWHwguNRxhy4ymjqHKiVV60DV1RGfZDMgckpgUAdpn8Okk7ic5Dn1vqsxEmJM3yXp2/Rb0F/TuBIYGC2rfFL/JxToI3P+fOEOcy/jvsgFogFYoH/KDAAZsEmmeWcV6q5CvfBCi+QL2AKTIADcAoWQYeO0cHPwDcGfwR14CHoA7fAjhJ+agtMcwVjY6BXjfvBGzX+AyYltoZf0ii3k5Ubnz3zlK1MWzX4aedgBBxxhW1wm59wDzSCfb77Cp64ciD0gHk6fgYzxORmwU5i1KUqLXwEPAINYB28BzvxrRwLxAKxwFUFkuAXWL6swF1QC44uIyDBC3xeK9eZbFp5Q5+AVy6fUsHtKvhllF9UcNIKruNuKhJIOlbeAB/YbMoKjDP4tZqbYz/M2P52FTpBF58/gTvskaYKTSxnZBXM6sIxGAaPwXfO/eb/DCVb2wm7sliNY66e48iDlFSOnmr/Yg908M3ojWcCDABDekqFJMdtvgAAAABJRU5ErkJggg==");
+ .title .stat span {
+ background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAABeCAYAAAAqoZR9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAupJREFUeNrsmM9rE0EUx3e1Vq3Gxh/k4K9EKkhBMN4FA5689SAlUNB4y0lUFFEQFPQovRU8pTd7MqJ/QIo3Rehq8WZJWlCwIIn2oIjt+n363fA6O7tZWws97INP2Z197zuT92ZnuuP6vu+sx7ZY2srAA6LcIT7byiFvGQHJgDrogCrIq2d5tnXokwmeaQF5MA3KRrAWOUufuikgQQtUrvl/TRw9hdgD+iwwpivgcYiOErBZjT5VxjguqyB/9jAt33ok/jSYo18hqEITLIGhBJUbpG9TCwQ2l0CgZSujr0pTTpCDDO/zwQjegjFQ430BPFT9PAMlcJn3Y4yZt5UxqLOnep42JlyojHoiBROmrgQ8NZlWTSSdxIugzaENG4mTElf5rE3f0Lugf45nSaAXDFvjxrzOebCX1+0/CbOYuxHrQSqQCqQC/1HgFJgAM2SCbU7c5iocBi+4gHwCd8ANMA9WwFNwSMfo4AvgC4Pfg35wHAyDnWBWCY+YAnfZQ2CXwAl1fxLcVve/wE2J7eMvGZDVyciNyz1zhVuZtq3gu5mDUbDIHt6BXfwJB8EAaPHZZ3DelgNhCDyh40fwiAS5mTKTGLWoyhY+Cs6AHeAVeAxm01U5FUgFUoH1CuTAD/B8rQIHwDawuBYBCZ7i9cteO5NJliv0Mrhm84kL3qeCr0T5RQXnjOB+jiaRQM7S8xvwmptNT4HrDL6l2ia5H1ZNf7MKR8BRXn8A+7lHBlXYzXJGViHoXVgCJXAOfGXbT/7PELu1LXNXFuuztG3nfeREyilHR23/Ysd0cLo3pgKpwGYSSGR4YyugAcbjnK7KCmRpL6rvhKZ8bEQJjCunimpvWM5TKjaBkuHU5NBt1u6uSEqgwC+0bMLUyBFpq1sF13XlkG3yH3JbDHXGhDX8ZFaKSuZIguBadyLxiK+gNLKhM8PVJsfE981hzyQctlSmaBu2bN33pDwxgTLRQhVybfPBPAJlhZzNeZb2W4ABABjYikWzwWlLAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
display: inline-block;
padding: 1px 8px 0 24px;
}
- .title .gh .w {
+ .title .stat .w {
background-position: 4px -24px;
}
- .title .gh .f {
+ .title .stat .f {
background-position: 4px -50px;
}
+ .title .stat .t {
+ background-position: 4px -75px;
+ }
li div.size {
float: right;
margin: 0 0 0 30px;
@@ -620,8 +623,8 @@ <h1 class="overlay">
function render(results){
var html=[], i=results.length;
while(i--) {
- results[i].gh = results[i].ghwatchers ? t('<div class="gh"><span class="w">{ghwatchers}</span><span class="f">{ghforks}</span></div>', results[i]) : ''
- html.push(t('<li><a href="{url}"><div class="size">{size}</div><div class="title"><h3>{name}</h3>{gh}</div>{description}</a></li>', results[i]))
+ results[i].stat = results[i].ghwatchers ? t('<div class="stat"><span class="w">{ghwatchers}</span><span class="f">{ghforks}</span><span class="t">{tweets}</span></div>', results[i]) : ''
+ html.push(t('<li><a href="{url}"><div class="size">{size}</div><div class="title"><h3>{name}</h3>{stat}</div>{description}</a></li>', results[i]))
}
$('results').innerHTML = html.join('');
}
View
4 lib/fetcher.js
@@ -1,11 +1,11 @@
var zip = require('zip')
, request = require('request')
- , requestPool = { maxSockets: 10 }
+ , requestPool = { maxSockets: 20 }
, unzip = function (zipEntry, buffer) {
var reader = zip.Reader(buffer)
- data = null
+ , data = null
// iterate through zipfile entries looking for the right name
reader.forEach(function(entry) {
if (zipEntry === entry._header.file_name) {
View
7 lib/gitstats.js
@@ -1,6 +1,6 @@
var request = require('request')
, githubSpecRegex = /^([^\/]+)\/(.*)$/
- , repoRegex = /github.com\/([\.\-\w]+)\/([^$/]+)/
+ , repoRegex = /github.com\/([\.\-\w]+)\/([^$\/]+)/
, GIT_API_REPO_URL = 'https://api.github.com/repos/{user}/{project}'
var GitStats = {
@@ -29,14 +29,14 @@ var GitStats = {
var data = JSON.parse(body)
if (!!data.forks && !!data.watchers) {
- this.success(lib, {
+ callback(null, {
forks: data.forks
, watchers: data.watchers
, url: data.html_url
, lastPush: data.pushed_at
//, user: user
//, project: project
- }, callback)
+ })
} else {
this.warn(lib, 'Looks like a GitHub project but can\'t get data from GitHub API')
callback()
@@ -48,7 +48,6 @@ var GitStats = {
module.exports.create = function (main, config) {
var gitStats = Object.create(GitStats)
- gitStats.success = main.gitSuccess.bind(main)
gitStats.warn = main.warn.bind(main)
gitStats.error = main.error.bind(main)
return gitStats
View
86 lib/main.js
@@ -33,55 +33,48 @@ var Main = {
return console.log(err.red)
this.data = data
- this.expectedTicks = data.length// * 2 // 2 ticks each lib, one for `process`, one for `gitstats`
+ this.expectedTicks = data.length
async.forEach(
data
- , this.tickWrap(this.processor.processLibrary, this.processor)
+ , this.processLibrary.bind(this)
, this.finish.bind(this)
)
}
- // wrap the function in another function that will increment 'ticks' and call progress() for us
- , tickWrap: function (fn, ctx) {
- return function (lib, callback) {
- fn.call(ctx, lib, function () {
- this.ticks++
- this.progress()
- callback()
- }.bind(this))
- }.bind(this)
- }
-
- // called when a library won't be included in the output, for whatever reason
- , error: function (lib, err, callback) {
- this.logger.log(ERROR, lib.name || 'UNKNOWN LIBRARY', err, lib.source ? lib.source : null)
- this.errorCount++
- callback()
- }
-
- // called when the library will be included but there is something odd
- , warn: function (lib, warning) {
- this.logger.log(WARNING, lib.name, warning)
- this.progress() // need to call this to redraw the progress bar after printing the warning
- }
-
- // called when the library is checked and sized and ready to pack into the output
- , success: function (lib, sizes, callback) {
- this.gitstats.processLibrary(lib, this.complete.bind(this, lib, sizes, callback))
+ , processLibrary: function (lib, callback) {
+ async.parallel(
+ {
+ sizes: this.processor.processLibrary.bind(this.processor, lib)
+ , ghstats: this.gitstats.processLibrary.bind(this.gitstats, lib)
+ , twstats: this.twitterstats.processLibrary.bind(this.twitterstats, lib)
+ }
+ , function (err, data) {
+ this.ticks++
+ if (err)
+ return callback(err)
+ this.complete(lib, data.sizes, data.ghstats, data.twstats, callback)
+ }.bind(this)
+ )
}
- , complete: function (lib, sizes, callback) {
+ , complete: function (lib, sizes, ghstats, twstats, callback) {
+ if (ghstats) {
+ lib.ghwatchers = strings.prettyLong(ghstats.watchers)
+ lib.ghforks = strings.prettyLong(ghstats.forks)
+ lib.ghlastpush = ghstats.lastPush
+ }
if (lib.ghlastpush && new Date(lib.ghlastpush).isBefore(this.ghLastPushCutoff)) {
this.warn(lib,'Too old! Last pushed to GitHub @ ' + new Date(lib.ghlastpush).toFormat('DD/MMM/YY') + ', ignoring')
callback()
} else {
// cleanup so we don't waste space
delete lib.ghlastpush
- delete lib.source
- delete lib.github
+ ;delete lib.source
+ ;delete lib.github
// overwrite the original size estimate with actual size
lib.size = strings.sizeToString(sizes.gzipped)
+ lib.tweets = strings.prettyLong(twstats.count)
this.atom.processLibrary(lib, function (err) {
if (err) {
@@ -93,21 +86,28 @@ var Main = {
SUCCESS
, lib.name
, ( 'raw: ' + strings.lpad(strings.sizeToString(sizes.raw), 8)
- + ', minified: ' + strings.lpad(strings.sizeToString(sizes.minified), 8)
- + ', gzipped: ' + strings.lpad(strings.sizeToString(sizes.gzipped), 8)
+ + ', minified: ' + strings.lpad(strings.sizeToString(sizes.minified), 7)
+ + ', gzipped: ' + strings.lpad(strings.sizeToString(sizes.gzipped), 6)
+ + ', watchers: ' + strings.lpad(ghstats ? lib.ghwatchers : '-', 4)
+ + ', forks: ' + strings.lpad(ghstats ? lib.ghforks : '-', 3)
+ + ', tweets: ' + strings.lpad(lib.tweets, 4)
))
callback()
}.bind(this))
}
}
- , gitSuccess: function (lib, ghData, callback) {
- if (ghData) {
- lib.ghwatchers = strings.prettyLong(ghData.watchers)
- lib.ghforks = strings.prettyLong(ghData.forks)
- lib.ghlastpush = ghData.lastPush
- }
- callback()
+ // called when a library won't be included in the output, for whatever reason
+ , error: function (lib, err, callback) {
+ this.logger.log(ERROR, lib.name || 'UNKNOWN LIBRARY', err, lib.source ? lib.source : null)
+ this.errorCount++
+ callback(err)
+ }
+
+ // called when the library will be included but there is something odd
+ , warn: function (lib, warning) {
+ this.logger.log(WARNING, lib.name, warning)
+ this.progress() // need to call this to redraw the progress bar after printing the warning
}
// called on error or success, to iterate our counter and write the output if we're all done
@@ -137,18 +137,18 @@ var Main = {
}.bind(this))
}
- // shortcut
, progress: function () {
this.logger.progress(this.ticks, this.expectedTicks)
}
-}
+ }
module.exports.create = function (config) {
var main = Object.create(Main)
main.input = require('./input').create(config.inFile)
main.output = require('./output').create(config.outFile)
main.processor = require('./processor').create(main, config)
main.gitstats = require('./gitstats').create(main, config)
+ main.twitterstats = require('./twitterstats').create(main, config)
main.atom = require('./atom')
main.logger = require('./logger').create(config)
main.ghLastPushCutoff = new Date().addMonths(-(config.githubLastPushCutoffMonths))
View
7 lib/processor.js
@@ -36,7 +36,7 @@ var Processor = {
if (!/^(http|ftp)/.test(source) && /function/.test(source)) {
lib.novalidate = true
data += source
- callback()
+ return callback()
} else {
// source is a zip with a bang-path to the file within the zip?
if (match = source.match(/^(.*\.zip)!\/(.*$)/)) {
@@ -76,15 +76,14 @@ var Processor = {
return this.error(lib, insane + ', ignoring', callback)
// holy moly! we got here?
- this.success(lib, sizes, callback)
+ callback(null, sizes)
}
}
module.exports.create = function (main, config) {
var processor = Object.create(Processor)
processor.error = main.error.bind(main)
- processor.success = main.success.bind(main)
processor.warn = main.warn.bind(main)
processor.validator = require('./validator').create(config)
return processor
-}
+}
View
16 lib/sizer.js
@@ -12,16 +12,14 @@ module.exports = function(source, callback) {
uglifyParser.parse(source))))
gzip(minified, function(err, data) {
- if (err) callback(err)
- else {
- callback(null, {
- raw: source.length
- , minified: minified.length
- , gzipped: data.length
- })
- }
+ if (err) return callback(err)
+ callback(null, {
+ raw: source.length
+ , minified: minified.length
+ , gzipped: data.length
+ })
})
} catch (ex) {
- callback && callback(ex)
+ callback(ex)
}
}
View
33 lib/twitterstats.js
@@ -0,0 +1,33 @@
+var request = require('request')
+ , TWITTER_API_URL = 'http://urls.api.twitter.com/1/urls/count.json?url={url}'
+
+var TwitterStats = {
+ processLibrary: function (lib, callback) {
+ request(
+ TWITTER_API_URL.replace('{url}', encodeURIComponent(lib.url))
+ , function (err, response, body) {
+ if (err)
+ return this.error(
+ lib
+ , 'Error requesting tweet count from Twitter for ' + lib.url + ': ' + err
+ , callback
+ )
+ var data = JSON.parse(body)
+
+ if (typeof data.count == 'number') {
+ callback(null, data)
+ } else {
+ this.warn(lib, 'Couldn\'t get tweet count from Twitter API')
+ callback()
+ }
+ }.bind(this)
+ )
+ }
+}
+
+module.exports.create = function (main, config) {
+ var twitterStats = Object.create(TwitterStats)
+ twitterStats.warn = main.warn.bind(main)
+ twitterStats.error = main.error.bind(main)
+ return twitterStats
+}
View
BIN resources/github.png
Deleted file not rendered
View
BIN resources/github.psd
Deleted file not rendered
View
BIN resources/icons.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN resources/icons.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2a18ef9

Please sign in to comment.