diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 06c0ed1..1f396fd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,14 +2,4 @@ 1. [ ] Have you ran update.js and pushed the resulting manifest to your forks repo? -2. [ ] Have you tested the generated manifest on jellyfin? - -### Adding sources: - -1. [ ] Have you removed any duplicate sources? - - - VSCode: ctrl + shift + p > Delete Duplicate Lines - -2. [ ] Have you sorted lines by ascending? - - - VSCode: ctrl + shift + p > Sort Lines Ascending +2. [ ] Have you tested the generated manifest on jellyfin? \ No newline at end of file diff --git a/.github/workflows/format-lists.yml b/.github/workflows/format-lists.yml new file mode 100644 index 0000000..4635ab3 --- /dev/null +++ b/.github/workflows/format-lists.yml @@ -0,0 +1,30 @@ +name: Format Sources Lists + +on: + pull_request: + paths: + - 'sources.txt' + - 'sourcesnsfw.txt' + workflow_dispatch: + +jobs: + format: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref || github.ref }} + + - name: Sort and remove duplicates + run: | + LC_ALL=C sort -u -o sources.txt sources.txt + LC_ALL=C sort -u -o sourcesnsfw.txt sourcesnsfw.txt + + - name: Commit changes + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add sources.txt sourcesnsfw.txt + git diff --quiet && git diff --staged --quiet || (git commit -m "Auto-format sources lists: sort and remove duplicates" && git push) \ No newline at end of file diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index c716d6e..b8914cc 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -2,7 +2,7 @@ name: Manifest updater on: push: - branches: [ main ] + branches: [ main, testing ] schedule: - cron: '0 0 * * *' @@ -21,6 +21,6 @@ jobs: - run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add manifest.json images/ + git add manifest.json manifestnsfw.json images/ git commit -m "Generate manifest" || exit 0 git push \ No newline at end of file diff --git a/README.md b/README.md index 276bd79..42aee78 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,14 @@ https://raw.githubusercontent.com/0belous/universal-plugin-repo/refs/heads/main/ ``` 5. Never add another repository again! +
+More plugins +You can optionally install the NSFW repo too +``` +https://raw.githubusercontent.com/0belous/universal-plugin-repo/refs/heads/main/manifestnsfw.json +``` +
+ # Security Most sources are from [awesome-jellyfin](https://github.com/awesome-jellyfin/awesome-jellyfin) The rest are from reputable developers, each source is reviewed before being added. diff --git a/sources.txt b/sources.txt index e0b7f06..18b218a 100644 --- a/sources.txt +++ b/sources.txt @@ -16,7 +16,6 @@ https://raw.githubusercontent.com/CherryFloors/jellyfin-plugin-cinemamode/main/m https://raw.githubusercontent.com/Cloud9Developer/Jellyfin-Newsletter-Plugin/master/manifest.json https://raw.githubusercontent.com/CodeDevMLH/jellyfin-plugin-manifest/refs/heads/main/manifest.json https://raw.githubusercontent.com/danieladov/JellyfinPluginManifest/master/manifest.json -https://raw.githubusercontent.com/DirtyRacer1337/Jellyfin.Plugin.Stash/main/manifest.json https://raw.githubusercontent.com/Eeeeelias/playlist-generator/refs/heads/main/manifest.json https://raw.githubusercontent.com/enoch85/bazarr-jellyfin/main/manifest.json https://raw.githubusercontent.com/Felitendo/jellyfin-plugin-lyrics/master/manifest.json @@ -33,7 +32,6 @@ https://raw.githubusercontent.com/KeksBombe/jellyfin-plugin-auto-collections/ref https://raw.githubusercontent.com/lostb1t/Gelato/refs/heads/gh-pages/repository.json https://raw.githubusercontent.com/lostb1t/jellyfin-plugin-collection-import/main/manifest.json https://raw.githubusercontent.com/luall0/jellyfin-luall0-plugins/refs/heads/main/manifest.json -https://raw.githubusercontent.com/metatube-community/jellyfin-plugin-metatube/dist/manifest.json https://raw.githubusercontent.com/MorganKryze/jellyflare/main/manifest.json https://raw.githubusercontent.com/n00bcodr/jellyfin-plugins/main/10.11/manifest.json https://raw.githubusercontent.com/Namo2/InPlayerEpisodePreview/master/manifest.json @@ -44,7 +42,6 @@ https://raw.githubusercontent.com/RomainPierre7/jellyfin-plugin-TelegramNotifier https://raw.githubusercontent.com/ryandash/jellyfin-plugin-myanimelist/main/manifest.json https://raw.githubusercontent.com/ShokoAnime/Shokofin/metadata/stable/manifest.json https://raw.githubusercontent.com/streamyfin/jellyfin-plugin-streamyfin/main/manifest.json -https://raw.githubusercontent.com/ThePornDatabase/Jellyfin.Plugin.ThePornDB/main/manifest.json https://raw.githubusercontent.com/TheXaman/jellyfin-plugin-languageTags/main/manifest.json https://raw.githubusercontent.com/tubearchivist/tubearchivist-jf-plugin/master/manifest.json https://raw.githubusercontent.com/Viperinius/jellyfin-plugins/master/manifest.json @@ -57,4 +54,4 @@ https://repo.xkrivo.net/jellyfin/manifest.json https://simoni.dev/jellyfin/repo.json https://www.iamparadox.dev/jellyfin/plugins/manifest.json https://xzonn.top/JellyfinPluginDouban/manifest.json -ttps://raw.githubusercontent.com/RadicalMuffinMan/moonfin-server/master/manifest.json +ttps://raw.githubusercontent.com/RadicalMuffinMan/moonfin-server/master/manifest.json \ No newline at end of file diff --git a/sourcesnsfw.txt b/sourcesnsfw.txt new file mode 100644 index 0000000..1acd791 --- /dev/null +++ b/sourcesnsfw.txt @@ -0,0 +1,3 @@ +https://raw.githubusercontent.com/ThePornDatabase/Jellyfin.Plugin.ThePornDB/main/manifest.json +https://raw.githubusercontent.com/DirtyRacer1337/Jellyfin.Plugin.Stash/main/manifest.json +https://raw.githubusercontent.com/metatube-community/jellyfin-plugin-metatube/dist/manifest.json \ No newline at end of file diff --git a/update.js b/update.js index 63cdf7d..86bd49a 100644 --- a/update.js +++ b/update.js @@ -15,13 +15,13 @@ async function getLatestJellyfinVersion() { return data.tag_name.replace('v', ''); } -async function getSources(){ +async function getSources(sourceFile){ let sources = []; try { - const fileContent = await fs.readFile('sources.txt', 'utf8'); + const fileContent = await fs.readFile(sourceFile, 'utf8'); sources = fileContent.split(/\r?\n/).filter(line => line.trim() !== '' && !line.trim().startsWith('#')); } catch (err) { - console.error("Error reading sources.txt:", err); + console.error(`Error reading ${sourceFile}:`, err.message); return []; } @@ -38,6 +38,7 @@ async function getSources(){ throw new Error(`Response status: ${response.status}`); } const json = await response.json(); + json.forEach(p => p._metaSourceUrl = url); mergedData.push(...json); console.log(` -> Merged ${json.length} plugins.`); @@ -103,19 +104,25 @@ function findGithubUrl(obj) { async function processDescriptions(pluginData) { try { + const genTime = new Date().toISOString().substring(11, 16) + ' UTC'; for (const plugin of pluginData) { const repoUrl = findGithubUrl(plugin); - if (repoUrl) { - const sourceLink = `\n\n${repoUrl}`; - const descriptionProp = ['description', 'Description', 'overview'].find(p => plugin[p]); + const sourceUrl = plugin._metaSourceUrl || 'Unknown'; + delete plugin._metaSourceUrl; - if (descriptionProp) { - if (!plugin[descriptionProp].includes(repoUrl)) { - plugin[descriptionProp] += sourceLink; - } - } else { - plugin.description = sourceLink.trim(); + let appendText = ` \n \nUniversal Repo: \nGenerated: ${genTime} \nSource: ${sourceUrl}`; + if (repoUrl) { + appendText += ` \nGithub: ${repoUrl}`; + } + + const descriptionProp = ['description', 'Description', 'overview'].find(p => plugin[p]); + + if (descriptionProp) { + if (!plugin[descriptionProp].includes("Universal Repo:")) { + plugin[descriptionProp] += appendText; } + } else { + plugin.description = appendText.trim(); } } console.log(`Sucessfully injected source URLs`); @@ -125,7 +132,6 @@ async function processDescriptions(pluginData) { } async function processImages(pluginData) { - await clearImagesFolder(); for (const plugin of pluginData) { if (plugin.imageUrl) { const ext = getImageExtension(plugin.imageUrl); @@ -143,26 +149,34 @@ async function processImages(pluginData) { } } -async function writeManifest(dataToWrite){ +async function writeManifest(dataToWrite, outputFile){ if (!dataToWrite || dataToWrite.length === 0) { - console.log("No data to write to manifest. Aborting."); + console.log(`No data to write to manifest ${outputFile}. Aborting.`); return; } try { const manifestJson = JSON.stringify(dataToWrite, null, 2); - await fs.writeFile('manifest.json', manifestJson); + await fs.writeFile(outputFile, manifestJson); } catch (err) { - console.error('Error writing manifest file:', err); + console.error(`Error writing manifest file ${outputFile}:`, err); + } + console.log(`\nSuccessfully created ${outputFile} with ${dataToWrite.length} total plugins`); +} + +async function processList(sourceFile, outputFile) { + const plugins = await getSources(sourceFile); + if (plugins.length > 0) { + await processDescriptions(plugins); + await processImages(plugins); + await writeManifest(plugins, outputFile); } - console.log(`\nSuccessfully created manifest.json with ${dataToWrite.length} total plugins`); } async function main() { userAgent = `Jellyfin-Server/${await getLatestJellyfinVersion()}`; - const plugins = await getSources(); - await processDescriptions(plugins); - await processImages(plugins); - await writeManifest(plugins); + await clearImagesFolder(); + await processList('sources.txt', 'manifest.json'); + await processList('sourcesnsfw.txt', 'manifestnsfw.json'); } main();