mirror of
https://github.com/glanceapp/glance.git
synced 2024-12-15 01:22:37 +03:00
184 lines
3.5 KiB
Go
184 lines
3.5 KiB
Go
|
package feed
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"sort"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type ForumPost struct {
|
||
|
Title string
|
||
|
DiscussionUrl string
|
||
|
TargetUrl string
|
||
|
TargetUrlDomain string
|
||
|
ThumbnailUrl string
|
||
|
CommentCount int
|
||
|
Score int
|
||
|
Engagement float64
|
||
|
TimePosted time.Time
|
||
|
}
|
||
|
|
||
|
type ForumPosts []ForumPost
|
||
|
|
||
|
type Calendar struct {
|
||
|
CurrentDay int
|
||
|
CurrentWeekNumber int
|
||
|
CurrentMonthName string
|
||
|
CurrentYear int
|
||
|
Days []int
|
||
|
}
|
||
|
|
||
|
type Weather struct {
|
||
|
Temperature int
|
||
|
ApparentTemperature int
|
||
|
WeatherCode int
|
||
|
CurrentColumn int
|
||
|
SunriseColumn int
|
||
|
SunsetColumn int
|
||
|
Columns []weatherColumn
|
||
|
}
|
||
|
|
||
|
type AppRelease struct {
|
||
|
Name string
|
||
|
Version string
|
||
|
NotesUrl string
|
||
|
TimeReleased time.Time
|
||
|
Downvotes int
|
||
|
}
|
||
|
|
||
|
type AppReleases []AppRelease
|
||
|
|
||
|
type Video struct {
|
||
|
ThumbnailUrl string
|
||
|
Title string
|
||
|
Url string
|
||
|
Author string
|
||
|
AuthorUrl string
|
||
|
TimePosted time.Time
|
||
|
}
|
||
|
|
||
|
type Videos []Video
|
||
|
|
||
|
type Stock struct {
|
||
|
Name string
|
||
|
Symbol string
|
||
|
Price float64
|
||
|
PercentChange float64
|
||
|
SvgChartPoints string
|
||
|
}
|
||
|
|
||
|
type Stocks []Stock
|
||
|
|
||
|
func (t Stocks) SortByAbsChange() {
|
||
|
sort.Slice(t, func(i, j int) bool {
|
||
|
return math.Abs(t[i].PercentChange) > math.Abs(t[j].PercentChange)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
var weatherCodeTable = map[int]string{
|
||
|
0: "Clear Sky",
|
||
|
1: "Mainly Clear",
|
||
|
2: "Partly Cloudy",
|
||
|
3: "Overcast",
|
||
|
45: "Fog",
|
||
|
48: "Rime Fog",
|
||
|
51: "Drizzle",
|
||
|
53: "Drizzle",
|
||
|
55: "Drizzle",
|
||
|
56: "Drizzle",
|
||
|
57: "Drizzle",
|
||
|
61: "Rain",
|
||
|
63: "Moderate Rain",
|
||
|
65: "Heavy Rain",
|
||
|
66: "Freezing Rain",
|
||
|
67: "Freezing Rain",
|
||
|
71: "Snow",
|
||
|
73: "Moderate Snow",
|
||
|
75: "Heavy Snow",
|
||
|
77: "Snow Grains",
|
||
|
80: "Rain",
|
||
|
81: "Moderate Rain",
|
||
|
82: "Heavy Rain",
|
||
|
85: "Snow",
|
||
|
86: "Snow",
|
||
|
95: "Thunderstorm",
|
||
|
96: "Thunderstorm",
|
||
|
99: "Thunderstorm",
|
||
|
}
|
||
|
|
||
|
func (w *Weather) WeatherCodeAsString() string {
|
||
|
if weatherCode, ok := weatherCodeTable[w.WeatherCode]; ok {
|
||
|
return weatherCode
|
||
|
}
|
||
|
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
const depreciatePostsOlderThanHours = 7
|
||
|
const maxDepreciation = 0.9
|
||
|
const maxDepreciationAfterHours = 24
|
||
|
|
||
|
func (p ForumPosts) CalculateEngagement() {
|
||
|
var totalComments int
|
||
|
var totalScore int
|
||
|
|
||
|
for i := range p {
|
||
|
totalComments += p[i].CommentCount
|
||
|
totalScore += p[i].Score
|
||
|
}
|
||
|
|
||
|
numberOfPosts := float64(len(p))
|
||
|
averageComments := float64(totalComments) / numberOfPosts
|
||
|
averageScore := float64(totalScore) / numberOfPosts
|
||
|
|
||
|
for i := range p {
|
||
|
p[i].Engagement = (float64(p[i].CommentCount)/averageComments + float64(p[i].Score)/averageScore) / 2
|
||
|
|
||
|
elapsed := time.Since(p[i].TimePosted)
|
||
|
|
||
|
if elapsed < time.Hour*depreciatePostsOlderThanHours {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
p[i].Engagement *= 1.0 - (math.Max(elapsed.Hours()-depreciatePostsOlderThanHours, maxDepreciationAfterHours)/maxDepreciationAfterHours)*maxDepreciation
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (p ForumPosts) SortByEngagement() {
|
||
|
sort.Slice(p, func(i, j int) bool {
|
||
|
return p[i].Engagement > p[j].Engagement
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (s *ForumPost) HasTargetUrl() bool {
|
||
|
return s.TargetUrl != ""
|
||
|
}
|
||
|
|
||
|
func (p ForumPosts) FilterPostedBefore(postedBefore time.Duration) []ForumPost {
|
||
|
recent := make([]ForumPost, 0, len(p))
|
||
|
|
||
|
for i := range p {
|
||
|
if time.Since(p[i].TimePosted) < postedBefore {
|
||
|
recent = append(recent, p[i])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return recent
|
||
|
}
|
||
|
|
||
|
func (r AppReleases) SortByNewest() AppReleases {
|
||
|
sort.Slice(r, func(i, j int) bool {
|
||
|
return r[i].TimeReleased.After(r[j].TimeReleased)
|
||
|
})
|
||
|
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func (v Videos) SortByNewest() Videos {
|
||
|
sort.Slice(v, func(i, j int) bool {
|
||
|
return v[i].TimePosted.After(v[j].TimePosted)
|
||
|
})
|
||
|
|
||
|
return v
|
||
|
}
|