Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						6e016b802b
	
				 | 
					
					
						|||
| 
						
						
							
						
						72b85ec281
	
				 | 
					
					
						|||
| 
						
						
							
						
						b2e3268ad1
	
				 | 
					
					
						|||
| 
						
						
							
						
						1af43b111c
	
				 | 
					
					
						|||
| 
						
						
							
						
						03312a0079
	
				 | 
					
					
						|||
| 
						
						
							
						
						a91163f845
	
				 | 
					
					
						|||
| 7d28d1cea8 | |||
| 3fda737af2 | |||
| 
						
						
							
						
						8cf3d4dda8
	
				 | 
					
					
						|||
| 
						
						
							
						
						2e18921a27
	
				 | 
					
					
						|||
| 
						
						
							
						
						f1efb1d67c
	
				 | 
					
					
						|||
| 
						
						
							
						
						457ede5b62
	
				 | 
					
					
						|||
| 
						
						
							
						
						7eb724d01f
	
				 | 
					
					
						|||
| 
						
						
							
						
						189bbb0874
	
				 | 
					
					
						|||
| 
						
						
							
						
						68da5f9658
	
				 | 
					
					
						|||
| 
						
						
							
						
						83cd0b722b
	
				 | 
					
					
						
@@ -7,8 +7,8 @@ EnableConsole = true
 | 
				
			|||||||
[WatchFolder]
 | 
					[WatchFolder]
 | 
				
			||||||
Path = "/mnt/watched"
 | 
					Path = "/mnt/watched"
 | 
				
			||||||
PollingInterval = 10
 | 
					PollingInterval = 10
 | 
				
			||||||
UsePolling = false
 | 
					UsePolling = false 
 | 
				
			||||||
UseInotify = true
 | 
					UseInotify = false 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[N_m3u8DLRE]
 | 
					[N_m3u8DLRE]
 | 
				
			||||||
Path = "nre"
 | 
					Path = "nre"
 | 
				
			||||||
@@ -168,7 +168,7 @@ func getDownloadCommand(item Item, mpdPath string, tempDir string) string {
 | 
				
			|||||||
	metadata := parseMetadata(item.Metadata)
 | 
						metadata := parseMetadata(item.Metadata)
 | 
				
			||||||
	keys := getKeys(item.Keys)
 | 
						keys := getKeys(item.Keys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	command := fmt.Sprintf("%s %s", config.N_m3u8DLRE.Path, mpdPath)
 | 
						command := fmt.Sprintf("%s '%s'", config.N_m3u8DLRE.Path, mpdPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, key := range keys {
 | 
						for _, key := range keys {
 | 
				
			||||||
		if key != "" {
 | 
							if key != "" {
 | 
				
			||||||
@@ -195,6 +195,10 @@ func getDownloadCommand(item Item, mpdPath string, tempDir string) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	command += fmt.Sprintf(" --tmp-dir \"%s\"", tempDir)
 | 
						command += fmt.Sprintf(" --tmp-dir \"%s\"", tempDir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if globalSpeedLimit != "" {
 | 
				
			||||||
 | 
							command += fmt.Sprintf(" -R %s", globalSpeedLimit)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println(command)
 | 
						fmt.Println(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return command
 | 
						return command
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,11 @@ func handleRoot(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
			CurrentFile string
 | 
								CurrentFile string
 | 
				
			||||||
			Paused      bool
 | 
								Paused      bool
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}{jobsInfo})
 | 
							GlobalSpeedLimit string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							Jobs:             jobsInfo,
 | 
				
			||||||
 | 
							GlobalSpeedLimit: globalSpeedLimit,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logger.LogError("Handle Root", fmt.Sprintf("Error executing template: %v", err))
 | 
							logger.LogError("Handle Root", fmt.Sprintf("Error executing template: %v", err))
 | 
				
			||||||
		http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
							http.Error(w, err.Error(), http.StatusInternalServerError)
 | 
				
			||||||
@@ -443,3 +447,32 @@ func broadcast(filename string, message []byte) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleSetSpeedLimit(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						logger.LogInfo("Set Speed Limit", "Received request to set speed limit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.Method != http.MethodPost {
 | 
				
			||||||
 | 
							logger.LogError("Set Speed Limit", "Invalid method")
 | 
				
			||||||
 | 
							http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var requestData struct {
 | 
				
			||||||
 | 
							SpeedLimit string `json:"speedLimit"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
 | 
				
			||||||
 | 
							logger.LogError("Set Speed Limit", "Invalid request body")
 | 
				
			||||||
 | 
							http.Error(w, "Invalid request", http.StatusBadRequest)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if requestData.SpeedLimit == "unlimited" {
 | 
				
			||||||
 | 
							globalSpeedLimit = ""
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							globalSpeedLimit = requestData.SpeedLimit
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger.LogInfo("Set Speed Limit", fmt.Sprintf("Global speed limit set to: %s", globalSpeedLimit))
 | 
				
			||||||
 | 
						w.WriteHeader(http.StatusOK)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,8 @@ var templates *template.Template
 | 
				
			|||||||
//go:embed templates
 | 
					//go:embed templates
 | 
				
			||||||
var templateFS embed.FS
 | 
					var templateFS embed.FS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var globalSpeedLimit string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	if err := os.MkdirAll(uploadDir, 0755); err != nil {
 | 
						if err := os.MkdirAll(uploadDir, 0755); err != nil {
 | 
				
			||||||
		fmt.Printf("Error creating upload directory: %v\n", err)
 | 
							fmt.Printf("Error creating upload directory: %v\n", err)
 | 
				
			||||||
@@ -83,6 +85,7 @@ func startWebServer() {
 | 
				
			|||||||
	http.HandleFunc("/resume", handleResume)
 | 
						http.HandleFunc("/resume", handleResume)
 | 
				
			||||||
	http.HandleFunc("/clear-completed", handleClearCompleted)
 | 
						http.HandleFunc("/clear-completed", handleClearCompleted)
 | 
				
			||||||
	http.HandleFunc("/ws", handleWebSocket)
 | 
						http.HandleFunc("/ws", handleWebSocket)
 | 
				
			||||||
 | 
						http.HandleFunc("/set-speed-limit", handleSetSpeedLimit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logger.LogInfo("Main", "Starting web server on http://0.0.0.0:8080")
 | 
						logger.LogInfo("Main", "Starting web server on http://0.0.0.0:8080")
 | 
				
			||||||
	http.ListenAndServe(":8080", nil)
 | 
						http.ListenAndServe(":8080", nil)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,6 @@
 | 
				
			|||||||
        input[type="file"], input[type="submit"] {
 | 
					        input[type="file"], input[type="submit"] {
 | 
				
			||||||
            background-color: #2d2d2d;
 | 
					            background-color: #2d2d2d;
 | 
				
			||||||
            color: #d4d4d4;
 | 
					            color: #d4d4d4;
 | 
				
			||||||
            border: 1px solid #444;
 | 
					 | 
				
			||||||
            padding: 8px 12px;
 | 
					            padding: 8px 12px;
 | 
				
			||||||
            border-radius: 4px;
 | 
					            border-radius: 4px;
 | 
				
			||||||
            margin-bottom: 10px;
 | 
					            margin-bottom: 10px;
 | 
				
			||||||
@@ -77,6 +76,11 @@
 | 
				
			|||||||
        .paused {
 | 
					        .paused {
 | 
				
			||||||
            color: #ffa500;
 | 
					            color: #ffa500;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit {
 | 
				
			||||||
 | 
					            font-size: 1em;
 | 
				
			||||||
 | 
					            color: #a0a0a0;
 | 
				
			||||||
 | 
					            margin-top: 10px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        @media (max-width: 600px) {
 | 
					        @media (max-width: 600px) {
 | 
				
			||||||
            body {
 | 
					            body {
 | 
				
			||||||
                padding: 10px;
 | 
					                padding: 10px;
 | 
				
			||||||
@@ -107,6 +111,94 @@
 | 
				
			|||||||
        #clear-completed:hover {
 | 
					        #clear-completed:hover {
 | 
				
			||||||
            background-color: #d32f2f;
 | 
					            background-color: #d32f2f;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        /* New CSS for speed limit form */
 | 
				
			||||||
 | 
					        .settings-section {
 | 
				
			||||||
 | 
					            margin-top: 30px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-form {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            justify-content: space-between;
 | 
				
			||||||
 | 
					            gap: 10px;
 | 
				
			||||||
 | 
					            margin-bottom: 20px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-form .form-group {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            gap: 10px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-form input[type="number"],
 | 
				
			||||||
 | 
					        .speed-limit-form select,
 | 
				
			||||||
 | 
					        .speed-limit-form button {
 | 
				
			||||||
 | 
					            background-color: #2d2d2d;
 | 
				
			||||||
 | 
					            color: #d4d4d4;
 | 
				
			||||||
 | 
					            border: 1px solid #444;
 | 
				
			||||||
 | 
					            padding: 8px 12px;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-form button {
 | 
				
			||||||
 | 
					            cursor: pointer;
 | 
				
			||||||
 | 
					            background-color: #4CAF50;
 | 
				
			||||||
 | 
					            color: white;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-form button:hover {
 | 
				
			||||||
 | 
					            background-color: #45a049;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            margin-bottom: 20px;
 | 
				
			||||||
 | 
					            background-color: #2d2d2d;
 | 
				
			||||||
 | 
					            padding: 8px 12px;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container .form-group {
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					            gap: 10px;
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container input[type="number"] {
 | 
				
			||||||
 | 
					            background-color: #2d2d2d;
 | 
				
			||||||
 | 
					            color: #d4d4d4;
 | 
				
			||||||
 | 
					            border: 1px solid #444;
 | 
				
			||||||
 | 
					            padding: 8px 12px;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					            height: 40px;
 | 
				
			||||||
 | 
					            box-sizing: border-box;
 | 
				
			||||||
 | 
					            flex-grow: 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container select,
 | 
				
			||||||
 | 
					        .speed-limit-container button {
 | 
				
			||||||
 | 
					            background-color: #2d2d2d;
 | 
				
			||||||
 | 
					            color: #d4d4d4;
 | 
				
			||||||
 | 
					            border: 1px solid #444;
 | 
				
			||||||
 | 
					            padding: 8px 12px;
 | 
				
			||||||
 | 
					            border-radius: 4px;
 | 
				
			||||||
 | 
					            height: 40px;
 | 
				
			||||||
 | 
					            box-sizing: border-box;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container button {
 | 
				
			||||||
 | 
					            cursor: pointer;
 | 
				
			||||||
 | 
					            background-color: #4CAF50;
 | 
				
			||||||
 | 
					            color: white;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container button:hover {
 | 
				
			||||||
 | 
					            background-color: #45a049;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container .speed-limit {
 | 
				
			||||||
 | 
					            color: #d4d4d4;
 | 
				
			||||||
 | 
					            margin-left: auto;
 | 
				
			||||||
 | 
					            display: flex;
 | 
				
			||||||
 | 
					            align-items: center;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .speed-limit-container .speed-limit span {
 | 
				
			||||||
 | 
					            margin-left: 5px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .current-speed-limit {
 | 
				
			||||||
 | 
					            color: #d4d4d4;
 | 
				
			||||||
 | 
					            margin-top: 10px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
@@ -135,6 +227,23 @@
 | 
				
			|||||||
        {{end}}
 | 
					        {{end}}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <button id="clear-completed" onclick="clearCompleted()">Clear Completed Jobs</button>
 | 
					    <button id="clear-completed" onclick="clearCompleted()">Clear Completed Jobs</button>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <div class="settings-section">
 | 
				
			||||||
 | 
					        <h2>Settings</h2>
 | 
				
			||||||
 | 
					        <div class="speed-limit-container">
 | 
				
			||||||
 | 
					            <div class="form-group">
 | 
				
			||||||
 | 
					                <label for="speedLimitValue">Speed Limit:</label>
 | 
				
			||||||
 | 
					                <input type="number" id="speedLimitValue" name="speedLimitValue" min="0" step="0.01" required>
 | 
				
			||||||
 | 
					                <select id="speedLimitUnit" name="speedLimitUnit">
 | 
				
			||||||
 | 
					                    <option value="GBps">GBps</option>
 | 
				
			||||||
 | 
					                    <option value="MBps" selected>MBps</option>
 | 
				
			||||||
 | 
					                    <option value="KBps">KBps</option>
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					                <button type="button" onclick="updateSpeedLimit(event)">Set Limit</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <script>
 | 
					    <script>
 | 
				
			||||||
        function clearCompleted() {
 | 
					        function clearCompleted() {
 | 
				
			||||||
            fetch('/clear-completed', { method: 'POST' })
 | 
					            fetch('/clear-completed', { method: 'POST' })
 | 
				
			||||||
@@ -147,6 +256,54 @@
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function updateSpeedLimit(event) {
 | 
				
			||||||
 | 
					            event.preventDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const speedLimitValue = document.getElementById('speedLimitValue').value;
 | 
				
			||||||
 | 
					            const speedLimitUnit = document.getElementById('speedLimitUnit').value;
 | 
				
			||||||
 | 
					            const speedLimit = speedLimitValue === "0" ? "unlimited" : speedLimitValue + speedLimitUnit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!validateSpeedLimit(speedLimitValue)) {
 | 
				
			||||||
 | 
					                alert('Please enter a valid speed limit.');
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fetch('/set-speed-limit', {
 | 
				
			||||||
 | 
					                method: 'POST',
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                body: JSON.stringify({ speedLimit }),
 | 
				
			||||||
 | 
					            }).then(response => {
 | 
				
			||||||
 | 
					                if (response.ok) {
 | 
				
			||||||
 | 
					                    alert('Speed limit updated successfully');
 | 
				
			||||||
 | 
					                    document.getElementById('currentSpeedLimit').textContent = speedLimit;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    alert('Failed to update speed limit');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function validateSpeedLimit(value) {
 | 
				
			||||||
 | 
					            const number = parseFloat(value);
 | 
				
			||||||
 | 
					            return !isNaN(number) && number >= 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        document.addEventListener('DOMContentLoaded', function() {
 | 
				
			||||||
 | 
					            const currentSpeedLimit = "{{if .GlobalSpeedLimit}}{{.GlobalSpeedLimit}}{{else}}0{{end}}";
 | 
				
			||||||
 | 
					            const speedLimitValueInput = document.getElementById('speedLimitValue');
 | 
				
			||||||
 | 
					            const speedLimitUnitSelect = document.getElementById('speedLimitUnit');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const match = currentSpeedLimit.match(/(\d+(\.\d+)?)([A-Za-z]+)/);
 | 
				
			||||||
 | 
					            if (match) {
 | 
				
			||||||
 | 
					                speedLimitValueInput.value = match[1];
 | 
				
			||||||
 | 
					                speedLimitUnitSelect.value = match[3];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                speedLimitValueInput.value = "0"; 
 | 
				
			||||||
 | 
					                speedLimitUnitSelect.value = "MBps";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    </script>
 | 
					    </script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user