LINUX.ORG.RU

Ищу утилиту для Linux

 ,


0

1

Всем привет!

Вопрос от чайника!!!

Есть в интернете доступное для скачивания приложение:

https://download.cdn.viber.com/desktop/Linux/viber.AppImage

Есть ли готовая утилита для терминала Linux, которая проверит, не обновился ли файл в интернете, и если обновился - скачает ко мне на комп новую версию?

Спасибо.

у wget есть опция -N –timestamping Turn on time-stamping.
файл скачивается только если отметки времени файлов не совпадают. если у файла совпадает отметка времени то пишет

Connecting to aaa.bb (aaa.bb)|88.88.88.88|:443... connected.
HTTP request sent, awaiting response... 304 Not Modified
File 'cccc.ddd' not modified on server. Omitting download.

и прекращает работу.
п.с.: файл должен быть в текущей директории, -O не работает.

в curl не нашел, но наверн тож чтонить есть.

pfg ★★★★★
()

на гитхабе где-то есть репозиторий со ссылками на эти appimage. можешь утилиту сам написать или использовать flatpak/snap, где viber есть в репах и его не нужно каждый раз качать полностью, а лишь бинарные «патчи» на него

rtxtxtrx ★★
()
Ответ на: комментарий от LongLiveUbuntu

в /tmp скачать, md5 вычислить, сравнить с тем, что на диске ИЛИ отправить запрос с заголовком If-Modified-Since и скачать по необходимости

rtxtxtrx ★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 1)

Я тебе как величайший ноукоде промпт-инжиниар (господе, какой же мерзотный копросленг зумерского отродия) сгенерировал утилиту:

утилита_linux.py:

#!/usr/bin/env python3

import argparse
import requests
import os
import hashlib
import tempfile
from datetime import datetime
from pathlib import Path
from typing import Optional, NamedTuple
from urllib.parse import urlparse, unquote

class FileInfo(NamedTuple):
    last_modified: str
    size: int
    md5: str

def get_file_info(file_path: str) -> Optional[FileInfo]:
    file_stat = os.stat(file_path)
    last_modified = datetime.utcfromtimestamp(file_stat.st_mtime).strftime('%a, %d %b %Y %H:%M:%S GMT')
    size = file_stat.st_size
    md5 = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
    return FileInfo(last_modified, size, md5)

def save_file(response: requests.Response, file_path: str) -> None:
    if response.status_code == 200:
        with open(file_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)

def check_file_integrity(file_path: str, size: int, md5: str) -> bool:
    new_size = os.path.getsize(file_path)
    new_md5 = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
    return new_size == size and new_md5 == md5

def replace_file_if_needed(url: str, file_path: str) -> None:
    file_info = get_file_info(file_path) if os.path.exists(file_path) else None
    last_modified = file_info.last_modified if file_info else None
    headers = {'If-Modified-Since': last_modified} if last_modified else {}

    response = requests.get(url, headers=headers, stream=True)
    if response.status_code == 304:
        print(f"Файл {file_path} не изменился.")
        return

    with tempfile.NamedTemporaryFile(delete=False) as temp_file:
        temp_path = temp_file.name

    save_file(response, temp_path)

    if file_info and check_file_integrity(temp_path, file_info.size, file_info.md5):
        print(f"Файл {file_path} не изменился.")
        os.remove(temp_path)
        return

    os.replace(temp_path, file_path)
    print(f"Файл {file_path} успешно обновлен.")

def main() -> None:
    parser = argparse.ArgumentParser(description="Скачивание файла с проверкой на изменение.")
    parser.add_argument('url', type=str, help="URL для скачивания файла")
    parser.add_argument('-D', '--directory', type=str, default=str(Path.cwd()), help="Каталог для сохранения файла")
    parser.add_argument('-O', '--output', type=str, default=None, help="Путь к файлу для сохранения")

    args = parser.parse_args()

    if args.output is None:
        url_path = urlparse(args.url).path
        file_name = unquote(os.path.basename(url_path))
        final_file_path = os.path.join(args.directory, file_name)
    else:
        final_file_path = args.output

    replace_file_if_needed(args.url, final_file_path)

if __name__ == "__main__":
    main()
rtxtxtrx ★★
()