This commit is contained in:
@@ -1,7 +1,13 @@
|
|||||||
FROM php:7.2-apache
|
FROM python:3.9-slim
|
||||||
|
|
||||||
COPY . /var/www/html
|
WORKDIR /app
|
||||||
COPY vhost.conf /etc/apache2/sites-available/000-default.conf
|
|
||||||
|
|
||||||
EXPOSE 80
|
COPY requirements.txt .
|
||||||
RUN chown -R www-data:www-data /var/www/html && a2enmod rewrite
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY main.py .
|
||||||
|
COPY version .
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["python", "main.py"]
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
# IPTV M3U filter
|
|
||||||
|
|
||||||
A simple web server that will download an M3U file, at most once a day, and filter that file down to selected groups.
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
To build and run the docker image use:
|
|
||||||
|
|
||||||
docker build -t iptv-filter .
|
|
||||||
docker run -itd --name iptv-filter -p 81:80 iptv-filter
|
|
||||||
|
|
||||||
You can connect to the container with:
|
|
||||||
|
|
||||||
docker exec -it iptv-filter /bin/bash
|
|
||||||
|
|
||||||
## Docker - Raspberry Pi
|
|
||||||
|
|
||||||
To build the image on a Raspberry Pi, use:
|
|
||||||
|
|
||||||
docker build -f Dockerfile.rpi -t iptv-filter .
|
|
||||||
docker run -itd --name iptv-filter -p 81:80 iptv-filter
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
exec('/var/www/html/iptv-boxsets.sh > /tmp/iptv-boxsets.m3u');
|
|
||||||
|
|
||||||
header("Content-Description: File Transfer");
|
|
||||||
header("Content-Type: application/octet-stream");
|
|
||||||
header("Content-Disposition: attachment; filename=\"iptv-boxsets.m3u\"");
|
|
||||||
readfile("/tmp/iptv-boxsets.m3u");
|
|
||||||
?>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
m3u_src="http://iptv.example.com/iptv.m3u"
|
|
||||||
m3u_file=/tmp/iptv-`date +%Y%m%d`.m3u
|
|
||||||
|
|
||||||
if [ ! -f "$m3u_file" ]; then
|
|
||||||
# Delete files downloaded over seven days ago.
|
|
||||||
find /tmp/iptv-* -mtime +7 -exec rm {} \;
|
|
||||||
|
|
||||||
# Download the m3u files.
|
|
||||||
curl -s $m3u_src --output $m3u_file
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "#EXTM3U"
|
|
||||||
grep -E "^#EXTINF.*group\-title=\"\|EN\| SERIES" -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
grep -E "^#EXTINF.*group\-title=\"\|EN.+MOVIES" -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
exec('/var/www/html/iptv-tv.sh > /tmp/iptv-tv.m3u');
|
|
||||||
|
|
||||||
header("Content-Description: File Transfer");
|
|
||||||
header("Content-Type: application/octet-stream");
|
|
||||||
header("Content-Disposition: attachment; filename=\"iptv-tv.m3u\"");
|
|
||||||
readfile("/tmp/iptv-tv.m3u");
|
|
||||||
?>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
m3u_src="http://iptv.example.com/iptv.m3u"
|
|
||||||
m3u_file=/tmp/iptv-`date +%Y%m%d`.m3u
|
|
||||||
|
|
||||||
if [ ! -f "$m3u_file" ]; then
|
|
||||||
# Delete files downloaded over seven days ago.
|
|
||||||
find /tmp/iptv-* -mtime +7 -exec rm {} \;
|
|
||||||
|
|
||||||
# Download the m3u files.
|
|
||||||
curl -s $m3u_src --output $m3u_file
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "#EXTM3U"
|
|
||||||
grep -E '^#EXTINF.*group\-title=\"IRE' -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
grep -E '^#EXTINF.*group\-title=\"UK\|' -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
grep -E '^#EXTINF.*group\-title=\"USA' -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
grep -E '^#EXTINF.*group\-title=\"CA' -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
grep -E '^#EXTINF.*group\-title=\"SP' -A 1 $m3u_file | sed "/^--$/d"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import schedule
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from flask import Flask, Response
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
SOURCE_URL = os.environ.get('SOURCE_URL', 'http://example.com/source.m3u8')
|
||||||
|
PORT = int(os.environ.get('PORT', 8000))
|
||||||
|
LOCAL_FILE_PATH = 'playlist.m3u8'
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
def download_m3u8():
|
||||||
|
"""Download the M3U8 file from the source URL"""
|
||||||
|
try:
|
||||||
|
print(f"{datetime.now()} - Downloading M3U8 from {SOURCE_URL}")
|
||||||
|
response = requests.get(SOURCE_URL, timeout=30)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
with open(LOCAL_FILE_PATH, 'wb') as f:
|
||||||
|
f.write(response.content)
|
||||||
|
print(f"{datetime.now()} - M3U8 file downloaded successfully")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"{datetime.now()} - Failed to download M3U8. Status code: {response.status_code}")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{datetime.now()} - Error downloading M3U8: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
@app.route('/playlist.m3u8')
|
||||||
|
def serve_playlist():
|
||||||
|
"""Serve the M3U8 file"""
|
||||||
|
try:
|
||||||
|
with open(LOCAL_FILE_PATH, 'rb') as f:
|
||||||
|
content = f.read()
|
||||||
|
return Response(content, mimetype='application/vnd.apple.mpegurl')
|
||||||
|
except Exception as e:
|
||||||
|
return str(e), 500
|
||||||
|
|
||||||
|
@app.route('/health')
|
||||||
|
def health_check():
|
||||||
|
"""Health check endpoint"""
|
||||||
|
if os.path.exists(LOCAL_FILE_PATH):
|
||||||
|
return "OK", 200
|
||||||
|
else:
|
||||||
|
return "Playlist not available", 503
|
||||||
|
|
||||||
|
def schedule_downloads():
|
||||||
|
"""Schedule the M3U8 download to run at midnight every day"""
|
||||||
|
schedule.every().day.at("00:00").do(download_m3u8)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(60) # Check every minute
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to start the application"""
|
||||||
|
# Initial download
|
||||||
|
if not download_m3u8():
|
||||||
|
print("Initial download failed. Retrying in 30 seconds...")
|
||||||
|
time.sleep(30)
|
||||||
|
if not download_m3u8():
|
||||||
|
print("Second attempt failed. Starting server anyway...")
|
||||||
|
|
||||||
|
# Start the scheduler in a separate thread
|
||||||
|
scheduler_thread = Thread(target=schedule_downloads)
|
||||||
|
scheduler_thread.daemon = True
|
||||||
|
scheduler_thread.start()
|
||||||
|
|
||||||
|
# Start the Flask app
|
||||||
|
print(f"{datetime.now()} - Starting web server on port {PORT}")
|
||||||
|
app.run(host='0.0.0.0', port=PORT)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
flask==2.0.1
|
||||||
|
requests==2.26.0
|
||||||
|
schedule==1.1.0
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<VirtualHost *:80>
|
|
||||||
DocumentRoot /var/www/html
|
|
||||||
|
|
||||||
<Directory "/var/www/html">
|
|
||||||
AllowOverride all
|
|
||||||
Require all granted
|
|
||||||
DirectoryIndex iptv-tv.php
|
|
||||||
</Directory>
|
|
||||||
</VirtualHost>
|
|
||||||
Reference in New Issue
Block a user