<aside> 💡 A limitation of this approach is that the server or remote computer must remain powered on.
</aside>
<aside> 💡 This method only works with key-based SSH authentication configured using ssh-copy-id.
</aside>
How to configure key-based authentication for SSH
import os
import time
from datetime import date
time.sleep(4) # A short delay to ensure the system has time to create the file
def get_newest_mp4_file(directory):
"""
Retrieves the newest .mp4 file from the specified directory.
Returns the filename if found, otherwise returns None.
"""
if not os.path.exists(directory):
print("Error: Directory does not exist -", directory)
return None
mp4_files = [f for f in os.listdir(directory) if f.endswith(".mp4")]
if not mp4_files:
print("No .mp4 files found in directory:", directory)
return None
newest_file = max(mp4_files, key=lambda f: os.path.getmtime(os.path.join(directory, f)))
return newest_file
# Remote server details
SSH_HOST = "192.168.0.xxx" # Remote server IP
SSH_USERNAME = "remote_username" # Remote username
REMOTE_PATH = "~/Desktop/" # Path on the remote server
# Define video storage path
video_base_path = "/data/media/sda4/"
# Get today's date in the correct format
formatted_date = date.today().strftime("%Y-%m-%d")
# Construct the full directory path for today's videos
video_directory = os.path.join(video_base_path, formatted_date)
# Get the newest .mp4 file from the directory
filename = get_newest_mp4_file(video_directory)
if filename:
# Construct the full local file path
file_path = os.path.join(video_directory, filename)
# Build the SCP command
scp_command = 'scp "{}" {}@{}:"{}"'.format(file_path, SSH_USERNAME, SSH_HOST, REMOTE_PATH)
# Execute the SCP command
os.system(scp_command)
else:
print("No file to transfer.")
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"time"
)
// Config struct to hold settings from JSON
type Config struct {
SSHHost string `json:"ssh_host"`
SSHUsername string `json:"ssh_username"`
RemotePath string `json:"remote_path"`
VideoBasePath string `json:"video_base_path"`
SleepTime int `json:"sleep_time"`
}
// LoadConfig reads JSON config file and parses it into Config struct
func LoadConfig(filename string) (*Config, error) {
file, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
var config Config
err = json.Unmarshal(file, &config)
if err != nil {
return nil, err
}
return &config, nil
}
// GetLatestMP4File finds the newest .mp4 file in a given directory
func GetLatestMP4File(directory string) (string, error) {
files, err := ioutil.ReadDir(directory)
if err != nil {
return "", err
}
var mp4Files []os.FileInfo
for _, file := range files {
if strings.HasSuffix(file.Name(), ".mp4") {
mp4Files = append(mp4Files, file)
}
}
if len(mp4Files) == 0 {
return "", fmt.Errorf("no .mp4 files found in %s", directory)
}
// Sort by modification time (newest first)
sort.Slice(mp4Files, func(i, j int) bool {
return mp4Files[i].ModTime().After(mp4Files[j].ModTime())
})
// Return the newest file name
return mp4Files[0].Name(), nil
}
// TransferFileViaSCP transfers a file to a remote server using SCP
func TransferFileViaSCP(filePath, sshUsername, sshHost, remotePath string) error {
scpCmd := fmt.Sprintf("scp \\"%s\\" %s@%s:\\"%s\\"", filePath, sshUsername, sshHost, remotePath)
cmd := exec.Command("sh", "-c", scpCmd)
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("SCP failed: %s, error: %v", string(output), err)
}
fmt.Println("File transferred successfully:", filePath)
return nil
}
func main() {
// Load configuration
config, err := LoadConfig("config.json")
if err != nil {
log.Fatalf("Error loading config: %v", err)
}
// Sleep for specified duration
time.Sleep(time.Duration(config.SleepTime) * time.Second)
// Get today's date in YYYY-MM-DD format
today := time.Now().Format("2006-01-02")
// Construct today's video directory
videoDir := filepath.Join(config.VideoBasePath, today)
// Get the latest .mp4 file
latestFile, err := GetLatestMP4File(videoDir)
if err != nil {
log.Fatalf("Error finding latest .mp4 file: %v", err)
}
// Full file path
filePath := filepath.Join(videoDir, latestFile)
// Transfer file via SCP
err = TransferFileViaSCP(filePath, config.SSHUsername, config.SSHHost, config.RemotePath)
if err != nil {
log.Fatalf("Error transferring file: %v", err)
}
}
// you could compile this
{
"ssh_host": "192.168.0.xxx",
"ssh_username": "remote_username",
"remote_path": "~/Desktop/",
"video_base_path": "/data/media/sda4/",
"sleep_time": 4
}
Then you just sync that folder to Google Drive.
On Mac and Windows, it is quite easy
On Linux follow this guide