From f199e6cf06f180ba7d6607c8278f89e608247eae Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 09:53:37 +0700 Subject: [PATCH 1/8] optimize code --- index.js | 81 +++++++++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) diff --git a/index.js b/index.js index dd4be5e..63733e8 100644 --- a/index.js +++ b/index.js @@ -29,8 +29,7 @@ let allAnimeData = []; const fetchAllAnimeData = async () => { try { const response = await ky.get(`${process.env.API_URL}/otakudesu/anime`).json(); - const animeData = response.data; - allAnimeData = animeData.flatMap(item => item.anime); + allAnimeData = response.data.flatMap(item => item.anime); } catch (error) { console.error('Error fetching all anime data:', error); } @@ -44,8 +43,7 @@ app.get('/', async (req, res) => { const page = req.query.page || 1; try { const response = await ky.get(`${process.env.API_URL}/otakudesu/ongoing?page=${page}`).json(); - const { data, pagination } = response; - res.render('index', { animes: data, pagination }); + res.render('index', { animes: response.data, pagination: response.pagination }); } catch (error) { console.error('Error fetching data:', error); res.status(500).send('Error fetching data'); @@ -54,18 +52,11 @@ app.get('/', async (req, res) => { // Search route with pagination app.get('/search', (req, res) => { - const query = req.query.q; - const page = parseInt(req.query.page) || 1; - const limit = 20; // Number of results per page - - if (!query) { - return res.redirect('/'); - } - - const filteredResults = allAnimeData.filter(anime => - anime.judul.toLowerCase().includes(query.toLowerCase()) - ); + const { q: query, page = 1 } = req.query; + if (!query) return res.redirect('/'); + const limit = 20; + const filteredResults = allAnimeData.filter(anime => anime.judul.toLowerCase().includes(query.toLowerCase())); const totalResults = filteredResults.length; const totalPages = Math.ceil(totalResults / limit); const startIndex = (page - 1) * limit; @@ -74,7 +65,7 @@ app.get('/search', (req, res) => { const pagination = { currentPage: page, - totalPages: totalPages, + totalPages, prevPage: page > 1 ? page - 1 : null, nextPage: page < totalPages ? page + 1 : null }; @@ -84,11 +75,9 @@ app.get('/search', (req, res) => { // Anime detail route app.get('/anime/:slug', async (req, res) => { - const slug = req.params.slug; try { - const response = await ky.get(`${process.env.API_URL}/otakudesu/anime/${slug}`).json(); - const anime = response.data; - res.render('detail', { anime }); + const response = await ky.get(`${process.env.API_URL}/otakudesu/anime/${req.params.slug}`).json(); + res.render('detail', { anime: response.data }); } catch (error) { console.error('Error fetching anime details:', error); res.status(500).send('Error fetching anime details'); @@ -97,14 +86,11 @@ app.get('/anime/:slug', async (req, res) => { // Episode detail route app.get('/episode', async (req, res) => { - const slug = req.query.slug; - if (!slug) { - return res.redirect('/'); - } + if (!req.query.slug) return res.redirect('/'); + try { - const response = await ky.get(`${process.env.API_URL}/otakudesu/episode/${slug}`).json(); - const episode = response.data; - res.render('episode', { episode }); + const response = await ky.get(`${process.env.API_URL}/otakudesu/episode/${req.query.slug}`).json(); + res.render('episode', { episode: response.data }); } catch (error) { console.error('Error fetching episode details:', error); res.status(500).send('Error fetching episode details'); @@ -112,9 +98,9 @@ app.get('/episode', async (req, res) => { }); // All anime route -app.get('/all-anime', async (req, res) => { - const page = req.query.page || 1; - const limit = 20; // Number of anime per page +app.get('/all-anime', (req, res) => { + const { page = 1 } = req.query; + const limit = 20; const totalAnimes = allAnimeData.length; const totalPages = Math.ceil(totalAnimes / limit); @@ -124,7 +110,7 @@ app.get('/all-anime', async (req, res) => { const pagination = { currentPage: page, - totalPages: totalPages, + totalPages, prevPage: page > 1 ? page - 1 : null, nextPage: page < totalPages ? page + 1 : null }; @@ -136,8 +122,7 @@ app.get('/all-anime', async (req, res) => { app.get('/genres', async (req, res) => { try { const response = await ky.get(`${process.env.API_URL}/otakudesu/genres`).json(); - const genres = response.data; - res.render('genres', { genres }); + res.render('genres', { genres: response.data }); } catch (error) { console.error('Error fetching genres:', error); res.status(500).send('Error fetching genres'); @@ -146,13 +131,12 @@ app.get('/genres', async (req, res) => { // Anime by genre route app.get('/genres/:slug', async (req, res) => { - const slug = req.params.slug; - const page = req.query.page || 1; + const { slug } = req.params; + const { page = 1 } = req.query; try { const response = await ky.get(`${process.env.API_URL}/otakudesu/genres/${slug}?page=${page}`).json(); - const { data, pagination } = response; - res.render('genre-anime', { animes: data, pagination, genre: slug }); + res.render('genre-anime', { animes: response.data, pagination: response.pagination, genre: slug }); } catch (error) { console.error('Error fetching anime by genre:', error); res.status(500).send('Error fetching anime by genre'); @@ -166,35 +150,24 @@ const fetchShortlink = (url) => { const request = protocol.get(url, (response) => { if (response.statusCode >= 300 && response.statusCode < 400) { - const location = response.headers.location; - if (location) { - return resolve(location); - } + return resolve(response.headers.location); } resolve(null); }); - request.on('error', (error) => { - reject(error); - }); - + request.on('error', reject); request.end(); }); }; // Route to decode shortlink app.get('/decode-shortlink', async (req, res) => { - const shortlink = req.query.url; - - if (!shortlink) { - return res.status(400).send('URL parameter is required'); - } + const { url: shortlink } = req.query; + if (!shortlink) return res.status(400).send('URL parameter is required'); try { const redirectionUrl = await fetchShortlink(shortlink); - if (redirectionUrl) { - return res.send(redirectionUrl); - } + if (redirectionUrl) return res.send(redirectionUrl); res.status(404).send('No redirection found'); } catch (error) { console.error('Error decoding shortlink:', error); @@ -205,4 +178,4 @@ app.get('/decode-shortlink', async (req, res) => { // Start the server app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); -}); +}); \ No newline at end of file From bb9ef1bb9db96d12db3923acecb121741ef5330c Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 10:00:45 +0700 Subject: [PATCH 2/8] add interval for fetchAllAnimeData every 60 minutes --- index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.js b/index.js index 63733e8..6bee590 100644 --- a/index.js +++ b/index.js @@ -38,6 +38,9 @@ const fetchAllAnimeData = async () => { // Fetch data on server start fetchAllAnimeData(); +// Periodically update all anime data (every 60 minutes) +setInterval(fetchAllAnimeData, 60 * 60 * 1000); + // Home route to list content with pagination app.get('/', async (req, res) => { const page = req.query.page || 1; From c9fbf8048845d4f6a48a0acb09c1770cce78166a Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 10:06:10 +0700 Subject: [PATCH 3/8] optimize code --- index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6bee590..e75a9fd 100644 --- a/index.js +++ b/index.js @@ -36,10 +36,14 @@ const fetchAllAnimeData = async () => { }; // Fetch data on server start -fetchAllAnimeData(); +(async () => { + await fetchAllAnimeData(); +})(); // Periodically update all anime data (every 60 minutes) -setInterval(fetchAllAnimeData, 60 * 60 * 1000); +setInterval(async () => { + await fetchAllAnimeData(); +}, 60 * 60 * 1000); // Home route to list content with pagination app.get('/', async (req, res) => { From f5f8bcb3c9e8499afb574d67abae71edf5835344 Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 12:55:50 +0700 Subject: [PATCH 4/8] update all-anime pages to use live search --- index.js | 43 +++++---- views/all-anime.ejs | 210 +++++++++++++++++++++++++++++++++----------- 2 files changed, 185 insertions(+), 68 deletions(-) diff --git a/index.js b/index.js index e75a9fd..65ccd66 100644 --- a/index.js +++ b/index.js @@ -57,27 +57,36 @@ app.get('/', async (req, res) => { } }); -// Search route with pagination -app.get('/search', (req, res) => { - const { q: query, page = 1 } = req.query; - if (!query) return res.redirect('/'); +// Search route with pagination parameters +app.get('/search-ajax', (req, res) => { + const { q: query, page = 1, limit = 20 } = req.query; + if (!query) return res.json({ results: [] }); - const limit = 20; - const filteredResults = allAnimeData.filter(anime => anime.judul.toLowerCase().includes(query.toLowerCase())); - const totalResults = filteredResults.length; - const totalPages = Math.ceil(totalResults / limit); + let filteredResults = allAnimeData.filter(anime => anime.judul.toLowerCase().includes(query.toLowerCase())); const startIndex = (page - 1) * limit; - const endIndex = startIndex + limit; - const paginatedResults = filteredResults.slice(startIndex, endIndex); + const endIndex = page * limit; + const results = filteredResults.slice(startIndex, endIndex); - const pagination = { - currentPage: page, - totalPages, - prevPage: page > 1 ? page - 1 : null, - nextPage: page < totalPages ? page + 1 : null - }; + res.json({ + results: results, + currentPage: parseInt(page, 10), + totalPages: Math.ceil(filteredResults.length / limit) + }); +}); + +// All anime route with pagination parameters +app.get('/all-anime-ajax', (req, res) => { + const { page = 1, limit = 20 } = req.query; - res.render('search', { results: paginatedResults, query, pagination }); + const startIndex = (page - 1) * limit; + const endIndex = page * limit; + const results = allAnimeData.slice(startIndex, endIndex); + + res.json({ + results: results, + currentPage: parseInt(page, 10), + totalPages: Math.ceil(allAnimeData.length / limit) + }); }); // Anime detail route diff --git a/views/all-anime.ejs b/views/all-anime.ejs index 29e8720..f7262ee 100644 --- a/views/all-anime.ejs +++ b/views/all-anime.ejs @@ -6,63 +6,171 @@ All Anime - ZANNIME + <%- include('navbar') %> -
-

All Anime

-
-
- - +
+
+

All Anime

+ +
+ + + + + + + + + <% animes.slice(0, 20).forEach(anime => { %> + + + + + <% }) %> + +
JudulAction
<%= anime.judul %> + View +
- - - - - - - - - - <% animes.forEach(anime => { %> - - - - - <% }) %> - -
JudulAction
<%= anime.judul %> - View -
- - + +
+ <%- include('footer') %>
- <%- include('footer') %> + \ No newline at end of file From 2b2512d02980664f89decb02ef8ade68f8027d2f Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 13:23:59 +0700 Subject: [PATCH 5/8] add Mega to streaming source --- views/episode.ejs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/views/episode.ejs b/views/episode.ejs index 5236041..f48ab49 100644 --- a/views/episode.ejs +++ b/views/episode.ejs @@ -22,7 +22,7 @@ <% episode.downloadUrl.forEach(quality => { %> <% if ((quality.kualitas === 'Mp4_720p') || (quality.kualitas === 'Mp4_1080p') || (quality.kualitas === 'MKV_1080p') || (quality.kualitas === '720p') || (quality.kualitas === '1080p')) { %> <% quality.urls.forEach(url => { %> - <% if ( ['Acefile', 'Pdrain', 'PDrain', 'KFiles', 'Kraken'].some(item => url.judul.toLowerCase().includes(item.toLowerCase())) ) { %> + <% if ( ['Acefile', 'Pdrain', 'PDrain', 'KFiles', 'Kraken', 'Mega'].some(item => url.judul.toLowerCase().includes(item.toLowerCase())) ) { %> <% } %> <% }) %> @@ -94,9 +94,15 @@ } else if (url.includes('acefile.co')) { const fileId = url.split('/f/')[1].split('/')[0]; return `https://acefile.co/player/${fileId}`; + } else if (url.includes('mega.nz')) { + const parts = url.split('#'); + if (parts.length !== 2) return url; + const fileId = parts[0].split('/').pop(); + const key = parts[1]; + return `https://mega.nz/embed/${fileId}#${key}`; } - return url; // Return the original URL if no specific format is found -} + return url; // Return the original URL if no specific format is found + } document.getElementById('streaming-source').addEventListener('change', async function() { const selectedUrl = this.value; From 5518673029b8c256db0ec83a8ea4ec3735ce0f46 Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 18:51:27 +0700 Subject: [PATCH 6/8] edit .dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 736d9d9..44e081b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,6 +11,7 @@ dockerfiles # Ignore Git-related files and directories .git .gitignore +.github README.md # Ignore log files From 6eb5440a920d7dfcb4ad92689e5a0ea44ba680d0 Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 18:53:52 +0700 Subject: [PATCH 7/8] edit cd --- .github/workflows/cd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index dd90a31..54f3919 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -45,7 +45,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} key: ${{ secrets.PRIVATE_KEY }} script: | - cd ~/.apps/zannime-dev + cd ~/.apps/zannime_dev git pull git status sudo docker compose -f docker-compose-dev.yaml build From b0ebce67953c9e3545bc957389b61da9b282b6de Mon Sep 17 00:00:00 2001 From: fauzanmhr Date: Thu, 22 Aug 2024 18:56:22 +0700 Subject: [PATCH 8/8] edit cd --- .dockerignore | 3 ++- .github/workflows/cd.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 44e081b..c5d68f2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -21,4 +21,5 @@ README.md *.tmp # Ignore any other unnecessary files or directories -wajik-anime-api \ No newline at end of file +wajik-anime-api +.idea \ No newline at end of file diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 54f3919..33d42ee 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -1,4 +1,4 @@ -name: Node.js CD +name: Auto Deploy To VPS on: push: