2021-02-13 02:49:36 +00:00
package main
import (
2021-06-30 22:28:53 +00:00
"context"
"encoding/json"
2021-02-13 02:49:36 +00:00
"fmt"
"log"
"net/http"
2021-03-17 23:14:24 +00:00
"strconv"
2021-06-30 22:28:53 +00:00
"time"
2021-02-13 02:49:36 +00:00
"github.com/jackc/pgx/v4"
)
2021-06-30 22:28:53 +00:00
var trendingexport string
2021-12-17 00:45:52 -05:00
var trendingHashTags string
var trendingwords string
var hashtagtotal map [ string ] interface { }
var wordstotal map [ string ] interface { }
//hashtagmeta := make(map[string]interface{});
2021-06-30 22:28:53 +00:00
2021-03-17 23:14:24 +00:00
func enableCors ( w * http . ResponseWriter ) {
( * w ) . Header ( ) . Set ( "Access-Control-Allow-Origin" , "*" )
}
2021-12-17 00:45:52 -05:00
func getTrendingHashtags ( ) {
sql := "SELECT UNNEST(activities.hashtags) as hashtags, count(actors.id) " +
"FROM activities " +
"LEFT JOIN actors ON activities.document->>'attributedTo'=actors.document->>'id' " +
"WHERE actors.bot=TRUE " +
//"AND activities.identifiedat > LOCALTIMESTAMP - INTERVAL '30 MINUTES' " +
"GROUP BY hashtags ORDER BY count DESC LIMIT 20"
2021-06-30 22:28:53 +00:00
for {
2021-12-17 00:45:52 -05:00
rows , err := pool . Query ( context . Background ( ) , sql )
if err != nil {
panic ( err )
}
hashtagitems := make ( [ ] interface { } , 0 ) ;
hashcount := 0
for rows . Next ( ) {
var hashtag string
var count int
err = rows . Scan ( & hashtag , & count )
if err != nil {
panic ( err )
}
hashtagitem := make ( map [ string ] interface { } )
hashtagitem [ "hashtag" ] = hashtag
hashtagitem [ "count" ] = count
hashtagitems = append ( hashtagitems , hashtagitem )
hashcount = hashcount + 1
}
rows . Close ( )
hashtagtotal = make ( map [ string ] interface { } ) ;
hashtagtotal [ "count" ] = hashcount
hashtagtotal [ "datetime" ] = time . Now ( ) . UTC ( )
hashtagtotal [ "items" ] = hashtagitems
totalJson := make ( map [ string ] interface { } )
totalJson [ "hashtags" ] = hashtagtotal
data , err := json . Marshal ( totalJson )
if err != nil {
log . Fatalf ( "error marshaling combined activity: %v\n" , err )
}
trendingHashTags = string ( data )
time . Sleep ( time . Minute * 30 )
}
}
func gettrends ( ) {
for {
rows , err := pool . Query ( context . Background ( ) , "SELECT word, ndoc FROM ts_stat($$ SELECT normalized_tsvector FROM activities WHERE activities.identifiedat > current_timestamp - interval '60 minutes' $$) ORDER BY ndoc DESC LIMIT 10" )
2021-06-30 22:28:53 +00:00
if err != nil {
panic ( err )
}
trenditems := make ( [ ] interface { } , 0 )
for rows . Next ( ) {
var word string
var ndoc int
err = rows . Scan ( & word , & ndoc )
if err != nil {
panic ( err )
}
trenditem := make ( map [ string ] interface { } )
trenditem [ "ndoc" ] = ndoc
trenditem [ "word" ] = word
trenditems = append ( trenditems , trenditem )
}
2021-12-17 00:45:52 -05:00
rows . Close ( )
2021-06-30 22:28:53 +00:00
totalJson := make ( map [ string ] interface { } )
totalJson [ "trends" ] = trenditems
data , err := json . Marshal ( totalJson )
if err != nil {
2021-12-09 21:12:00 +00:00
log . Fatalf ( "error marshaling combined activity: %v\n" , err )
2021-06-30 22:28:53 +00:00
}
trendingexport = string ( data )
time . Sleep ( time . Second * 60 )
}
}
2021-12-17 00:45:52 -05:00
func
func gettrending ( w http . ResponseWriter , r * http . Request ) {
enableCors ( & w )
// fmt.Fprintf(w, "%s", trendingexport)
}
func gettrendinghashtags ( w http . ResponseWriter , r * http . Request ) {
enableCors ( & w )
fmt . Fprintf ( w , "%s" , trendingHashTags )
}
func gettrendingwords ( w http . ResponseWriter , r * http . Request ) {
2021-06-30 22:28:53 +00:00
enableCors ( & w )
fmt . Fprintf ( w , "%s" , trendingexport )
}
2021-12-17 00:45:52 -05:00
func getsearch ( w http . ResponseWriter , r * http . Request ) {
2021-03-17 23:14:24 +00:00
enableCors ( & w )
searchkeys , exists_search := r . URL . Query ( ) [ "s" ]
offsetkeys , exists_offset := r . URL . Query ( ) [ "o" ]
2021-02-13 02:49:36 +00:00
var err error
var rows pgx . Rows
var searchKey string
2021-03-17 23:14:24 +00:00
if exists_search {
2021-02-13 02:49:36 +00:00
searchKey = searchkeys [ 0 ]
}
2021-03-17 23:14:24 +00:00
var offsetKey int
if exists_offset {
offsetKey , _ = strconv . Atoi ( offsetkeys [ 0 ] )
} else {
offsetKey = - 1
}
2021-02-13 02:49:36 +00:00
2021-03-17 23:14:24 +00:00
if exists_search && searchKey != "" {
if offsetKey == - 1 {
2021-06-30 15:00:08 +00:00
rows , err = pool . Query ( context . Background ( ) , "SELECT activities.id, activities.document, actors.document FROM activities as activities INNER JOIN actors as actors ON activities.document->>'actor' = actors.document->>'id' WHERE activities.normalized_tsvector @@ plainto_tsquery($1) ORDER BY activities.id DESC LIMIT 10" , searchKey )
2021-03-17 23:14:24 +00:00
} else {
2021-06-30 15:00:08 +00:00
rows , err = pool . Query ( context . Background ( ) , "SELECT activities.id, activities.document, actors.document FROM activities as activities INNER JOIN actors as actors ON activities.document->>'actor' = actors.document->>'id' WHERE activities.normalized_tsvector @@ plainto_tsquery($1) AND activities.id < $2 ORDER BY activities.id DESC LIMIT 10" , searchKey , offsetKey )
2021-03-17 23:14:24 +00:00
}
2021-02-13 02:49:36 +00:00
} else {
2021-03-17 23:14:24 +00:00
if offsetKey == - 1 {
2021-06-30 15:00:08 +00:00
rows , err = pool . Query ( context . Background ( ) , "SELECT activities.id, activities.document, actors.document FROM activities as activities INNER JOIN actors as actors ON activities.document->>'actor' = actors.document->>'id' ORDER BY activities.id DESC LIMIT 10" )
2021-03-17 23:14:24 +00:00
} else {
2021-06-30 15:00:08 +00:00
rows , err = pool . Query ( context . Background ( ) , "SELECT activities.id, activities.document, actors.document FROM activities as activities INNER JOIN actors as actors ON activities.document->>'actor' = actors.document->>'id' AND activities.id < $1 ORDER BY activities.id DESC LIMIT 10" , offsetKey )
2021-03-17 23:14:24 +00:00
}
2021-02-13 02:49:36 +00:00
}
if err != nil {
panic ( err )
}
defer rows . Close ( )
2021-06-30 15:00:08 +00:00
var earliestid int
earliestid = 0
2021-02-13 02:49:36 +00:00
var activitiesJson [ ] map [ string ] json . RawMessage
for rows . Next ( ) {
var id int
var activityRaw string
var actorRaw string
var activityJson map [ string ] json . RawMessage
err = rows . Scan ( & id , & activityRaw , & actorRaw )
if err != nil {
panic ( err )
}
err := json . Unmarshal ( [ ] byte ( activityRaw ) , & activityJson )
if err != nil {
fmt . Println ( err )
}
2021-06-30 15:00:08 +00:00
if earliestid == 0 {
earliestid = id
} else if earliestid > id {
earliestid = id
2021-03-17 23:14:24 +00:00
}
2021-02-13 02:49:36 +00:00
activityJson [ "actor" ] = json . RawMessage ( actorRaw )
activitiesJson = append ( activitiesJson , activityJson )
}
2021-03-17 23:14:24 +00:00
requestData := make ( map [ string ] int )
2021-06-30 15:00:08 +00:00
requestData [ "earliestid" ] = earliestid
2021-03-17 23:14:24 +00:00
2021-06-30 22:28:53 +00:00
totalJson := make ( map [ string ] interface { } )
2021-03-17 23:14:24 +00:00
totalJson [ "requestdata" ] = requestData
totalJson [ "activities" ] = activitiesJson
data , err := json . Marshal ( totalJson )
2021-02-13 02:49:36 +00:00
if err != nil {
2021-12-09 21:12:00 +00:00
log . Fatalf ( "error marshaling combined activity: %v\n" , err )
2021-02-13 02:49:36 +00:00
}
fmt . Fprintf ( w , "%s" , data )
}
func main ( ) {
pool = getDbPool ( )
2021-06-30 22:28:53 +00:00
go gettrends ( )
2021-12-17 00:45:52 -05:00
go getTrendingHashtags ( )
2021-06-30 22:28:53 +00:00
2021-12-17 00:45:52 -05:00
http . HandleFunc ( "/api/v1/search" , getsearch )
http . HandleFunc ( "/api/v1/trending" , gettrending )
http . HandleFunc ( "/api/v1/trending/hashtags" , gettrendinghashtags )
http . HandleFunc ( "/api/v1/trending/words" , gettrendingwords )
2021-06-30 22:28:53 +00:00
log . Print ( "Starting HTTP inbox on port http://0.0.0.0:6431" )
2021-06-30 15:00:08 +00:00
log . Fatal ( http . ListenAndServe ( "0.0.0.0:6431" , nil ) )
2021-02-13 02:49:36 +00:00
}