-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgetvod.php
380 lines (342 loc) · 15.2 KB
/
getvod.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
<?php
/**
* @package GetVod
* @version 1.4 BETA
* @author Jules Potvin ([email protected])
* @copyright (C) 2001 - 2022 ROCKMYM3U.COM All rights reserved.
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
* @link https://rockmym3u.com
*
*
* GetVod is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* GetVod is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with GetVod. If not, see http://www.gnu.org/licenses/.
*
* Version 1.2
* Improved download reliability
* Various code changes for better performance
* Added option to write movie strm files into sub directories
* Added curl option, uncomment the current download method if you prefer; you will need curl built into php
* Added override for tv and movie; allows you to override the logic to make a TV strm into the movie dir;
* we didn't test the tv override
* Added more information print statements
* Corrected my bad spelling
* Bug could not remove directories with [ ] in their name due to stupid php bugs; so if we have a vod with [] in
* the name we rename it using ()
* This means if you have directories or strm files with a [ or ] in their name you will have the manually delete them
*
* Version 1.3
* remove if isset from directory check; bugs and didn't work right all the time; maybe add back with php8
*
* Version 1.4
* added multiple playlists
* added bom removel to deal with utf8 lists; was causing the getvod to exit early
* added some debug for json so we can understand better when bad things happen
*
* Version 1.41
* cleaned up comments no code changes
*/
ini_set('memory_limit', '4G'); // upper memory limit for large stream file
//
// Modify these variables for your setup
//
$tv = "/media/vod_tv/"; //Library for TV Shows & Must have trailing /
$movie = "/media/vod_movie/"; // Library for Movies & Must have trailing /
$strmdir = "/media/"; // Where we store the strm file
$strm = "rockmym3u.strm"; // the downloaded file name
//
// Carefull - each playlist is held in memory
// If there are duplicates in the playlist, the last one will overwrite if you set $overwritecontents = true
//
$rockmym3uurl[] = 'https://m3u.mwlists.com/m3u/strm.php?key=xxxxxxxxx'; //Playlist from RockMyM3U M3U Editor
//$rockmym3uurl[] = 'https://rockmym3u.com/m3u/strm.php?key=xxxxxxxxx'; //Playlist from RockMyM3U M3U Editor
//$rockmym3uurl[] = 'https://rockmym3u.com/m3u/strm.php?key=xxxxxxxxx'; //Playlist from RockMyM3U M3U Editor
$includegroup = false; //include group name in folder name
$overwritecontents = false; // this may cause a lengthy media scan depending on your setup; maybe use this once a month ?
$moviedir = true; //put movies into a directory example : /movies/The_Shawshank_Redemption_(1994)/The_Shawshank_Redemption_(1994).strm
//
//stuff to remove
//
$lefttrim = ""; // trim this text from the left of the file name
$remove[] = "'"; //remove stuff we don't want in the file name
$remove[] = '"';
$remove[] = '-';
//
// Override one per line
//
$thisisamovie[] = 'S1m0ne'; // https://www.imdb.com/title/tt0258153/
$thisisatvshow[] = '';
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Do not Modify below this point //
//////////////////////////////////////////////////////////////////////////////////////////////////////
$type = 0; //type of entry 0 for tv 1 for movie
$tvitems = array(); //an array of the tv items from mwlists
$movieitems = array(); //same for movies
// not needed for production
//register_shutdown_function("fatal_handler");
function fatal_handler() {
$errfile = "unknown file";
$errstr = "shutdown";
$errno = E_CORE_ERROR;
$errline = 0;
$error = error_get_last();
if ($error !== null) {
$errno = $error["type"];
$errfile = $error["file"];
$errline = $error["line"];
$errstr = $error["message"];
print("Error: Line=$errline, message: $errstr \n\n");
}
}
//
// validate the settings
//
if (!is_dir($tv)) {
print("\n Directory ($tv) does not exist\n\n");
die();
}
if (!is_dir($movie)) {
print("\n Directory ($movie) does not exist\n\n");
die();
}
if (!is_dir($strmdir)) {
print("\n Directory ($strmdir) does not exist\n\n");
die();
}
foreach ($rockmym3uurl as $downloadurl) {
try {
print("Download : $downloadurl\n");
$tmpfile = ($strmdir . substr($downloadurl, strpos($downloadurl, "=") + 1) . '-' . $strm);
$in = fopen($downloadurl, "rb") or die('Error opening STRM file from RockMyM3U! ');
$fp = fopen($tmpfile, 'w+') or die('Error opening STRM file for write ! Check working directory permissions ! ');
while (!feof($in)) {
fwrite($fp, fread($in, 8192));
}
fclose($fp);
fclose($in);
$obj = json_decode(trim(file_get_contents($tmpfile), "\x0")); // load the file into a object; would probably not work on a pi due to memory; remove BOM as well
} catch (exception $e) {
print("\n Tragedy struck contacting RockMyM3U, try again later\n");
echo $e->getMessage();
print("\n\n");
die();
}
switch (json_last_error()) {
case JSON_ERROR_NONE:
//echo " - No errors\n";
break;
case JSON_ERROR_DEPTH:
echo " JSON - Maximum stack depth exceeded $downloadurl\n";
die();
case JSON_ERROR_STATE_MISMATCH:
echo " JSON - Underflow or the modes mismatch $downloadurl\n";
die();
case JSON_ERROR_CTRL_CHAR:
echo " JSON - Unexpected control character found $downloadurl\n";
die();
case JSON_ERROR_SYNTAX:
echo " JSON - Syntax error, malformed JSON $downloadurl\n";
die();
case JSON_ERROR_UTF8:
echo " JSON - Malformed UTF-8 characters, possibly incorrectly encoded $downloadurl\n";
die();
default:
echo " JSON - Unknown error $downloadurl\n";
die();
}
if ($obj === null || is_bool($obj)) {
print("\n Error geting file from MWLISTS; not a json file or file corrupt\n\n");
die();
}
if (count($obj) < 100) { //less than 100 VODs maybe it died?
print("\n WARNING: File seems incomplete less then 100 vod? If so modify source code.\n\n");
die;
}
print("Processing File for new VOD from $downloadurl \n");
//
//Loop through the list from rockmym3u and create the file for emby to read
//
foreach ($obj as $key) {
$file = str_replace(' ', '_', $key->tvg_name);
$file = str_replace('[', "(", $file);
$file = str_replace(']', ")", $file);
$file = str_replace($remove, "", $file);
$group = str_replace(' ', '_', $key->group_title);
$group = str_replace($remove, "", $group);
$url = $key->url;
if ($lefttrim != null) { // leave as null and nothing gets removed
$file = ltrim($file, $lefttrim); //remove left characters
} // we should probably add a rtrim here but nobody asked so, Bob's your uncle?
$safe_filename = Vod::sanitizeFileName($file); // use a safe file name
// in this if else code we are -
// checking to see if the .strm is a movie or tv show
// depending on the type we are going to set the directory structure
// based on the user prefs. At the end $dir will contain the
// intended destination for the stream
//
if ((preg_match("/S(?:100|\d{1,2})/", $file) || isin($file, $thisisatvshow)) && !(isin($file, $thisisamovie))) { // this is a TV Episode
$type = 0; //tv
$x = preg_split('/S(?:100|\d{1,2})/', $file);
$n = rtrim($x[0], '_'); // this is the name of the series
preg_match_all('/S(?:100|\d{1,2})/', $file, $m);
$s = $m[0][0]; // this is the season number
//printf("Series Name: $n Season: $s Stream url: $url\n");
if ($includegroup) {
$dir = $tv . $group . '/' . $n . '/' . $s . '/'; // this is the full directory path the season episode
} else {
$dir = $tv . $n . '/' . $s . '/'; // this is the full directory path the season episode
}
} else { // this is a Movie
$type = 1; //movie
if ($includegroup) {
if ($moviedir) { // place the strm in it's own folder
$dir = $movie . $group . '/' . $safe_filename . '/';
} else {
$dir = $movie . $group . '/';
}
} else {
if ($moviedir) { // place the strm into it's own folder
$dir = $movie . $safe_filename . '/'; // for emby we don't need an elaborate path for the movies
} else {
$dir = $movie;
}
}
}
//
//if type is tv, create the structure and maintain an array of stream names
//
if ($type == 0) { //tv items need a season stucture
$tvitems[] = ($dir . $safe_filename . ".strm"); // add the stream file name to an array; use later to delete streams provide does not have
//
//create the directory structure
//
if ($includegroup) { // group directory name
if (!file_exists($tv . $group)) {
mkdir($tv . $group, 0777, true); //season name
}
if (!file_exists($tv . $group . '/' . $n)) {
mkdir($tv . $group . '/' . $n, 0777, true); //season name
}
if (!file_exists($tv . $group . '/' . $n . '/' . $s)) {
mkdir($tv . $group . '/' . $n . '/' . $s, 0777, true); //season i.e. 01
}
} else {
//
if (!file_exists($tv . $n)) {
mkdir($tv . $n, 0777, true); //season name
}
if (!file_exists($tv . $n . '/' . $s)) {
mkdir($tv . $n . '/' . $s, 0777, true); //season i.e. 01
}
}
} else { // this is a movie, so let's create the directories
$movieitems[] = ($dir . $safe_filename . ".strm"); //Add the name of the stream to an array
if ($includegroup) { // group directory name
if (!file_exists($movie . $group)) {
mkdir($movie . $group, 0777, true); //group title in directory name
}
if (!file_exists($movie . $group . '/' . $safe_filename)) {
mkdir($movie . $group . '/' . $safe_filename, 0777, true); //group title in directory name
}
} else {
if (!file_exists($movie . $safe_filename)) {
mkdir($movie . $safe_filename, 0777, true); // don't need group title
}
}
}
// now we have the file name, and the directory it's intened for, lets write the strm file
if (!is_file($dir . $safe_filename . ".strm")) { // if the stream does not exist create it and add the url
print("Created: " . $dir . $safe_filename . ".strm\n");
file_put_contents($dir . $safe_filename . ".strm", $url); // Save our content to the file.
} elseif ($overwritecontents) {
print("Updated: " . $dir . $safe_filename . ".strm\n");
file_put_contents($dir . $safe_filename . ".strm", $url); // Save our content to the file.
}
}
} //end processing playlists; Let's remove stuff we don't have
//
print_r("Crosscheck anything we have the provider(s) deleted\n");
$dirtv = getDirContents($tv); // directory contents tv only .strm files will be added to array
$dirmovie = getDirContents($movie); //directory contents movie only .strm files will be added to array`
//
//delete tv strm not in provider
//
foreach ($dirtv as $n) {
if (!(in_array($n, $tvitems))) {
print_r("Delete $n\n"); //the getDirContents only collects .strm files, therefore we don't have to check the file name we are about to delete
unlink($n);
}
}
//
//delete movie strm not in provider
//
foreach ($dirmovie as $n) {
if (!(in_array($n, $movieitems))) {
print_r("Delete $n\n"); //the getDirContents only collects .strm files, therefore we don't have to check the file name we are about to delete
unlink($n);
}
}
print_r("Finished\n\n");
exit(0);
//
//Built in php functions are too slow; so we built our own
//
function getDirContents($dir, &$results = array()) {
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (!is_dir($path)) {
if (strpos($path, '.strm')) { // only stream files are checked and deleted
$results[] = $path;
}
} elseif ($value != "." && $value != "..") {
getDirContents($path, $results);
RemoveEmptySubFolders($path); //remove empty directories
}
}
return $results;
}
function stringEndsWith($haystack, $needle, $case = true) {
$expectedPosition = strlen($haystack) - strlen($needle);
if ($case) {
return strrpos($haystack, $needle, 0) === $expectedPosition;
}
return strripos($haystack, $needle, 0) === $expectedPosition;
}
function RemoveEmptySubFolders($path) {
$empty = true;
foreach (glob($path . DIRECTORY_SEPARATOR . "*") as $file) {
$empty &= is_dir($file) && RemoveEmptySubFolders($file);
}
if ($empty) {
printf("Remove Empty Directory : " . $path . "\n");
}
return $empty && rmdir($path);
}
function isin($search, $needles) { // seach the string of array values
$find = ($search != str_ireplace($needles, "XX", $search)) ? true : false;
return ($find);
}
class Vod {
/**
* Returns a safe filename, for a given platform (OS), by replacing all
* dangerous characters with an underscore.
*
* @param string $dangerous_filename The source filename to be "sanitized"
* @param string $platform The target OS
*
* @return Boolean string A safe version of the input filename
*/
public static function sanitizeFileName($dangerous_filename, $platform = 'Unix') {
if (in_array(strtolower($platform), array('unix', 'linux'))) {
// our list of "dangerous characters", add/remove characters if necessary
$dangerous_characters = array(" ", '"', "'", "&", "/", "\\", "?", "#");
} else {
// no OS matched? return the original filename then...
return $dangerous_filename;
}
// every forbidden character is replace by an underscore
$dangerous_filename = ltrim($dangerous_filename, '.'); //remove . although legel is a hidden file in Linux
return str_replace($dangerous_characters, '_', $dangerous_filename);
}
}