mirror of
https://github.com/Dvorinka/PPve.git
synced 2026-06-03 20:12:59 +00:00
w355w
This commit is contained in:
@@ -47,7 +47,7 @@ func formatCzechTimeWithDay(t time.Time) string {
|
|||||||
// Detect device type from User-Agent
|
// Detect device type from User-Agent
|
||||||
func detectDevice(userAgent string) string {
|
func detectDevice(userAgent string) string {
|
||||||
userAgent = strings.ToLower(userAgent)
|
userAgent = strings.ToLower(userAgent)
|
||||||
|
|
||||||
// Mobile devices
|
// Mobile devices
|
||||||
if strings.Contains(userAgent, "iphone") || strings.Contains(userAgent, "ipod") {
|
if strings.Contains(userAgent, "iphone") || strings.Contains(userAgent, "ipod") {
|
||||||
return "iPhone"
|
return "iPhone"
|
||||||
@@ -61,7 +61,7 @@ func detectDevice(userAgent string) string {
|
|||||||
} else if strings.Contains(userAgent, "windows phone") {
|
} else if strings.Contains(userAgent, "windows phone") {
|
||||||
return "Windows Phone"
|
return "Windows Phone"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desktop devices
|
// Desktop devices
|
||||||
if strings.Contains(userAgent, "windows") {
|
if strings.Contains(userAgent, "windows") {
|
||||||
return "Windows PC"
|
return "Windows PC"
|
||||||
@@ -70,7 +70,7 @@ func detectDevice(userAgent string) string {
|
|||||||
} else if strings.Contains(userAgent, "linux") {
|
} else if strings.Contains(userAgent, "linux") {
|
||||||
return "Linux PC"
|
return "Linux PC"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other devices
|
// Other devices
|
||||||
if strings.Contains(userAgent, "playstation") {
|
if strings.Contains(userAgent, "playstation") {
|
||||||
return "PlayStation"
|
return "PlayStation"
|
||||||
@@ -79,12 +79,12 @@ func detectDevice(userAgent string) string {
|
|||||||
} else if strings.Contains(userAgent, "nintendo") {
|
} else if strings.Contains(userAgent, "nintendo") {
|
||||||
return "Nintendo"
|
return "Nintendo"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bots and crawlers
|
// Bots and crawlers
|
||||||
if strings.Contains(userAgent, "bot") || strings.Contains(userAgent, "crawler") {
|
if strings.Contains(userAgent, "bot") || strings.Contains(userAgent, "crawler") {
|
||||||
return "Bot/Crawler"
|
return "Bot/Crawler"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unknown Device"
|
return "Unknown Device"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,41 +100,41 @@ type Visitor struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VisitorStats struct {
|
type VisitorStats struct {
|
||||||
TotalVisits int `json:"total_visits"`
|
TotalVisits int `json:"total_visits"`
|
||||||
TodayVisits int `json:"today_visits"`
|
TodayVisits int `json:"today_visits"`
|
||||||
LastVisit time.Time `json:"last_visit"`
|
LastVisit time.Time `json:"last_visit"`
|
||||||
MonthlyVisits int `json:"monthly_visits"`
|
MonthlyVisits int `json:"monthly_visits"`
|
||||||
WeeklyVisits int `json:"weekly_visits"`
|
WeeklyVisits int `json:"weekly_visits"`
|
||||||
LastUpdated time.Time `json:"last_updated"`
|
LastUpdated time.Time `json:"last_updated"`
|
||||||
UniqueVisitors map[string]*Visitor `json:"unique_visitors"`
|
UniqueVisitors map[string]*Visitor `json:"unique_visitors"`
|
||||||
MostActiveHours []struct {
|
MostActiveHours []struct {
|
||||||
Hour int `json:"hour"`
|
Hour int `json:"hour"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
} `json:"most_active_hours"`
|
} `json:"most_active_hours"`
|
||||||
MostActiveDays []struct {
|
MostActiveDays []struct {
|
||||||
Day string `json:"day"`
|
Day string `json:"day"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
} `json:"most_active_days"`
|
} `json:"most_active_days"`
|
||||||
BrowserStats map[string]int `json:"browser_stats"`
|
BrowserStats map[string]int `json:"browser_stats"`
|
||||||
OSStats map[string]int `json:"os_stats"`
|
OSStats map[string]int `json:"os_stats"`
|
||||||
ReferrerStats map[string]int `json:"referrer_stats"`
|
ReferrerStats map[string]int `json:"referrer_stats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format VisitorStats with Czech dates
|
// Format VisitorStats with Czech dates
|
||||||
func (v *VisitorStats) FormatForDisplay() map[string]interface{} {
|
func (v *VisitorStats) FormatForDisplay() map[string]interface{} {
|
||||||
displayStats := map[string]interface{}{
|
displayStats := map[string]interface{}{
|
||||||
"total_visits": v.TotalVisits,
|
"total_visits": v.TotalVisits,
|
||||||
"today_visits": v.TodayVisits,
|
"today_visits": v.TodayVisits,
|
||||||
"last_visit": formatCzechTimeWithDay(v.LastVisit),
|
"last_visit": formatCzechTimeWithDay(v.LastVisit),
|
||||||
"monthly_visits": v.MonthlyVisits,
|
"monthly_visits": v.MonthlyVisits,
|
||||||
"weekly_visits": v.WeeklyVisits,
|
"weekly_visits": v.WeeklyVisits,
|
||||||
"last_updated": formatCzechTimeWithDay(v.LastUpdated),
|
"last_updated": formatCzechTimeWithDay(v.LastUpdated),
|
||||||
"unique_visitors": make(map[string]interface{}),
|
"unique_visitors": make(map[string]interface{}),
|
||||||
"most_active_hours": make([]map[string]interface{}, len(v.MostActiveHours)),
|
"most_active_hours": make([]map[string]interface{}, len(v.MostActiveHours)),
|
||||||
"most_active_days": make([]map[string]interface{}, len(v.MostActiveDays)),
|
"most_active_days": make([]map[string]interface{}, len(v.MostActiveDays)),
|
||||||
"browser_stats": v.BrowserStats,
|
"browser_stats": v.BrowserStats,
|
||||||
"os_stats": v.OSStats,
|
"os_stats": v.OSStats,
|
||||||
"referrer_stats": v.ReferrerStats,
|
"referrer_stats": v.ReferrerStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format unique visitors
|
// Format unique visitors
|
||||||
@@ -185,11 +185,11 @@ func (v *VisitorStats) init() {
|
|||||||
v.LastUpdated = time.Now()
|
v.LastUpdated = time.Now()
|
||||||
v.UniqueVisitors = make(map[string]*Visitor)
|
v.UniqueVisitors = make(map[string]*Visitor)
|
||||||
v.MostActiveHours = make([]struct {
|
v.MostActiveHours = make([]struct {
|
||||||
Hour int `json:"hour"`
|
Hour int `json:"hour"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(v.MostActiveDays) == 0 {
|
if len(v.MostActiveDays) == 0 {
|
||||||
v.MostActiveDays = make([]struct {
|
v.MostActiveDays = make([]struct {
|
||||||
Day string `json:"day"`
|
Day string `json:"day"`
|
||||||
@@ -202,26 +202,26 @@ const visitorStatsFile = "data/visitor_stats.json"
|
|||||||
|
|
||||||
func loadVisitorStats() (*VisitorStats, error) {
|
func loadVisitorStats() (*VisitorStats, error) {
|
||||||
stats := &VisitorStats{
|
stats := &VisitorStats{
|
||||||
TotalVisits: 0,
|
TotalVisits: 0,
|
||||||
TodayVisits: 0,
|
TodayVisits: 0,
|
||||||
MonthlyVisits: 0,
|
MonthlyVisits: 0,
|
||||||
WeeklyVisits: 0,
|
WeeklyVisits: 0,
|
||||||
LastVisit: time.Now(),
|
LastVisit: time.Now(),
|
||||||
LastUpdated: time.Now(),
|
LastUpdated: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize all fields
|
// Initialize all fields
|
||||||
stats.init()
|
stats.init()
|
||||||
|
|
||||||
data, err := os.ReadFile(visitorStatsFile)
|
data, err := os.ReadFile(visitorStatsFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stats, nil // Return default stats if file doesn't exist
|
return stats, nil // Return default stats if file doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(data, stats); err != nil {
|
if err := json.Unmarshal(data, stats); err != nil {
|
||||||
return nil, fmt.Errorf("failed to unmarshal visitor stats: %v", err)
|
return nil, fmt.Errorf("failed to unmarshal visitor stats: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,211 +230,211 @@ func saveVisitorStats(stats *VisitorStats) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal visitor stats: %v", err)
|
return fmt.Errorf("failed to marshal visitor stats: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.WriteFile(visitorStatsFile, data, 0644)
|
return os.WriteFile(visitorStatsFile, data, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomString(n int) string {
|
func randomString(n int) string {
|
||||||
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
bytes := make([]byte, n)
|
bytes := make([]byte, n)
|
||||||
for i := range bytes {
|
for i := range bytes {
|
||||||
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error generating random number: %v", err)
|
log.Printf("Error generating random number: %v", err)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
bytes[i] = letters[num.Int64()]
|
bytes[i] = letters[num.Int64()]
|
||||||
}
|
}
|
||||||
return string(bytes)
|
return string(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getVisitorId(w http.ResponseWriter, r *http.Request) string {
|
func getVisitorId(w http.ResponseWriter, r *http.Request) string {
|
||||||
// Check if visitor ID is in cookie
|
// Check if visitor ID is in cookie
|
||||||
cookie, err := r.Cookie("visitor_id")
|
cookie, err := r.Cookie("visitor_id")
|
||||||
if err == nil && cookie.Value != "" {
|
if err == nil && cookie.Value != "" {
|
||||||
return cookie.Value
|
return cookie.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new unique ID
|
// Generate a new unique ID
|
||||||
visitorId := fmt.Sprintf("%x", md5.Sum([]byte(time.Now().String() + randomString(16))))
|
visitorId := fmt.Sprintf("%x", md5.Sum([]byte(time.Now().String()+randomString(16))))
|
||||||
|
|
||||||
// Set the cookie to expire in 1 year
|
// Set the cookie to expire in 1 year
|
||||||
http.SetCookie(w, &http.Cookie{
|
http.SetCookie(w, &http.Cookie{
|
||||||
Name: "visitor_id",
|
Name: "visitor_id",
|
||||||
Value: visitorId,
|
Value: visitorId,
|
||||||
Path: "/",
|
Path: "/",
|
||||||
MaxAge: 365 * 24 * 60 * 60, // 1 year
|
MaxAge: 365 * 24 * 60 * 60, // 1 year
|
||||||
HttpOnly: true,
|
HttpOnly: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
return visitorId
|
return visitorId
|
||||||
}
|
}
|
||||||
|
|
||||||
func trackVisit(w http.ResponseWriter, r *http.Request) {
|
func trackVisit(w http.ResponseWriter, r *http.Request) {
|
||||||
stats, err := loadVisitorStats()
|
stats, err := loadVisitorStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error loading visitor stats: %v", err)
|
log.Printf("Error loading visitor stats: %v", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize stats if needed
|
// Initialize stats if needed
|
||||||
stats.init()
|
stats.init()
|
||||||
|
|
||||||
// Get visitor info
|
// Get visitor info
|
||||||
visitorId := getVisitorId(w, r)
|
visitorId := getVisitorId(w, r)
|
||||||
ip := r.RemoteAddr
|
ip := r.RemoteAddr
|
||||||
userAgent := r.UserAgent()
|
userAgent := r.UserAgent()
|
||||||
|
|
||||||
// Detect device information
|
// Detect device information
|
||||||
device := detectDevice(userAgent)
|
device := detectDevice(userAgent)
|
||||||
browser := detectBrowser(userAgent)
|
browser := detectBrowser(userAgent)
|
||||||
os := detectOS(userAgent)
|
os := detectOS(userAgent)
|
||||||
|
|
||||||
// Update visit counts
|
// Update visit counts
|
||||||
stats.TotalVisits++
|
stats.TotalVisits++
|
||||||
stats.TodayVisits++
|
stats.TodayVisits++
|
||||||
stats.LastVisit = time.Now()
|
stats.LastVisit = time.Now()
|
||||||
stats.LastUpdated = time.Now()
|
stats.LastUpdated = time.Now()
|
||||||
|
|
||||||
// Reset weekly visits on Monday
|
// Reset weekly visits on Monday
|
||||||
if time.Now().Weekday() == time.Monday && stats.LastUpdated.Weekday() != time.Monday {
|
if time.Now().Weekday() == time.Monday && stats.LastUpdated.Weekday() != time.Monday {
|
||||||
stats.WeeklyVisits = 1
|
stats.WeeklyVisits = 1
|
||||||
} else {
|
} else {
|
||||||
stats.WeeklyVisits++
|
stats.WeeklyVisits++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset monthly visits at the start of the month
|
// Reset monthly visits at the start of the month
|
||||||
if stats.LastUpdated.Month() != time.Now().Month() {
|
if stats.LastUpdated.Month() != time.Now().Month() {
|
||||||
stats.MonthlyVisits = 1
|
stats.MonthlyVisits = 1
|
||||||
} else {
|
} else {
|
||||||
stats.MonthlyVisits++
|
stats.MonthlyVisits++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update unique visitors
|
// Update unique visitors
|
||||||
if _, ok := stats.UniqueVisitors[visitorId]; !ok {
|
if _, ok := stats.UniqueVisitors[visitorId]; !ok {
|
||||||
stats.UniqueVisitors[visitorId] = &Visitor{
|
stats.UniqueVisitors[visitorId] = &Visitor{
|
||||||
FirstVisit: time.Now(),
|
FirstVisit: time.Now(),
|
||||||
LastVisit: time.Now(),
|
LastVisit: time.Now(),
|
||||||
Visits: 1,
|
Visits: 1,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
UserAgent: userAgent,
|
UserAgent: userAgent,
|
||||||
Device: device,
|
Device: device,
|
||||||
Browser: browser,
|
Browser: browser,
|
||||||
OS: os,
|
OS: os,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
visitor := stats.UniqueVisitors[visitorId]
|
visitor := stats.UniqueVisitors[visitorId]
|
||||||
visitor.LastVisit = time.Now()
|
visitor.LastVisit = time.Now()
|
||||||
visitor.Visits++
|
visitor.Visits++
|
||||||
stats.UniqueVisitors[visitorId] = visitor
|
stats.UniqueVisitors[visitorId] = visitor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update device stats
|
// Update device stats
|
||||||
if stats.BrowserStats == nil {
|
if stats.BrowserStats == nil {
|
||||||
stats.BrowserStats = make(map[string]int)
|
stats.BrowserStats = make(map[string]int)
|
||||||
}
|
}
|
||||||
stats.BrowserStats[browser]++
|
stats.BrowserStats[browser]++
|
||||||
|
|
||||||
// Update OS stats
|
// Update OS stats
|
||||||
if stats.OSStats == nil {
|
if stats.OSStats == nil {
|
||||||
stats.OSStats = make(map[string]int)
|
stats.OSStats = make(map[string]int)
|
||||||
}
|
}
|
||||||
stats.OSStats[os]++
|
stats.OSStats[os]++
|
||||||
|
|
||||||
// Update device stats
|
// Update device stats
|
||||||
if stats.ReferrerStats == nil {
|
if stats.ReferrerStats == nil {
|
||||||
stats.ReferrerStats = make(map[string]int)
|
stats.ReferrerStats = make(map[string]int)
|
||||||
}
|
}
|
||||||
stats.ReferrerStats[device]++
|
stats.ReferrerStats[device]++
|
||||||
|
|
||||||
// Update referrer stats
|
// Update referrer stats
|
||||||
referrer := r.Referer()
|
referrer := r.Referer()
|
||||||
if referrer != "" {
|
if referrer != "" {
|
||||||
if stats.ReferrerStats == nil {
|
if stats.ReferrerStats == nil {
|
||||||
stats.ReferrerStats = make(map[string]int)
|
stats.ReferrerStats = make(map[string]int)
|
||||||
}
|
}
|
||||||
stats.ReferrerStats[referrer]++
|
stats.ReferrerStats[referrer]++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update active hours
|
// Update active hours
|
||||||
hour := time.Now().Hour()
|
hour := time.Now().Hour()
|
||||||
found := false
|
found := false
|
||||||
for i, h := range stats.MostActiveHours {
|
for i, h := range stats.MostActiveHours {
|
||||||
if h.Hour == hour {
|
if h.Hour == hour {
|
||||||
stats.MostActiveHours[i].Count++
|
stats.MostActiveHours[i].Count++
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
stats.MostActiveHours = append(stats.MostActiveHours, struct {
|
stats.MostActiveHours = append(stats.MostActiveHours, struct {
|
||||||
Hour int `json:"hour"`
|
Hour int `json:"hour"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
}{Hour: hour, Count: 1})
|
}{Hour: hour, Count: 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update active days
|
// Update active days
|
||||||
day := time.Now().Weekday().String()
|
day := time.Now().Weekday().String()
|
||||||
found = false
|
found = false
|
||||||
for i, d := range stats.MostActiveDays {
|
for i, d := range stats.MostActiveDays {
|
||||||
if d.Day == day {
|
if d.Day == day {
|
||||||
stats.MostActiveDays[i].Count++
|
stats.MostActiveDays[i].Count++
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
stats.MostActiveDays = append(stats.MostActiveDays, struct {
|
stats.MostActiveDays = append(stats.MostActiveDays, struct {
|
||||||
Day string `json:"day"`
|
Day string `json:"day"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
}{Day: day, Count: 1})
|
}{Day: day, Count: 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save visitor stats
|
// Save visitor stats
|
||||||
if err := saveVisitorStats(stats); err != nil {
|
if err := saveVisitorStats(stats); err != nil {
|
||||||
log.Printf("Error saving visitor stats: %v", err)
|
log.Printf("Error saving visitor stats: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to extract browser from User-Agent
|
// Helper function to extract browser from User-Agent
|
||||||
func detectBrowser(userAgent string) string {
|
func detectBrowser(userAgent string) string {
|
||||||
userAgent = strings.ToLower(userAgent)
|
userAgent = strings.ToLower(userAgent)
|
||||||
if strings.Contains(userAgent, "chrome") {
|
if strings.Contains(userAgent, "chrome") {
|
||||||
return "Chrome"
|
return "Chrome"
|
||||||
} else if strings.Contains(userAgent, "safari") && !strings.Contains(userAgent, "chrome") {
|
} else if strings.Contains(userAgent, "safari") && !strings.Contains(userAgent, "chrome") {
|
||||||
return "Safari"
|
return "Safari"
|
||||||
} else if strings.Contains(userAgent, "firefox") {
|
} else if strings.Contains(userAgent, "firefox") {
|
||||||
return "Firefox"
|
return "Firefox"
|
||||||
} else if strings.Contains(userAgent, "msie") || strings.Contains(userAgent, "trident") {
|
} else if strings.Contains(userAgent, "msie") || strings.Contains(userAgent, "trident") {
|
||||||
return "Internet Explorer"
|
return "Internet Explorer"
|
||||||
} else if strings.Contains(userAgent, "edge") {
|
} else if strings.Contains(userAgent, "edge") {
|
||||||
return "Edge"
|
return "Edge"
|
||||||
} else if strings.Contains(userAgent, "opera") {
|
} else if strings.Contains(userAgent, "opera") {
|
||||||
return "Opera"
|
return "Opera"
|
||||||
} else {
|
} else {
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to extract OS from User-Agent
|
// Helper function to extract OS from User-Agent
|
||||||
func detectOS(userAgent string) string {
|
func detectOS(userAgent string) string {
|
||||||
userAgent = strings.ToLower(userAgent)
|
userAgent = strings.ToLower(userAgent)
|
||||||
if strings.Contains(userAgent, "windows") {
|
if strings.Contains(userAgent, "windows") {
|
||||||
return "Windows"
|
return "Windows"
|
||||||
} else if strings.Contains(userAgent, "mac os") || strings.Contains(userAgent, "macintosh") {
|
} else if strings.Contains(userAgent, "mac os") || strings.Contains(userAgent, "macintosh") {
|
||||||
return "macOS"
|
return "macOS"
|
||||||
} else if strings.Contains(userAgent, "iphone") || strings.Contains(userAgent, "ipad") || strings.Contains(userAgent, "ipod") {
|
} else if strings.Contains(userAgent, "iphone") || strings.Contains(userAgent, "ipad") || strings.Contains(userAgent, "ipod") {
|
||||||
return "iOS"
|
return "iOS"
|
||||||
} else if strings.Contains(userAgent, "android") {
|
} else if strings.Contains(userAgent, "android") {
|
||||||
return "Android"
|
return "Android"
|
||||||
} else if strings.Contains(userAgent, "linux") {
|
} else if strings.Contains(userAgent, "linux") {
|
||||||
return "Linux"
|
return "Linux"
|
||||||
} else if strings.Contains(userAgent, "bsd") {
|
} else if strings.Contains(userAgent, "bsd") {
|
||||||
return "BSD"
|
return "BSD"
|
||||||
} else {
|
} else {
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to extract OS from User-Agent
|
// Helper function to extract OS from User-Agent
|
||||||
@@ -450,7 +450,7 @@ func getVisitorStats(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if err := json.NewEncoder(w).Encode(stats); err != nil {
|
if err := json.NewEncoder(w).Encode(stats); err != nil {
|
||||||
log.Printf("Error encoding visitor stats: %v", err)
|
log.Printf("Error encoding visitor stats: %v", err)
|
||||||
@@ -524,9 +524,9 @@ func main() {
|
|||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
|
||||||
// Visitor tracking endpoints
|
// Visitor tracking endpoints
|
||||||
r.HandleFunc("/api/track-visit", trackVisit).Methods("GET")
|
r.HandleFunc("/api/track-visit", trackVisit).Methods("GET")
|
||||||
r.HandleFunc("/api/visitor-stats", getVisitorStats).Methods("GET")
|
r.HandleFunc("/api/visitor-stats", getVisitorStats).Methods("GET")
|
||||||
|
|
||||||
// Set up reverse proxy to kontakt service
|
// Set up reverse proxy to kontakt service
|
||||||
kontaktURL, _ := url.Parse("http://webportal:8080")
|
kontaktURL, _ := url.Parse("http://webportal:8080")
|
||||||
@@ -1423,11 +1423,11 @@ func handleSubmit(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sendEmail(entry TripEntry, parsedDateStart, parsedDateEnd time.Time, czechMonths []string) error {
|
func sendEmail(entry TripEntry, parsedDateStart, parsedDateEnd time.Time, czechMonths []string) error {
|
||||||
smtpHost := "mail.pp-kunovice.cz"
|
smtpHost := "smtp.purelymail.com"
|
||||||
smtpPort := 465
|
smtpPort := 465
|
||||||
sender := "sluzebnicek@pp-kunovice.cz"
|
sender := "info@tdvorak.dev"
|
||||||
password := "7g}qznB5bj"
|
password := "%8s3Yad*!b3*t"
|
||||||
recipient := "sluzebnicek@pp-kunovice.cz"
|
recipient := "info@tdvorak.dev"
|
||||||
|
|
||||||
m := gomail.NewMessage()
|
m := gomail.NewMessage()
|
||||||
m.SetHeader("From", sender)
|
m.SetHeader("From", sender)
|
||||||
|
|||||||
Reference in New Issue
Block a user