Created
November 15, 2018 01:15
-
-
Save theGeekPirate/f2a451190f64b9aa9af0239c3b9c4589 to your computer and use it in GitHub Desktop.
BAPCSalesLiveFeed will show a constant stream of live updates from the /r/bapcsalescanada subreddit. It was hacked together as quickly as possible in preparation for Black Friday.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// BAPCSalesLiveFeed will show a constant stream of live updates from the /r/bapcsalescanada subreddit. | |
// It was hacked together as quickly as possible in preparation for Black Friday. | |
// Note that this leaks memory _very slowly_ due to us constantly adding IDs to the postCache. | |
// This isn't a big deal since the amount of data stored is miniscule, but worth noting if you're | |
// going to be running it non-stop for a couple of years on a memory-constrained system for whatever reason. | |
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"log" | |
"net/http" | |
"os" | |
"strconv" | |
"strings" | |
"time" | |
"github.com/faiface/beep/speaker" | |
"github.com/faiface/beep/wav" | |
"github.com/fatih/color" | |
) | |
const ( | |
subreddit = "bapcsalescanada" | |
redditURL = "https://www.reddit.com/r/" + subreddit + "/new" | |
userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36" | |
// The notification sound comes from https://www.leshylabs.com/apps/sfMaker/ | |
// Copy-and-paste the string below into the "Sound Text" field, then click on "Load Text". | |
// W=44100,f=992.364,v=113.026,V=9.898,t=1.598,T=0.112,_=0.047,d=286.446,D=0.164,p=1.729,b=1.6,r=0.3,c=-27,C=48.503,s=164,S=5.336,z=Down,g=0.419,l=0.33,L=0.605 | |
soundFile = "notification.wav" | |
) | |
var postCache = make(map[string]struct{}) | |
type reddit struct { | |
Data struct { | |
Children []struct { | |
Data struct { | |
ID string `json:"id"` | |
Title string `json:"title"` | |
Domain string `json:"domain"` | |
Permalink string `json:"permalink"` | |
URL string `json:"url"` | |
CreatedUtc float64 `json:"created_utc"` | |
} `json:"data"` | |
} `json:"children"` | |
} `json:"data"` | |
} | |
func main() { | |
run(false) | |
for range time.Tick(time.Second * 10) { | |
run(true) | |
} | |
} | |
func run(playSound bool) { | |
r := parseJSON() | |
for i := 0; i <= len(r.Data.Children)-1; i++ { | |
item := r.Data.Children[len(r.Data.Children)-1-i].Data | |
_, exists := postCache[item.ID] | |
if exists { | |
continue | |
} | |
postCache[item.ID] = struct{}{} | |
timeInt, err := strconv.Atoi(strings.Split(strconv.FormatFloat(item.CreatedUtc, 'f', 6, 64), ".")[0]) | |
if err != nil { | |
log.Println(color.RedString("Unable to convert UTC time to int: " + err.Error())) | |
} | |
localTime := color.YellowString(time.Unix(int64(timeInt), int64(0)).Format("3:04PM")) | |
title := item.Title | |
redditLink := color.BlueString("https://www.reddit.com" + item.Permalink) | |
var storeLink string | |
if item.Domain != "self."+subreddit { | |
storeLink = color.CyanString(item.URL) | |
} | |
fmt.Println(localTime + " " + title + "\n" + redditLink) | |
if storeLink != "" { | |
fmt.Println(storeLink) | |
} | |
fmt.Println(strings.Repeat("-", 80)) | |
if playSound { | |
f, err := os.Open(soundFile) | |
if err != nil { | |
log.Println(color.RedString("Missing sound file: " + soundFile + ": " + err.Error())) | |
playSound = false | |
continue | |
} | |
s, format, err := wav.Decode(f) | |
if err != nil { | |
log.Println(color.RedString("Unable to decode sound file: " + soundFile + ": " + err.Error())) | |
playSound = false | |
continue | |
} | |
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) | |
speaker.Play(s) | |
} | |
} | |
} | |
func parseJSON() reddit { | |
req, err := http.NewRequest("GET", redditURL+".json", nil) | |
if err != nil { | |
log.Fatalln(color.RedString("Error retrieving HTTP: " + err.Error())) | |
} | |
// Setting a User-Agent is required otherwise reddit will block the request. | |
req.Header.Set("User-Agent", userAgent) | |
client := &http.Client{} | |
resp, err := client.Do(req) | |
if err != nil { | |
log.Println(color.RedString("Error receiving a response: " + err.Error())) | |
return parseJSON() | |
} | |
defer resp.Body.Close() | |
r := reddit{} | |
json.NewDecoder(resp.Body).Decode(&r) | |
if err != nil { | |
log.Println(color.RedString("Error decoding JSON: " + err.Error())) | |
return parseJSON() | |
} | |
return r | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment