mirror of
https://github.com/karl0ss/JDRssDownloader.git
synced 2025-04-27 20:03:40 +01:00
commit
cefd13c8da
@ -3,68 +3,66 @@ const { linkAdder } = require('./JDLinkAdder');
|
|||||||
const { getLinksFromURL } = require('./LinkGrabber')
|
const { getLinksFromURL } = require('./LinkGrabber')
|
||||||
const { checkFileName } = require('./checkFileName')
|
const { checkFileName } = require('./checkFileName')
|
||||||
const { checkDownloadHistory } = require('./checkDownloadHistory')
|
const { checkDownloadHistory } = require('./checkDownloadHistory')
|
||||||
const { telegrambot } = require('./telegramCommunication')
|
|
||||||
|
|
||||||
async function filterFeed() {
|
async function filterFeed() {
|
||||||
let myshowlist = JSON.parse(fs.readFileSync('config.json')).Shows
|
let myshowlist = JSON.parse(fs.readFileSync('config.json')).Shows
|
||||||
let hevcSwitch = JSON.parse(fs.readFileSync('config.json')).OnlyHEVC
|
let hevcSwitch = JSON.parse(fs.readFileSync('config.json')).OnlyHEVC
|
||||||
let feed = JSON.parse(fs.readFileSync('./feedCache.json'));
|
let feed = JSON.parse(fs.readFileSync('./feedCache.json'));
|
||||||
let retry_show_cache = []
|
let retryShowCache = []
|
||||||
let urls_to_check = []
|
let urlsToCheck = []
|
||||||
|
|
||||||
|
|
||||||
for (let show of myshowlist) {
|
for (let show of myshowlist) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Find show on feed
|
// Find show on feed
|
||||||
let list_filtered_for_show = feed.filter(item => item.title.includes(show.Name))
|
let listFilteredForShow = feed.filter(item => item.title.includes(show.Name))
|
||||||
if (list_filtered_for_show.length > 0) {
|
if (listFilteredForShow.length > 0) {
|
||||||
for (let match of list_filtered_for_show) {
|
for (let match of listFilteredForShow) {
|
||||||
// If show is found get url then return all links on that page
|
// If show is found get url then return all links on that page
|
||||||
let full_link_list_from_page = await getLinksFromURL(match.link)
|
let fullLinkListFromPage = await getLinksFromURL(match.link)
|
||||||
if (hevcSwitch) {
|
if (hevcSwitch) {
|
||||||
// Only get urls with HEVC in name
|
// Only get urls with HEVC in name
|
||||||
urls_to_check = full_link_list_from_page.filter(item => item.includes('HEVC'))
|
urlsToCheck = fullLinkListFromPage.filter(item => item.includes('HEVC'))
|
||||||
if (urls_to_check.length == 0) {
|
if (urlsToCheck.length == 0) {
|
||||||
// If no urls with HEVC check for H265
|
// If no urls with HEVC check for H265
|
||||||
urls_to_check = full_link_list_from_page.filter(item => item.includes('H265'))
|
urlsToCheck = fullLinkListFromPage.filter(item => item.includes('H265'))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
urls_to_check = full_link_list_from_page
|
urlsToCheck = fullLinkListFromPage
|
||||||
}
|
}
|
||||||
// Only keep urls that match show quality
|
// Only keep urls that match show quality
|
||||||
let urls_with_quality_in_url = urls_to_check.filter(item => item.includes(show.Quality))
|
let urlsWithQualityInUrl = urlsToCheck.filter(item => item.includes(show.Quality))
|
||||||
// Remove any url trying to direct to a torrent site search
|
// Remove any url trying to direct to a torrent site search
|
||||||
let urls_without_torrent_in_url = urls_with_quality_in_url.filter(item => !item.includes('torrent'))
|
let urlsWithoutTorrentInUrl = urlsWithQualityInUrl.filter(item => !item.includes('torrent'))
|
||||||
// Remove any url that doesn't include MeGusta
|
// Remove any url that doesn't include MeGusta
|
||||||
if (hevcSwitch) {
|
if (hevcSwitch) {
|
||||||
pre_nitroFlare = urls_without_torrent_in_url.filter(item => item.includes('MeGusta'))
|
preNitroflare = urlsWithoutTorrentInUrl.filter(item => item.includes('MeGusta'))
|
||||||
} else {
|
} else {
|
||||||
pre_nitroFlare = urls_without_torrent_in_url
|
preNitroflare = urlsWithoutTorrentInUrl
|
||||||
}
|
}
|
||||||
// NitroFlare doesn't group with the rest of the links in JD, remove them.
|
// NitroFlare doesn't group with the rest of the links in JD, remove them.
|
||||||
let remove_nitroflare = pre_nitroFlare.filter(item => !item.includes('nitro'))
|
let removeNitroflare = preNitroflare.filter(item => !item.includes('nitro'))
|
||||||
// Do some stuff
|
// Do some stuff
|
||||||
urlObj = checkFileName(remove_nitroflare)
|
urlObj = checkFileName(removeNitroflare)
|
||||||
let download_list = urlObj.urlList
|
let downloadList = urlObj.urlList
|
||||||
// Send Links to JDdownloader
|
// Send Links to JDdownloader
|
||||||
if (download_list.length !== 0) {
|
if (downloadList.length !== 0) {
|
||||||
if (checkDownloadHistory(urlObj)) {
|
if (checkDownloadHistory(urlObj)) {
|
||||||
log.info(urlObj.fileName + ' already downloaded, skipped.')
|
log.info(urlObj.fileName + ' already downloaded, skipped.')
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
log.info(download_list.length + ' links for ' + urlObj.fileName + ' have been sent to JDdownloader.')
|
log.tele(downloadList.length + ' links for ' + urlObj.fileName + ' have been sent to JDdownloader.')
|
||||||
if (TelegramBotConfig) {
|
linkAdder(downloadList)
|
||||||
telegrambot(download_list.length + ' links for ' + urlObj.fileName + ' have been sent to JDdownloader.')
|
global.linkCheckTime = new Date();
|
||||||
}
|
|
||||||
linkAdder(download_list)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No HEVC links found
|
// No HEVC links found
|
||||||
log.info(download_list.length + ' links for ' + show.Name + ' have been found, will recheck next time.')
|
log.info(downloadList.length + ' links for ' + show.Name + ' have been found, will recheck next time.')
|
||||||
for (let feed_item of list_filtered_for_show) {
|
for (let feedItem of listFilteredForShow) {
|
||||||
retry_show_cache.push(feed_item)
|
retryShowCache.push(feedItem)
|
||||||
}
|
}
|
||||||
|
global.linkCheckTime = new Date();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -73,10 +71,12 @@ async function filterFeed() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error('Something went wrong ' + error)
|
log.error('Something went wrong ' + error)
|
||||||
|
global.linkCheckTime = new Date();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info('Wiping feed cache')
|
log.info('Wiping feed cache')
|
||||||
fs.writeFileSync('./feedCache.json', JSON.stringify(retry_show_cache));
|
fs.writeFileSync('./feedCache.json', JSON.stringify(retryShowCache));
|
||||||
|
global.linkCheckTime = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -20,8 +20,7 @@ async function feedUpdater() {
|
|||||||
// Save the file
|
// Save the file
|
||||||
log.info(updatedArray.length + ' items in file cache')
|
log.info(updatedArray.length + ' items in file cache')
|
||||||
fs.writeFileSync('./feedCache.json', JSON.stringify(updatedArray));
|
fs.writeFileSync('./feedCache.json', JSON.stringify(updatedArray));
|
||||||
|
global.rssRefreshTime = new Date();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,37 +1,57 @@
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
config = JSON.parse(fs.readFileSync('config.json'))
|
||||||
|
|
||||||
const { feedUpdater } = require('./FeedUpdater')
|
const { feedUpdater } = require('./FeedUpdater')
|
||||||
const { filterFeed } = require('./FeedFilter')
|
const { filterFeed } = require('./FeedFilter')
|
||||||
const { telegrambot } = require('./telegramCommunication')
|
const { telegrambot } = require('./telegramCommunication')
|
||||||
const version = require('./package.json').version;
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const cors = require('cors');
|
||||||
|
const path = require("path");
|
||||||
|
const basicAuth = require('express-basic-auth')
|
||||||
|
const app = express();
|
||||||
|
app.set("views", path.join(__dirname, "views"));
|
||||||
|
app.set("view engine", "pug");
|
||||||
|
app.use(express.static(path.join(__dirname, "public")));
|
||||||
|
app.use(cors());
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
require('./routes')(app);
|
||||||
|
app.use(basicAuth({
|
||||||
|
users: { 'admin': config.AdminPassword },
|
||||||
|
challenge: true,
|
||||||
|
}))
|
||||||
|
|
||||||
global.TelegramBotConfig = JSON.parse(fs.readFileSync('config.json')).TelegramBot
|
global.rssRefreshTime = new Date();
|
||||||
|
global.linkCheckTime = new Date();
|
||||||
|
global.version = require('./package.json').version;
|
||||||
|
|
||||||
global.log = require('simple-node-logger').createSimpleLogger({
|
global.log = require('simple-node-logger').createSimpleLogger({
|
||||||
logFilePath: 'jdrssdownloader.log',
|
logFilePath: 'jdrssdownloader.log',
|
||||||
timestampFormat: 'YYYY-MM-DD HH:mm:ss.SSS'
|
timestampFormat: 'YYYY-MM-DD HH:mm:ss.SSS'
|
||||||
});
|
});
|
||||||
|
|
||||||
async function main() {
|
log.tele = function () {
|
||||||
log.info('Running JDRssDownloader version ' + version)
|
var args = Array.prototype.slice.call(arguments),
|
||||||
|
entry = log.log('info', args);
|
||||||
|
process.nextTick(function () {
|
||||||
|
if (config.TelegramBot) {
|
||||||
|
telegrambot(entry.msg[0])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (TelegramBotConfig) {
|
async function main() {
|
||||||
telegrambot('Running JDRssDownloader version ' + version)
|
log.tele('Running JDRssDownloader version ' + global.version)
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
RSSFeedRefreshMins = JSON.parse(fs.readFileSync('config.json')).RSSFeedRefreshMins
|
RSSFeedRefreshMins = config.RSSFeedRefreshMins
|
||||||
JDPostLinksMins = JSON.parse(fs.readFileSync('config.json')).JDPostLinksMins
|
JDPostLinksMins = config.JDPostLinksMins
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error('config.json file is missing.')
|
log.error('config.json file is missing.')
|
||||||
}
|
}
|
||||||
log.info('Refreshing RSS Items every ' + RSSFeedRefreshMins + ' Minutes')
|
log.tele('Refreshing RSS Items every ' + RSSFeedRefreshMins + ' Minutes')
|
||||||
if (TelegramBotConfig) {
|
log.tele('Checking for links and sending to JDdownloader every ' + JDPostLinksMins + ' Minutes')
|
||||||
telegrambot('Refreshing RSS Items every ' + RSSFeedRefreshMins + ' Minutes')
|
app.listen(config.WebUIPort, () => log.info(`WebUi is listening on ${config.WebUIPort}!`))
|
||||||
}
|
|
||||||
log.info('Checking for links and sending to JDdownloader every ' + JDPostLinksMins + ' Minutes')
|
|
||||||
if (TelegramBotConfig) {
|
|
||||||
telegrambot('Checking for links and sending to JDdownloader every ' + JDPostLinksMins + ' Minutes')
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(await feedUpdater, RSSFeedRefreshMins * 60000);
|
setInterval(await feedUpdater, RSSFeedRefreshMins * 60000);
|
||||||
setInterval(await filterFeed, JDPostLinksMins * 60000);
|
setInterval(await filterFeed, JDPostLinksMins * 60000);
|
||||||
}
|
}
|
||||||
|
10
README.md
10
README.md
@ -19,11 +19,16 @@ There is a `config-sample.json` file that needs to be renamed to `config.json`,
|
|||||||
|
|
||||||
- JDUserName - Your MyJDownloader Username
|
- JDUserName - Your MyJDownloader Username
|
||||||
- JDPassword - Your MyJDownloader Password
|
- JDPassword - Your MyJDownloader Password
|
||||||
|
- AdminPassword - Password to be set for the WebUI
|
||||||
|
- WebUIPort - Port for the WebUI to run on
|
||||||
- RSSFeed - The url to the rss feed you want to watch (Only tested with - rlsbb)
|
- RSSFeed - The url to the rss feed you want to watch (Only tested with - rlsbb)
|
||||||
- RSSFeedRefreshMins - How often to poll your rss feed down to local file cache
|
- RSSFeedRefreshMins - How often to poll your rss feed down to local file cache
|
||||||
- JDPostLinksMins - How often to check your file cache for your shows and send found links to JDownloader
|
- JDPostLinksMins - How often to check your file cache for your shows and send found links to JDownloader
|
||||||
- Autostart - Tells JDownloader to add and start the downloads straight away (true/false)
|
- Autostart - Tells JDownloader to add and start the downloads straight away (true/false)
|
||||||
- OnlyHEVC - If false, this will download any files that it finds on the post that matches the quality (true/false)
|
- OnlyHEVC - If false, this will download any files that it finds on the post that matches the quality (true/false)
|
||||||
|
- TelegramBot - Set to true if you wish to have updates sent via telegramBot
|
||||||
|
- TelegramBotID - Set this to the id you recieve from TheBotFather
|
||||||
|
- TelegramChatID - Chat or Group ID for the bot to send messages to
|
||||||
- Shows - This needs to be a comma separated list of json objects of the show and quality you want to check for.
|
- Shows - This needs to be a comma separated list of json objects of the show and quality you want to check for.
|
||||||
|
|
||||||
An example shown below
|
An example shown below
|
||||||
@ -32,11 +37,16 @@ An example shown below
|
|||||||
{
|
{
|
||||||
"JDUserName": "User",
|
"JDUserName": "User",
|
||||||
"JDPassword": "Pass",
|
"JDPassword": "Pass",
|
||||||
|
"AdminPassword":"",
|
||||||
|
"WebUIPort": 3100,
|
||||||
"RSSFeed": "https://mypage.com/feed/",
|
"RSSFeed": "https://mypage.com/feed/",
|
||||||
"RSSFeedRefreshMins": 10,
|
"RSSFeedRefreshMins": 10,
|
||||||
"JDPostLinksMins": 180,
|
"JDPostLinksMins": 180,
|
||||||
"Autostart": false,
|
"Autostart": false,
|
||||||
"OnlyHEVC": true,
|
"OnlyHEVC": true,
|
||||||
|
"TelegramBot": true,
|
||||||
|
"TelegramBotID":"",
|
||||||
|
"TelegramChatID":123456789,
|
||||||
"Shows": [
|
"Shows": [
|
||||||
{
|
{
|
||||||
"Name": "Obi-Wan Kenobi",
|
"Name": "Obi-Wan Kenobi",
|
||||||
|
47
apiFunctions.js
Normal file
47
apiFunctions.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { config } = require('process');
|
||||||
|
|
||||||
|
async function addNewShow(showData) {
|
||||||
|
let config = JSON.parse(fs.readFileSync('config.json'))
|
||||||
|
let exist = false
|
||||||
|
for (let show of config.Shows) {
|
||||||
|
if (show.Name == showData.showName) {
|
||||||
|
exist = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exist) {
|
||||||
|
log.error(showData.showName + ' Already exists in list and not added')
|
||||||
|
} else {
|
||||||
|
config.Shows.push({
|
||||||
|
"Name": showData.showName,
|
||||||
|
"Quality": showData.quality
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
fs.writeFileSync('config.json', JSON.stringify(config));
|
||||||
|
log.info(showData.showName + ' Added to the list, checking for ' + showData.quality + 'p')
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeShow(showData) {
|
||||||
|
let config = JSON.parse(fs.readFileSync('config.json'))
|
||||||
|
|
||||||
|
myArray = config.Shows.filter(function (obj) {
|
||||||
|
return obj.Name !== showData.showName;
|
||||||
|
});
|
||||||
|
|
||||||
|
config.Shows = myArray
|
||||||
|
try {
|
||||||
|
fs.writeFileSync('config.json', JSON.stringify(config));
|
||||||
|
log.info(showData.showName + ' Removed from tracking list.')
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addNewShow, removeShow
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,14 @@
|
|||||||
{
|
{
|
||||||
"JDUserName": "",
|
"JDUserName": "",
|
||||||
"JDPassword": "",
|
"JDPassword": "",
|
||||||
|
"AdminPassword":"",
|
||||||
|
"WebUIPort": 3100,
|
||||||
"RSSFeed": "",
|
"RSSFeed": "",
|
||||||
"RSSFeedRefreshMins": 10,
|
"RSSFeedRefreshMins": 10,
|
||||||
"JDPostLinksMins": 180,
|
"JDPostLinksMins": 180,
|
||||||
"Autostart": false,
|
"Autostart": false,
|
||||||
"OnlyHEVC": true,
|
"OnlyHEVC": true,
|
||||||
|
"TelegramBot": true,
|
||||||
"TelegramBotID":"",
|
"TelegramBotID":"",
|
||||||
"TelegramChatID":123456789,
|
"TelegramChatID":123456789,
|
||||||
"Shows": [
|
"Shows": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jdrssdownloader",
|
"name": "jdrssdownloader",
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "JDRssDownloader.js",
|
"main": "JDRssDownloader.js",
|
||||||
"bin": "JDRssDownloader.js",
|
"bin": "JDRssDownloader.js",
|
||||||
@ -12,9 +12,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cheerio": "^1.0.0-rc.11",
|
"cheerio": "^1.0.0-rc.11",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"express-basic-auth": "^1.2.1",
|
||||||
"jdownloader-client": "^1.0.0",
|
"jdownloader-client": "^1.0.0",
|
||||||
|
"line-reader": "^0.4.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"node-telegram-bot-api": "^0.59.0",
|
"node-telegram-bot-api": "^0.59.0",
|
||||||
|
"pug": "^3.0.2",
|
||||||
"rss-parser": "^3.12.0",
|
"rss-parser": "^3.12.0",
|
||||||
"simple-node-logger": "^21.8.12"
|
"simple-node-logger": "^21.8.12"
|
||||||
},
|
},
|
||||||
|
152
public/style.css
Normal file
152
public/style.css
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css?family=Raleway:800|Merriweather+Sans|Share+Tech+Mono");
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--ui-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.06),
|
||||||
|
0 4px 5px 0 rgba(0, 0, 0, 0.06), 0 1px 10px 0 rgba(0, 0, 0, 0.08);
|
||||||
|
fill: rgba(0, 0, 0, 0.54);
|
||||||
|
--ui-shadow-border: 1px solid rgba(0, 0, 0, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||||
|
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
|
sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
||||||
|
background-color: #0e0e0e;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
font-family: "Raleway", sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
color: #2a3747;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.View {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
font-family: "Merriweather Sans", sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Banner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
background: white;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
font-family: "Share Tech Mono", monospace;
|
||||||
|
|
||||||
|
border-bottom: var(--ui-shadow-border);
|
||||||
|
box-shadow: var(--ui-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Message {
|
||||||
|
background: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-bottom: var(--ui-shadow-border);
|
||||||
|
box-shadow: var(--ui-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Message > .Title {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Message > .Details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NavButtons {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NavButton {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
height: 55px;
|
||||||
|
width: 150px;
|
||||||
|
|
||||||
|
background: #fa4141;
|
||||||
|
|
||||||
|
border-radius: 30px;
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
text-transform: capitalize;
|
||||||
|
|
||||||
|
border-bottom: var(--ui-shadow-border);
|
||||||
|
box-shadow: var(--ui-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
td { border-left: 1px solid #000;
|
||||||
|
border-right: 1px solid #000;
|
||||||
|
}
|
10
routes/index.js
Normal file
10
routes/index.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
module.exports = function(app) {
|
||||||
|
fs.readdirSync(__dirname).forEach(function(file) {
|
||||||
|
if (file === "index.js" || file.substr(file.lastIndexOf('.') + 1) !== 'js')
|
||||||
|
return;
|
||||||
|
var name = file.substr(0, file.indexOf('.'));
|
||||||
|
require('./' + name)(app);
|
||||||
|
});
|
||||||
|
}
|
15
routes/logFIle.js
Normal file
15
routes/logFIle.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const lineReader = require("line-reader");
|
||||||
|
const Promise = require("bluebird");
|
||||||
|
|
||||||
|
module.exports = function (app) {
|
||||||
|
app.get("/logFile", (req, res) => {
|
||||||
|
logFile = []
|
||||||
|
const eachLine = Promise.promisify(lineReader.eachLine);
|
||||||
|
eachLine('jdrssdownloader.log', function (line) {
|
||||||
|
logFile.push(line)
|
||||||
|
}).then(() => {
|
||||||
|
logFile = logFile.slice((logFile.length - 30), logFile.length)
|
||||||
|
res.render("logFile", { title: "App Logs", logFile: logFile.reverse() });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
11
routes/root.js
Normal file
11
routes/root.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const { nextLinkCheck, nextRssRefresh } = require('.././utils')
|
||||||
|
|
||||||
|
module.exports = function (app) {
|
||||||
|
|
||||||
|
app.get("/", (req, res) => {
|
||||||
|
showListLength = JSON.parse(fs.readFileSync('config.json')).Shows.length
|
||||||
|
a =
|
||||||
|
res.render("index", { title: "Home", showListLength: showListLength, version: global.version, rssTime: nextRssRefresh(), linkCheck: nextLinkCheck() });
|
||||||
|
});
|
||||||
|
}
|
28
routes/shows.js
Normal file
28
routes/shows.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const { addNewShow, removeShow } = require('.././apiFunctions')
|
||||||
|
|
||||||
|
module.exports = function (app) {
|
||||||
|
app.get("/shows", (req, res) => {
|
||||||
|
showList = JSON.parse(fs.readFileSync('config.json')).Shows
|
||||||
|
res.render("shows", { title: "Show List", showList: showList });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/shows/add", (req, res) => {
|
||||||
|
res.render("addshow", { title: "Add Show" });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/shows/remove", (req, res) => {
|
||||||
|
showList = JSON.parse(fs.readFileSync('config.json')).Shows
|
||||||
|
res.render("removeshow", { title: "Remove Show", showList: showList });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/addNewShow', (req, res) => {
|
||||||
|
addNewShow(req.body)
|
||||||
|
res.redirect("/shows");
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/removeShow', (req, res) => {
|
||||||
|
removeShow(req.body)
|
||||||
|
res.redirect("/shows");
|
||||||
|
});
|
||||||
|
}
|
22
utils.js
Normal file
22
utils.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
config = JSON.parse(fs.readFileSync('config.json'))
|
||||||
|
var moment = require('moment');
|
||||||
|
|
||||||
|
function returnUpdatedDate(date, offset) {
|
||||||
|
var newDate = moment(date);
|
||||||
|
newDate.add(offset, 'm');
|
||||||
|
return new moment(newDate).format("ddd, LTS")
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextRssRefresh() {
|
||||||
|
return returnUpdatedDate(global.rssRefreshTime, config.RSSFeedRefreshMins)
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextLinkCheck() {
|
||||||
|
return returnUpdatedDate(global.linkCheckTime, config.JDPostLinksMins)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
nextRssRefresh, nextLinkCheck
|
||||||
|
}
|
||||||
|
|
17
views/addshow.pug
Normal file
17
views/addshow.pug
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block layout-content
|
||||||
|
div.View
|
||||||
|
h1.Banner Add Show
|
||||||
|
div.Message
|
||||||
|
form(action="/addNewShow" method="POST")
|
||||||
|
p Show Name:
|
||||||
|
input(type="text" name="showName" placeholder="Enter the show to track ")
|
||||||
|
p Quality:
|
||||||
|
select(name="quality")
|
||||||
|
option(value='720') #{'720p'}
|
||||||
|
option(value='1080') #{'1080p'}
|
||||||
|
input(type="submit", value="Add Show")
|
||||||
|
div.NavButtons
|
||||||
|
a(href="/")
|
||||||
|
div.NavButton Home
|
22
views/index.pug
Normal file
22
views/index.pug
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block layout-content
|
||||||
|
div.View
|
||||||
|
h1.Banner JDRssDownloader #{version}
|
||||||
|
body
|
||||||
|
div.Message
|
||||||
|
h3 Number of Tracked Shows
|
||||||
|
h1 #{showListLength}
|
||||||
|
h3 Next RSS Refresh
|
||||||
|
h1 #{rssTime}
|
||||||
|
h3 Next Link Check
|
||||||
|
h1 #{linkCheck}
|
||||||
|
div.NavButtons
|
||||||
|
a(href="/shows")
|
||||||
|
div.NavButton Show List
|
||||||
|
a(href="/shows/add")
|
||||||
|
div.NavButton Add New Show
|
||||||
|
a(href="/shows/remove")
|
||||||
|
div.NavButton Remove Show
|
||||||
|
a(href="/logFile")
|
||||||
|
div.NavButton Logs
|
13
views/layout.pug
Normal file
13
views/layout.pug
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
block variables
|
||||||
|
doctype html
|
||||||
|
html
|
||||||
|
head
|
||||||
|
meta(charset="utf-8")
|
||||||
|
link(rel="shortcut icon", href="/favicon.ico")
|
||||||
|
meta(name="viewport", content="width=device-width, initial-scale=1, shrink-to-fit=no")
|
||||||
|
meta(name="theme-color", content="#000000")
|
||||||
|
title #{title} | JDRssDownloader
|
||||||
|
link(rel="stylesheet" href="/style.css")
|
||||||
|
body
|
||||||
|
div#root
|
||||||
|
block layout-content
|
11
views/logFile.pug
Normal file
11
views/logFile.pug
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block layout-content
|
||||||
|
div.View
|
||||||
|
h1.Banner Log File
|
||||||
|
div.Message
|
||||||
|
each val in logFile
|
||||||
|
li= val
|
||||||
|
div.NavButtons
|
||||||
|
a(href="/")
|
||||||
|
div.NavButton Home
|
15
views/removeshow.pug
Normal file
15
views/removeshow.pug
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block layout-content
|
||||||
|
div.View
|
||||||
|
h1.Banner Remove Show
|
||||||
|
div.Message
|
||||||
|
form(action="/removeShow" method="POST")
|
||||||
|
p Show Name:
|
||||||
|
select(name="showName")
|
||||||
|
each show in showList
|
||||||
|
option(value=show.Name) #{show.Name}
|
||||||
|
input(type="submit", value="Remove Show")
|
||||||
|
div.NavButtons
|
||||||
|
a(href="/")
|
||||||
|
div.NavButton Home
|
19
views/shows.pug
Normal file
19
views/shows.pug
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block layout-content
|
||||||
|
div.View
|
||||||
|
h1.Banner Show List
|
||||||
|
div.Message
|
||||||
|
table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th Show Name
|
||||||
|
th Quality
|
||||||
|
tbody
|
||||||
|
each val, key in showList
|
||||||
|
tr
|
||||||
|
td= val.Name
|
||||||
|
td= val.Quality
|
||||||
|
div.NavButtons
|
||||||
|
a(href="/")
|
||||||
|
div.NavButton Home
|
Loading…
x
Reference in New Issue
Block a user