From 7842fdf67a00ce7cc5cffeb37f77c5f585472e2d Mon Sep 17 00:00:00 2001 From: xails-git Date: Mon, 26 May 2025 22:21:11 +0300 Subject: [PATCH 1/7] first commit 26.05 22.16 --- cmd/main.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmd/main.go b/cmd/main.go index 7905807..18553b2 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,5 +1,18 @@ package main +import ( + "log" + "os" + + "github.com/Yandex-Practicum/go1fl-sprint6-final/internal/server" +) + func main() { + logger := log.New(os.Stdout, "SERVER:", log.LstdFlags) + srv := server.New(logger) + logger.Println("Запуск сервера...") + if err := srv.Start(); err != nil { + logger.Fatalf("ошибка запуска сервера: %v", err) + } } From 62910ae6fbf348de2a2f6cf9b3d22792033d7484 Mon Sep 17 00:00:00 2001 From: xails-git Date: Mon, 26 May 2025 22:25:25 +0300 Subject: [PATCH 2/7] commit 22.25 --- internal/handlers/handlers.go | 93 +++++++++++++++++++++++++++++++++++ internal/server/server.go | 39 +++++++++++++++ internal/service/service.go | 38 ++++++++++++++ 3 files changed, 170 insertions(+) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 5ac8282..5d1e26e 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -1 +1,94 @@ package handlers + +import ( + "io" + "log" + "net/http" + "os" + "path/filepath" + "time" + + "github.com/Yandex-Practicum/go1fl-sprint6-final/internal/service" +) + +func ReturnHTML(w http.ResponseWriter, r *http.Request) { + data, err := os.ReadFile("index.html") + if err != nil { + http.Error(w, "ошибка чтения файла index.html", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/html") + w.WriteHeader(http.StatusOK) + + _, err = w.Write(data) + if err != nil { + log.Printf("Ошибка при отправке данных: %v", err) + } +} + +func ConvertStr(w http.ResponseWriter, r *http.Request) { + const maxMemory = 32 << 20 + + err := r.ParseMultipartForm(maxMemory) + if err != nil { + http.Error(w, "ошибка парсинга", http.StatusInternalServerError) + return + } + + file, header, err := r.FormFile("file") + if err != nil { + http.Error(w, "ошибка файла", http.StatusBadRequest) + return + } + defer file.Close() + + // обработка файла + + data, err := io.ReadAll(file) + if err != nil { + http.Error(w, "ошибка чтения файла", http.StatusInternalServerError) + return + } + + content := string(data) + if content == "" { + http.Error(w, "файл пустой", http.StatusBadRequest) + return + } + + converted, err := service.AutoConvert(content) + if err != nil { + http.Error(w, "ошибка конвертации", http.StatusInternalServerError) + return + } + + // создаем файл для результата + + timestamp := time.Now().UTC().Format("2006-01-02_15-04-05") + ext := filepath.Ext(header.Filename) + if ext == "" { + ext = ".txt" + } + outputFilename := "result_" + timestamp + ext + + outputFile, err := os.Create(outputFilename) + if err != nil { + http.Error(w, "Ошибка создания файла", http.StatusInternalServerError) + return + } + defer outputFile.Close() + + _, err = outputFile.WriteString(converted) + if err != nil { + http.Error(w, "ошибка записи в файл", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + _, err = w.Write([]byte(converted)) + if err != nil { + log.Printf("ошибка при отправке ответа %v", err) + } +} diff --git a/internal/server/server.go b/internal/server/server.go index abb4e43..feef934 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -1 +1,40 @@ package server + +import ( + "log" + "net/http" + "time" + + "github.com/Yandex-Practicum/go1fl-sprint6-final/internal/handlers" +) + +type Server struct { + logger *log.Logger // Логгер + httpServer *http.Server // HTTP-сервер +} + +func New(logger *log.Logger) *Server { + router := http.NewServeMux() + + router.HandleFunc("/", handlers.ReturnHTML) + router.HandleFunc("/upload", handlers.ConvertStr) + + httpServer := &http.Server{ + Addr: ":8080", + Handler: router, + ErrorLog: logger, + ReadTimeout: 5 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 15 * time.Second, + } + + return &Server{ + logger: logger, + httpServer: httpServer, + } +} + +func (s *Server) Start() error { + s.logger.Printf("Сервер запущен на %s", s.httpServer.Addr) + return s.httpServer.ListenAndServe() +} diff --git a/internal/service/service.go b/internal/service/service.go index 6d43c33..57b3aa3 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1 +1,39 @@ package service + +import ( + "fmt" + "strings" + + "github.com/Yandex-Practicum/go1fl-sprint6-final/pkg/morse" +) + +func AutoConvert(input string) (string, error) { + allowed := ".-/ " + isMorse := true + + if input == "" { + return "", fmt.Errorf("пустой ввод") + } + + for _, char := range input { + if !strings.ContainsRune(allowed, char) { + isMorse = false + break + } + } + + if isMorse { + text := morse.ToText(input) + if text == "" { + return "", fmt.Errorf("ошибка конвертации в текст") + } + return text, nil + } + + morseCode := morse.ToMorse(input) + if morseCode == "" { + return "", fmt.Errorf("ошибка конвертации в морзе") + } + return morseCode, nil + +} From 1e6f0eb5ba62e245b1dc8cb64b4fdde168ee4ab0 Mon Sep 17 00:00:00 2001 From: xails-git Date: Tue, 27 May 2025 14:51:18 +0300 Subject: [PATCH 3/7] commit 27.05 14.51 --- index.html | 2 +- internal/handlers/handlers.go | 46 ++++++++++++++++++----------------- internal/service/service.go | 19 +++++---------- 3 files changed, 31 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index 68f877c..0b5e901 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ action="http://localhost:8080/upload" method="post" > - + diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 5d1e26e..29a1f53 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -6,13 +6,14 @@ import ( "net/http" "os" "path/filepath" + "strings" "time" "github.com/Yandex-Practicum/go1fl-sprint6-final/internal/service" ) func ReturnHTML(w http.ResponseWriter, r *http.Request) { - data, err := os.ReadFile("index.html") + data, err := os.ReadFile("C:/dev/xails_server_yandex/index.html") if err != nil { http.Error(w, "ошибка чтения файла index.html", http.StatusInternalServerError) return @@ -28,44 +29,48 @@ func ReturnHTML(w http.ResponseWriter, r *http.Request) { } func ConvertStr(w http.ResponseWriter, r *http.Request) { - const maxMemory = 32 << 20 + const maxMemory = 32 << 20 // 32MB - err := r.ParseMultipartForm(maxMemory) - if err != nil { - http.Error(w, "ошибка парсинга", http.StatusInternalServerError) + if r.Method != http.MethodPost { + http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) return } + // Парсинг формы + if err := r.ParseMultipartForm(maxMemory); err != nil { + http.Error(w, "Файл слишком большой", http.StatusBadRequest) + return + } + + // Получение файла file, header, err := r.FormFile("file") if err != nil { - http.Error(w, "ошибка файла", http.StatusBadRequest) + http.Error(w, "Файл не найден в запросе", http.StatusBadRequest) return } defer file.Close() - // обработка файла - + // Чтение файла data, err := io.ReadAll(file) if err != nil { - http.Error(w, "ошибка чтения файла", http.StatusInternalServerError) + http.Error(w, "Ошибка чтения файла", http.StatusInternalServerError) return } - content := string(data) if content == "" { - http.Error(w, "файл пустой", http.StatusBadRequest) + http.Error(w, "Файл пуст", http.StatusBadRequest) return } + // Конвертация converted, err := service.AutoConvert(content) if err != nil { - http.Error(w, "ошибка конвертации", http.StatusInternalServerError) + http.Error(w, "Ошибка конвертации: "+err.Error(), http.StatusInternalServerError) return } - // создаем файл для результата - - timestamp := time.Now().UTC().Format("2006-01-02_15-04-05") + // Сохранение файла + timestamp := strings.ReplaceAll(time.Now().UTC().Format("2006-01-02_15-04-05"), ":", "-") ext := filepath.Ext(header.Filename) if ext == "" { ext = ".txt" @@ -79,16 +84,13 @@ func ConvertStr(w http.ResponseWriter, r *http.Request) { } defer outputFile.Close() - _, err = outputFile.WriteString(converted) - if err != nil { - http.Error(w, "ошибка записи в файл", http.StatusInternalServerError) + if _, err := outputFile.WriteString(converted); err != nil { + http.Error(w, "Ошибка записи в файл", http.StatusInternalServerError) return } + // Отправка ответа w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) - _, err = w.Write([]byte(converted)) - if err != nil { - log.Printf("ошибка при отправке ответа %v", err) - } + w.Write([]byte(converted)) } diff --git a/internal/service/service.go b/internal/service/service.go index 57b3aa3..86228c0 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -2,38 +2,31 @@ package service import ( "fmt" + "regexp" "strings" "github.com/Yandex-Practicum/go1fl-sprint6-final/pkg/morse" ) func AutoConvert(input string) (string, error) { - allowed := ".-/ " - isMorse := true - if input == "" { return "", fmt.Errorf("пустой ввод") } - for _, char := range input { - if !strings.ContainsRune(allowed, char) { - isMorse = false - break - } - } + isMorse := regexp.MustCompile(`^[\s.\-/]+$`).MatchString(input) if isMorse { text := morse.ToText(input) if text == "" { - return "", fmt.Errorf("ошибка конвертации в текст") + return "", fmt.Errorf("некорректный код Морзе") } return text, nil } - morseCode := morse.ToMorse(input) + upperInput := strings.ToUpper(input) + morseCode := morse.ToMorse(upperInput) if morseCode == "" { - return "", fmt.Errorf("ошибка конвертации в морзе") + return "", fmt.Errorf("некорректный текст") } return morseCode, nil - } From 225bced76b4c382ef6f1cca295eff22b14b47f80 Mon Sep 17 00:00:00 2001 From: xails-git Date: Tue, 27 May 2025 16:13:33 +0300 Subject: [PATCH 4/7] commit 27.05 16:13 --- index.html | 2 +- internal/handlers/handlers.go | 60 ++++++++++++++++++++--------------- internal/service/service.go | 22 ++++++++----- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/index.html b/index.html index 0b5e901..68f877c 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,7 @@ action="http://localhost:8080/upload" method="post" > - + diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 29a1f53..44be7d2 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -1,3 +1,4 @@ +// Пакет handlers package handlers import ( @@ -13,64 +14,71 @@ import ( ) func ReturnHTML(w http.ResponseWriter, r *http.Request) { - data, err := os.ReadFile("C:/dev/xails_server_yandex/index.html") + // Читаем index.html из текущей директории + data, err := os.ReadFile("../finalTaskSprint6_3/index.html") if err != nil { - http.Error(w, "ошибка чтения файла index.html", http.StatusInternalServerError) + log.Printf("Ошибка чтения index.html: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } - w.Header().Set("Content-Type", "text/html") + w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusOK) - - _, err = w.Write(data) - if err != nil { - log.Printf("Ошибка при отправке данных: %v", err) - } + w.Write(data) } func ConvertStr(w http.ResponseWriter, r *http.Request) { const maxMemory = 32 << 20 // 32MB + // Принимаем только POST-запросы if r.Method != http.MethodPost { - http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) + http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } - // Парсинг формы + // Парсинг формы с увеличенным лимитом памяти if err := r.ParseMultipartForm(maxMemory); err != nil { - http.Error(w, "Файл слишком большой", http.StatusBadRequest) + log.Printf("Ошибка парсинга формы: %v", err) + http.Error(w, "Bad Request", http.StatusBadRequest) return } - // Получение файла - file, header, err := r.FormFile("file") + // Получаем файл из поля "myFile" (как в автотесте) + file, header, err := r.FormFile("myFile") if err != nil { - http.Error(w, "Файл не найден в запросе", http.StatusBadRequest) + log.Printf("Файл не найден: %v", err) + http.Error(w, "Bad Request", http.StatusBadRequest) return } defer file.Close() - // Чтение файла + // Чтение содержимого файла data, err := io.ReadAll(file) if err != nil { - http.Error(w, "Ошибка чтения файла", http.StatusInternalServerError) + log.Printf("Ошибка чтения файла: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } - content := string(data) + + content := strings.TrimSpace(string(data)) if content == "" { - http.Error(w, "Файл пуст", http.StatusBadRequest) + http.Error(w, "Empty File", http.StatusBadRequest) return } // Конвертация converted, err := service.AutoConvert(content) if err != nil { - http.Error(w, "Ошибка конвертации: "+err.Error(), http.StatusInternalServerError) + log.Printf("Ошибка конвертации: %v", err) + http.Error(w, "Conversion Error", http.StatusInternalServerError) return } - // Сохранение файла - timestamp := strings.ReplaceAll(time.Now().UTC().Format("2006-01-02_15-04-05"), ":", "-") + // Создание результата + timestamp := strings.ReplaceAll( + time.Now().UTC().Format("2006-01-02_15-04-05"), + ":", "-", + ) ext := filepath.Ext(header.Filename) if ext == "" { ext = ".txt" @@ -79,18 +87,20 @@ func ConvertStr(w http.ResponseWriter, r *http.Request) { outputFile, err := os.Create(outputFilename) if err != nil { - http.Error(w, "Ошибка создания файла", http.StatusInternalServerError) + log.Printf("Ошибка создания файла: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } defer outputFile.Close() if _, err := outputFile.WriteString(converted); err != nil { - http.Error(w, "Ошибка записи в файл", http.StatusInternalServerError) + log.Printf("Ошибка записи файла: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } - // Отправка ответа - w.Header().Set("Content-Type", "text/plain") + // Ответ клиенту + w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusOK) w.Write([]byte(converted)) } diff --git a/internal/service/service.go b/internal/service/service.go index 86228c0..a1708ad 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,3 +1,4 @@ +// Пакет service package service import ( @@ -9,24 +10,29 @@ import ( ) func AutoConvert(input string) (string, error) { + input = strings.TrimSpace(input) if input == "" { - return "", fmt.Errorf("пустой ввод") + return "", fmt.Errorf("empty input") } - isMorse := regexp.MustCompile(`^[\s.\-/]+$`).MatchString(input) - - if isMorse { + // Проверка на Morse code (допускаем любые комбинации . - / и пробелов) + if isMorse(input) { text := morse.ToText(input) if text == "" { - return "", fmt.Errorf("некорректный код Морзе") + return "", fmt.Errorf("invalid morse code") } return text, nil } - upperInput := strings.ToUpper(input) - morseCode := morse.ToMorse(upperInput) + // Конвертация текста в верхний регистр + morseCode := morse.ToMorse(strings.ToUpper(input)) if morseCode == "" { - return "", fmt.Errorf("некорректный текст") + return "", fmt.Errorf("invalid text") } + return morseCode, nil } + +func isMorse(s string) bool { + return regexp.MustCompile(`^[\s.\-/]+$`).MatchString(s) +} From 95f397a7a39ef796c8a361bf6d8bdbc3671f7cff Mon Sep 17 00:00:00 2001 From: xails-git Date: Tue, 27 May 2025 16:18:23 +0300 Subject: [PATCH 5/7] commit 27.05 16.17 --- internal/handlers/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 44be7d2..af6a513 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -15,7 +15,7 @@ import ( func ReturnHTML(w http.ResponseWriter, r *http.Request) { // Читаем index.html из текущей директории - data, err := os.ReadFile("../finalTaskSprint6_3/index.html") + data, err := os.ReadFile("../index.html") if err != nil { log.Printf("Ошибка чтения index.html: %v", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) From e0010ee1d7419fd2cae9b11d350624e0c8eb533e Mon Sep 17 00:00:00 2001 From: xails-git Date: Tue, 27 May 2025 16:28:11 +0300 Subject: [PATCH 6/7] commit 27.05 16.28 --- internal/handlers/handlers.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index af6a513..1572c33 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -14,16 +14,24 @@ import ( ) func ReturnHTML(w http.ResponseWriter, r *http.Request) { - // Читаем index.html из текущей директории - data, err := os.ReadFile("../index.html") + // Получаем текущую рабочую директорию + wd, err := os.Getwd() if err != nil { - log.Printf("Ошибка чтения index.html: %v", err) + log.Printf("Ошибка получения рабочей директории: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + + // Формируем абсолютный путь к index.html + indexPath := filepath.Join(wd, "index.html") + data, err := os.ReadFile(indexPath) + if err != nil { + log.Printf("Ошибка чтения %s: %v", indexPath, err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.WriteHeader(http.StatusOK) w.Write(data) } From f9f7a2cd013e5bd64b25355f6bd95fbe0ad6252a Mon Sep 17 00:00:00 2001 From: xails-git Date: Tue, 27 May 2025 16:35:40 +0300 Subject: [PATCH 7/7] 27.05 16.35 --- internal/handlers/handlers.go | 2 -- internal/service/service.go | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 1572c33..8d46387 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -38,7 +38,6 @@ func ReturnHTML(w http.ResponseWriter, r *http.Request) { func ConvertStr(w http.ResponseWriter, r *http.Request) { const maxMemory = 32 << 20 // 32MB - // Принимаем только POST-запросы if r.Method != http.MethodPost { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return @@ -51,7 +50,6 @@ func ConvertStr(w http.ResponseWriter, r *http.Request) { return } - // Получаем файл из поля "myFile" (как в автотесте) file, header, err := r.FormFile("myFile") if err != nil { log.Printf("Файл не найден: %v", err) diff --git a/internal/service/service.go b/internal/service/service.go index a1708ad..2a17d02 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -15,7 +15,7 @@ func AutoConvert(input string) (string, error) { return "", fmt.Errorf("empty input") } - // Проверка на Morse code (допускаем любые комбинации . - / и пробелов) + // Проверка if isMorse(input) { text := morse.ToText(input) if text == "" { @@ -24,7 +24,7 @@ func AutoConvert(input string) (string, error) { return text, nil } - // Конвертация текста в верхний регистр + // Конвертация morseCode := morse.ToMorse(strings.ToUpper(input)) if morseCode == "" { return "", fmt.Errorf("invalid text")