GilbertClaus commited on
Commit
55afdee
·
1 Parent(s): 673499e
Files changed (7) hide show
  1. Dockerfile +21 -0
  2. app.py +72 -0
  3. download_queue.json +1 -0
  4. extra.py +107 -0
  5. miyuki-0.7.7-py3-none-any.whl +0 -0
  6. process.py +77 -0
  7. requirements.txt +2 -0
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Install dependencies
4
+ RUN apt-get update && apt-get install -y \
5
+ ffmpeg \
6
+ && rm -rf /var/lib/apt/lists/*
7
+
8
+ # Set working directory
9
+ WORKDIR /app
10
+
11
+ # Copy project files
12
+ COPY . .
13
+
14
+ # Install Python dependencies
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Expose port for Gradio
18
+ EXPOSE 7860
19
+
20
+ # Run Gradio app
21
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import gradio as gr
3
+ import webbrowser
4
+ import threading
5
+ from process import *
6
+ from extra import *
7
+ install_miyuki()
8
+
9
+ # Load existing queue
10
+ download_queue = load_queue()
11
+
12
+ def open_browser():
13
+ webbrowser.open("http://127.0.0.1:7860")
14
+
15
+ def add_to_queue(video_url, quality):
16
+ if not video_url.startswith("http"):
17
+ return "Error: Please enter a valid URL."
18
+
19
+ if video_url in download_queue:
20
+ return "Warning: This URL is already in the queue."
21
+
22
+ download_queue[video_url] = {
23
+ "URL": video_url,
24
+ "Status": "Not Started",
25
+ "Log": ""
26
+ }
27
+ save_queue(download_queue)
28
+ return f"Added {video_url} to the queue."
29
+
30
+ def start_download():
31
+ for url, task in download_queue.items():
32
+ if task["Status"] == "Not Started":
33
+ status, log = download_file(url, "720")
34
+ download_queue[url]["Status"] = status
35
+ download_queue[url]["Log"] = log
36
+ save_queue(download_queue)
37
+ return "Downloads started."
38
+
39
+ def view_queue():
40
+ return [(url, data["Status"]) for url, data in download_queue.items()]
41
+
42
+ def check_status():
43
+ for url, task in download_queue.items():
44
+ if task["Status"] in ["Downloading", "Not Started"]:
45
+ status, log = check_task_status(url, task["Log"])
46
+ download_queue[url]["Status"] = status
47
+ download_queue[url]["Log"] = log
48
+ save_queue(download_queue)
49
+ return "Queue status updated."
50
+
51
+ with gr.Blocks() as app:
52
+ gr.Markdown("# Miyuki GUI Downloader")
53
+
54
+ with gr.Row():
55
+ video_url = gr.Textbox(label="Video URL")
56
+ quality = gr.Dropdown(["360", "480", "720"], label="Quality", value="360")
57
+ add_button = gr.Button("Add to Queue")
58
+ start_button = gr.Button("Start Download")
59
+
60
+ add_button.click(add_to_queue, inputs=[video_url, quality], outputs=None)
61
+
62
+ start_button.click(start_download, outputs=None)
63
+
64
+ check_button = gr.Button("Check Status")
65
+ check_button.click(check_status, outputs=None)
66
+
67
+ queue_list = gr.Dataframe(headers=["URL", "Status"], datatype=["str", "str"], label="Download Queue")
68
+ view_button = gr.Button("View Queue")
69
+ view_button.click(view_queue, outputs=queue_list)
70
+
71
+ threading.Thread(target=open_browser).start()
72
+ app.launch()
download_queue.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {}
extra.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import subprocess
4
+
5
+ def apostrof(text):
6
+ # Pola untuk mencari apostrof apapun diikuti dengan huruf kapital (baik 'S, ’S, atau ‘S)
7
+ text = re.sub(r"([’‘'\"])S", r"\1s", text)
8
+ text = re.sub(r"([’‘'\"])T", r"\1t", text)
9
+ return text
10
+
11
+ def rename_miyuki(folder_path = "./movies_folder_miyuki", dest_folder = "./Download MissAV"):
12
+ if not os.path.exists(folder_path):
13
+ return
14
+
15
+ dest_video = os.path.join(dest_folder, "Video")
16
+ dest_cover = os.path.join(dest_folder, "Cover")
17
+ if not os.path.exists(dest_video):
18
+ os.makedirs(dest_video)
19
+ if not os.path.exists(dest_cover):
20
+ os.makedirs(dest_cover)
21
+
22
+ for filename in os.listdir(folder_path):
23
+ if filename.endswith(".mp4"):
24
+ file_path = os.path.join(folder_path, filename)
25
+
26
+ # Pisahkan kode dan shortname
27
+ name, ext = os.path.splitext(filename)
28
+ kode = name.split(" ")[0]
29
+ shortname = " ".join(name.split(" ")[1:]).rsplit(".", 1)[0]
30
+
31
+ # Buat nama baru
32
+ new_name = f"{kode.upper().replace('_1080P','').replace('_720P','').replace('_480P','').replace('_360P','')} {apostrof(shortname.replace('"', '').title())}"
33
+ new_name = new_name.strip() + ".mp4"
34
+ new_path = os.path.join(dest_video, new_name.replace("..", ".").replace(" .MP4 .mp4", ".mp4"))
35
+
36
+ # Rename file
37
+ os.rename(file_path, new_path)
38
+ print(f"Renamed '{filename}' to '{new_name}'")
39
+
40
+ for filename in os.listdir(folder_path):
41
+ if filename.endswith(".jpg"):
42
+ file_path = os.path.join(folder_path, filename)
43
+ if os.path.splitext(os.path.basename(new_path))[0] in filename.upper():
44
+
45
+ # Buat nama baru
46
+ new_name = new_name.replace(".mp4", " Cover.jpg")
47
+ new_path = os.path.join(dest_cover, new_name)
48
+
49
+ # Rename file
50
+ os.rename(file_path, new_path)
51
+ print(f"Renamed '{filename}' to '{new_name}'")
52
+
53
+ def search(string, path="."):
54
+ hasil = []
55
+ output = ""
56
+
57
+ for root, dirs, files in os.walk(path):
58
+ # Cek folder yang mengandung string
59
+ for dir_name in dirs:
60
+ if string.lower() in dir_name.lower():
61
+ hasil.append(os.path.join(root, dir_name))
62
+
63
+ # Cek file yang mengandung string
64
+ for file_name in files:
65
+ if string.lower() in file_name.lower():
66
+ hasil.append(os.path.join(root, file_name))
67
+
68
+ # Menampilkan hasil pencarian
69
+ if hasil:
70
+ output += "\nHasil Pencarian:"
71
+ for i, item in enumerate(hasil, 1):
72
+ output += f"\n{i}. {item}"
73
+ else:
74
+ output += "Tidak ada hasil ditemukan."
75
+
76
+ return output
77
+
78
+ def search_jav(path="."):
79
+ video_files = []
80
+ image_files = []
81
+
82
+ for root, _, files in os.walk(path):
83
+ for file in files:
84
+ if file.lower().endswith(".mp4"):
85
+ video_files.append(os.path.join(root, file)) # Simpan path lengkap
86
+ elif file.lower().endswith(".jpg"):
87
+ image_files.append(os.path.join(root, file))
88
+
89
+ return video_files, image_files
90
+
91
+ def run_command(command):
92
+ try:
93
+ result = subprocess.run(command, shell=True, text=True, capture_output=True)
94
+ if result.stdout:
95
+ return result.stdout # Kembalikan output jika ada
96
+ # Jika output kosong, lempar error
97
+ raise RuntimeError("Perintah tidak menghasilkan output!")
98
+ except Exception as e:
99
+ return search(command)
100
+
101
+ def install_miyuki():
102
+ try:
103
+ import miyuki
104
+ return "Miyuki is already installed."
105
+ except ImportError:
106
+ command = "pip install miyuki-0.7.7-py3-none-any.whl"
107
+ return run_command(command)
miyuki-0.7.7-py3-none-any.whl ADDED
Binary file (13 kB). View file
 
process.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import uuid
3
+ import json
4
+ import time
5
+ import subprocess
6
+
7
+ static_dir = os.path.join(os.getcwd(), "static")
8
+ queue_file = os.path.join(os.getcwd(), "download_queue.json")
9
+ if not os.path.exists(static_dir):
10
+ os.makedirs(static_dir)
11
+
12
+ def load_queue():
13
+ if os.path.exists(queue_file):
14
+ with open(queue_file, "r") as f:
15
+ return json.load(f)
16
+ return {}
17
+
18
+ def save_queue(queue):
19
+ with open(queue_file, "w") as f:
20
+ json.dump(queue, f)
21
+
22
+ def download_file(video_url_input, quality):
23
+ movie_id = video_url_input.split("/")[-1]
24
+ log_id = uuid.uuid4()
25
+ log_file_path = os.path.join(static_dir, f"{log_id}.log")
26
+ command = f"miyuki -ffmpeg -auto {video_url_input} -quality {quality} -cover"
27
+
28
+ with open(log_file_path, "w") as log_file:
29
+ subprocess.Popen(
30
+ command, stdout=log_file, stderr=log_file, text=True, shell=True
31
+ )
32
+
33
+ log_link = f"./static/{log_id}.log"
34
+ return "Downloading", log_link
35
+
36
+ def check_task_status(url, log_link):
37
+ if not log_link:
38
+ return "Not Started", ""
39
+
40
+ log_file = log_link.split("/static/")[-1]
41
+ log_path = os.path.join(static_dir, log_file)
42
+
43
+ if os.path.exists(log_path):
44
+ with open(log_path, "r") as f:
45
+ content = f.read()
46
+ movie_id = url.split("/")[-1]
47
+
48
+ if f"File integrity for {movie_id}: 100.00%" in content:
49
+ return "Success", log_link
50
+ elif "Failed to fetch HTML for" in content:
51
+ return "Failed", log_link
52
+
53
+ return "Downloading", log_link
54
+
55
+ def clean_log_files():
56
+ queue = load_queue()
57
+ urls_to_remove = []
58
+
59
+ for url, task in queue.items():
60
+ if task["Status"] in ["Success", "Failed"]:
61
+ if task["Log"]:
62
+ log_file = task["Log"].split("/static/")[-1]
63
+ log_path = os.path.join(static_dir, log_file)
64
+ if os.path.exists(log_path):
65
+ os.remove(log_path)
66
+ urls_to_remove.append(url)
67
+
68
+ for url in urls_to_remove:
69
+ del queue[url]
70
+
71
+ save_queue(queue)
72
+
73
+ for filename in ["downloaded_urls_miyuki.txt", "ffmpeg_input_miyuki.txt", "tmp_movie_miyuki.html", "miyuki.log"]:
74
+ try:
75
+ os.remove(filename)
76
+ except FileNotFoundError:
77
+ pass
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ pandas