feat: add frontend + backend + database to retrieve and compute news from Yahoo
This commit is contained in:
75
backend/internal/scraper/scraper.go
Normal file
75
backend/internal/scraper/scraper.go
Normal file
@ -0,0 +1,75 @@
|
||||
package scraper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/tradarr/backend/internal/models"
|
||||
)
|
||||
|
||||
type Article struct {
|
||||
Title string
|
||||
Content string
|
||||
URL string
|
||||
PublishedAt *time.Time
|
||||
Symbols []string
|
||||
}
|
||||
|
||||
type Scraper interface {
|
||||
Name() string
|
||||
Scrape(ctx context.Context, symbols []string) ([]Article, error)
|
||||
}
|
||||
|
||||
// detectSymbols extrait les symboles mentionnés dans un texte
|
||||
func DetectSymbols(text string, watchlist []string) []string {
|
||||
found := map[string]bool{}
|
||||
for _, s := range watchlist {
|
||||
// Recherche du symbole en majuscules dans le texte
|
||||
if containsWord(text, s) {
|
||||
found[s] = true
|
||||
}
|
||||
}
|
||||
result := make([]string, 0, len(found))
|
||||
for s := range found {
|
||||
result = append(result, s)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func containsWord(text, word string) bool {
|
||||
upper := []byte(text)
|
||||
w := []byte(word)
|
||||
for i := 0; i <= len(upper)-len(w); i++ {
|
||||
match := true
|
||||
for j := range w {
|
||||
c := upper[i+j]
|
||||
if c >= 'a' && c <= 'z' {
|
||||
c -= 32
|
||||
}
|
||||
if c != w[j] {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
// Vérifier que c'est un mot entier
|
||||
before := i == 0 || !isAlphaNum(upper[i-1])
|
||||
after := i+len(w) >= len(upper) || !isAlphaNum(upper[i+len(w)])
|
||||
if before && after {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isAlphaNum(b byte) bool {
|
||||
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
|
||||
}
|
||||
|
||||
// ScraperResult est le résultat d'un job de scraping
|
||||
type ScraperResult struct {
|
||||
Source *models.Source
|
||||
Articles []Article
|
||||
Err error
|
||||
}
|
||||
Reference in New Issue
Block a user