var twitter = {};
var accounts = store.get("accounts") || [];
twitter.version = 4;
twitter.consumerKey = "JPRtaafuUN3zcqFjxXCbJQ";
twitter.consumerSecret = "VOT7yrQ5AZ57QzqljTRRjwylf5KPUfWoUujibZMEw";
twitter.growlId = "bmnmjejkpblabmgiehpgjpiglmnhocoi";
twitter.setup = function () {
localStorage.removeItem("timelineCache");
var a = $.get("https://api.twitter.com/1/help/test.json", function (c) {
OAuth.correctTimestamp(new Date(a.getResponseHeader("Date")).getTime() / 1000);
for (var b in accounts) {
if (!accounts[b].accessToken) {
accounts.splice(b, 1);
updateAccounts();
document.location.reload()
} else {
if (accounts.length == 1) {
accounts[b]["default"] = true
}
twitter.loadAccount(accounts[b])
}
}
});
twitter.messagesDB = window.webkitIndexedDB.open("messagesDB");
twitter.messagesDB.onsuccess = function () {
twitter.messagesDB = twitter.messagesDB.result;
if (twitter.messagesDB.version == "") {
var b = twitter.messagesDB.setVersion(1);
b.onsuccess = function (f) {
for (var d in accounts) {
var c = twitter.messagesDB.createObjectStore(accounts[d].id, {
keyPath: "id_str"
});
c.createIndex("sender_id", "sender_id", {
unique: false
});
c.createIndex("recipient_id", "recipient_id", {
unique: false
})
}
}
}
}
};
twitter.oauthRequest = function (d) {
accessor = {
consumerSecret: twitter.consumerSecret
};
message = {
action: d.url,
method: d.method || "GET",
parameters: [
["oauth_consumer_key", twitter.consumerKey],
["oauth_signature_method", "HMAC-SHA1"],
["oauth_version", "1.0"]
]
};
d.token = d.token || d.account.accessToken;
d.tokenSecret = d.tokenSecret || d.account.accessTokenSecret;
if (d.token != true) {
message.parameters.push(["oauth_token", d.token])
}
if (d.tokenSecret != true) {
accessor.tokenSecret = d.tokenSecret
}
for (var a in d.parameters) {
if (d.parameters[a][0] == "oauth_callback") {
d.parameters[a][1] = unescape(d.parameters[a][1])
}
message.parameters.push(d.parameters[a])
}
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
if (d.stream) {
console.log("Opening user stream for user " + d.account.screenName);
$.ajax({
url: message.action,
type: message.method,
data: OAuth.getParameterMap(message.parameters),
dataType: d.type || "json",
xhr: function () {
d.account.stream.connection = new XMLHttpRequest();
d.account.stream.connection.addEventListener("progress", function () {
processResponse(d.account)
}, false);
return d.account.stream.connection
},
complete: function (f, g) {
streamComplete(f.status, d.account)
}
});
setInterval(function () {
checkStream(d.account)
}, 45000)
} else {
var e = true;
if (d.media) {
e = false;
var c = new FormData();
c.append("media[]", d.media);
c.append("status", d.status);
if (d.replyID) {
c.append("in_reply_to_status_id", d.replyID)
}
var b = function (f) {
f.setRequestHeader("Authorization", OAuth.getAuthorizationHeader("", message.parameters))
}
}
$.ajax({
url: message.action,
type: message.method,
data: c || OAuth.getParameterMap(message.parameters),
dataType: d.type || "json",
contentType: (d.media) ? false : "application/x-www-form-urlencoded",
processData: e,
beforeSend: b ||
function () {},
xhr: d.xhr,
success: function (g, f, i) {
if (d.success) {
d.success(g)
}
},
error: function (g, f, i) {
console.log(g.responseText);
if (d.error) {
d.error(g.responseText, d.parameters, g)
}
}
})
}
};
function processResponse(f) {
f.stream.response = f.stream.connection.responseText.split("\r");
while (f.stream.response[f.stream.index + 1]) {
if (f.stream.response[f.stream.index].length > 1) {
var e;
if (e = jQuery.parseJSON(f.stream.response[f.stream.index])) {
if (e.text) {
f.stream.timeline.unshift(e);
if (e.entities.user_mentions) {
var b = false;
for (var c in e.entities.user_mentions) {
if (e.entities.user_mentions[c].screen_name == f.screenName) {
b = true;
f.stream.mentions.unshift(e);
var d = false;
var c = 0;
while (f.stream.friends[c] && !d) {
if (f.stream.friends[c] == e.user.id) {
d = true
}
c++
}
if (!d) {
f.stream.timeline.splice(0, 1)
}
}
}
}
if (e.user.id == f.id) {
f.stream.userTimeline.unshift(e)
}
if (f.notifyTweet || (f.notifyMention && b)) {
twitter.notify(f, f.stream.index)
}
while (f.stream.timeline.length > 100) {
f.stream.timeline.pop()
}
while (f.stream.mentions.length > 100) {
f.stream.mentions.pop()
}
while (f.stream.userTimeline.length > 100) {
f.stream.mentions.pop()
}
var a = chrome.extension.getViews({});
for (var c in a) {
if (a[c].updateTimeline) {
a[c].updateTimeline("home", f);
if (b) {
a[c].updateTimeline("mentions", f)
}
if (e.user.id == f.id) {
a[c].updateTimeline("userTimeline", f)
}
}
}
} else {
if (e.direct_message) {
twitter.messagesDB.transaction([f.id], webkitIDBTransaction.READ_WRITE).objectStore(f.id).add(e.direct_message);
if (f.notifyDm) {
twitter.notify(f, f.stream.index)
}
var a = chrome.extension.getViews({});
for (var c in a) {
if (a[c].updateMessage) {
a[c].updateMessage(f.id, e.direct_message)
}
}
} else {
if (e["delete"]) {
var c = 0;
if (f.stream.timeline[c]) {
while (f.stream.timeline[c].id_str > e["delete"].status.id_str || f.stream.timeline[c].retweeted_by && f.stream.timeline[c].id_str != e["delete"].status.id_str) {
c++;
if (!f.stream.timeline[c]) {
break
}
}
}
if (f.stream.timeline[c]) {
if (f.stream.timeline[c].id_str == e["delete"].status.id_str) {
f.stream.timeline.splice(c, 1)
}
}
var a = chrome.extension.getViews({});
for (var c in a) {
if (a[c].deleteStatus) {
a[c].deleteStatus(f.id, e["delete"].status.id_str)
}
}
} else {
if (e.friends) {
f.stream.friends = e.friends
}
}
}
}
} else {
f.stream.connection.abort()
}
}
f.stream.index++
}
}
function checkStream(a) {
console.log("Checking stream activity...");
if (a.stream.connection) {
if (a.stream.connection.responseText.length > 5000000 || a.stream.lastIndex == a.stream.index) {
a.stream.connection.abort()
}
a.stream.lastIndex = a.stream.index
}
}
function updateAccounts() {
var a = [];
for (var b in accounts) {
a[b] = jQuery.extend({}, accounts[b]);
delete a[b].stream
}
if (a.length == 0) {
store.set("accounts", "")
} else {
store.set("accounts", a)
}
}
twitter.stream = function (a) {
this.response = "";
this.timeline = [];
this.mentions = [];
this.userTimeline = [];
this.connection = "";
this.index = 0;
this.lastIndex = 0;
this.wait = a || 0;
this.start = function (e) {
console.log("Fetching timelines...");
twitter.getTimeline({
accountId: e.id,
type: "home",
success: function (f) {
e.stream.timeline = f;
console.log("Fetched home")
}
});
twitter.getUserTimeline({
accountId: e.id,
success: function (f) {
e.stream.userTimeline = f;
console.log("Fetched user")
}
});
twitter.getMentions({
accountId: e.id,
success: function (f) {
e.stream.mentions = f;
console.log("Fetched mentions")
}
});
var c = 0;
while (twitter.messagesDB.objectStoreNames[c] && twitter.messagesDB.objectStoreNames[c] != e.id) {
c++
}
function b(f) {
twitter.messagesDB.transaction([f]).objectStore(f).openCursor(null, webkitIDBCursor.PREV).onsuccess = function (j) {
console.log("Loaded messages DB cursor");
var k = j.target.result;
if (k) {
var i = k.key;
var g = [
["since_id", twitter.decrementID(k.key)]
]
}
if (!i) {
var g = [
["count", 200]
]
}
twitter.getMessages({
accountId: f,
parameters: g,
success: function (n) {
var m = twitter.messagesDB.transaction([e.id], webkitIDBTransaction.READ_WRITE).objectStore(e.id);
var l = function () {
for (var o in n) {
m.add(n[o])
}
};
if (n.length) {
if (n[n.length - 1].id_str != i) {
m.openCursor().onsuccess = function (o) {
var p = o.target.result;
if (p) {
p["delete"]();
p["continue"]()
} else {
l()
}
}
} else {
n.pop();
l()
}
}
console.log("Fetched messages")
}
})
}
}
if (!twitter.messagesDB.objectStoreNames[c]) {
console.log("Creating object store");
var d = twitter.messagesDB.setVersion(parseInt(twitter.messagesDB.version) + 1).onsuccess = function (g) {
var f = chrome.extension.getBackgroundPage().twitter.messagesDB.createObjectStore(e.id, {
keyPath: "id_str"
});
f.createIndex("sender_id", "sender_id", {
unique: false
});
f.createIndex("recipient_id", "recipient_id", {
unique: false
});
b(e.id)
}
} else {
b(e.id)
}
twitter.oauthRequest({
url: "https://userstream.twitter.com/2/user.json",
stream: true,
account: e
})
}
};
function streamComplete(a, b) {
console.log(b.screenName + " stream complete");
delete b.stream.connection;
if (!b.disabled) {
if (a > 200) {
if (b.stream.wait < 240000) {
setTimeout(function () {
b.stream = new twitter.stream(b.stream.wait);
b.stream.start(b)
}, b.stream.wait);
if (b.stream.wait == 0) {
b.stream.wait = 5000
}
b.stream.wait *= 2
} else {
notif = webkitNotifications.createNotification("images/48.png", "Twitter Error", "Twitter Notifier couldn't connect to Twitter - maybe Twitter's down, or maybe you aren't logged in properly. Go to the options page to logout and in again.");
notif.show();
setTimeout(function () {
b.stream = new twitter.stream(b.stream.wait);
b.stream.start(b)
}, 10000)
}
} else {
if (b.stream.wait < 30000) {
setTimeout(function () {
b.stream = new twitter.stream(b.stream.wait);
b.stream.start(b)
}, b.stream.wait);
b.stream.wait += 10000
} else {
connectionError()
}
}
b.waitReset = setTimeout(function () {
b.wait = 0
}, 320000)
}
}
function connectionError() {
var a = webkitNotifications.createNotification("images/48.png", "Connection Error", "Twitter Notifier couldn't connect to Twitter - are you sure you're connected to the internet? Connection will be tried again in 1 minute.");
if (store.get("connectionErrors")) {
a.show()
}
setTimeout(function () {
a.cancel();
document.location.reload()
}, 60000)
}
twitter.requestToken = function () {
var a = Date.now();
twitter.oauthRequest({
url: "https://api.twitter.com/oauth/request_token",
type: "text",
method: "POST",
token: true,
tokenSecret: true,
parameters: [
["oauth_callback", escape(window.top.location + "?t=" + a)]
],
success: function (d) {
d = d.split("&");
var b = [];
for (var c in d) {
var e = d[c].split("=");
b[e[0]] = e[1]
}
accounts.push({
requestToken: b.oauth_token,
requestTokenSecret: b.oauth_token_secret,
timestamp: a
});
updateAccounts();
if (b.oauth_token) {
chrome.tabs.create({
url: "https://api.twitter.com/oauth/authorize?oauth_token=" + b.oauth_token
})
} else {
setTimeout(function () {
alert("An error occurred! Please check you have internet access and your clock is set correctly and try again.")
}, 5000)
}
},
error: function (d, c) {
webkitNotifications.createNotification("images/error.png", "Failed to authenticate with Twitter", "Check you have internet access and your computer's clock is set correctly (common cause of error) and try again.").show()
}
})
};
twitter.accessToken = function (a, e) {
accounts = chrome.extension.getBackgroundPage().accounts;
for (var b in accounts) {
if (accounts[b].timestamp == e) {
var d = accounts[b];
var c = b
}
}
twitter.oauthRequest({
url: "https://api.twitter.com/oauth/access_token",
type: "text",
method: "POST",
token: d.requestToken,
tokenSecret: d.requestTokenSecret,
parameters: [
["oauth_verifier", a]
],
success: function (j) {
j = j.split("&");
var f = [];
for (var g in j) {
var k = j[g].split("=");
f[k[0]] = k[1]
}
for (var g in accounts) {
if (accounts[g].accessToken == f.oauth_token) {
accounts.splice(c, 1);
c = false
}
}
if (c) {
delete d.timestamp;
delete d.requestToken;
delete d.requestTokenSecret;
d.accessToken = f.oauth_token;
d.accessTokenSecret = f.oauth_token_secret;
d.notifyDm = true;
d.notifyTweet = true;
d.notifyMention = true;
chrome.extension.getBackgroundPage().twitter.loadNewAccount(d);
webkitNotifications.createNotification("images/48.png", "Authorised!", "Twitter Notifier is now authorised and running.").show()
} else {
webkitNotifications.createNotification("images/48.png", "Not Authorised", "That account has already been connected to Twitter Notifier.").show()
}
updateAccounts();
chrome.tabs.getCurrent(function (i) {
chrome.tabs.remove(i.id)
})
}
})
};
twitter.loadAccount = function (a) {
console.log("Loading account " + a.screenName);
twitter.oauthRequest({
url: "https://api.twitter.com/1/account/verify_credentials.json",
account: a,
success: function (c) {
try {
a.id = c.id;
a.name = c.name;
a.screenName = c.screen_name;
a.image = c.profile_image_url;
a.stream = new twitter.stream();
console.log("Updating accounts store");
updateAccounts();
if (!a.disabled) {
a.stream.start(a)
}
} catch (b) {
connectionError()
}
},
error: function (c, b) {
webkitNotifications.createNotification("images/48.png", "Could not authenticate user @" + a.screenName, "Twitter Notifier failed to authorise this account with Twitter. Try logging out and logging in of this account on the accounts page.").show()
}
})
};
twitter.loadNewAccount = function (b) {
for (var a in accounts) {
if (accounts[a].accessToken == b.accessToken) {
twitter.loadAccount(accounts[a])
}
}
};
twitter.getAccountById = function (b) {
for (var a in accounts) {
if (accounts[a].id == b) {
return accounts[a]
}
}
};
twitter.favourite = function (d, c, b) {
var a = twitter.getAccountById(c);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/favorites/create/" + d + ".json",
account: a,
success: b ||
function () {},
error: function (e) {
e = jQuery.parseJSON(e);
webkitNotifications.createNotification("images/error.png", "Could not favourite", "Error: " + e.error).show()
}
})
};
twitter.unfavourite = function (d, c, b) {
var a = twitter.getAccountById(c);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/favorites/destroy/" + d + ".json",
account: a,
success: b ||
function () {},
error: function (e) {
e = jQuery.parseJSON(e);
webkitNotifications.createNotification("images/error.png", "Could not unfavourite", "Error: " + e.error).show()
}
})
};
twitter.retweet = function (d, c, b) {
var a = twitter.getAccountById(c);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/statuses/retweet/" + d + ".json",
account: a,
success: b ||
function () {},
error: function (e) {
e = jQuery.parseJSON(e);
webkitNotifications.createNotification("images/error.png", "Retweet failed", "Error: " + e.error).show()
}
})
};
twitter.deleteStatus = function (d, c, b) {
var a = twitter.getAccountById(c);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/statuses/destroy/" + d + ".json",
account: a,
success: b ||
function () {},
error: function (e) {
e = jQuery.parseJSON(e);
webkitNotifications.createNotification("images/error.png", "Retweet failed", "Error: " + e.error).show()
}
})
};
twitter.update = function (f, c, e, d) {
var b = twitter.getAccountById(f);
var a = [
["status", c]
];
if (e) {
a.push(["in_reply_to_status_id", e])
}
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/statuses/update.json",
parameters: a,
account: b,
success: d ||
function () {},
error: function (g, k) {
g = jQuery.parseJSON(g);
console.log(g);
webkitNotifications.createNotification("images/error.png", "Status could not be sent", "Error: " + g.error).show();
for (var j in k) {
if (k[j][0] == "status") {
k = k[j][1]
}
}
chrome.tabs.create({
url: "http://twitter.com/?status=" + k
})
}
})
};
twitter.updateWithMedia = function (i, e, d, g, f, a) {
var c = twitter.getAccountById(i);
var b = [];
twitter.oauthRequest({
method: "POST",
url: "https://upload.twitter.com/1/statuses/update_with_media.json",
parameters: b,
account: c,
media: d,
status: e,
replyID: g || false,
xhr: function () {
var j = new XMLHttpRequest();
j.upload.addEventListener("progress", a ||
function () {}, false);
return j
},
success: f ||
function () {},
error: function (j, l) {
j = jQuery.parseJSON(j);
console.log(j);
webkitNotifications.createNotification("images/error.png", "Status could not be sent", "Error: " + j.error).show();
for (var k in l) {
if (l[k][0] == "status") {
l = l[k][1]
}
}
chrome.tabs.create({
url: "http://twitter.com/?status=" + l
})
}
})
};
twitter.dm = function (e, b, d, c) {
var a = twitter.getAccountById(e);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/direct_messages/new.json",
parameters: [
["text", b],
["user_id", d]
],
account: a,
error: function (f) {
webkitNotifications.createNotification("images/error.png", "DM Could not be sent", "Error: " + jQuery.parseJSON(f)["error"]).show()
},
success: c ||
function () {}
})
};
twitter.getTimeline = function (c) {
var b = twitter.getAccountById(c.accountId);
var a = [
["include_rts", "true"],
["include_entities", "true"],
["include_my_retweet", "true"]
];
if (c.parameters) {
a = a.concat(c.parameters)
}
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/statuses/home_timeline.json",
account: b,
parameters: a,
success: c.success ||
function () {},
error: c.error ||
function () {}
})
};
twitter.getUserTimeline = function (c) {
var b = twitter.getAccountById(c.accountId);
var a = [
["include_rts", "true"],
["include_entities", "true"],
["include_my_retweet", "true"]
];
if (c.parameters) {
a = a.concat(c.parameters)
}
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/statuses/user_timeline.json",
account: b,
parameters: a,
success: c.success ||
function () {},
error: c.error ||
function () {}
})
};
twitter.getMentions = function (c) {
var b = twitter.getAccountById(c.accountId);
var a = [
["include_rts", "true"],
["include_entities", "true"]
];
if (c.parameters) {
a = a.concat(c.parameters)
}
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/statuses/mentions.json",
account: b,
parameters: a,
success: c.success ||
function () {},
error: c.error ||
function () {}
})
};
twitter.getMessages = function (d) {
var c = twitter.getAccountById(d.accountId);
var b = [
["skip_status", "true"]
];
if (d.parameters) {
b = b.concat(d.parameters)
}
if (b.sent) {
var a = "https://api.twitter.com/1/direct_messages/sent.json";
delete b.sent
}
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/direct_messages.json",
account: c,
parameters: b,
success: function (e) {
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/direct_messages/sent.json",
account: c,
parameters: b,
success: function (f) {
e = e.concat(f);
e.sort(function (i, g) {
return new Date(g.created_at) - new Date(i.created_at)
});
d.success(e);
console.log(e)
},
error: d.error ||
function () {}
})
},
error: d.error ||
function () {}
})
};
twitter.getUsers = function (b) {
var a = twitter.getAccountById(b.accountId);
twitter.oauthRequest({
method: "POST",
url: "https://api.twitter.com/1/users/lookup.json",
account: a,
parameters: b.parameters,
success: b.success ||
function () {},
error: b.error ||
function () {}
})
};
twitter.getFriendships = function (b) {
var a = twitter.getAccountById(b.accountId);
twitter.oauthRequest({
method: "GET",
url: "https://api.twitter.com/1/friendships/show.json",
account: a,
parameters: b.parameters,
success: b.success ||
function () {},
error: b.error ||
function () {}
})
};
twitter.openReplyWindow = function (a) {
if (navigator.appVersion.indexOf("Mac") != -1) {
w = 449;
h = 90
} else {
w = 463;
h = 126
}
chrome.windows.create({
url: "reply.html" + a,
width: w,
height: h,
type: "popup",
focused: true
})
};
twitter.notify = function (b, a) {
var c = {};
if (store.get("growl")) {
var d = jQuery.parseJSON(b.stream.response[a]);
if (d.direct_message) {
if (d.direct_message.sender.id == b.id) {
c.title = "Message to " + d.direct_message.recipient.name
} else {
c.title = "Message from " + d.direct_message.sender.name
}
c.text = $("<div/>").html(d.direct_message.text).text();
c.url = "http://twitter.com/messages";
c.image = d.direct_message.sender.profile_image_url
} else {
if (d.retweeted_status) {
d = d.retweeted_status
}
c.title = d.user.name;
c.text = $("<div/>").html(d.text).text();
c.url = "http://twitter.com/" + d.user.screen_name + "/status/" + d.id_str;
c.image = d.user.profile_image_url
}
chrome.extension.sendRequest(twitter.growlId, c, function (e) {
webkitNotifications.createHTMLNotification("notification.html?account=" + b.id + "&id=" + a).show()
})
} else {
webkitNotifications.createHTMLNotification("notification.html?account=" + b.id + "&id=" + a).show()
}
};
twitter.decrementID = function (b) {
var a = -1;
while (b.substr(a, 1) == "0") {
a--
}
return b.slice(0, a) + (b.substr(a) - 1)
};
function removeObjectStore(b) {
var a = twitter.messagesDB.setVersion(parseInt(twitter.messagesDB.version) + 1);
a.onsuccess = function (c) {
twitter.messagesDB.deleteObjectStore(b)
}
}
$(document).ready(function () {
var d = window.location.href.split("?");
if (d[1]) {
d = d[1].split("&") || null;
for (var b in d) {
d[b] = d[b].split("=");
if (d[b][0] == "oauth_verifier") {
var a = d[b][1]
}
if (d[b][0] == "t") {
var c = d[b][1]
}
}
}
if (a) {
twitter.accessToken(a, c)
} else {
if (!localStorage.firstRun) {
if (!localStorage.version) {
chrome.tabs.create({
url: "options/index.html"
});
localStorage.timeout = 10;
localStorage.fontSize = 13;
localStorage.version = twitter.version
} else {
accounts = [{
accessToken: localStorage.accessToken,
accessTokenSecret: localStorage.accessTokenSecret,
id: parseInt(localStorage.id),
image: localStorage.image,
name: localStorage.name,
notifyDm: localStorage.notifyDm,
notifyMention: localStorage.notifyMention,
notifyTweet: localStorage.notifyTweet,
screenName: localStorage.screenName
}];
for (var b in accounts[0]) {
if (accounts[0][b] == "true") {
accounts[0][b] = true
}
if (accounts[0][b] == "false") {
accounts[0][b] = false
}
}
localStorage.removeItem("screenName");
localStorage.removeItem("id");
localStorage.removeItem("accessToken");
localStorage.removeItem("accessTokenSecret");
localStorage.removeItem("image");
localStorage.removeItem("name");
localStorage.removeItem("notifyDm");
localStorage.removeItem("notifyTweet");
localStorage.removeItem("notifyMention");
updateAccounts()
}
localStorage.firstRun = true
}
if (localStorage.version < twitter.version) {
localStorage.version = twitter.version;
webkitNotifications.createNotification("images/48.png", "Twitter Notifier Updated!", "Twitter Notifier has been updated to the latest and greatest version!").show()
}
twitter.setup()
}
});