#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import struct
import os

sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()

print('Connected: ', addr)

file_ext_len = struct.unpack('H', conn.recv(2))[0]  # Получение длины расширения
conn.send('OK'.encode('UTF-8'))  # Отсылка OK, чтобы продолжилось выполнение кода

file_ext = struct.unpack('{}s'.format(file_ext_len), conn.recv(file_ext_len))[0].decode('UTF-8')  # Получение расширения файла, распаковка и расшифровка
conn.send('OK'.encode('UTF-8'))  # Отсылка OK, чтобы клиент понял, что данные дошли.

files = sorted([file for file in os.listdir() if file.endswith(file_ext)])  # Создается отсортированный список файлов, находящихся в одной папке с файлом server и имеющих необходимое расширение

quantity_of_files = struct.pack('Q', len(files))  # Запаковывается количество файлов в папке и отсылается клиенту, чтобы он знал, сколько файлов принимать
conn.send(quantity_of_files)  # Отсылание количества файлов с необходимым расширением, находящихся в папке, клиенту


for file in files:  # Итерации по именам файлов в папке, имеющих необходимое расширение
    with open(file, mode='rb') as open_file:  # Открывается файл
        read_file = open_file.read()  # Файл считывается в переменную (записывается в оперативную память

        file_size = len(read_file)  # Определение размера файла в байтах
        encoded_filename = file.encode('UTF-8')  # Декодируется имя файла, чтобы его затем запакавать и отправить (таким образом вводится поддержка UNICODE)
        file_name_size = len(encoded_filename)  # Определение размера имени файла в байтах

        struct_file_size = struct.pack('Q', file_size)  # Запаковывается размер файла
        struct_file_name_size = struct.pack('H', file_name_size)  # Запаковывается размер имени файла в байтах (максимум - 32768 символов)
        struct_file_name = struct.pack('{}s'.format(file_name_size), encoded_filename)  # Запаковывается имя файла

        conn.send(struct_file_size)  # Отсылается размер файла
        if conn.recv(2).decode("UTF-8") == "OK":  # Ждет получения OK
            conn.send(struct_file_name_size)  # Отсылает размер имени файла
            if conn.recv(2).decode("UTF-8") == "OK":  # Ждет получения OK
                conn.send(struct_file_name)  # Отсылает имя файла
                if conn.recv(2).decode("UTF-8") == "OK":  # Ждет получения OK
                    conn.send(read_file)  # Отсылает файл
                    if conn.recv(2).decode("UTF-8") == "OK":  # Ждет получения OK
                        print(file, ' transmitted')  # Вывыодит сообщение об окончании передачи файла
                        continue

conn.close()  # Закрывает сокет
sock.close()

input('Press Enter to close')


