KitsuLabs
.
Edit Snippet
Perbarui kode atau detail snippet ini.
Filename / Title
Language
JavaScript
Python
HTML
CSS
JSON
SQL
Bash
TypeScript
PHP
Java
Go
Rust
Description
(Optional)
Short drama, directly using dramaboxdb api server.
Tags
Code Content
*
/*** @ Base: https://dramabox.web.id/ @ Author: Shannz @ Desc: Short drama, directly using dramaboxdb api server ***/ import axios from 'axios'; import * as cheerio from 'cheerio'; const CONFIG = { BASE_URL: 'https://dramabox.web.id', HEADERS: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } }; const request = async (url) => { try { const response = await axios.get(url, { headers: CONFIG.HEADERS }); return cheerio.load(response.data); } catch (error) { throw new Error(`Network Error: ${error.message}`); } }; const resolveUrl = (link) => { if (link && !link.startsWith('http')) { return `${CONFIG.BASE_URL}/${link.replace(/^\//, '')}`; } return link; }; const getBookIdFromUrl = (urlStr) => { try { const match = urlStr.match(/\/watch\/(\d+)/); if (match) return match[1]; const urlObj = new URL(urlStr); return urlObj.searchParams.get('bookId'); } catch (e) { return null; } }; export const dramabox = { home: async () => { const $ = await request(`${CONFIG.BASE_URL}/in`); const latest = []; $('.drama-grid .drama-card').each((_, el) => { const link = resolveUrl($(el).find('.watch-button').attr('href')); const episodes = $(el).find('.drama-meta span[itemprop="numberOfEpisodes"]').text().replace(/[^0-9]/g, ''); latest.push({ title: $(el).find('.drama-title').text().trim(), book_id: getBookIdFromUrl(link), image: $(el).find('.drama-image img').attr('src') || $(el).find('.drama-image img').attr('data-src'), episodes: episodes }); }); const trending = []; $('.sidebar-widget .rank-list .rank-item').each((_, el) => { const link = resolveUrl($(el).attr('href')); const episodes = $(el).find('.rank-meta span').text().replace(/[^0-9]/g, ''); trending.push({ rank: $(el).find('.rank-number').text().trim(), title: $(el).find('.rank-title').text().trim(), book_id: getBookIdFromUrl(link), image: $(el).find('.rank-image img').attr('src') || $(el).find('.rank-image img').attr('data-src'), episodes: episodes }); }); return { latest, trending }; }, search: async (query) => { const targetUrl = `${CONFIG.BASE_URL}/search.php?lang=in&q=${encodeURIComponent(query)}`; const $ = await request(targetUrl); const results = []; $('.drama-grid .drama-card').each((_, el) => { const link = resolveUrl($(el).find('.watch-button').attr('href')); const viewsRaw = $(el).find('.drama-meta span').first().text().trim(); results.push({ title: $(el).find('.drama-title').text().trim(), book_id: getBookIdFromUrl(link), views: viewsRaw, image: $(el).find('.drama-image img').attr('src') || $(el).find('.drama-image img').attr('data-src') }); }); return results; }, detail: async (bookId) => { if (!bookId) throw new Error("Book ID is required"); const targetUrl = `${CONFIG.BASE_URL}/watch/${bookId}`; const $ = await request(targetUrl); const fullTitle = $('.video-title').text().trim(); const cleanTitle = fullTitle.split('- Episode')[0].trim(); const episodes = []; $('.episodes-grid .episode-btn').each((_, el) => { episodes.push({ episode: parseInt($(el).text().trim()), id: $(el).attr('data-episode') }); }); const followersRaw = $('.video-meta span').first().text().trim(); const totalEpRaw = $('span[itemprop="numberOfEpisodes"]').text().replace(/[^0-9]/g, ''); return { book_id: bookId, title: cleanTitle, description: $('.video-description').text().trim(), thumbnail: $('meta[itemprop="thumbnailUrl"]').attr('content'), upload_date: $('meta[itemprop="uploadDate"]').attr('content'), stats: { followers: followersRaw, total_episodes: totalEpRaw, }, episode_list: episodes }; }, stream: async (bookId, episode) => { if (!bookId || episode === undefined || episode === null) { throw new Error("Book ID and Episode are required"); } const epPath = episode == 0 ? '' : `/ep-${episode}`; const targetUrl = `${CONFIG.BASE_URL}/watch/${bookId}${epPath}`; const $ = await request(targetUrl); const videoUrls = []; const rawHtml = $.html(); const qualitiesRegex = /const\s+initialQualities\s*=\s*(\[.*?\]);/s; const match = rawHtml.match(qualitiesRegex); if (match && match[1]) { try { const qualitiesData = JSON.parse(match[1]); qualitiesData.forEach(item => { if (item.quality && item.videoPath) { videoUrls.push({ quality: `${item.quality}p`, url: item.videoPath }); } }); } catch (error) { console.error("Gagal parsing JSON kualitas, lanjut ke metode fallback."); } } if (videoUrls.length === 0) { $('#qualityMenu .quality-option').each((_, el) => { const quality = $(el).attr('data-quality'); const url = $(el).attr('data-url'); if (quality && url) { videoUrls.push({ quality: `${quality}p`, url: url }); } }); } if (videoUrls.length === 0) { let fallbackUrl = $('#mainVideo source').attr('src') || $('#mainVideo').attr('data-hls-url') || $('#mainVideo').attr('src'); if (fallbackUrl) { videoUrls.push({ quality: 'default', url: fallbackUrl }); } } return { book_id: bookId, episode: episode, videos: videoUrls }; } }; /* (async () => { // Get Home console.log("Fetching Home..."); const home = await dramabox.home(); console.log("Result Home:", home); // Search Drama console.log("Searching Drama..."); const search = await dramabox.search('ceo'); console.log("Result Search:", search); // Detail Drama console.log("Detail Drama..."); const detail = await dramabox.detail(41000103051); console.log("Result Detail:", detail); // Get Stream Drama console.log("Fetching Stream Episode..."); const stream = await dramabox.stream(41000103051, 1) console.log("Result Stream Episode:", stream); })(); */
Editor is always dark mode for better readability.
Admin Access
Update Snippet
Cancel