// ==UserScript==
// @name            Add Torrents to the uTorrent WebUI 2
// @namespace       http://www.merhar.si
// @description     Lets you download torrents using the uTorrent WebUI (use only with Token Auth WebUI versions - uTorrent 2.0) - token support by BaK
// ==/UserScript==


var uTorrentWebUICallbacks =
{
	tvtorrents: function(str)
	{
		if ((typeof uTorrentWebUICallbacks.tvtorrentsHash == 'undefined') || (typeof uTorrentWebUICallbacks.tvtorrentsDigest == 'undefined')) {
			// run only once
			var hash = document.lastChild.innerHTML.match(/hash='([^']+)';/);
			uTorrentWebUICallbacks.tvtorrentsHash = hash[1];
			var digest = document.lastChild.innerHTML.match(/digest='([^']+)';/);
			uTorrentWebUICallbacks.tvtorrentsDigest = digest[1];

			// fix ajax links
			if (document.getElementById('showmenu_0')) {
				var links = document.getElementById('showmenu_0').parentNode.getElementsByTagName('a');
				for (var i = 0; i < links.length; i++) {
					links[i].addEventListener('click', function(event) { setTimeout(function() { uTorrentWebUI.run() }, 1000); }, true );
				}
			}
		}
		var info_hash = str.match(/\?info_hash=(.+)/);
		info_hash = info_hash[1];
		return 'http://torrent.tvtorrents.com/FetchTorrentServlet?info_hash=' + info_hash + '&digest=' + uTorrentWebUICallbacks.tvtorrentsDigest + '&hash=' + uTorrentWebUICallbacks.tvtorrentsHash;
	},
}

var uTorrentWebUI =
{
  /* START USER-CONFIGURABLE SETTINGS */

  sites: {
    'isohunt'        : 'isohunt\\.com/download/',
    'bt-chat'        : 'bt-chat\\.com/download1\\.php\\?',
    'torrentreactor' : 'dl\\.torrentreactor\\.net/download.php\\?',
    'mininova'       : 'mininova\\.org/get/',
    'mininova-tor'   : 'mininova\\.org/tor/',
    'torrentspy'     : 'torrentspy\\.com/download.asp\\?',
    'mybittorrent'   : 'mybittorrent\\.com/dl/',
    'bushtorrent'    : 'bushtorrent\\.com/download\\.php\\?',
    'partis'         : 'partis\\.si/torrent/prenesi/',
    'thebox'         : 'thebox\\.bz/download.php/',
    'tvtorrents'     : 'tvtorrents\\.com/loggedin/torrent\\.do\\?info_hash=',
    'demonoid'       : 'demonoid\\.com/files/download/HTTP/',
    'slobytes'       : 'slobytes\\.net/download\\.php/',
    'hdbits'         : 'hdbits\\.org/download\\.php\\?',
    'sdbits'         : 'sdbits\\.org/download\\.php\\?',
    'acehd'          : 'acehd\\.net/download\\.php\\?',
    'general'        : '\\.torrent$',
  },
  
  cookies: {
    'partis'         : { 'auth_token': null },
    'thebox'         : { 'uid': null, 'pass': null },
    'demonoid'       : { 'uid': null, 'uhsh': null },
    'slobytes'       : { 'uid': null, 'pass': null },
    'hdbits'         : { 'uid': null, 'pass': null },
    'sdbits'         : { 'uid': null, 'pass': null },
    'acehd'          : { 'uid': null, 'pass': null },
  },

  transforms: {
    'mininova-tor'   : { '/tor/' : '/get/' },
    'tvtorrents'     : { '.+' : uTorrentWebUICallbacks.tvtorrents },
  },

  proxies: {
    'bt-chat\\.com/download\\.php\\?': '(http://www\\.bt-chat\\.com/download1\\.php\\?[^"]+)',
    'fulldls\\.com/get_': '(download-[^"]+\\.torrent)',
    'fulldls\\.com/torrent-': '(download-[^"]+\\.torrent)',
  },

  proxiesEnabled : false,

  /* END USER-CONFIGURABLE SETTINGS */
  
  image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFdQTFRF3+nxAJ4Fm6i3ZnmP////AI4E3+jvANt/AJ0uAK9QAJ0YgL6FAJYB3ubtAJ4MYLBgAKdMAK1PAI0qAIwWv97LMJ447/fvn8+gQKFIAI4KMJoxAJIL////acrhPgAAAB10Uk5T/////////////////////////////////////wBZhudqAAAAcUlEQVR42pTK2Q7DIAxEUROGFDCFbN35/+8sGbWoeeyVRrKOLHU4VGUQGXsitkExvUJoh3MptRnzAQe4ff9BuQHP9APAdX8h5PwA9H5RfWVCjCuwRkbwftm2xTNCCPM0zYER9NRTwrfx3LJS7aH6FmAAkqEFk4NPHiwAAAAASUVORK5CYII=',
  imageClicked: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAghJREFUeNpiDN8Zy1ArXd7AQAZoftrZwHjlypUGBQUFsMD///+J0nj9403h/S8O6pt8NNjHAhO8cOECw+PHjwlqvs1xV/061+0QJT7FKyA+3ABkzX/+/AHTTExMYPrfv39g+hbPXe3bXPeC/zP8Z+RgYv8JVoNuA0hzTEwMGIM0gjCIreiiLA3UHAjSDDYUSjMR4+dX319xzru2MBSomRkm9vrHawmiDZh0abrn1z/f+JHFuFi4vmA14BHnE/mPvz6ygdiKiooMDJpMSnc+3tWFyTP/Z/6u+01zaZ1+5WoUAz4xf+Y5yHc05BLvtYQVt1cbg8TMLc0Zj3456QpTw8bE9t3wk+4i5R+Kd2BiYAOW3FthAtSc857lozaIf+zFSRuQK6Yen6nz/ud7sF9ZGFl+evG6LZb8Jf4C2cVgA4yEDO7z/OO5DxP8+fcn17JbK03Ofj7nAOIzMjD+1/yquobh/r/nzMzMDBgGaAlovHX8aLNS8afcdqDivyCxw8+POf1i+i0EYsv8ktqH7GxkAE9ILCwsDMY/DU7x/ud9f4XjWti////Acvx/+W6a/zA+glDJgOkCEFBRUWHg5uZmMGTVu232z3gZyCXMDMzf7RittoLEkTFILYYLVFVVwRgE7Bjs7gs/FNn4698vlgBF/8+wjIac2WDJmxGUndNYEsjKzrP+LGgACDAAAIXRQgQRvOcAAAAASUVORK5CYII=',
  host: '',
  authToken: '',

  run: function()
  {
    if (this.loadSettings()) {
      this.attachEvents();
      GM_xmlhttpRequest({
        method: 'GET',
        url: this.host + 'token.html',
        onload: this.parseToken,
      });
    }
  },

  parseToken: function(transport)
  {
    var xmltoken = transport.responseText;
    var parser = new DOMParser();
    var dom = parser.parseFromString(xmltoken, 'application/xml');
    var token = dom.getElementsByTagName('div')[0].textContent;
    if (xmltoken == 'invalid request') return;
    uTorrentWebUI.authToken = token;
    uTorrentWebUI.createLinks();
  },

  loadSettings: function()
  {
    this.host = GM_getValue('host', '');
    if (!this.host) this.setHost();
    return !!this.host;
  },

  setHost: function()
  {
    var text =
      "Add Torrents to the uTorrent WebUI Greasemonkey script\n\n" +
      "Please enter the URL of your uTorrent WebUI.\n" +
      "Open your uTorrent WebUI and copy the entire URL\n" +
      "from the address bar, then paste it here.\n\n" +
      "Example: http://torrent.example.com:1234/gui/";
    uTorrentWebUI.host = prompt(text, GM_getValue('host', ''));
    if (uTorrentWebUI.host) GM_setValue('host', uTorrentWebUI.host);
  },

  attachEvents: function()
  {
    window.addEventListener('keypress', this.keyPress, false);
  },

  keyPress: function(event)
  {
    if (event.ctrlKey && event.altKey && event.shiftKey && (event.which == 85)) {
      uTorrentWebUI.setHost();
    }
  },

  createLinks: function()
  {
    var links = this.fetchLinks();
  
    for (var i = 0; i < links.length; i++) {
      this.createLink(links[i]);
    }
  },

  fetchLinks: function()
  {
    var elements = document.getElementsByTagName('a');
    var links = new Array();
    for (var i = 0; i < elements.length; i++) {
      links.push(elements[i]);
    }
    return links;
  },

  createLink: function(source, href)
  {
    if (!href && this.isProxy(source)) return;
    if (!href) href = source.href;
    href = this.getHref(href);
    if (!href) return;
    // create link
    var link = document.createElement('a');
    link.href = href;
    link.title = 'Download using uTorrent WebUI';
    link.style.padding = '0';
    link.style.marginRight = '0.5em';
    link.style.background = 'none';
    // create image
    var image = document.createElement('img');
    image.src = this.image;
    image.style.border = 'none';
    link.appendChild(image);
    // add to document
    source.parentNode.insertBefore(link, source);
    link.addEventListener('click', this.ajaxClick, false);
  },

  isProxy: function(link)
  {
    if (!this.proxiesEnabled) return;
    if (!link.href) return;
    for (var pattern in this.proxies) {
      var regex = new RegExp(pattern);
      if (link.href.match(regex)) {
        this.ajaxProxy(link, this.proxies[pattern]);
        return true;
      }
    }
    return false;
  },

  ajaxProxy: function(link, regex)
  {
    GM_xmlhttpRequest({
      method: 'GET',
      url: link.href,
      onload: function(transport) { uTorrentWebUI.proxySuccess.call(uTorrentWebUI, transport, regex, link) },
    });
  },

  proxySuccess: function(transport, regex, link)
  {
    var regex = new RegExp(regex);
    var matches = regex.exec(transport.responseText);
    if (!matches || !matches[1]) return;
    var href = matches[1];
    if (href.substring(0, 1) == '/') {
      href = link.href.substring(0, link.href.indexOf('/', 8)) + href;
    } else if (href.substring(0, 7) != 'http://') {
      href = link.href.substring(0, link.href.lastIndexOf('/') + 1) + href;
    }
    this.createLink(link, href);
  },

  ajaxClick: function(event)
  {
    link = this;
    link.firstChild.src = uTorrentWebUI.image;
    GM_xmlhttpRequest({
      method: 'GET',
      url: this.href,
      onload: function() { uTorrentWebUI.clickSuccess(link) },
      onerror: uTorrentWebUI.clickError
    });
    event.preventDefault();
  },

  clickSuccess: function(link)
  {
    link.firstChild.src = uTorrentWebUI.imageClicked;
    link.blur();
  },

  clickError: function()
  {
    alert('Error adding torrent to uTorrent!');
  },

  getHref: function(href)
  {
    var matched = false;
    for (var site in this.sites) {
      var regex = new RegExp(this.sites[site]);
      if (href.match(regex)) {
        matched = site;
        break;
      }
    }
    if (matched) {
      var url = this.host + '?token=' + this.authToken + '&action=add-url&s=';
      return url + escape(this.transformHref(site, href) + this.getCookies(site));
    } else {
      return false;
    }
  },

  transformHref: function(site, href)
  {
    var rules = this.transforms[site];
    if (rules) {
      for (var rule in rules) {
        href = href.replace(new RegExp(rule), rules[rule]);
      }
    }
    return href;
  },

  getCookies: function(site)
  {
    var names = this.cookies[site];
    if (!names) return '';
    var cookies = {};
    var exist = false;
    for (var name in names) {
      var value = names[name];
      if (!value) value = this.readCookie(name);
      if (value) {
        cookies[name] = value;
        exist = true;
      }
    }
    if (!exist) return '';
    var first = true;
    var result = ':COOKIE:';
    for (var name in cookies) {
      var value = cookies[name];
      var cookie = name + '=' + value;
      if (!first) result += ';';
      result += cookie;
      first = false;
    }
    return result;
  },

  readCookie: function(name)
  {
    name += '=';
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
      var c = ca[i];
      while (c.charAt(0) == ' ') c = c.substring(1, c.length);
      if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
    }
    return null;
  },

}

uTorrentWebUI.run();
