# HG changeset patch # User Mathias Gebbe # Date 1409244039 -7200 # Node ID 3e3fa35e3ce23e8d0e06bf619269a4f0f16c073b # Parent 34cfa565f565794384ca4dc93718405945b8e56e twitter sync likes, recommend mongodb configure pump2twitter, twitter2pump in webui diff -r 34cfa565f565 -r 3e3fa35e3ce2 index.js_to_pump.io-client-app_lib_routes --- a/index.js_to_pump.io-client-app_lib_routes Tue Jul 29 16:06:05 2014 +0200 +++ b/index.js_to_pump.io-client-app_lib_routes Thu Aug 28 18:40:39 2014 +0200 @@ -23,6 +23,7 @@ User = require("../models/user"), Host = require("../models/host"), Usermap = require("../../../../lib/usermap"), + //Usermap = require("../../../../src/usermap"), RequestToken = require("../models/requesttoken"), RememberMe = require("../models/rememberme"), site = require("../models/site"); @@ -42,17 +43,21 @@ var hosts, users, bank = Host.bank(); if (req.user) { - var fb=false, gp=false, tw=false; + var fb=false, gp=false, tw=false, twfromesn=true, twtoesn=true; Usermap.search({ user_pumpio: req.user.id }, function(err, result) { if(err) res.render('login', { pageTitle: "pumpbridge" }); _.each(result, function(um) { if ( um.id.indexOf('@facebook') != -1 ) fb=true; - if ( um.id.indexOf('@twitter') != -1 ) tw=true; + if ( um.id.indexOf('@twitter') != -1 ) { + tw=true; + if(typeof um.fromesn != "undefined") twfromesn = um.fromesn; + if(typeof um.toesn != "undefined") twtoesn = um.toesn; + } if ( um.id.indexOf('@google') != -1 ) gp=true; }); - res.render('index', { pageTitle: "pumpbridge" , user: req.user, usermapfb: fb, usermapgp: gp, usermaptw: tw}); + res.render('index', { pageTitle: "pumpbridge" , user: req.user, usermapfb: fb, usermapgp: gp, usermaptw: tw, twfromesn: twfromesn, twtoesn: twtoesn}); }); } else { res.render('login', { pageTitle: "pumpbridge" }); diff -r 34cfa565f565 -r 3e3fa35e3ce2 pumpbridge.json.example --- a/pumpbridge.json.example Tue Jul 29 16:06:05 2014 +0200 +++ b/pumpbridge.json.example Thu Aug 28 18:40:39 2014 +0200 @@ -1,6 +1,6 @@ { -"driver": "redis", -"params": {"host":"localhost","database":14,"port":6379}, +"driver": "mongodb", +"params": {"host":"localhost","dbname": "pumpbridge"}, "secret": "takeanother", "port": 443, "bounce": true, diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/facebook.coffee --- a/src/facebook.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/facebook.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -450,7 +450,6 @@ https.get(options, (res) -> #console.log "Got response: " + res.statusCode - res.on "data", (chunk) -> data += chunk return diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/google.coffee --- a/src/google.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/google.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -1,7 +1,7 @@ # Copyright (C) 2014 by Intevation GmbH # Author: Mathias Gebbe # -# This file is Free Software under the Apache License, Version 2.0; +# This file is Free Software under the Apache License, Version 3.0; # and comes with NO WARRANTY! # See the documentation coming with pumpbridge for details. diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/pumpio.coffee --- a/src/pumpio.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/pumpio.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -140,6 +140,33 @@ callback null, result return +getLikes = (user, callback) -> + id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) + server = user.user_ESN.substr(user.user_ESN.indexOf('@')+1,user.user_ESN.length) + token = user.oauth_token.substr(0,user.oauth_token.indexOf(';')) + secret = user.oauth_token.substr(user.oauth_token.indexOf(';')+1,user.oauth_token.length) + # https://io.intevation.de/api/user/mgebbe/favorites + url = "https://" + server + "/api/user/" + id + "/favorites" + # get tokens and ask pump.io api for userinformation then update userdb + async.waterfall [ + (callback) -> + Host.search {hostname: server}, callback + (host,callback) -> + # get host from db + host = JSON.stringify(host) + host = JSON.parse(host) + #console.log JSON.stringify host + oauth = new OAuth.OAuth(host[0].request_token_endpoint, host[0].access_token_endpoint, host[0].client_id, host[0].client_secret, "1.0A", null, "HMAC-SHA1") + oauth.get url, token, secret, callback + ], (err,result) -> + if err + callback null, null + else + callback null, (result) + return + + + isPublicActivity = (act) -> recip = [] _.each [ @@ -159,4 +186,5 @@ exports.getUserFeed = getUserFeed exports.getUser = getUser exports.getNote = getNote +exports.getLikes = getLikes exports.postUser = postUser diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/restartSYNC.sh --- a/src/restartSYNC.sh Tue Jul 29 16:06:05 2014 +0200 +++ b/src/restartSYNC.sh Thu Aug 28 18:40:39 2014 +0200 @@ -1,8 +1,8 @@ #!/bin/bash -cd /home/pumpbridge/pumpbridge/lib +cd /home/pumpbridge/pumpbridge/src -until node syncALONE.js; do +until coffee syncALONE.coffee; do echo "sync crashed with exit code $?. Respawning.." >&2 sleep 1 done diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/routes.coffee --- a/src/routes.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/routes.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -50,6 +50,10 @@ twdelete = req.body.twdelete + twmode = req.body.twmode + if(req.body.twtoesn?) then twtoesn=true else twtoesn=false + if(req.body.twfromesn?) then twfromesn=true else twfromesn=false + # create/update userdb entrys # SET THE CONNECTION BETWEENS PUMPIO AND ESN-ACCOUNT (facebook or google) @@ -104,6 +108,19 @@ saveUsermap(pumpid,fbid,token,fbtoken, (err, result) -> console.log 'fbsave.') + #### Twitter MODUS ### + if (twmode?) + console.log "mod tw account" + async.waterfall [ + (callback) -> + Usermap.search {user_pumpio: twmode}, callback + (result, callback) -> + _.each result, (um) -> + if um.user_ESN.indexOf('@twitter') isnt -1 + saveUsermapSelect(um.user_pumpio, um.user_ESN, um.oauth_token, um.extra_token,twfromesn,twtoesn,callback) + return + ], (err, result) -> + if (fbdelete?) console.log "delete fb account" async.waterfall [ @@ -156,6 +173,25 @@ saveMap.save (cb) -> #console.log 'saved.' callback null, saveMap + return + +# update or create usermap +saveUsermapSelect = (pumpid, esnid, esntoken, extra, fromesn, toesn, callback) -> + saveMap = new Usermap( + id : Usermap.key(pumpid,esnid) + user_pumpio : pumpid + user_ESN : esnid + oauth_token : esntoken + extra_token : extra + fromesn : fromesn + toesn: toesn + created : Date.now() + ) + saveMap.save (cb) -> + #console.log 'saved.' + callback null, saveMap + return + # only create and not update usermap createUsermap = (pumpid,esnid,esntoken) -> diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/sync.coffee --- a/src/sync.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/sync.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -112,6 +112,7 @@ if network is 'twitter' post.text = post.text.replace(/(http[s]?:\/\/[^ ]+)/ig,'$1<\/a>') + parsed = " " + post.user.name + " writes via " + network + " at " + post.created_at + ":

" + post.text _.each post.entities.media, (attachment) -> parsed += "
" diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/syncALONE.coffee --- a/src/syncALONE.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/syncALONE.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -39,9 +39,14 @@ try Usermap.scan ((user) -> if user.id.indexOf('@twitter') isnt -1 - console.log "start sync for twitter user" - Twitter.syncToESN(user) - Twitter.syncFromESN(user) + # do if true or undefined + unless user.toesn is false + console.log "start sync TOESN for twitter user" + Twitter.syncToESN(user) + unless user.fromesn is false + console.log "start sync FROMESN for twitter user" + Twitter.syncFromESN(user) + Twitter.postLike(user) ), (err) -> catch err console.log 'Twitter Error!' + err diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/twitter.coffee --- a/src/twitter.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/twitter.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -117,7 +117,7 @@ (feed, callback) -> return if not feed? ti = new Date().getTime() - interval - async.eachLimit feed.items, 5, ((post, callback) -> + async.eachLimit feed.items, 1, ((post, callback) -> # do for each post ts = Date.parse(post.updated) if (ts >= ti and post.verb is "post" or post.verb is "share") and (post.object.objectType is "note" or post.object.objectType is "image") and (Pump.isPublicActivity(post)) and (typeof post.object.deleted is "undefined") @@ -185,13 +185,13 @@ return if not data? or data.length is 0 console.log "data isnt empty for " + me ti = (new Date().getTime() - interval) - async.eachLimit data, 1, ((tweet, cb) -> + async.eachLimit data, 3, ((tweet, cb) -> async.waterfall [ (callback) -> - FromESN.search {uid: tweet.id + "@twitter_to_" + me}, callback + FromESN.search {uid: tweet.id_str + "@twitter_to_" + me}, callback (result, callback) -> return if result.length isnt 0 or tweet.user.id_str is id - console.log "new tweet found" + console.log "tweet found" twitterdate = new Date(Date.parse(tweet.created_at.replace(/( +)/, " UTC$1"))) ts = Date.parse(twitterdate) if (ts >= ti) @@ -208,16 +208,16 @@ console.log "parse err " + err return FromESN.create - postid: tweet.id + "@twitter" + postid: tweet.id_str + "@twitter" sourceUser: tweet.user.id - sourcePost: 'https://twitter.com/'+tweet.user.name+"/status/" + tweet.id + sourcePost: 'https://twitter.com/'+tweet.user.screen_name+"/status/" + tweet.id_str pumpPost: pumppost.object.id recipientUser: me created: Date.now() , callback ], (err, result) -> console.log "post a tweet to user " + me - cb() + cb ), (err) -> if (err) console.log "Error: " + err @@ -225,6 +225,45 @@ console.log "done FromESN twitter user " + me return + postLike: (user) -> + i = 0 + me = user.user_pumpio + id = user.user_ESN.substr(0,user.user_ESN.indexOf('@')) + token = user.oauth_token + secret = user.extra_token + twit = new twitter( + consumer_key: client_id + consumer_secret: client_secret + access_token_key: token + access_token_secret: secret + ) + console.log "try 2 find twitter likes for " + me + async.waterfall [ + (callback) -> + Usermap.search {id: me + '_to_' + me}, callback + (pumpuser, callback) -> + Pump.getLikes(pumpuser[0], callback) + (likearray, callback) -> + return if not (likearray?) or likearray.length is 0 + likes = JSON.parse(likearray) + return if not (likes?) or likes.items.length is 0 + async.each likes.items,((note, cb) -> + async.waterfall [ + (callback) -> + FromESN.search {recipientUser: me, pumpPost: note.id}, callback + (fromesn, callback) -> + if (fromesn?) and fromesn.length isnt 0 and fromesn[0].sourcePost.indexOf('twitter.com') isnt -1 + #console.log fromesn[0] + obj = fromesn[0].postid.substr(0,fromesn[0].postid.indexOf('@')) + twit.post "/favorites/create.json", + id: obj + , (data) -> + console.log "Twitter " + obj + " liked" + ], (err, result) -> + ), (err) -> + ], (err, result) -> + return + getOAuth: (site) -> new OAuth(request_token_endpoint, access_token_endpoint, client_id, client_secret, "1.0", site.url("/authorized-for-twitter"), "HMAC-SHA1", null, # nonce size; use default "User-Agent": site.userAgent() diff -r 34cfa565f565 -r 3e3fa35e3ce2 src/usermap.coffee --- a/src/usermap.coffee Tue Jul 29 16:06:05 2014 +0200 +++ b/src/usermap.coffee Thu Aug 28 18:40:39 2014 +0200 @@ -17,6 +17,8 @@ "user_ESN" "oauth_token" "extra_token" + "fromesn" + "toesn" "created" ] indices: [ diff -r 34cfa565f565 -r 3e3fa35e3ce2 views/index.jade --- a/views/index.jade Tue Jul 29 16:06:05 2014 +0200 +++ b/views/index.jade Thu Aug 28 18:40:39 2014 +0200 @@ -42,7 +42,7 @@ 'response_type' : 'code', 'accesstype': 'offline', 'approvalprompt': 'force', - 'cookiepolicy': "https://server.example", + 'cookiepolicy': "https://pumpbridge.me", 'requestvisibleactions': 'http://schemas.google.com/AddActivity', 'scope': 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email' }); @@ -128,6 +128,16 @@ var twstatus = getCookie('twitterid') if (twstatus != "") $('#twstatus').html(' ' + getCookie('twitteruser') + ''); + var twfromesn = "#{twfromesn}"; + var twtoesn = "#{twtoesn}"; + + + if (twtoesn == "true") $("#twtoesn").prop("checked", true); + else $("#twtoesn").prop("checked", false); + + if (twfromesn == "true") $("#twfromesn").prop("checked", true); + else $("#twfromesn").prop("checked", false); + $.ajaxSetup({ cache: true }); @@ -222,11 +232,23 @@ #tw-info.tw-info i(id='twstatus') not logged in br + if usermaptw + form(class='',action='/bridge',method='post') + input(id='twmode',name='twmode',hidden='true',value=user.id) + input(id='twtoesn',name='twtoesn',type='checkbox',value='pump2twitter') + | pump2twitter + br + input(id='twfromesn',name='twfromesn',type='checkbox',value='twitter2pump') + | twitter2pump + br + button(id='twsavemode',type='submit',class='btn btn-default btn-xs') + | save modus + br form(class='',action='/bridge',method='post') input(id='twdeleted',name='twdelete',hidden='true',value=user.id) button(id='twdeletebutton',type='submit',class='btn btn-default btn-xs') | delete credentials - button(id='twloginbutton2',name='twloginbutton2',type='submit',class='btn btn-default btn-xs',onClick='location.href="/add-account"') + button(id='twloginbutton2',name='twloginbutton2',type='submit',class='btn btn-default btn-xs',onClick='location.href="/add-account"') | add credentials form(class='',action='/bridge',method='post') input(id='pumpid',name='pumpid',hidden='true',value=user.id) @@ -238,9 +260,7 @@ input(id='gpid',name='gpid',hidden='true') input(id='gptoken',name='gptoken',hidden='true',size=100) br - | you need to extra save the credentials - br - | for facebook and googleplus + | you need to extra save the credentials (facebook / google+) br input(type='submit',class='btn btn-default',value='save credentials') .footer @@ -252,6 +272,6 @@ p. pumpbridge is Free Software and available under the Apache License 2.0.
- visit https://wald.intevation.org/projects/pumpbridge for more informations! + visit https://wald.intevation.org/projects/pumpbridge for more information!
pumpbridge is hosted and operated by Mathias Gebbe (Contact)
diff -r 34cfa565f565 -r 3e3fa35e3ce2 views/login.jade --- a/views/login.jade Tue Jul 29 16:06:05 2014 +0200 +++ b/views/login.jade Thu Aug 28 18:40:39 2014 +0200 @@ -4,7 +4,7 @@ title= pageTitle link(rel='stylesheet', href='/stylesheets/style.css') link(rel='stylesheet', href='/stylesheets/bootstrap.min.css') - link(rel='icon', href='/images/favicon.ico',type='image/x-icon') + link(rel='icon', href='/images/favicon.ico',type='image/x-icon') body block content @@ -14,7 +14,7 @@ h1(class='headline') pumpbridge.
connecting social networks form(action='/login', method='post') |Login with your pump.io account (WebFinger ID) to get started. - br + br |(No pump.io account yet? Try it!) br input(class='login',id='webfinger',name='webfinger',size=30,type='text',placeholder='user@server.example') @@ -27,6 +27,6 @@ p. pumpbridge is Free Software and available under the Apache License 2.0.
- visit https://wald.intevation.org/projects/pumpbridge for more informations! + visit https://wald.intevation.org/projects/pumpbridge for more information!
pumpbridge is hosted and operated by Mathias Gebbe (Contact)