diff --git a/pyth/.env b/.env similarity index 71% rename from pyth/.env rename to .env index 7051493..37209d9 100644 --- a/pyth/.env +++ b/.env @@ -4,4 +4,6 @@ DB_HOST =localhost DB_PORT =5432 DB_USER =svevijesti DB_PASSWORD =salmonela pljusti 221 hamo -DB_NAME =svevijestiweb \ No newline at end of file +DB_NAME =svevijestiweb + +API_KEY=abb35e21bdcbad6d1b00141a2b25cf5a diff --git a/go.mod b/go.mod index a5b4e5d..dc841ad 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gosimple/slug v1.12.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/kennygrant/sanitize v1.2.4 // indirect github.com/lib/pq v1.10.4 // indirect github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect diff --git a/go.sum b/go.sum index b68be6c..f45828e 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/gosimple/slug v1.12.0 h1:xzuhj7G7cGtd34NXnW/yF0l+AGNfWqwgh/IXgFy7dnc= github.com/gosimple/slug v1.12.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o= github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= diff --git a/internal/database/articles.go b/internal/database/articles.go index bd96180..3d73394 100644 --- a/internal/database/articles.go +++ b/internal/database/articles.go @@ -49,7 +49,7 @@ func ArticlesForDay(store *Store, day time.Time) (articles []model.DisplayArticl result := []model.DisplayArticle{} query, err := store.Prepare(` - select id,title, content, slug, original_url, source_id, created_at from articles where created_at > $1 and created_at < $2 and LENGTH(content) > 10 order by id desc; + select id,title, content, slug, original_url, source_id, created_at, category from articles where created_at > $1 and created_at < $2 and LENGTH(content) > 10 order by id desc; `) if err != nil { return result, err @@ -68,7 +68,7 @@ func ArticlesForDay(store *Store, day time.Time) (articles []model.DisplayArticl for rows.Next() { r := model.DisplayArticle{} - err = rows.Scan(&r.ID, &r.Title, &r.Content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt) + err = rows.Scan(&r.ID, &r.Title, &r.Content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt, &r.Category) if err != nil { return result, err } @@ -96,7 +96,7 @@ func ArticleByID(store *Store, ID int, slug string) (article model.DisplayArticl result := model.DisplayArticle{} query, err := store.Prepare(` - select id,title, content, slug, original_url, source_id, created_at from articles where id = $1 and slug = $2; + select id,title, content, slug, original_url, source_id, created_at, category from articles where id = $1 and slug = $2; `) if err != nil { return result, err @@ -110,7 +110,7 @@ func ArticleByID(store *Store, ID int, slug string) (article model.DisplayArticl r := model.DisplayArticle{} content := "" - err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt) + err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt, &r.Category) if err != nil { return result, err } @@ -139,7 +139,7 @@ func PreviousAndNextArticleUrlByID(store *Store, ID int) (nextUrl string, previo nextResult, previousResult := "#", "#" query, err := store.Prepare(` - select id,title, content, slug, original_url, source_id, created_at from articles where id < $1 and id > $2 order by id desc limit 1; + select id,title, content, slug, original_url, source_id, created_at, category from articles where id < $1 and id > $2 order by id desc limit 1; `) if err != nil { fmt.Println("Err 1:", err) @@ -155,7 +155,7 @@ func PreviousAndNextArticleUrlByID(store *Store, ID int) (nextUrl string, previo r := model.DisplayArticle{} content := "" - err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt) + err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt, &r.Category) if err != nil { return nextResult, previousResult, err } @@ -163,7 +163,7 @@ func PreviousAndNextArticleUrlByID(store *Store, ID int) (nextUrl string, previo previousResult = fmt.Sprintf("/%d/%s", r.ID, r.Slug) query2, err := store.Prepare(` - select id,title, content, slug, original_url, source_id, created_at from articles where id < $1 and id > $2 order by id asc limit 1; + select id,title, content, slug, original_url, source_id, created_at, category from articles where id < $1 and id > $2 order by id asc limit 1; `) if err != nil { fmt.Println("Err 1:", err) @@ -178,7 +178,7 @@ func PreviousAndNextArticleUrlByID(store *Store, ID int) (nextUrl string, previo } content = "" - err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt) + err = row.Scan(&r.ID, &r.Title, &content, &r.Slug, &r.OriginalUrl, &r.SourceId, &r.CreatedAt, &r.Category) if err != nil { fmt.Println("Err 4:", err) return nextResult, previousResult, err @@ -187,48 +187,3 @@ func PreviousAndNextArticleUrlByID(store *Store, ID int) (nextUrl string, previo return nextResult, previousResult, nil } - -func ArticleByCategory(store *Store, day time.Time) (cateogry []model.DisplayArticle, err error) { - - result := []model.DisplayArticle{} - query, err := store.Prepare(`select id,title,content,slug,created_at,source_id,category from articles where created_at > $1 and created_at < $2 and LENGTH(content) > 10 order by id desc;`) - if err != nil { - return result, err - } - defer query.Close() - - tomorow := day.AddDate(0, 0, 1) - todayDate := day.Format("2024-01-26") - tomorrowDate := tomorow.Format("2024:01:26") - - rows, err := query.Query(todayDate, tomorrowDate) - if err != nil { - return result, err - } - defer rows.Close() - - for rows.Next() { - r := model.DisplayArticle{} - err = rows.Scan(&r.ID, &r.Title, &r.Content, &r.Slug, &r.CreatedAt, &r.OriginalUrl, &r.SourceId, &r.CreatedAt, &r.Category) - if err != nil { - return result, err - } - - ago := time.Now().Sub(r.CreatedAt) - hours := ago.Hours() - - if hours < 1 { - r.FormatedCreatedAt = fmt.Sprintf("Prije %d sati.", int(math.Floor(ago.Minutes()))) - } else if hours > 24 { - r.FormatedCreatedAt = r.CreatedAt.Format("28.01.2024. 01:03:05") - } else { - r.FormatedCreatedAt = fmt.Sprintf("Prije %d sati.", int(math.Floor(ago.Minutes()))) - } - - r.SourceName = model.SourceName(r.SourceId) - - result = append(result, r) - } - return result, nil - -} diff --git a/internal/server/articles.go b/internal/server/articles.go index e67f098..2cdb4a5 100644 --- a/internal/server/articles.go +++ b/internal/server/articles.go @@ -25,11 +25,25 @@ func rootHandler(wr http.ResponseWriter, req *http.Request) { dayBefore := "/dan/" + time.Now().Add(-24*time.Hour).Format("2006-01-02") + cities := []string{"Sarajevo", "Banja Luka", "Zenica", "Tuzla", "Mostar"} + + var weatherInfo []WeatherData + for _, city := range cities { + data, err := getWeather(city) + if err != nil { + fmt.Printf("Error fetching weather for %s: %v\n", city, err) + continue + } + weatherInfo = append(weatherInfo, data) + } + data := map[string]interface{}{ - "title": title, - "articles": articles, - "previous": dayBefore, - "next": "/", + "title": title, + "articles": articles, + "previous": dayBefore, + "next": "/", + "weatherInfo": weatherInfo, + "categories": CategoryMenu, } err = templates.ExecuteTemplate(wr, "homeHTML", data) @@ -63,11 +77,24 @@ func dailyArticlesHandler(wr http.ResponseWriter, req *http.Request) { http.Error(wr, err.Error(), http.StatusInternalServerError) } + cities := []string{"Sarajevo", "Banja Luka", "Zenica", "Tuzla", "Mostar"} + + var weatherInfo []WeatherData + for _, city := range cities { + data, err := getWeather(city) + if err != nil { + fmt.Printf("Error fetching weather for %s: %v\n", city, err) + continue + } + weatherInfo = append(weatherInfo, data) + } + data := map[string]interface{}{ - "title": title, - "articles": articles, - "previous": dayBefore, - "next": dayAfter, + "title": title, + "articles": articles, + "previous": dayBefore, + "next": dayAfter, + "weatherInfo": weatherInfo, } err = templates.ExecuteTemplate(wr, "homeHTML", data) @@ -98,10 +125,11 @@ func articleHandler(wr http.ResponseWriter, req *http.Request) { title := article.Title data := map[string]interface{}{ - "title": title, - "article": article, - "previous": previous, - "next": next, + "title": title, + "article": article, + "previous": previous, + "next": next, + "categories": CategoryMenu, } err = templates.ExecuteTemplate(wr, "articleHTML", data) diff --git a/internal/server/category.go b/internal/server/category.go index 9c2c6f3..df5d119 100644 --- a/internal/server/category.go +++ b/internal/server/category.go @@ -4,31 +4,65 @@ import ( "net/http" "time" + "github.com/gorilla/mux" "gitlab.com/kbr4/svevijesti/internal/database" "gitlab.com/kbr4/svevijesti/internal/model" ) -func categoryHandler(wr http.ResponseWriter, r *http.Request) { +var CategoryMenu = []string{ + "Politika", + "Biznis", + "Sport", + "Magazin", + "Nauka i tehnologija", + "Ostalo", +} + +func handleCategory(wr http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + category := vars["category"] store, err := database.Connect() - if err != nil { http.Error(wr, err.Error(), http.StatusInternalServerError) + return + } + defer store.Close() + + currentDate, err := time.Parse("2006-01-02", category) + if err != nil { + currentDate = time.Now() } - articles, err := database.ArticleByCategory(store, time.Now()) + articles, err := database.ArticlesForDay(store, currentDate) + if err != nil { + http.Error(wr, err.Error(), http.StatusInternalServerError) + return + } articlesByCategory := make(map[string][]model.DisplayArticle) - for _, article := range articles { articlesByCategory[article.Category] = append(articlesByCategory[article.Category], article) } - for category, articles := range articlesByCategory { - data := map[string]interface{}{"Category": category, "Articles": articles} - err := templates.ExecuteTemplate(wr, "categoryHTML", data) - if err != nil { - panic(err) - } + var categories []string + for cat := range articlesByCategory { + categories = append(categories, cat) + } + + prevDay := currentDate.AddDate(0, 0, -1) + + data := map[string]interface{}{ + "title": category, + "currentCategory": category, + "articles": articlesByCategory[category], + "categories": CategoryMenu, + "previous": prevDay.Format("2006-01-02"), + "next": "/", + } + err = templates.ExecuteTemplate(wr, "categoryHTML", data) + if err != nil { + http.Error(wr, err.Error(), http.StatusInternalServerError) + return } } diff --git a/internal/server/server.go b/internal/server/server.go index ae07f3b..40b4ebc 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -44,6 +44,6 @@ func CreateRoutes() *mux.Router { r.HandleFunc("/{id:[0-9]+}/{slug}", articleHandler) r.HandleFunc("/", rootHandler) r.HandleFunc("/weather", WeatherHandler) - r.HandleFunc("/{category}", categoryHandler) + r.HandleFunc("/{category}", handleCategory) return r } diff --git a/internal/server/weather.go b/internal/server/weather.go index 1ee43fe..4247f12 100644 --- a/internal/server/weather.go +++ b/internal/server/weather.go @@ -5,9 +5,27 @@ import ( "fmt" "io/ioutil" "net/http" + "os" + + "github.com/joho/godotenv" ) -const apiKey = "abb35e21bdcbad6d1b00141a2b25cf5a" +var apiKey string + +func init() { + err := godotenv.Load() + if err != nil { + fmt.Println("Error loading .env file:", err) + os.Exit(1) + } + + apiKey = os.Getenv("API_KEY") + + if apiKey == "" { + fmt.Println("API_KEY environment variable not set.") + os.Exit(1) + } +} type WeatherData struct { Coord struct { @@ -74,24 +92,13 @@ func WeatherHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{ "title": title, "weatherInfo": weatherInfo, + "categories": CategoryMenu, } - err := templates.ExecuteTemplate(w, "fullweatherHTML", data) + err := templates.ExecuteTemplate(w, "weatherHTML", data) if err != nil { fmt.Println("Error executing template:", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } - for _, info := range weatherInfo { - widgetData := map[string]interface{}{ - "Temperature": info.Main.Temp, - "City": info.Name, - } - err := templates.ExecuteTemplate(w, "weatherwidgetHTML", widgetData) - if err != nil { - fmt.Println("Error executing template:", err) - http.Error(w, "Internal Server Error", http.StatusInternalServerError) - return - } - } } diff --git a/pyth/__pycache__/get_articles.cpython-310.pyc b/pyth/__pycache__/get_articles.cpython-310.pyc index a788959..a140733 100644 Binary files a/pyth/__pycache__/get_articles.cpython-310.pyc and b/pyth/__pycache__/get_articles.cpython-310.pyc differ diff --git a/pyth/get_articles.py b/pyth/get_articles.py index 20d36f3..dda1301 100644 --- a/pyth/get_articles.py +++ b/pyth/get_articles.py @@ -123,6 +123,15 @@ if __name__ == '__main__': category_options = ['politics','business','sport','magazine','scitech'] + category_translation = { + 'politics': 'Politika', + 'business': 'Biznis', + 'sport': 'Sport', + 'magazine': 'Magazin', + 'scitech': 'Nauka i tehnologija', + 'other': 'Ostalo', + } + if ttk > 1900: title_text = slice_title_if_needed(title_text) try: @@ -146,9 +155,10 @@ if __name__ == '__main__': else: category = 'other' + category = category_translation.get(category, category.capitalize()) + vector = embeddings.embed_query(generated_text) - print(f"Title: {title}") print(f"Category: {category}") if not is_similar_data(title, text, link, vector, threshold=0.98): diff --git a/web/data/articles.html b/web/data/articles.html index 2931132..2666df3 100644 --- a/web/data/articles.html +++ b/web/data/articles.html @@ -1,17 +1,5 @@ {{define "articlesHTML"}} - -