-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.php
122 lines (102 loc) · 3.5 KB
/
index.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
<?php
require __DIR__.'/vendor/autoload.php';
use Dflydev\ApacheMimeTypes\PhpRepository;
use Dflydev\ApacheMimeTypes\RepositoryInterface;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
$resolver = new OptionsResolver();
$resolver->setDefined([
'FEED_ROOT',
'FEED_MIMES',
'FEED_MAX',
'FEED_NAME',
'FEED_DESCRIPTION',
'FEED_URL',
'FEED_BASE_URL',
]);
$resolver->setRequired([
'FEED_URL',
]);
$resolver->setDefaults([
'FEED_ROOT' => '/srv/files',
'FEED_MIMES' => 'video/*, audio/*',
'FEED_MAX' => 50,
'FEED_NAME' => 'AutoFeed RSS',
'FEED_DESCRIPTION' => 'AutoFeed RSS',
'FEED_BASE_URL' => function (Options $options) {
return $options['FEED_URL'];
},
]);
$resolver->setNormalizer('FEED_MIMES', function (Options $options, $value) {
return array_map('trim', explode(',', $value));
});
$resolver->setNormalizer('FEED_MAX', function (Options $options, $value) {
return intval($value);
});
$resolver->setNormalizer('FEED_BASE_URL', function (Options $options, $value) {
return rtrim($value, '/').'/';
});
$options = [];
foreach ($resolver->getDefinedOptions() as $key) {
if (false !== $value = getenv($key, true)) {
$options[$key] = $value;
}
}
$options = $resolver->resolve($options);
function scan(string $directory, array &$paths, array $allowedMimes, RepositoryInterface $mimeTypeRepository)
{
$files = scandir($directory);
foreach ($files as $filename) {
if (strpos($filename, '.') === 0) {
continue;
}
$path = $directory.'/'.$filename;
if (!is_readable($path)) {
continue;
}
if (is_dir($path)) {
scan($path, $paths, $allowedMimes, $mimeTypeRepository);
continue;
}
$mimetype = $mimeTypeRepository->findType(pathinfo($path, PATHINFO_EXTENSION));
foreach ($allowedMimes as $pattern) {
if (fnmatch($pattern, $mimetype)) {
$paths[] = [
'path' => $path,
'timestamp' => filemtime($path),
'size' => filesize($path),
'mimetype' => $mimetype,
];
break;
}
}
}
}
$paths = [];
scan($options['FEED_ROOT'], $paths, $options['FEED_MIMES'], new PhpRepository());
usort($paths, function ($a, $b) {
$at = $a['timestamp'];
$bt = $b['timestamp'];
return $at == $bt ? 0 : ($at > $bt ? -1 : 1);
});
$paths = array_slice($paths, 0, $options['FEED_MAX']);
$xml = new SimpleXMLElement('<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"/>');
$channel = $xml->addChild('channel');
$channel->addChild('title', $options['FEED_NAME']);
$channel->addChild('link', $options['FEED_URL']);
$channel->addChild('description', $options['FEED_DESCRIPTION']);
foreach ($paths as $row) {
$title = pathinfo($row['path'], PATHINFO_BASENAME);
$path = substr($row['path'], strlen($options['FEED_ROOT']) + 1);
$link = sprintf('%s%s', $options['FEED_BASE_URL'], $path);
$item = $channel->addChild('item');
$item->addChild('title', htmlspecialchars($title));
$item->addChild('guid', htmlspecialchars($link));
$item->addChild('pubDate', date(DATE_RFC7231, $row['timestamp']));
$media = $item->addChild('enclosure');
$media->addAttribute('url', $link);
$media->addAttribute('length', $row['size']);
$media->addAttribute('type', $row['mimetype']);
}
Header('Content-type: text/xml');
echo $xml->asXML();