Permalink
Browse files

second popup waypoint

  • Loading branch information...
1 parent 13b425e commit df424f3c9659f5522ce99791bb9a16a6037ec4cf @michaelficarra committed Mar 4, 2011
Showing with 301 additions and 269 deletions.
  1. +6 −4 README.md
  2. +1 −0 background.html
  3. +5 −205 background.js
  4. +4 −0 chrome.css
  5. +1 −0 options.html
  6. +2 −23 options.js
  7. +8 −11 popup.css
  8. +12 −9 popup.html
  9. +234 −17 popup.js
  10. +28 −0 util.js
View
@@ -2,26 +2,28 @@
## TODO (before release)
+* stop using global variable to pass along server and authentication info
* use proper node function signatures (first argument is `err`)
+* handle errors by adding retry button (must be using node style callback signatures first)
* verify bug fix: add torrent successfully, change host, attempt to add torrent again; infinite loop (partially due to cached session id)
-* add "popup" prompt for symmetric key when using encrypted credentials
-* add message area to popup for outputting status messages (torrent added, trackers added, etc.)
+* make popup ask for symmetric key when using encrypted credentials
+* clean up and standardize logged messages
* inspect [license of icon file](http://www.veryicon.com/icons/system/arcade-daze-apps-vol-1/transmission-2.html)
* set up automatic updates
* do rigorous hand testing
-* remove logging
* bump version
* package the plugin
* write up installation/usage for README
## TODO (after release)
+* don't make user type in password repeatedly (send request to background page to store password in closure for X seconds)
* don't require save button on options page
* find a way to test this thing
* go to transmission web interface (on torrent add) if tab is already open (see [goToInbox function](http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/gmail/background.html?content-type=text/plain))
+* standardize element id naming convention (underscore or camel case)
* add support for multiple servers (don't forget to no longer cache the session ID as a single value!)
-* make popup come up on click, select server, enter encryption key (only show input if passwords are encrypted), press go button, wait for response, close popup or present error and retry button
* write handlers for some more torrent websites without magnet links or with better alternatives
* modularize and DRY up everything
* function for trying an XHR with an array of inputs until we make a function pass
View
@@ -3,6 +3,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="Base64.js"></script>
+ <script type="text/javascript" src="util.js"></script>
<script type="text/javascript" src="background.js"></script>
</head>
<body>
View
@@ -12,26 +12,11 @@
localStorage.defaultAddTrackers = JSON.stringify(true);
localStorage.defaultAdditionalTrackers = JSON.stringify([]);
- var log = function(){
- var args = Array.prototype.slice.call(arguments);
- console.log.apply(console,['transmissionDownload','--'].concat(args));
- }
-
- var getOption = function(opt){
- var def, obj;
- if((obj=localStorage['opt'+opt])!=null) return JSON.parse(obj);
- return (def=localStorage['default'+opt])!=null ? JSON.parse(def) : null;
- };
-
- var transmissionSessionId = null,
- server,
- authentication;
-
var supportedUrls =
[ /^https?:\/\/([^\/]*\.)?torrentz\.(com|eu|me)\/(announce_)?[a-f0-9]{40}/i
//, /^http:\/\/([^\/]*\.)?bitsnoop.com\/.*\-q[0-9]+\.html$/
//, /^http:\/\/([^\/]*\.)?kickasstorrents.com\/.*\-t[0-9]+\.html$/
- ]
+ ];
var isSupportedUrl = function(url){
for(var i=0,l=supportedUrls.length; i<l; ++i) {
if(supportedUrls[i](url)) return true;
@@ -44,7 +29,7 @@
chrome.tabs.sendRequest(tab.id, {type:'hasMagnet'}, function(response){
if(response) chrome.pageAction.show(tab.id);
});
- }
+ };
// show icon as page action on tab change
chrome.tabs.onSelectionChanged.addListener(function(tabId) {
chrome.tabs.get(tabId,refreshIcon);
@@ -54,195 +39,10 @@
if(changeInfo.status == 'complete') refreshIcon(tab);
});
-
- var getTrackers = function(info_hash, callback){
- info_hash = info_hash.toLowerCase();
- var trackers = [], running = 0,
- finish = function(){
- if(--running < 1 && typeof callback == 'function')
- callback(trackers);
- };
-
- var xhrTorrentz = new XMLHttpRequest,
- torrentzDomains =
- [ 'https://torrentz.eu'
- , 'https://torrentz.me'
- , 'http://torrentz.eu'
- , 'http://torrentz.me'
- , 'https://torrentz.com'
- , 'http://torrentz.com'
- ]
- var tryTorrentz = function(){
- var url = torrentzDomains.shift();
- if(!url) return finish();
- xhrTorrentz.onreadystatechange = function(){
- if(xhrTorrentz.readyState!=4) return;
- if(xhrTorrentz.status != 200) tryTorrentz();
- var text = xhrTorrentz.responseText;
- if(!text) tryTorrentz();
- var list = text.match(/(.{0,3}ps?:\/\/.+\/announce)/gi);
- if(!list || list.length < 1) tryTorrentz();
- for(var i=0,l=list.length; i<l; ++i)
- if(0 > trackers.indexOf(list[i]))
- trackers.push(list[i]);
- finish();
- };
- xhrTorrentz.open('GET', url + '/announce_' + info_hash, true);
- xhrTorrentz.send();
- }
-
- var xhrBitsnoop = new XMLHttpRequest;
- var url = 'http://bitsnoop.com/api/trackers.php?json=1&hash=' + info_hash;
- xhrBitsnoop.onreadystatechange = function(){
- if(xhrBitsnoop.readyState != 4) return;
- if(xhrBitsnoop.status != 200) return finish();
- var text = xhrBitsnoop.responseText;
- if(!text || text == 'NOTFOUND' || text == 'ERROR') return finish();
- var json = JSON.parse(text);
- if(!json || typeof json.length != 'number' || json.length < 1) return finish();
- for(var i=0,l=json.length; i<l; ++i)
- if(0 > trackers.indexOf(json[i]['ANNOUNCE']))
- trackers.push(json[i]['ANNOUNCE']);
- return finish();
- };
- xhrBitsnoop.open('GET', url, true);
-
- ++running;
- xhrBitsnoop.send();
-
- ++running;
- tryTorrentz();
- };
-
- var buildUrl = function(protocol, host, port, path){
- return protocol + '://' + host + ':' + port + path.replace(/\/(\.?\/)+/g, '/');
- };
-
- var startSession = function(callback){
- log('initiating transmission session');
- if(transmissionSessionId) {
- if(typeof callback=='function')
- callback(transmissionSessionId);
- return;
- }
- var xhr = new XMLHttpRequest;
- xhr.onreadystatechange = function(){
- if(xhr.readyState!=4) return
- var sessionId = xhr.getResponseHeader('X-Transmission-Session-Id');
- if(xhr.status!=409 && xhr.status!=200 || !sessionId)
- throw new Error('Could not establish a secure session with the transmission server');
- transmissionSessionId = sessionId;
- log('retrieved session id', sessionId, callback);
- if(typeof callback=='function') callback(sessionId);
- };
- xhr.open('GET', buildUrl(server.protocol, server.host, server.port, server.path), true);
- var basicAuth = 'Basic '+Base64.encode(authentication.username+':'+authentication.password);
- if(authentication.enabled) xhr.setRequestHeader('Authorization', basicAuth);
- xhr.send();
- };
-
- var addTorrent = function(info_hash, callback){
- log('adding torrent for',info_hash);
- if(!info_hash) throw new Error('Cannot add torrent without info_hash');
- var sources =
- [ 'http://torrage.com/torrent/#{info_hash}.torrent'
- , 'http://torcache.com/torrent/#{info_hash}.torrent'
- , 'http://zoink.it/torrent/#{info_hash}.torrent'
- , 'http://torrage.ws/torrent/#{info_hash}.torrent'
- ];
- var tryAgain;
- (tryAgain = function(){
- var source = sources.shift();
- if(!source) return log('no more hosts');
- log('attempting host',source);
- var xhr = new XMLHttpRequest;
- xhr.onreadystatechange = function(){
- if(xhr.readyState!=4) return;
- // handle 409s (for CSRF token timeout) by asking for a new token
- if(xhr.status==409)
- return startSession(function(newSessionId){
- if(!newSessionId) return;
- addTorrent(info_hash, callback);
- });
- if(xhr.status!=200) return tryAgain();
- var response = JSON.parse(xhr.responseText);
- if(response.result != 'success') throw new Error("transmission returned error: " + response.result);
- log('retrieved successful response', response.arguments['torrent-added'].id, response);
- if(typeof callback=='function') callback(response.arguments['torrent-added']);
- };
- var postData =
- { method: 'torrent-add'
- , arguments:
- { filename: source.replace('#{info_hash}', info_hash.toUpperCase())
- , paused: !getOption('StartAutomatically')
- }
- };
- log('postData',postData, JSON.stringify(postData));
- xhr.open('POST', buildUrl(server.protocol, server.host, server.port, server.path), true);
- xhr.setRequestHeader('X-Transmission-Session-Id', transmissionSessionId);
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- var basicAuth = 'Basic '+Base64.encode(authentication.username+':'+authentication.password);
- if(authentication.enabled) xhr.setRequestHeader('Authorization', basicAuth);
- xhr.send(JSON.stringify(postData));
- })();
- };
-
- var addTrackers = function(torrent, callback){
- if(!torrent || !torrent.id || !torrent.hashString)
- throw new Error('Attempted to add trackers to an invalid torrent');
- getTrackers(torrent.hashString, function(trackers){
- var additionalTrackers = getOption('AdditionalTrackers');
- trackers = trackers.concat(additionalTrackers);
- log('retrieved trackers',trackers);
- var xhr = new XMLHttpRequest;
- xhr.onreadystatechange = function(){
- if(xhr.readyState!=4 || xhr.status!=200) return;
- if(typeof callback=='function') callback();
- };
- var postData =
- { method: 'torrent-set'
- , arguments:
- { ids: torrent.id
- , trackerAdd: trackers
- }
- };
- log('postData',postData, JSON.stringify(postData));
- xhr.open('POST', buildUrl(server.protocol, server.host, server.port, server.path), true);
- xhr.setRequestHeader('X-Transmission-Session-Id', transmissionSessionId);
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- var basicAuth = 'Basic '+Base64.encode(authentication.username+':'+authentication.password);
- if(authentication.enabled) xhr.setRequestHeader('Authorization', basicAuth);
- xhr.send(JSON.stringify(postData));
- });
- };
-
+ /*
chrome.extension.onRequest.addListener(function(request, sender, respond){
- if(request.type != 'addTorrent') return respond(null);
- console.log('background.js addTorrent request received');
- chrome.tabs.getSelected(null, function(tab) {
- chrome.tabs.sendRequest(tab.id, {type:'info_hash'}, function(info_hash){
- log('determined info_hash',info_hash);
- if(!info_hash) throw new Error('Could not determine info_hash');
- server =
- { protocol: getOption('ServerProtocol')
- , host: getOption('ServerHost')
- , port: getOption('ServerPort')
- , path: getOption('ServerPath')
- };
- authentication =
- { enabled: getOption('AuthenticationEnabled')
- , encrypted: getOption('AuthenticationEncrypted')
- , username: getOption('AuthenticationUsername')
- , password: getOption('AuthenticationPassword')
- };
- if(authentication.encrypted) throw new Error('Encrypted usernames/passwords not yet supported');
- addTorrent(info_hash, function(torrent){
- addTrackers(torrent, function(){
- respond({type:'close'});
- });
- });
- });
- });
+ if(request.type != ...) return respond(null);
});
+ */
})(this)
View
@@ -21,6 +21,10 @@ a:active {
color: grey;
}
+.hidden {
+ display: none !important;
+}
+
.overlay {
-webkit-box-align: center;
-webkit-box-pack: center;
View
@@ -6,6 +6,7 @@
<link rel="stylesheet" type="text/css" href="options.css" />
<script type="text/javascript" src="AES.js"></script>
<script type="text/javascript" src="Base64.js"></script>
+ <script type="text/javascript" src="util.js"></script>
</head>
<body class="container">
View
@@ -1,16 +1,4 @@
-(function($, global, undefined){
-
- var hasClass = function(klass){
- return new RegExp('(^|\\s)'+klass+'(\\s|$)').test(this.className);
- },
- addClass = function(klass){
- if(hasClass.call(this,klass)) return;
- this.className = this.className.split(' ').concat(klass).join(' ');
- },
- removeClass = function(klass){
- if(!hasClass.call(this,klass)) return;
- this.className = this.className.replace(new RegExp('(^|\\s+)'+klass+'($|\\s+)','g'),' ');
- };
+(function(global, undefined){
var updateFullRpcUrl = function(){
$('protocol_output').innerText = $('protocol').value;
@@ -94,15 +82,6 @@
loadOptions();
});
- var getOption = function(opt){
- var def, obj;
- if((obj=localStorage['opt'+opt])!=null) return JSON.parse(obj);
- return (def=localStorage['default'+opt])!=null ? JSON.parse(def) : null;
- },
- setOption = function(opt, value){
- localStorage['opt'+opt] = value==null ? null : JSON.stringify(value);
- };
-
var loadOptions;
(loadOptions = function(){
var elemProtocol = $('protocol'),
@@ -161,4 +140,4 @@
saveOptions();
});
-})(function(){ return document.getElementById.apply(document,arguments) }, this)
+})(this)
View
@@ -1,32 +1,29 @@
body {
- width: 280px;
+ min-width: 280px;
}
-#addTorrent {
+input#symmetric_key {
+ display: block;
+ margin: 5px auto;
width: 100%;
+ padding: 3px 0;
}
#log {
- display: none;
list-style-type: none;
margin: 0;
padding: 0;
}
-
#log li {
border-left: 4px solid;
padding-left: 0.5em;
margin: 5px 0;
}
-#log li.info { border-color: #55d976; }
+#log li.info { border-color: #ddd; }
+#log li.done { border-color: #55d976; }
#log li.error {
border-color: #d96255;
color: #c94235;
}
-#symmetric_key {
- display: block;
- margin: 5px auto;
- width: 100%;
- padding: 3px 0;
-}
+button#addTorrent, button#close { width: 100%; }
Oops, something went wrong.

0 comments on commit df424f3

Please sign in to comment.