Kufirc Thumbnail Display

Displays thumbnails for torrents on Kufirc browse pages

Size

8.1 KB

Version

1.1.4

Created

Feb 25, 2026

Updated

about 2 months ago

1// ==UserScript==
2// @name		Kufirc Thumbnail Display
3// @description		Displays thumbnails for torrents on Kufirc browse pages
4// @version		1.1.4
5// @match		https://*.kufirc.com/*
6// @icon		https://kufirc.com/favicon.ico?v=1756621831
7// @grant		GM.xmlHttpRequest
8// ==/UserScript==
9(function() {
10    'use strict';
11
12    console.log('Kufirc Thumbnail Display extension loaded');
13
14    // Add styles for thumbnails
15    GM_addStyle(`
16        .thumbnail-container {
17            display: inline-block;
18            margin-left: 10px;
19            vertical-align: middle;
20            position: relative;
21        }
22        
23        .thumbnail-preview {
24            max-width: 250px;
25            max-height: 170px;
26            border: 2px solid #444;
27            border-radius: 4px;
28            cursor: pointer;
29            transition: transform 0.2s, box-shadow 0.2s;
30        }
31        
32        .thumbnail-preview:hover {
33            transform: scale(1.05);
34            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
35            border-color: #666;
36        }
37        
38        .thumbnail-loading {
39            display: inline-block;
40            width: 250px;
41            height: 170px;
42            background: #2a2a2a;
43            border: 2px solid #444;
44            border-radius: 4px;
45            text-align: center;
46            line-height: 170px;
47            color: #888;
48            font-size: 12px;
49        }
50        
51        .thumbnail-error {
52            display: inline-block;
53            width: 250px;
54            height: 170px;
55            background: #3a2a2a;
56            border: 2px solid #644;
57            border-radius: 4px;
58            text-align: center;
59            line-height: 170px;
60            color: #a66;
61            font-size: 11px;
62        }
63        
64        .thumbnail-modal {
65            display: none;
66            position: fixed;
67            z-index: 10000;
68            left: 0;
69            top: 0;
70            width: 100%;
71            height: 100%;
72            background-color: rgba(0,0,0,0.9);
73            justify-content: center;
74            align-items: center;
75        }
76        
77        .thumbnail-modal.active {
78            display: flex;
79        }
80        
81        .thumbnail-modal img {
82            max-width: 90%;
83            max-height: 90%;
84            border: 3px solid #666;
85            border-radius: 8px;
86        }
87        
88        .thumbnail-modal-close {
89            position: absolute;
90            top: 20px;
91            right: 40px;
92            color: #fff;
93            font-size: 40px;
94            font-weight: bold;
95            cursor: pointer;
96            z-index: 10001;
97        }
98        
99        .thumbnail-modal-close:hover {
100            color: #ccc;
101        }
102    `);
103
104    // Create modal for full-size image viewing
105    const modal = document.createElement('div');
106    modal.className = 'thumbnail-modal';
107    modal.innerHTML = '<span class="thumbnail-modal-close">&times;</span><img src="" alt="Full size thumbnail">';
108    document.body.appendChild(modal);
109
110    const modalImg = modal.querySelector('img');
111    const closeBtn = modal.querySelector('.thumbnail-modal-close');
112
113    closeBtn.addEventListener('click', () => {
114        modal.classList.remove('active');
115    });
116
117    modal.addEventListener('click', (e) => {
118        if (e.target === modal) {
119            modal.classList.remove('active');
120        }
121    });
122
123    // Function to fetch torrent page and extract thumbnail
124    async function fetchThumbnail(torrentId) {
125        try {
126            console.log(`Fetching thumbnail for torrent ID: ${torrentId}`);
127            
128            const response = await GM.xmlhttpRequest({
129                method: 'GET',
130                url: `https://kufirc.com/torrents.php?id=${torrentId}`
131            });
132
133            const parser = new DOMParser();
134            const doc = parser.parseFromString(response.responseText, 'text/html');
135
136            // Look for images in the torrent page
137            const allImages = Array.from(doc.querySelectorAll('img')).filter(img => {
138                const src = img.src;
139                return src && 
140                       src.startsWith('http') && 
141                       !src.includes('icon') && 
142                       !src.includes('arrow') && 
143                       !src.includes('snatched') && 
144                       !src.includes('logo') &&
145                       !src.includes('seeders') &&
146                       !src.includes('leechers') &&
147                       !src.includes('favicon') &&
148                       !src.includes('freedownload');
149            });
150
151            if (allImages.length > 0) {
152                const thumbnailUrl = allImages[0].src;
153                console.log(`Found thumbnail: ${thumbnailUrl}`);
154                return thumbnailUrl;
155            }
156
157            console.log(`No thumbnail found for torrent ID: ${torrentId}`);
158            return null;
159        } catch (error) {
160            console.error(`Error fetching thumbnail for torrent ${torrentId}:`, error);
161            return null;
162        }
163    }
164
165    // Function to add thumbnail to torrent row
166    async function addThumbnailToRow(link) {
167        // Check if thumbnail already added
168        if (link.dataset.thumbnailAdded === 'true') {
169            return;
170        }
171        link.dataset.thumbnailAdded = 'true';
172
173        // Extract torrent ID from link
174        const match = link.href.match(/id=(\d+)/);
175        if (!match) {
176            console.log('Could not extract torrent ID from link:', link.href);
177            return;
178        }
179
180        const torrentId = match[1];
181
182        // Create thumbnail container
183        const container = document.createElement('div');
184        container.className = 'thumbnail-container';
185        
186        // Add loading indicator
187        const loading = document.createElement('div');
188        loading.className = 'thumbnail-loading';
189        loading.textContent = 'Loading...';
190        container.appendChild(loading);
191
192        // Insert after the link
193        link.parentNode.appendChild(container);
194
195        // Fetch thumbnail
196        const thumbnailUrl = await fetchThumbnail(torrentId);
197
198        if (thumbnailUrl) {
199            // Replace loading with actual thumbnail
200            const img = document.createElement('img');
201            img.className = 'thumbnail-preview';
202            img.src = thumbnailUrl;
203            img.alt = 'Torrent thumbnail';
204            
205            img.addEventListener('click', () => {
206                modalImg.src = thumbnailUrl;
207                modal.classList.add('active');
208            });
209
210            img.addEventListener('error', () => {
211                container.innerHTML = '<div class="thumbnail-error">Failed to load</div>';
212            });
213
214            container.innerHTML = '';
215            container.appendChild(img);
216        } else {
217            // No thumbnail found
218            container.innerHTML = '<div class="thumbnail-error">No thumbnail</div>';
219        }
220    }
221
222    // Function to process all torrent links on the page
223    function processTorrentLinks() {
224        const torrentLinks = document.querySelectorAll('a[href*="/torrents.php?id="]');
225        console.log(`Found ${torrentLinks.length} torrent links`);
226
227        torrentLinks.forEach((link, index) => {
228            // Add a small delay between requests to avoid overwhelming the server
229            setTimeout(() => {
230                addThumbnailToRow(link);
231            }, index * 500);
232        });
233    }
234
235    // Initialize when page is ready
236    function init() {
237        console.log('Initializing Kufirc Thumbnail Display');
238        
239        // Wait for the torrent table to be present
240        const checkTable = setInterval(() => {
241            const torrentTable = document.querySelector('#torrent_table, .torrent_table');
242            if (torrentTable) {
243                clearInterval(checkTable);
244                console.log('Torrent table found, processing links');
245                processTorrentLinks();
246            }
247        }, 500);
248
249        // Stop checking after 10 seconds
250        setTimeout(() => clearInterval(checkTable), 10000);
251    }
252
253    // Run when DOM is ready
254    if (document.readyState === 'loading') {
255        document.addEventListener('DOMContentLoaded', init);
256    } else {
257        init();
258    }
259})();
Kufirc Thumbnail Display | Robomonkey