Необходимо разработать приложение командной строки (CLI) для управления альбомами, фотографиями в облачном хранилище Yandex Object Storage, для формирования и публикации веб-страниц фотоархива.

1. Наименование программы

Программа должна называться cloudphoto.

2. Функциональные требования

Программа cloudphoto должна выполнять следующие команды:

  • upload — отправка фотографий в облачное хранилище.

  • download — загрузка фотографий из облачного хранилища.

  • list — вывод списка альбомов и фотографий в облачном хранилище.

  • delete — удаление альбомов и фотографий в облачном хранилище.

  • mksite — формирование и публикация веб-страниц фотоархива.

  • init — инициализация программы.

Команды могут иметь опции.

Общий синтаксис запуска программы cloudphoto
cloudphoto COMMAND [OPTION]...

2.1. Отправка фотографий в облачное хранилище

Для отправки фотографий в облачное хранилище используется команда upload.

Синтаксис команды upload

cloudphoto upload --album ALBUM [--path PHOTOS_DIR]

Требования для реализации команды upload

  1. Если опция --path не задана, то программа cloudphoto должна в качестве PHOTOS_DIR использовать текущий каталог.

  2. Если в облачном хранилище существует альбом с именем ALBUM, то программа cloudphoto должна отправить все фотографии из каталога с именем PHOTOS_DIR (без обхода вложенных подкаталогов) в облачное хранилище и привязать их к альбому с именем ALBUM.

  3. Если в облачном хранилище нет альбома с именем ALBUM, то программа cloudphoto должна создать в облачном хранилище альбом с именем ALBUM, а так же отправить все фотографии из каталога PHOTOS_DIR (без обхода вложенных подкаталогов) в облачное хранилище и привязать их к альбому с именем ALBUM.

  4. Программа cloudphoto должна для каждой фотографии сохранить в облачном хранилище имя отправляемого файла с учётом регистра символов (далее — исходное имя файла).

  5. Если в облачном хранилище в альбоме с именем ALBUM существует фотография, у которой исходное имя файла совпадает с именем отправляемого файла, то программа cloudphoto должна заменить фотографию в облачном хранилище на отправляемую фотографию.

  6. Ели при отправке фотографии в облачное хранилище произошла ошибка любого характера, то программа cloudphoto должна вывести предупреждение и продолжить отправку других файлов.

  7. Если каталог с именем PHOTOS_DIR не доступен, то программа cloudphoto должна завершиться с ошибкой.

  8. Если в каталоге с именем PHOTOS_DIR нет фотографий, то программа cloudphoto должна завершиться с ошибкой.

2.2. Загрузка фотографий из облачного хранилища

Для загрузки фотографий из облачного хранилища используется команда download.

Синтаксис команды download

cloudphoto download --album ALBUM [--path PHOTOS_DIR]

Требования для реализации команды download

  1. Если опция --path не задана, то программа cloudphoto должна в качестве PHOTOS_DIR использовать текущий каталог.

  2. Программа cloudphoto должна загрузить из облачного хранилища все фотографии из альбома с именем ALBUM и сохранить их в каталог с именем PHOTOS_DIR.

  3. При сохранении фотографий программа cloudphoto должна задать имя для сохраняемого файла такое же как исходное имя файла загружаемой фотографии.

  4. Если при сохранении фотографии в каталоге PHOTOS_DIR существует файл таким же именем как исходное имя файла у фотографии, то программа cloudphoto должна заменить существующей файл на фотографию их облачного хранилища.

  5. Если каталог с именем PHOTOS_DIR не доступен для сохранения файлов, то программа cloudphoto должна завершиться с ошибкой.

  6. Если в облачном хранилище нет альбома с именем ALBUM, то программа cloudphoto должна завершиться с ошибкой.

2.3. Просмотр списка альбомов и фотографий в альбоме

Для просмотра списка альбомов и фотографий в облачном хранилище используется команда list.

Синтаксис команды list

cloudphoto list [--album ALBUM]

Требования для реализации команды list

  1. Если не указана опция --album, то программа cloudphoto должна вывести наименование всех альбомов в облачном хранилище. Каждое имя альбома должно выводиться на отдельной строке.

  2. Если задана опция --album, то программа cloudphoto должна вывести имена исходных файлов всех фотографий в альбоме с именем ALBUM. Каждое исходное имя файла должно выводиться на отдельной строке.

  3. Если не указана опция --album и в облачном хранилище нет альбомом, то программа cloudphoto должна завершиться с ошибкой.

  4. Если задана опция --album и в облачном хранилище нет альбома с именем ALBUM, то программа cloudphoto должна завершиться с ошибкой.

  5. Если задана опция --album и в альбоме с именем ALBUM нет фотографий, то программа cloudphoto должна завершиться с ошибкой.

2.4. Удаление альбомов и фотографий

Для удаления альбомов и фотографий в облачном хранилище используется команда delete.

Синтаксис команды delete

cloudphoto delete --album ALBUM [--photo PHOTO]

Требования для реализации команды delete

  1. Если не указана опция --photo, то программа cloudphoto должна удалить в облачном хранилище все фотографии из альбома с именем ALBUM и удалить альбом с именем ALBUM.

  2. Если не указана опция --photo и в облачном хранилище в альбоме с именем ALBUM нет фотографий, то программа cloudphoto должна удалить альбом с именем ALBUM.

  3. Если задана опция --photo, то программа cloudphoto должна удалить в облачном хранилище в альбоме с именем ALBUM фотографию с исходным именем PHOTO.

  4. Если в облачном хранилище нет альбома ALBUM, то программа cloudphoto должна завершиться с ошибкой.

  5. Если задана опция --photo и в облачном хранилище в альбоме с именем ALBUM нет фотографии с исходным именем PHOTO, то программа cloudphoto должна завершиться с ошибкой.

2.5. Генерация и публикация веб-страниц фотоархива

Синтаксис команды mksite

cloudphoto mksite

Требования для реализации команды mksite

  1. Программа cloudphoto должна настроить для бакета публичный доступ на чтение объектов и добавить настройку хостинга статического сайта со следующими значениями параметров:

    • для параметра Главная страница сайта значение index.html,

    • для параметра Страница ошибки значение error.html.

  2. Программа cloudphoto должна временно пронумеровать альбомы натуральными числами от 1 до числа равного количеству альбомов, далее для каждого альбома сформировать HTML документ по шаблону "Шаблон HTML документа "Страница альбома"" и сохранить его в облачном хранилище в объекте с уникальным ключом album{N}.html, где вместо {N} вставить временный номер альбома. Если в облачном хранилище существует объект с ключом album{N}.html, то программа cloudphoto должна заменить его новым.

  3. Программа cloudphoto должна сформировать HTML документ по шаблону "Шаблон HTML документа "Индексная страница"" и сохранить его в облачном хранилище с ключом index.html. Если в облачном хранилище существует объект с ключом index.html, то программа cloudphoto должна заменить его новым.

  4. Программа cloudphoto должна сформировать HTML документ по шаблону "Шаблон HTML документа "Страница ошибки"" и сохранить его в облачном хранилище с ключом error.html. Если в облачном хранилище существует объект с ключом error.html, то программа cloudphoto должна заменить его новым.

  5. Программа cloudphoto должна вывести ссылку https://bucket_name.website.yandexcloud.net/, где bucket_name, должен быть заменён на название бакета, которое указано в конфигурационном файле.

2.6. Инициализация программы

Для формирования файла настроек и создания бакета используется команда init.

Синтаксис команды init

cloudphoto init

Требования для реализации команды init

  1. Программа cloudphoto должна в интерактивном режиме запросить у пользователя значение параметров: aws_access_key_id, aws_secret_access_key, bucket и сохранить их в конфигурационном файле.

  2. Если в облачном хранилище нет бакета с именем, которое указано в конфигурационном файле, то программа cloudphoto должна создать в облачном хранилище бакет с именем, которое указано в конфигурационном файле.

3. Дополнительные требования

3.1. Требования к исполнению

  1. Программа cloudphoto должна запускаться в Unix подобных операционных системах, включая подсистему WSL2 в Windows и дополнительные требования к программе cloudphoto описаны с учётом этой особенности.

  2. При запуске программа cloudphoto должна проверить наличие конфигурационного файла и заполненность всех параметров, кроме запуска с командой init, и если конфигурационный файл не доступен или в нём заполнены не все параметры, то программа cloudphoto должна завершиться с ошибкой.

  3. Если не корректно заданы опции у команды или указана не действительная команда, то программа cloudphoto должна завершиться с ошибкой.

  4. Программа cloudphoto должна данные выводить на стандартный поток вывода (stdout), а сообщения об ошибках и предупреждения выводить на стандартный поток для ошибок (stderr).

  5. Программа cloudphoto должна данные от пользователя считывать со стандартного потока ввода (stdin).

  6. При завершении без ошибок программа cloudphoto должна завершаться с код возврата (exit status) равным 0.

  7. При завершении с ошибками программа cloudphoto должна завершаться с код возврата (exit status) равным 1.

3.2. Требования к настройкам

  1. Конфигурационный файл программы cloudphoto должен находиться в домашнем каталоге пользователя по пути .config/cloudphoto/cloudphotorc.

  2. Формат конфигурационного файла должен соответствовать шаблону "Формат конфигурационного файла (ini-файл)".

  3. Программа cloudphoto не должна зависеть от других конфигурационных файлов и от специальных переменных окружения.

3.3. Требование к файлам с фотографиями

Для данного задания файл с фотографией — это файл, имя которого в независимости от регистра оканчивается на:

  • .jpg

  • .jpeg

3.4. Требования к организации облачного хранилища

Все альбомы, фотографии, веб-страницы должны храниться в одном бакете, который указан в настройках программы cloudphoto.

3.5. Требования к регистрам символов

Везде где есть сравнение текстовых строк, такое сравнение должно выполняться с учётом регистра символов, если не указано иное сравнение.

4. Шаблоны

Шаблон HTML документа "Индексная страница"

<!doctype html>
<html>
    <head>
        <title>Фотоархив</title>
    </head>
<body>
    <h1>Фотоархив</h1>
    <ul>(1)
        <li><a href="album1.html">Имя альбома 1</a></li>
        <li><a href="album2.html">Имя альбома 2</a></li>
        <li><a href="...">...</a></li>
        <li><a href="album{N}.html">Имя альбома N</a></li>
    </ul>
</body
1 В списке нужно перечислить все ссылки на страницы альбомом и указать имена альбомов.

Шаблон HTML документа "Страница альбома"

<!doctype html>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/galleria/1.6.1/themes/classic/galleria.classic.min.css" />
        <style>
            .galleria{ width: 960px; height: 540px; background: #000 }
        </style>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/galleria/1.6.1/galleria.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/galleria/1.6.1/themes/classic/galleria.classic.min.js"></script>
    </head>
    <body>
        <div class="galleria">(1)
            <img src="URL_на_фотографию_1_в_альбоме" data-title="Имя_исходного_файла_фотографии_1">
            <img src="URL_на_фотографию_2_в_альбоме" data-title="Имя_исходного_файла_фотографии_2">
            <img src="..." data-title="...">
            <img src="URL_на_фотографию_N_в_альбоме" data-title="Имя_исходного_файла_фотографии_N">
        </div>
        <p>Вернуться на <a href="index.html">главную страницу</a> фотоархива</p>
        <script>
            (function() {
                Galleria.run('.galleria');
            }());
        </script>
    </body>
</html>
1 В блоке нужно сформировать тег img для каждой фотографии в альбоме с указанием ссылки на фотографию и имени исходного файла фотографии.

Шаблон HTML документа "Страница ошибки"

<!doctype html>
<html>
    <head>
        <title>Фотоархив</title>
    </head>
<body>
    <h1>Ошибка</h1>
    <p>Ошибка при доступе к фотоархиву. Вернитесь на <a href="index.html">главную страницу</a> фотоархива.</p>
</body>
</html>

Формат конфигурационного файла (ini-файл)

[DEFAULT]
bucket = INPUT_BUCKET_NAME (1)
aws_access_key_id = INPUT_AWS_ACCESS_KEY_ID (2)
aws_secret_access_key = INPUT_AWS_SECRET_ACCESS_KEY (3)
region = ru-central1 (4)
endpoint_url = https://storage.yandexcloud.net (5)
1 При инициализации INPUT_BUCKET_NAME заменяется на название бакета, которое ввёл пользователь.
2 При инициализации INPUT_AWS_ACCESS_KEY_ID заменяется на идентификатор секретного статического ключа, который ввёл пользователь.
3 При инициализации INPUT_AWS_SECRET_ACCESS_KEY заменяется на секретный статичный ключа, которое ввёл пользователь.
4 Строка не меняется.
5 Строка не меняется.