Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeline Collection #398

Open
wants to merge 58 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
aec0e73
attempting a clean merge of Timeline, some very funky things happened…
quartzjer Oct 2, 2011
98ce09e
cleaning up merge tirds
quartzjer Oct 2, 2011
2163f54
Merge remote-tracking branch 'upstream/master'
quartzjer Oct 14, 2011
babe16e
Merge remote-tracking branch 'upstream/master'
quartzjer Oct 21, 2011
007866e
Merge remote-tracking branch 'upstream/master'
quartzjer Oct 21, 2011
2ffc000
lots of fixes, pretty solid response support, and early link-based de…
quartzjer Nov 2, 2011
c5efafd
fixes to make links more usable
quartzjer Nov 2, 2011
503269f
Merge remote-tracking branch 'upstream/master'
quartzjer Nov 2, 2011
b33cb83
make a bit more sane, still could use a nice refactoring
quartzjer Nov 2, 2011
f321b0a
adding instagram support and checking text-based dedup
quartzjer Nov 5, 2011
3b6c761
instagram merging and from bugfix
quartzjer Nov 5, 2011
99bc058
fix a regression
quartzjer Nov 5, 2011
8a0b798
cleaning up the api endpoints
quartzjer Nov 6, 2011
9fbbc00
added twitter rt and reply support, lots of api cleanup and bugfixing
quartzjer Nov 6, 2011
09cf8ce
more timeline fixes and start of a simple viewer
quartzjer Nov 7, 2011
6e887ea
better update processing and adding ref resolving
quartzjer Nov 7, 2011
d27ed1c
when a bad response happens, handle the error
quartzjer Nov 7, 2011
1f48e84
Merge remote-tracking branch 'upstream/master'
quartzjer Nov 7, 2011
2a13169
ooh, 4sq shouts
quartzjer Nov 7, 2011
d0cc404
take both kinds of ids
quartzjer Nov 7, 2011
eaf49d8
sort default by time, and handle ids better
quartzjer Nov 7, 2011
66f4a23
more bugfixes, and process links on an update
quartzjer Nov 7, 2011
8deab93
simple viewer updates
quartzjer Nov 7, 2011
eb67142
Merge remote-tracking branch 'upstream/master'
quartzjer Nov 13, 2011
18196af
wasnt handling real link events properly, fixed
quartzjer Nov 14, 2011
d8098ab
tiny safety check
quartzjer Nov 18, 2011
bf72faf
fix merge conflict
quartzjer Nov 18, 2011
75f5753
trying to add some more query options to test
quartzjer Nov 18, 2011
fdc7c8a
merge conflict
quartzjer Dec 14, 2011
03a2638
updated Timeline collection to handle idrs
smurthas Dec 16, 2011
de5a197
Merge pull request #1 from smurthas/timeline
quartzjer Dec 22, 2011
cc4e6f7
tweak
quartzjer Dec 22, 2011
7fa5846
Merge branch 'master' of github.com:quartzjer/Locker
quartzjer Dec 22, 2011
c150cf7
merge conflict
quartzjer Dec 24, 2011
af6fabc
general cleanups
quartzjer Dec 26, 2011
754809c
converting fixtures to new event format
quartzjer Dec 27, 2011
fc931d7
fixed up and tested all the fixtures, very close
quartzjer Dec 28, 2011
cd4a4f9
added instagram-4sq deduping (plus time based), reorgd the code some,…
quartzjer Dec 28, 2011
8ef2d4a
add facebook story support
quartzjer Dec 28, 2011
ef1961c
easier to test it, can expand responses
quartzjer Dec 28, 2011
d0ccd95
more facebook fuzzies
quartzjer Dec 28, 2011
e629286
Merge remote-tracking branch 'upstream/master'
quartzjer Dec 28, 2011
1704fd5
adding event generation support
quartzjer Dec 28, 2011
6888fa5
letting things happen more fluidly, and enabling deep update again
quartzjer Dec 28, 2011
005eb70
safely serialize things, if stuff truly happens in parallel the dedup…
quartzjer Dec 29, 2011
4091986
Merge remote-tracking branch 'upstream/master'
quartzjer Jan 19, 2012
0828ea3
bring up to locker upstream current, fix logger references and generi…
quartzjer Jan 19, 2012
46864fc
updating test app and removing synclet depreciated code
quartzjer Jan 19, 2012
d4bcfa3
Merge remote-tracking branch 'upstream/master'
quartzjer Jan 28, 2012
aa565f5
basic work load scheduling management signals by core
quartzjer Jan 31, 2012
da31166
in-progress reorg for dynamic updating
quartzjer Feb 2, 2012
92c035a
background syncing seems to be working now
quartzjer Feb 2, 2012
8c5f3d3
better status update in test app, update links to enable querying of …
quartzjer Feb 2, 2012
05c6766
merge conflict fix
quartzjer Feb 2, 2012
8f135e9
Merge remote-tracking branch 'upstream/master'
quartzjer Feb 4, 2012
accf22d
Merge remote-tracking branch 'upstream/master'
quartzjer Feb 4, 2012
860f739
starting to migrate to sqlite-cursor since mongo can't handle the tim…
quartzjer Feb 4, 2012
15285da
merge conflict again ugh
quartzjer Mar 7, 2012
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file added Apps/HelloTimeline/img/facebook.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Apps/HelloTimeline/img/foursquare.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Apps/HelloTimeline/img/instagram.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Apps/HelloTimeline/img/twitter.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions Apps/HelloTimeline/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Timeline Viewer</title>

<style type="text/css">
body {
margin: 40px;
}

h1 {
font-size: 24pt;
text-align: center;
margin-bottom:40px;
}
</style>

</head>

<body>
<span id='status'></span>
<h1>Forever Timeless</h1>
<ul id="test" class="items"></ul>
<button id="moar">Load more</button>

</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="script.js"></script>
<script src='/static/js/viewer.js'></script> <!-- optional, only loaded when hosted, common locker viewer utilities -->
</html>
31 changes: 31 additions & 0 deletions Apps/HelloTimeline/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"author": "Singly, Inc. <nerds@singly.com>",
"name": "hellotimeline",
"description": "A simple way to view your timeline.",
"version": "0.0.1",
"homepage": "https://github.com/LockerProject/locker",
"repository": {
"type": "app",
"title": "Hello Timeline",
"status": "stable",
"static": true,
"hidden": true,
"handle": "hellotimeline",
"update": true,
"uses": {
"services": [
"facebook",
"foursquare",
"instagram",
"twitter"
]
},
"github": "https://github.com/LockerProject/locker",
"url": ""
},
"engines": {
"node": ">=0.4.9"
},
"dependencies": {},
"devDependencies": {}
}
103 changes: 103 additions & 0 deletions Apps/HelloTimeline/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
var baseUrl = false;

$(document).ready(function() {
if(baseUrl === false) window.alert("Couldn't find your locker, you might need to add a config.js (see dev.singly.com)");
});

var offset=0;
$(function() {
// be careful with the limit, some people have large datasets ;)
loadStuff();
loadStatus();
$("#moar").click( function(){
offset += 50;
loadStuff();
});
});

var max = 20;
function loadStatus()
{
$.getJSON(baseUrl + '/Me/timeline/state',{}, function(data) {
if(!data) return $("#status").text("timeline failed :(");
if(data.ready == 1) return $("#status").text("");
var name = (data.current) ? data.current.type + " at "+data.current.offset : "";
$("#status").text("timeline is indexing "+name);
if(max-- <= 0) return $("#status").text("plz reload");
window.setTimeout(loadStatus, 10000); // poll for a bit
});
}

function loadStuff(){
$.getJSON(baseUrl + '/Me/timeline/',{limit:50, offset:offset}, function(data) {
if(!data || !data.length) return;
var html = '<h4>'+ago(data[0].first)+'</h4>';
for(var i in data)
{
var p = data[i];
p.refs.forEach(function(ref){ html += icon(ref); });
var resp = p.comments + p.ups;
html += "<i>"+p.from.name+"</i>: <span title='"+JSON.stringify(p,null,'\t')+"'>" + p.text + '</span>';
html += ' <a href="'+baseUrl+'/Me/timeline/ref?id='+escape(p.ref)+'">.js</a>';
if(resp > 0) html += "<div id='"+p.id+"'><a href='javascript:loadResp(\""+p.id+"\")'>["+resp+"]</a></div> ";
html += '<hr>';
}
$("#test").append(html);
});
}

function loadResp(id)
{
$.getJSON(baseUrl + '/Me/timeline/getResponses',{item:id}, function(data) {
$("#"+id).html("");
if(!data || !data.length) return;
var ups = " ups: ";
var coms = "";
for(var i in data)
{
var r = data[i];
if(r.type == "up")
{
ups += icon(r.ref);
ups += " "+r.from.name+", ";
}
if(r.type == "comment")
{
coms += "<br>"
coms += icon(r.ref);
coms += " "+r.from.name+": ";
coms += r.text;
}
}
$("#"+id).append(ups+coms);
});
}

function icon(ref)
{
var start = ref.indexOf('//')+2;
var net = ref.substr(start,ref.indexOf('/',start+2)-start);
if(net == "links") return "";
return "<img src='img/"+net+".png' width=16 height=16 />";

}

function ago(at)
{
var tip = '';
var timeDiff = Date.now() - at;
if (timeDiff < 60000) {
tip += 'last updated less than a minute ago';
} else if (timeDiff < 3600000) {
tip += 'last updated ' + Math.floor(timeDiff / 60000) + ' minutes ago';
} else if (timeDiff < 43200000) {
tip += 'last updated over an hour ago';
} else if (timeDiff < 43800000) {
tip += 'last updated ' + Math.floor(timeDiff / 3600000) + ' hours ago';
} else {
var d = new Date;
d.setTime(at);
tip += 'last updated ' + d.toString();
}
return tip;
}
1 change: 1 addition & 0 deletions Apps/prolific_posters
Submodule prolific_posters added at 591b54
26 changes: 26 additions & 0 deletions Collections/Links/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,32 @@ module.exports = function(app, lockerInfo) {
});
});

// get just encounters raw!
// expose way to get raw links and encounters
app.get('/encounters', function(req, res) {
var options = {sort:{"_id":-1}};
if(!req.query["all"]) options.limit = 20; // default 20 unless all is set
if (req.query.limit) {
options.limit = parseInt(req.query.limit);
}
if (req.query.offset) {
options.offset = parseInt(req.query.offset);
}
if(req.query['stream'] == "true")
{
res.writeHead(200, {'content-type' : 'application/jsonstream'});
}
var results = [];
dataStore.getEncounters(options, function(item) {
if(req.query['stream'] == "true") return res.write(JSON.stringify(item)+'\n');
results.push(item);
}, function(err){
if(err) logger.error(err);
if(req.query['stream'] == "true") return res.end();
return res.send(results);
});
});

}

function isFull(full) {
Expand Down
14 changes: 9 additions & 5 deletions Collections/Links/dataIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ var encounterQueue = async.queue(function(e, callback) {
async.forEach(urls,function(u,cb){
linkMagic(u,function(link){
// make sure to pass in a new object, asyncutu
dataStore.addEncounter(lutil.extend(true,{orig:u,link:link},e), function(err,doc){
dataStore.addEncounter(lutil.extend(true,{orig:u,link:link.link},e), function(err,doc){
if(err) return cb(err);
dataStore.updateLinkAt(doc.link, doc.at, function(err, obj){
if(err) return cb(err);
obj.encounters = [doc]; // include this encounter!
locker.ievent(lutil.idrNew("link","links",obj.id),obj,"update"); // let happen independently
cb();
});
Expand Down Expand Up @@ -140,6 +141,7 @@ function linkMagic(origUrl, callback){
dataStore.checkUrl(origUrl,function(linkUrl){
if(linkUrl) return callback(linkUrl); // short circuit!
// new one, expand it to a full one
var linkUrl;
util.expandUrl({url:origUrl},function(u2){linkUrl=u2},function(){
// fallback use orig if errrrr
if(!linkUrl) {
Expand All @@ -149,7 +151,7 @@ function linkMagic(origUrl, callback){
// does this full one already have a link stored?
dataStore.getLinks({link:linkUrl,limit:1},function(l){link=l},function(err){
if(link) {
return callback(link.link); // yeah short circuit dos!
return callback(link); // yeah short circuit dos!
}
// new link!!!
link = {link:linkUrl};
Expand All @@ -164,11 +166,13 @@ function linkMagic(origUrl, callback){
if (!link.at) link.at = Date.now();
dataStore.addLink(link,function(err, obj){
locker.ievent(lutil.idrNew("link","links",obj.id),obj); // let happen independently
callback(link.link); // TODO: handle when it didn't get stored or is empty better, if even needed
callback(link); // TODO: handle when it didn't get stored or is empty better, if even needed
// background fetch oembed and save it on the link if found
oembed.fetch({url:link.link, html:html}, function(e){
if(!e) return;
dataStore.updateLinkEmbed(link.link, e, function(){});
dataStore.updateLinkEmbed(link.link, e, function(err, obj){
locker.ievent(lutil.idrNew("link","links",obj.id),obj,"update");
});
});
});
});
Expand Down Expand Up @@ -205,7 +209,7 @@ function getEncounterTwitter(event)
{
var tweet = event.data;
var txt = (tweet.retweeted_status && tweet.retweeted_status.text) ? tweet.retweeted_status.text : tweet.text;
var e = {id:tweet.id
var e = {id:tweet.id_str
, idr:event.idr
, network:"twitter"
, text: txt + " " + tweet.user.screen_name
Expand Down
4 changes: 2 additions & 2 deletions Collections/Links/dataStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ exports.checkUrl = function(origUrl, callback) {
if(err) return callback();
cursor.nextObject(function(err, item){
if(err || !item || !item.link) return callback();
callback(item.link);
callback(item);
});
});
}
Expand All @@ -93,7 +93,7 @@ exports.getLinks = function(arg, cbEach, cbDone) {
linkCDS.findWrap(f,arg,cbEach,cbDone);
}

exports.getFullLink = function(id, cbDone) {
exports.getLink = function(id, cbDone) {
var link = null;
exports.getLinks({link:id}, function(l) { link = l; }, function() { cbDone(link); });
}
Expand Down
19 changes: 19 additions & 0 deletions Collections/Timeline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
The "feeds" collection is all of the socially shared items across any service, facebook newsfeed, twitter timeline, foursquare recents, etc.

It consists of a primary type called an "item" which can have an array of "responses" that are comments, likes, retweets, etc from other people.

The goal is to dedup cross-posts to multiple networks from one person, particularly things like a foursquare checkin.


Notes:

id references and keys
cross-collection reference storage with links
link based dedup of foursquare
dedup uses keys as guids across networks and for text matching variations
/update takes type arg for individual updates
idrs as via, no original storage
prioritization scheme in merging items
generic from object, list of froms
references array of all sources
generalized responses and top-level statistics