add parser

This commit is contained in:
2026-03-26 01:56:29 +07:00
parent 05a68caa87
commit ad7bc9f7dd
18 changed files with 899 additions and 10 deletions
@@ -0,0 +1,7 @@
package data_parser
import "context"
type IDataParser interface {
Parse(ctx context.Context, url string, v interface{}) error
}
+42
View File
@@ -0,0 +1,42 @@
package data_parser
import (
"context"
"fmt"
"net/http"
"regexp"
"github.com/gocarina/gocsv"
)
type parser struct{}
func NewGoogleTableScheduleParser() IDataParser {
return &parser{}
}
func (p *parser) Parse(_ context.Context, url string, v interface{}) error {
re := regexp.MustCompile(`/d/([a-zA-Z0-9-_]+)`)
matches := re.FindStringSubmatch(url)
if len(matches) < 2 {
return fmt.Errorf("Не удалось найти ID таблицы в ссылке")
}
sheetID := matches[1]
csvURL := fmt.Sprintf("https://docs.google.com/spreadsheets/d/%s/export?format=csv", sheetID)
resp, err := http.Get(csvURL)
if err != nil {
return fmt.Errorf("Ошибка при скачивании таблицы: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Ошибка: статус код %d (убедитесь, что таблица публичная)", resp.StatusCode)
}
if err := gocsv.Unmarshal(resp.Body, v); err != nil {
return fmt.Errorf("Ошибка при парсинге CSV в структуру: %v", err)
}
return nil
}
@@ -0,0 +1,7 @@
package date_parser
import "time"
type IDateParser interface {
Parse(date string) (time.Time, error)
}
+53
View File
@@ -0,0 +1,53 @@
package date_parser
import (
"fmt"
"strconv"
"strings"
"time"
)
var (
ruMonths = map[string]time.Month{
"января": time.January,
"февраля": time.February,
"марта": time.March,
"апреля": time.April,
"мая": time.May,
"июня": time.June,
"июля": time.July,
"августа": time.August,
"сентября": time.September,
"октября": time.October,
"ноября": time.November,
"декабря": time.December,
}
)
type parser struct{}
func NewDateParser() IDateParser {
return &parser{}
}
func (p *parser) Parse(date string) (time.Time, error) {
parts := strings.Fields(date)
if len(parts) < 2 {
return time.Time{}, fmt.Errorf("Неверный формат даты, ожидалось 'День Месяц', получено: '%s'", date)
}
day, err := strconv.Atoi(parts[0])
if err != nil {
return time.Time{}, fmt.Errorf("Не удалось получить день: %v", err)
}
monthStr := strings.ToLower(parts[1])
month, ok := ruMonths[monthStr]
if !ok {
return time.Time{}, fmt.Errorf("Неизвестный месяц: %s", monthStr)
}
year := time.Now().Year()
return time.Date(year, month, day, 0, 0, 0, 0, time.Local), nil
}