Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 98 additions & 42 deletions db/migrations/20240401145225_create_and_insert_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ CREATE TABLE sight
description text,
city_id integer REFERENCES city (id),
country_id integer REFERENCES country (id),
latitude double precision,
longitude double precision,
UNIQUE (name, city_id)
);

Expand Down Expand Up @@ -92,6 +94,38 @@ CREATE TABLE quiz
created_at timestamptz
);

CREATE TABLE question
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
text text NOT NULL
);

CREATE TABLE quiz
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_id integer REFERENCES user_data (id),
rating integer NOT NULL CHECK (rating > 0 AND rating <= 5),
question_id integer REFERENCES question (id),
created_at timestamptz DEFAULT NOW()
);

CREATE TABLE album
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_id integer REFERENCES user_data(id),
name text NOT NULL,
description text,
UNIQUE(user_id, name)
);

CREATE TABLE album_photo
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
album_id integer REFERENCES album(id),
path text UNIQUE,
description text
);

INSERT INTO country(country)
VALUES ('Россия'),
('Беларусь'),
Expand All @@ -118,89 +152,121 @@ VALUES ('Москва', 1),
('Сулакский каньон', 5);


INSERT INTO sight(name, description, city_id, country_id)
INSERT INTO sight(name, description, city_id, country_id, longitude, latitude)
VALUES ('У дяди Вани',
'Ресторан с видом на Сталинскую высотку.',
1,
1),
1,
55.768329,
37.597468),
('Государственный музей изобразительных искусств имени А.С. Пушкина',
'Музей.',
1,
1),
1,
55.747277,
37.605194),
('МГТУ им. Н. Э. Баумана',
'Хороший вуз.',
1,
1),
1,
55.766471,
37.683446),
('Вкусно - и точка',
'Неплохое кафе, вызывает гастрит.',
1,
1),
1,
55.771585,
37.681730),
('Краеведческий музей',
'Один из самых больших провинциальных музеев краеведческого профиля.',
2,
1),
1,
53.148541,
48.456204),
('Спасо-Преображенский кафедральный собор',
'Спасо-Преображенский кафедральный собор расположен в центре города и является первым каменным храмом Тамбова и старейшим в Тамбовской обл.',
3,
1),
1,
52.727371,
41.459110),
('Мирский замок',
'Памятник архитектуры, внесён в список Всемирного наследия ЮНЕСКО.',
9,
2),
2,
53.900162,
27.551518),
('Чуфут-Кале',
'Пещерный город в Крыму. Топ.',
4,
4),
4,
44.733255,
33.934201),
('Сасык-Сиваш',
'Розовое озеро. Оно реально розовое.',
5,
4),
4,
45.181475,
33.576833),
('Крепость Чембело',
'Остатки крепости.',
6,
4),
4,
44.512136,
33.598321),
('Мечеть Кул Зариф',
'Главная джума-мечеть республики Татарстан и города Казани.',
7,
3),
3,
55.798399,
49.105147),
('Салтинский Подземный Водопад',
'Единственный в России подземный водопад.',
8,
5),
5,
42.380378,
47.042068),
('Озеро Рица',
'Рица — горное озеро ледниково-тектонического происхождения на Западном Кавказе, в Гудаутском районе Абхазии',
10,
6)
,
6,
43.480130,
40.542047),
('Архитектурный комплекс Цитадель Нарын-Кала',
'Древняя дербентская крепость, возведённая по повелению персидского правителя Хосрова I Ануширвана в VI веке, включена ЮНЕСКО в Список Всемирного наследия.',
11,
5)
,
5,
42.055340,
48.276883),
('Сторожевые башни Северного Кавказа',
'Хорошо сохранившиеся родовые башни XIV–XVI веков, которые выполняли роль жилища и защиты от врагов.',
13,
5)
,
5,
42.086155,
47.603964),
('Сулакский каньон',
'У истоков реки Сулак берёт начало уникальный каньон. Давным-давно бурная река расколола гору, разделив Салатавский и Гимринский хребты.',
14,
5)
,
5,
43.017452,
46.824505),
('Стрелка Волги и Оки',
'Место, где реки Ока и Волга, сливаясь, образуют живописный треугольный мыс, называют Стрелкой. Это природная достопримечательность Нижнего Новгорода.',
12,
1)
,
1,
56.335336,
43.967053),
('Чкаловская лестница',
'Чкаловская лестница - один из символов Нижнего Новгорода. Между Верхневолжской и Нижневолжской набережными находится интересная нижегородская достопримечательность, которая видна даже на космических снимках',
12,
1)
,
1,
56.330091,
44.008924),
('Нижегородский Кремль',
'Нижегородский кремль – древняя крепость и одновременно главная историческая достопримечательность Нижнего Новгорода',
12,
1);
1,
56.328437,
44.003111);


INSERT INTO image_data(path, sight_id)
Expand All @@ -226,7 +292,8 @@ VALUES ('public/1.jpg', 1),

INSERT INTO question(text)
VALUES ('Насколько вы удовлетворены удобством КудаТуда?'),
('Насколько интуитивно понятен интерфейс?');
('Насколько интуитивно понятен интерфейс?'),
('Оцените представленные достопримечательности');


CREATE OR REPLACE FUNCTION create_profile()
Expand Down Expand Up @@ -267,21 +334,10 @@ AFTER UPDATE ON feedback
FOR EACH ROW
EXECUTE FUNCTION update_sight_rating();

CREATE TABLE question
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
text text NOT NULL
);

CREATE TABLE quiz
(
id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
user_id integer REFERENCES user_data (id),
rating integer NOT NULL CHECK (rating > 0 AND rating <= 5),
question_id integer REFERENCES question (id),
created_at timestamptz
);

CREATE TRIGGER after_delete_feedback
AFTER DELETE ON feedback
FOR EACH ROW
EXECUTE FUNCTION update_sight_rating();

-- +goose Down
-- +goose StatementBegin
Expand Down
16 changes: 15 additions & 1 deletion db/normalized/ERD_description.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,29 @@
integer rating
text feedback
}
ALBUM {
integer id PK
integer user_id FK
text name UK
text description
}
ALBUM_PHOTO {
integer id PK
integer album_id FK
text path UK
text description
}

PROFILE ||--|| USER : has
SIGHT }o--|| CITY: includes
CITY }0--|| COUNTRY: includes
CITY }o--|| COUNTRY: includes
JOURNEY }o--|| USER : creates
JOURNEY_SIGHT }|--|| JOURNEY: has
JOURNEY_SIGHT }|--|| SIGHT : contains
FEEDBACK }o--|| USER : writes
FEEDBACK }o--|| SIGHT : belongs_to
IMAGE }|--|| SIGHT : belongs_to
ALBUM }o--|| USER : creates
ALBUM_PHOTO }|--|| ALBUM : has

```
Binary file removed images/arg_messi.jpeg
Binary file not shown.
5 changes: 5 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Config struct {
Dsn `yaml:"dsn"`
Redis `yaml:"redis"`
FileUploadPath string `env:"FILE_UPLOAD_PATH"`
Drive `yaml:"token"`
}

type HTTPServer struct {
Expand All @@ -41,6 +42,10 @@ type Redis struct {
Password string `yaml:"password" env:"DB_REDIS_PASSWORD"`
}

type Drive struct {
Token string `yaml:"token" env:"YANDEX_TOKEN"`
}

func LoadConfig() (*Config, error) {
if err := godotenv.Load(); err != nil {
return nil, errors.Wrap(err, "error loading .env file")
Expand Down
32 changes: 10 additions & 22 deletions internal/delivery/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,22 @@ type FileResponse struct {
var (
maxFileSizeMB = 1
maxFileSizeBytes = int64(maxFileSizeMB) * 1024 * 1024
magicTable = map[string]string{
"\xff\xd8\xff": "image/jpeg",
"\x89PNG\r\n\x1a\n": "image/png",
"GIF87a": "image/gif",
"GIF89a": "image/gif",
}
)

func DetectType(b []byte) bool {
flag := false
s := string(b)
for key, val := range magicTable {
if strings.HasPrefix(s, key) {
fmt.Println(val)
flag = true
}
}
return flag
}

func ValidateFileExtension(file multipart.File) bool {
func ValidateFileExtension(fileHeader multipart.FileHeader) bool {
buff := make([]byte, 512)
file, err := fileHeader.Open()
if err != nil {
return false
}
defer file.Close()
if _, err := file.Read(buff); err != nil {
return false
}

val := DetectType(buff)
fileType := strings.ToLower(http.DetectContentType(buff))

return val
return fileType == "image/png" || fileType == "image/jpeg" || fileType == "image/jpg" || fileType == "image/webp"
}

func ValidateFileSize(handler *multipart.FileHeader) bool {
Expand All @@ -70,10 +57,11 @@ func SaveFile(r *http.Request) (string, error) {
logger.Error("Error while retrieving file:", "error", err)
return string(""), err
}
fmt.Println("No")
defer file.Close()

// Validate
flag := ValidateFileExtension(file)
flag := ValidateFileExtension(*handler)
if !flag {
logger.Error("Not valid format!")
return string(""), errors.New("Not valid format!")
Expand Down
Loading