123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- 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
- Tags []string
- }
- 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 {
- Source ReleaseSource
- 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
- var currencyToSymbol = map[string]string{
- "USD": "$",
- "EUR": "€",
- "JPY": "¥",
- "CAD": "C$",
- "AUD": "A$",
- "GBP": "£",
- "CHF": "Fr",
- "NZD": "N$",
- "INR": "₹",
- "BRL": "R$",
- "RUB": "₽",
- "TRY": "₺",
- "ZAR": "R",
- "CNY": "¥",
- "KRW": "₩",
- "HKD": "HK$",
- "SGD": "S$",
- "SEK": "kr",
- "NOK": "kr",
- "DKK": "kr",
- "PLN": "zł",
- "PHP": "₱",
- }
- type MarketRequest struct {
- Name string `yaml:"name"`
- Symbol string `yaml:"symbol"`
- ChartLink string `yaml:"chart-link"`
- SymbolLink string `yaml:"symbol-link"`
- }
- type Market struct {
- MarketRequest
- Currency string `yaml:"-"`
- Price float64 `yaml:"-"`
- PercentChange float64 `yaml:"-"`
- SvgChartPoints string `yaml:"-"`
- }
- type Markets []Market
- func (t Markets) 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
- }
|