mikmc commited on
Commit
ed2e9a7
·
verified ·
1 Parent(s): 3f80a77

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +183 -183
index.js CHANGED
@@ -1,183 +1,183 @@
1
- const express = require('express');
2
- const { addonBuilder, getRouter } = require('stremio-addon-sdk');
3
- const cors = require('cors');
4
- const fs = require('fs');
5
- const path = require('path');
6
-
7
- const manifest = {
8
- id: 'hy.yourtvshows.org',
9
- version: '1.0.0',
10
- name: 'TV Club',
11
- description: 'Stream TV series categorized by genre with search capability',
12
- resources: ['catalog', 'stream', 'meta'],
13
- types: ['series'],
14
- idPrefixes: ['tt'],
15
- catalogs: [
16
- {
17
- id: 'main-catalog',
18
- type: 'series',
19
- name: 'All Series',
20
- extra: [
21
- { name: 'genre', options: [] },
22
- { name: 'search', isRequired: false }
23
- ]
24
- }
25
- ]
26
- };
27
-
28
- const builder = new addonBuilder(manifest);
29
-
30
- // Function to read JSON files
31
- function readJSONFile(filename) {
32
- const filePath = path.join(__dirname, filename);
33
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
34
- }
35
-
36
- // Load and parse series data files
37
- const seriesDataFiles = fs.readdirSync(__dirname)
38
- .filter(file => file.endsWith('_series_data.json'));
39
-
40
- console.log("Found series data files:", seriesDataFiles);
41
-
42
- // Store catalogs and metadata
43
- const catalogs = [];
44
- const metaData = {};
45
-
46
- // Process each series data file dynamically
47
- seriesDataFiles.forEach(filename => {
48
- const data = readJSONFile(filename);
49
- const catalogType = 'series'; // Assuming 'series' for all catalogs
50
-
51
- // Add categories to genre options in manifest
52
- Object.keys(data).forEach(category => {
53
- if (!manifest.catalogs[0].extra[0].options.includes(category)) {
54
- manifest.catalogs[0].extra[0].options.push(category);
55
- }
56
- });
57
-
58
- // Process each category in the file
59
- Object.entries(data).forEach(([category, seriesList]) => {
60
- // Add series metadata for each series in the category
61
- seriesList.forEach(series => {
62
- const seriesMeta = {
63
- id: series.id,
64
- type: catalogType,
65
- name: series.name,
66
- genres: [category],
67
- poster: series.poster || null
68
- };
69
-
70
- // Store metadata and catalog information
71
- metaData[series.id] = {
72
- ...seriesMeta,
73
- seasons: series.seasons.map(season => ({
74
- season: season.season,
75
- episodes: season.episodes.map(ep => ({
76
- episode: ep.episode,
77
- stream_url: ep.stream_url
78
- }))
79
- }))
80
- };
81
-
82
- catalogs.push({
83
- category,
84
- meta: seriesMeta
85
- });
86
- });
87
- });
88
- });
89
-
90
- // Catalog handler to list series by genre and enable search
91
- builder.defineCatalogHandler(({ type, extra }) => {
92
- return new Promise((resolve) => {
93
- if (type === 'series') {
94
- const genre = extra.genre;
95
- const searchQuery = extra.search ? extra.search.toLowerCase() : null;
96
-
97
- let seriesCatalog = catalogs
98
- .filter(catalog => !genre || catalog.category === genre) // Filter by genre if provided
99
- .map(catalog => catalog.meta);
100
-
101
- // Filter by search query if provided
102
- if (searchQuery) {
103
- seriesCatalog = seriesCatalog.filter(meta =>
104
- meta.name.toLowerCase().includes(searchQuery)
105
- );
106
- }
107
-
108
- resolve({ metas: seriesCatalog });
109
- } else {
110
- resolve({ metas: [] });
111
- }
112
- });
113
- });
114
-
115
- // Meta handler to get details of a specific series
116
- builder.defineMetaHandler(({ id }) => {
117
- return new Promise((resolve) => {
118
- const seriesMeta = metaData[id];
119
- if (seriesMeta) {
120
- resolve({
121
- meta: {
122
- id: seriesMeta.id,
123
- type: 'series',
124
- name: seriesMeta.name,
125
- poster: seriesMeta.poster,
126
- genres: seriesMeta.genres,
127
- seasons: seriesMeta.seasons.map(season => ({
128
- number: season.season,
129
- episodes: season.episodes.map(ep => ({
130
- id: `${seriesMeta.id}:${season.season}:${ep.episode}`,
131
- title: `Episode ${ep.episode}`,
132
- season: season.season,
133
- number: ep.episode
134
- }))
135
- }))
136
- }
137
- });
138
- } else {
139
- resolve({});
140
- }
141
- });
142
- });
143
-
144
- // Stream handler to fetch specific episode streams
145
- builder.defineStreamHandler(({ type, id }) => {
146
- return new Promise((resolve) => {
147
- if (type === 'series') {
148
- const [seriesId, seasonNumber, episodeNumber] = id.split(':');
149
- const seriesMeta = metaData[seriesId];
150
- if (seriesMeta) {
151
- const season = seriesMeta.seasons.find(s => s.season == seasonNumber);
152
- if (season) {
153
- const episode = season.episodes.find(e => e.episode == episodeNumber);
154
- if (episode) {
155
- resolve({
156
- streams: [{
157
- title: `${seriesMeta.name} S${seasonNumber}E${episodeNumber}`,
158
- url: episode.stream_url
159
- }]
160
- });
161
- return;
162
- }
163
- }
164
- }
165
- }
166
- resolve({ streams: [] });
167
- });
168
- });
169
-
170
- const addonInterface = builder.getInterface();
171
-
172
- const app = express();
173
- app.use(cors());
174
- app.use('/', getRouter(addonInterface));
175
- app.use((err, req, res, next) => {
176
- console.error(err.stack);
177
- res.status(500).send('Something went wrong!');
178
- });
179
-
180
- const PORT = process.env.PORT || 7000;
181
- app.listen(PORT, () => {
182
- console.log(`TV Club Stremio Addon running on port ${PORT}`);
183
- });
 
1
+ const express = require('express');
2
+ const { addonBuilder, getRouter } = require('stremio-addon-sdk');
3
+ const cors = require('cors');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const manifest = {
8
+ id: 'hy.yourtvshows.org',
9
+ version: '1.0.0',
10
+ name: 'TV Club',
11
+ description: 'Stream TV series categorized by genre with search capability',
12
+ resources: ['catalog', 'stream', 'meta'],
13
+ types: ['series'],
14
+ idPrefixes: ['tt'],
15
+ catalogs: [
16
+ {
17
+ id: 'main-catalog',
18
+ type: 'series',
19
+ name: 'All Series',
20
+ extra: [
21
+ { name: 'genre', options: [] },
22
+ { name: 'search', isRequired: false }
23
+ ]
24
+ }
25
+ ]
26
+ };
27
+
28
+ const builder = new addonBuilder(manifest);
29
+
30
+ // Function to read JSON files
31
+ function readJSONFile(filename) {
32
+ const filePath = path.join(__dirname, filename);
33
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
34
+ }
35
+
36
+ // Load and parse series data files
37
+ const seriesDataFiles = fs.readdirSync(__dirname)
38
+ .filter(file => file.endsWith('_series_data.json'));
39
+
40
+ console.log("Found series data files:", seriesDataFiles);
41
+
42
+ // Store catalogs and metadata
43
+ const catalogs = [];
44
+ const metaData = {};
45
+
46
+ // Process each series data file dynamically
47
+ seriesDataFiles.forEach(filename => {
48
+ const data = readJSONFile(filename);
49
+ const catalogType = 'series'; // Assuming 'series' for all catalogs
50
+
51
+ // Add categories to genre options in manifest
52
+ Object.keys(data).forEach(category => {
53
+ if (!manifest.catalogs[0].extra[0].options.includes(category)) {
54
+ manifest.catalogs[0].extra[0].options.push(category);
55
+ }
56
+ });
57
+
58
+ // Process each category in the file
59
+ Object.entries(data).forEach(([category, seriesList]) => {
60
+ // Add series metadata for each series in the category
61
+ seriesList.forEach(series => {
62
+ const seriesMeta = {
63
+ id: series.id,
64
+ type: catalogType,
65
+ name: series.name,
66
+ genres: [category],
67
+ poster: series.poster || null
68
+ };
69
+
70
+ // Store metadata and catalog information
71
+ metaData[series.id] = {
72
+ ...seriesMeta,
73
+ seasons: series.seasons.map(season => ({
74
+ season: season.season,
75
+ episodes: season.episodes.map(ep => ({
76
+ episode: ep.episode,
77
+ stream_url: ep.stream_url
78
+ }))
79
+ }))
80
+ };
81
+
82
+ catalogs.push({
83
+ category,
84
+ meta: seriesMeta
85
+ });
86
+ });
87
+ });
88
+ });
89
+
90
+ // Catalog handler to list series by genre and enable search
91
+ builder.defineCatalogHandler(({ type, extra }) => {
92
+ return new Promise((resolve) => {
93
+ if (type === 'series') {
94
+ const genre = extra.genre;
95
+ const searchQuery = extra.search ? extra.search.toLowerCase() : null;
96
+
97
+ let seriesCatalog = catalogs
98
+ .filter(catalog => !genre || catalog.category === genre) // Filter by genre if provided
99
+ .map(catalog => catalog.meta);
100
+
101
+ // Filter by search query if provided
102
+ if (searchQuery) {
103
+ seriesCatalog = seriesCatalog.filter(meta =>
104
+ meta.name.toLowerCase().includes(searchQuery)
105
+ );
106
+ }
107
+
108
+ resolve({ metas: seriesCatalog });
109
+ } else {
110
+ resolve({ metas: [] });
111
+ }
112
+ });
113
+ });
114
+
115
+ // Meta handler to get details of a specific series
116
+ builder.defineMetaHandler(({ id }) => {
117
+ return new Promise((resolve) => {
118
+ const seriesMeta = metaData[id];
119
+ if (seriesMeta) {
120
+ resolve({
121
+ meta: {
122
+ id: seriesMeta.id,
123
+ type: 'series',
124
+ name: seriesMeta.name,
125
+ poster: seriesMeta.poster,
126
+ genres: seriesMeta.genres,
127
+ seasons: seriesMeta.seasons.map(season => ({
128
+ number: season.season,
129
+ episodes: season.episodes.map(ep => ({
130
+ id: `${seriesMeta.id}:${season.season}:${ep.episode}`,
131
+ title: `Episode ${ep.episode}`,
132
+ season: season.season,
133
+ number: ep.episode
134
+ }))
135
+ }))
136
+ }
137
+ });
138
+ } else {
139
+ resolve({});
140
+ }
141
+ });
142
+ });
143
+
144
+ // Stream handler to fetch specific episode streams
145
+ builder.defineStreamHandler(({ type, id }) => {
146
+ return new Promise((resolve) => {
147
+ if (type === 'series') {
148
+ const [seriesId, seasonNumber, episodeNumber] = id.split(':');
149
+ const seriesMeta = metaData[seriesId];
150
+ if (seriesMeta) {
151
+ const season = seriesMeta.seasons.find(s => s.season == seasonNumber);
152
+ if (season) {
153
+ const episode = season.episodes.find(e => e.episode == episodeNumber);
154
+ if (episode) {
155
+ resolve({
156
+ streams: [{
157
+ title: `${seriesMeta.name} S${seasonNumber}E${episodeNumber}`,
158
+ url: episode.stream_url
159
+ }]
160
+ });
161
+ return;
162
+ }
163
+ }
164
+ }
165
+ }
166
+ resolve({ streams: [] });
167
+ });
168
+ });
169
+
170
+ const addonInterface = builder.getInterface();
171
+
172
+ const app = express();
173
+ app.use(cors());
174
+ app.use('/', getRouter(addonInterface));
175
+ app.use((err, req, res, next) => {
176
+ console.error(err.stack);
177
+ res.status(500).send('Something went wrong!');
178
+ });
179
+
180
+ const PORT = process.env.PORT || 3000;
181
+ app.listen(PORT, () => {
182
+ console.log(`TV Club Stremio Addon running on port ${PORT}`);
183
+ });