您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Mark snatched torrents for tc
- // ==UserScript==
- // @name tehConnection Snatch Script
- // @namespace http://tehconnection.eu
- // @description Mark snatched torrents for tc
- // @author jonls on what.cd (adapted for TC by Dafreak)
- // @include http://tehconnection.eu/*
- // @include https://tehconnection.eu/*
- // @require http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_deleteValue
- // @grant GM_xmlhttpRequest
- // @grant GM_registerMenuCommand
- // @grant GM_addStyle
- // @grant GM_log
- // @version 0.2
- // @date 2010-10-27
- // ==/UserScript==
- (function() {
- var DEFAULT_STYLE =
- '.group_snatched { color: #E5B244; } '+
- '.snatched { color: #35BF00; } '+
- '.uploaded { color: red; } '+
- '.leeching { color: #2B75A1; }'+
- '.seeding { border-bottom: 1px dotted red; }';
- var AUTO_UPDATE_INTERVAL = 10*60; /* seconds */
- /* Throttled proxy */
- function Proxy(url_base, delay) {
- var last_req = new Date(0);
- var queue = [];
- var processing = false;
- return {
- get: function(req) {
- var now = new Date();
- queue.push(req);
- if (!processing) {
- /* Race condition: atomic test and set would be appropriate here, to ensure thread safety (is it a problem?) */
- processing = true;
- var diff = last_req.getTime() + delay - now.getTime();
- if (diff > 0) {
- var that = this;
- window.setTimeout(function() { that.process_queue(); }, diff);
- } else {
- this.process_queue();
- }
- }
- },
- process_queue: function() {
- var req = queue.shift();
- this.do_request(req);
- processing = (queue.length > 0);
- if (processing) {
- var that = this;
- window.setTimeout(function() { that.process_queue(); }, delay);
- }
- },
- do_request: function(req) {
- last_req = new Date();
- var timer;
- var req_timed_out = false; /* We cannot abort a request, so we need keep track of whether it timed out */
- /* Create timeout handler */
- timer = window.setTimeout(function() {
- /* Race condition: what if the request returns successfully now? */
- req_timed_out = true;
- if (req.error) req.error(null, 'Network timeout');
- }, req.timeout || 10000);
- /* Do the actual request */
- GM_xmlhttpRequest({
- method: req.method || 'GET',
- url: url_base+req.url,
- headers: { 'User-Agent': navigator.userAgent, 'Accept': req.accept || 'text/xml' },
- onload: function(response) {
- window.clearTimeout(timer);
- if (!req_timed_out) req.callback(response);
- },
- onerror: function(response) {
- window.clearTimeout(timer);
- if (!req_timed_out && req.error) req.error(response, 'GM_xmlhttpRequest error');
- }
- });
- }
- };
- }
- /* Simple rounding (extracted from jQuery Corner)*/
- $.fn.round = function(radius) {
- radius = radius || "10px";
- return this.each(function(i) {
- if ($.browser.mozilla && /gecko/i.test(navigator.userAgent)) {
- $(this).css('-moz-border-radius', radius);
- } else if ($.browser.safari && $.browser.version >= 3) {
- $(this).css('-webkit-border-radius', radius);
- }
- });
- };
- /* Global status area - feel free to reuse in your own scripts :)
- Requires jQuery and the round extension above. */
- function StatusBox(title) {
- /* Setup status area */
- var status_area = $('#greasemonkey_status_area').eq(0);
- if (status_area.length == 0) {
- status_area = $('<div id="greasemonkey_status_area"></div>').css({
- 'position': 'fixed',
- 'top': '0', 'right': '0',
- 'margin': '20px',
- 'width': '20%',
- 'z-index': 500
- });
- $('body').append(status_area);
- }
- /* Create box */
- var box = $('<div></div>').hide();
- box.css({
- 'color': 'white',
- 'background-color': 'black',
- 'opacity': 0.5,
- 'margin': '0 0 10px 0',
- 'padding': '10px 10px 20px 10px'}).round();
- box.append($('<div>'+title+'</div>').css('font-weight', 'bold'));
- /* Create contents area */
- var contents = $('<div></div>');
- box.append(contents);
- var timer = null;
- var timeout = 0;
- var inhibit_fade = false;
- function set_visible(visible) {
- if (visible && box.is(':hidden')) box.fadeIn(500);
- else if (!visible && box.is(':visible')) box.fadeOut(500);
- }
- function clear_timer() {
- if (timer) {
- window.clearTimeout(timer);
- timer = null;
- }
- }
- function set_timer() {
- if (!timer && timeout > 0) {
- timer = window.setTimeout(function() { clear_timer(); set_visible(false); }, timeout);
- }
- }
- function update_timer(t) {
- clear_timer();
- timeout = t;
- if (!inhibit_fade) set_timer();
- }
- function set_inhibit_fade(inhibit) {
- inhibit_fade = inhibit;
- if (!inhibit_fade) { set_timer(); }
- else clear_timer();
- }
- /* Register event handlers */
- box.mouseenter(function(event) {
- set_inhibit_fade(true);
- $(this).fadeTo(500, 0.8);
- });
- box.mouseleave(function(event) {
- set_inhibit_fade(false);
- $(this).fadeTo(500, 0.5);
- });
- box.click(function(event) {
- clear_timer();
- set_visible(false);
- });
- /* Append to global status area */
- status_area.append(box);
- return {
- contents: function() {
- return contents;
- },
- show: function(t) {
- t = t || 0;
- update_timer(t);
- set_visible(true);
- },
- hide: function() {
- clear_timer();
- set_visible(false);
- }
- };
- }
- /* Cache */
- function Cache(name, def_value) {
- var cache;
- return {
- serialize: function() {
- GM_setValue(name, uneval(cache));
- },
- unserialize: function() {
- cache = eval(GM_getValue(name, 'false'));
- if (!cache) cache = $.extend({}, def_value); /* clone */
- return cache;
- },
- clear: function() {
- cache = $.extend({}, def_value); /* clone */
- this.serialize();
- }
- };
- }
- /* Get what.CD base URL */
- var whatcd_url_base = document.URL.match(/^(https:\/\/tehconnection\.eu|http:\/\/tehconnection\.eu)/)[1];
- /* Create proxy */
- var whatcd_proxy = Proxy(whatcd_url_base, 1000);
- /* Get user id of this user */
- var whatcd_id = (function() {
- var m = $('#header .username').eq(0).attr('href').match(/user\.php\?id=(\d+)/);
- if (m) return m[1];
- return null;
- })();
- if (!whatcd_id) return; /* Exceptional condition: User ID not found */
- /* Create status box */
- var status = StatusBox('TehConnection.Eu Snatched');
- /* Cache of snatched torrents */
- var snatch_cache = Cache('snatch_cache', { groups: {}, torrents: {} });
- /* Scan torrent table in doc and mark links as type in cache */
- function scan_torrent_page(doc, type) {
- var torrent_table = doc.find('.torrent_table').eq(0);
- if (torrent_table.length == 0){
- return 0;
- }
- var found = 0;
- var d = snatch_cache.unserialize();
- torrent_table.find('tr').not('.colhead').each(function(i) {
- /* Find group and torrent ID */
- var group_id;
- var torrent_id;
- var link = $(this).children('td').eq(1).children('a:last').eq(0);
- var m = link.attr('href').match(/torrents\.php\?id=(\d+)&torrentid=(\d+)/);
- if (m) {
- group_id = m[1];
- torrent_id = m[2];
- } else {
- m = link.attr('href').match(/torrents\.php\?id=(\d+)/);
- if (m) {
- group_id = m[1];
- link = $(this).children('td').eq(1).children('span').eq(0).children('a').eq(0);
- m = link.attr('href').match(/torrents\.php\?action=download&id=(\d+)/);
- if (m) torrent_id = m[1];
- }
- if (!m) {
- status.contents().append('<div><span style="color: red;">Failed:</span> '+$(this).children('td').eq(1).text()+'</div>');
- status.show();
- }
- }
- /* Save in cache */
- if (group_id && torrent_id) {
- if (!d.torrents[torrent_id] ||
- (type != 'seeding' && d.torrents[torrent_id].type != type) ||
- (type == 'seeding' && !d.torrents[torrent_id].seeding)) {
- var name = $.trim($(this).children('td').eq(1).clone().children('span, div').remove().end().text().match(/\s+([^[]+)(\s+\[|$)/)[1]);
- d.groups[group_id] = { name: name };
- if (type == 'seeding') { /* Special case seeding */
- if (d.torrents[torrent_id]) d.torrents[torrent_id].seeding = true;
- else d.torrents[torrent_id] = { type: 'unknown', seeding: true };
- } else {
- if (d.torrents[torrent_id]) d.torrents[torrent_id].type = type;
- else d.torrents[torrent_id] = { type: type, seeding: false };
- }
- found += 1;
- }
- }
- });
- if (found == 0) return 0;
- snatch_cache.serialize();
- return found;
- }
- /* Fetch and scan all pages of type, call callback when done */
- function scan_all_torrent_pages(type, page_cb, finish_cb) {
- var page = 1;
- var total = 0;
- function request_url() {
- return '/torrents.php?type='+type+'&userid='+whatcd_id+'&page='+page;
- }
- function error_handler(response, reason) {
- alert("Error in loading snatches");
- status.contents().append('<div><span style="color: red;">Error:</span> Unable to fetch '+type+' page '+page+' ('+reason+')</div>');
- status.show();
- finish_cb(total);
- }
- function page_handler(response) {
- if (response.status == 200) {
- var doc = $(new DOMParser().parseFromString(response.responseText, 'text/xml'));
- page_cb(type, page);
- var found = scan_torrent_page(doc, type);
- total += found;
- if (found == 0) { finish_cb(type, total); return; } /* End of asynchronous chain */
- page += 1;
- whatcd_proxy.get({ url: request_url(), callback: page_handler, error: error_handler });
- } else {
- error_handler(response, 'HTTP '+response.status);
- }
- }
- whatcd_proxy.get({ url: request_url(), callback: page_handler, error: error_handler });
- }
- /* Reset command */
- GM_registerMenuCommand('TehConnection.Eu Snatched: Reset', function() { snatch_cache.clear(); GM_setValue('last_update', '0'); location.reload(); });
- /* Register menu command to enter custom style */
- var custom_style = GM_getValue('custom_style', DEFAULT_STYLE);
- GM_registerMenuCommand('TehConnection.Eu Snatched: Enter custom style...', function() {
- var style = window.prompt('Enter CSS style (or blank to use default)\nClasses: .group_snatched, .snatched, .uploaded, .leeching, .seeding', custom_style);
- if (style) {
- GM_setValue('custom_style', style);
- location.reload();
- } else if (style == '') {
- GM_deleteValue('custom_style');
- location.reload();
- }
- });
- /* Inject CSS style */
- GM_addStyle(custom_style);
- /* Mark all links to torrents that are snatched/uploaded/leeching */
- function mark_snatched_links() {
- var d = snatch_cache.unserialize();
- /* Go through all links */
- $('#content').find('a').each(function(i) {
- var href = $(this).attr('href');
- if (href) {
- var group_id;
- var torrent_id;
- /* Find and mark links to snatched torrents */
- var m = href.match(/torrents\.php\?id=(\d+)&torrentid=(\d+)/);
- if (m) {
- group_id = m[1];
- torrent_id = m[2];
- } else {
- m = href.match(/torrents\.php\?torrentid=(\d+)/);
- if (m) {
- torrent_id = m[1];
- } else {
- m = href.match(/torrents\.php\?id=(\d+)/);
- if (m) group_id = m[1];
- }
- }
- /* Add classes */
- if (group_id && d.groups[group_id] &&
- (!torrent_id || !$(this).parent().parent().is('.group_torrent'))) {
- $(this).addClass('group_snatched');
- }
- if (torrent_id && d.torrents[torrent_id]) {
- $(this).addClass(d.torrents[torrent_id].type);
- if (d.torrents[torrent_id].seeding) $(this).addClass('seeding');
- }
- /* Change text if text is url */
- if ($(this).text() == $(this).attr('href') && group_id &&
- d.groups[group_id] && d.groups[group_id].name) {
- $(this).text(d.groups[group_id].name);
- }
- }
- });
- /* Mark links on album page in torrent table */
- if (/tehconnection\.eu\/torrents\.php/.test(document.URL)) {
- /* Parse search */
- var search = {};
- var search_list = document.location.search.substring(1).split('&');
- for (var i = 0; i < search_list.length; i++) {
- var pair = search_list[i].split('=');
- search[pair[0]] = pair[1];
- }
- if (search.id) {
- /* Album page */
- $('#content .torrent_table:first tr.group_torrent').each(function(i) {
- /* Find torrent id */
- var torrent_id;
- $(this).children('td').eq(0).children('span').eq(0).children('a').each(function(i) {
- var href = $(this).attr('href');
- if (href) {
- var m = href.match(/torrents\.php\?torrentid=(\d+)/);
- if (m) {
- torrent_id = m[1];
- $(this).removeClass('group_snatched snatched uploaded leeching seeding');
- return false;
- }
- }
- });
- if (torrent_id && d.torrents[torrent_id]) {
- var link = $(this).children('td').eq(0).children('a').eq(0);
- link.addClass(d.torrents[torrent_id].type);
- if (d.torrents[torrent_id].seeding) link.addClass('seeding');
- }
- });
- }
- }
- }
- /* Mark torrent as leeching when download link is clicked */
- function mark_download_links() {
- $('#content').find('a').each(function(i) {
- var href = $(this).attr('href');
- if (href) {
- /* Find download links */
- var m = href.match(/torrents\.php\?action=download&id=(\d+)/);
- if (m) {
- var torrent_id = m[1];
- $(this).click(function(event) {
- var d = snatch_cache.unserialize();
- d.torrents[torrent_id] = { type: 'leeching', seeding: false };
- snatch_cache.serialize();
- mark_snatched_links();
- });
- }
- }
- });
- }
- /* Scan current page */
- if (/tehconnection\.eu\/torrents\.php/.test(document.URL)) {
- /* Parse search */
- var search = {};
- var search_list = document.location.search.substring(1).split('&');
- for (var i = 0; i < search_list.length; i++) {
- var pair = search_list[i].split('=');
- search[pair[0]] = pair[1];
- }
- if ((search.type == 'snatched' || search.type == 'uploaded'
- || search.type == 'seeding' || search.type == 'leeching') && search.userid == whatcd_id) {
- var scan_status = $('<div>Scanning current page... <span></span></div>');
- status.contents().append(scan_status);
- status.show();
- /* Scan current page */
- var found = scan_torrent_page($(document), search.type);
- scan_status.children('span').text('Done ('+((found > 0) ? (found+' updates found') : 'no updates found')+')')
- status.show(5000);
- }
- }
- /* Mark links */
- mark_download_links();
- mark_snatched_links();
- /* Auto update */
- var now = new Date();
- var last_update = parseInt(GM_getValue('last_update', '0'));
- if (last_update + AUTO_UPDATE_INTERVAL*1000 < now.getTime()) {
- GM_setValue('last_update', now.getTime().toString());
- var jobs = 4;
- var total_found = {};
- /* Show auto update status */
- if (last_update == 0) {
- var update_status = {
- snatched: $('<div>Updating snatched: <span>Initializing...</span></div>'),
- uploaded: $('<div>Updating uploaded: <span>Initializing...</span></div>'),
- leeching: $('<div>Updating leeching: <span>Initializing...</span></div>'),
- seeding: $('<div>Updating seeding: <span>Initializing...</span></div>')
- };
- for (var type in update_status) status.contents().append(update_status[type]);
- status.show();
- }
- function scan_page_handler(type, page) {
- if (last_update == 0) {
- update_status[type].children('span').text('Page '+page+'...');
- status.show();
- }
- }
- function scan_finished_handler(type, found) {
- if (last_update == 0) {
- update_status[type].children('span').text('Done ('+((found > 0) ? (found+' updates found') : 'no updates found')+')');
- }
- jobs -= 1;
- total_found[type] = found;
- if (jobs == 0) {
- mark_snatched_links();
- if (last_update == 0) {
- var total = [];
- for (var type in total_found) if (total_found[type] > 0) total.push(type+': '+total_found[type]);
- status.contents().append('<div>Auto update done</div>');
- status.show(5000);
- }
- }
- }
- /* Rescan all types of torrent lists */
- scan_all_torrent_pages('snatched', scan_page_handler, scan_finished_handler);
- scan_all_torrent_pages('uploaded', scan_page_handler, scan_finished_handler);
- scan_all_torrent_pages('leeching', scan_page_handler, scan_finished_handler);
- scan_all_torrent_pages('seeding', scan_page_handler, scan_finished_handler);
- }
- })();