mirror of
https://github.com/gurnec/removeddit.git
synced 2026-03-11 08:54:27 +00:00
180 lines
4.5 KiB
Go
180 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"html/template"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// consts
|
|
const (
|
|
userAgent = "Javascript:" + appName + ":" + version + "s (by /u/" + userName + ")"
|
|
tokenURL = "https://www.reddit.com/api/v1/access_token"
|
|
commentIDsURL = "https://api.pushshift.io/reddit/submission/comment_ids/"
|
|
commentsURL = "https://api.pushshift.io/reddit/comment/search?ids="
|
|
tmplFolder = "templates/"
|
|
errorHTML = "<h3 style=\"colorError;font-family: verdana, arial, helvetica, sans-serif;\">Error: %s</h3>"
|
|
)
|
|
|
|
var (
|
|
client = &http.Client{Timeout: time.Second * 10}
|
|
tokenData = url.Values{"grant_type": []string{"client_credentials"}}
|
|
templates = template.Must(template.ParseFiles(
|
|
tmplFolder+"header.html",
|
|
tmplFolder+"footer.html",
|
|
tmplFolder+"thread.html",
|
|
tmplFolder+"frontpage.html",
|
|
tmplFolder+"error.html",
|
|
))
|
|
|
|
accessLog *log.Logger
|
|
errorLog *log.Logger
|
|
)
|
|
|
|
type tokenResponse struct {
|
|
AccessToken string `json:"access_token"`
|
|
TokenType string `json:"token_type"`
|
|
ExpiresIn int `json:"expires_in"`
|
|
Scope string `json:"scope"`
|
|
}
|
|
|
|
type pushshiftAPI struct {
|
|
Data []string `json:"data"`
|
|
}
|
|
|
|
type pageData struct {
|
|
Token string
|
|
Subreddit string
|
|
ThreadID string
|
|
CommentIDs []string
|
|
}
|
|
|
|
func main() {
|
|
initLogging()
|
|
accessLog.Println("Staring server")
|
|
/*
|
|
s := &http.Server{
|
|
Addr: ":8080",
|
|
Handler: myHandler,
|
|
ReadTimeout: 10 * time.Second,
|
|
WriteTimeout: 10 * time.Second,
|
|
MaxHeaderBytes: 1 << 20,
|
|
}*/
|
|
|
|
// Only serve local static files for debugging, otherwise use cdn.rawgit.com
|
|
fs := http.FileServer(http.Dir("static"))
|
|
http.Handle("/static/", http.StripPrefix("/static/", fs))
|
|
|
|
http.HandleFunc("/", pageHandler(mainHandler))
|
|
http.HandleFunc("/r/", pageHandler(threadHandler))
|
|
http.HandleFunc("/comments/", pageHandler(commentHandler))
|
|
|
|
http.ListenAndServe(":9000", nil)
|
|
}
|
|
|
|
func initLogging() {
|
|
accessFile, _ := os.OpenFile("access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
|
errorFile, _ := os.OpenFile("error.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
|
|
|
accessLog = log.New(accessFile, "", log.Ldate|log.Ltime|log.Lshortfile)
|
|
errorLog = log.New(errorFile, "", log.Ldate|log.Ltime|log.Lshortfile)
|
|
}
|
|
|
|
// Wrap handle function for the access log
|
|
func pageHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
accessLog.Println(r.URL.Path)
|
|
fn(w, r)
|
|
}
|
|
}
|
|
|
|
func renderTemplate(w http.ResponseWriter, pageName string, data interface{}) {
|
|
templates.ExecuteTemplate(w, "header.html", nil)
|
|
templates.ExecuteTemplate(w, pageName+".html", data)
|
|
templates.ExecuteTemplate(w, "footer.html", nil)
|
|
}
|
|
|
|
func mainHandler(w http.ResponseWriter, r *http.Request) {
|
|
renderTemplate(w, "frontpage", nil)
|
|
}
|
|
|
|
func threadHandler(w http.ResponseWriter, r *http.Request) {
|
|
pathParts := strings.Split(r.URL.Path, "/")
|
|
|
|
if len(pathParts) < 5 {
|
|
handleError(w, "Missing necessary parts of the URL")
|
|
return
|
|
}
|
|
|
|
resp, _ := client.Get(commentIDsURL + pathParts[4])
|
|
if resp.StatusCode != 200 {
|
|
handleError(w, "Trouble getting removed comments from pushshift")
|
|
return
|
|
}
|
|
|
|
token, err := getAPIToken()
|
|
if err != nil {
|
|
handleError(w, err.Error())
|
|
return
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
var dataStructure pushshiftAPI
|
|
json.Unmarshal(body, &dataStructure)
|
|
|
|
data := &pageData{
|
|
Token: token,
|
|
Subreddit: pathParts[2],
|
|
ThreadID: pathParts[4],
|
|
CommentIDs: dataStructure.Data,
|
|
}
|
|
|
|
renderTemplate(w, "thread", data)
|
|
}
|
|
|
|
func handleError(w http.ResponseWriter, msg string) {
|
|
renderTemplate(w, "error", msg)
|
|
errorLog.Println(msg)
|
|
}
|
|
|
|
func commentHandler(w http.ResponseWriter, r *http.Request) {
|
|
commentIDs := r.FormValue("c")
|
|
if commentIDs == "" {
|
|
handleError(w, "Not enough arguments provided")
|
|
return
|
|
}
|
|
|
|
resp, err := client.Get(commentsURL + commentIDs)
|
|
|
|
if err != nil {
|
|
handleError(w, "Trouble getting removed comments from pushshift")
|
|
return
|
|
}
|
|
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
|
fmt.Fprintf(w, string(body))
|
|
}
|
|
|
|
func getAPIToken() (string, error) {
|
|
req, _ := http.NewRequest("POST", tokenURL, strings.NewReader(tokenData.Encode()))
|
|
req.Header.Add("User-Agent", userAgent)
|
|
req.SetBasicAuth(clientID, clientSecret)
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return "", errors.New("Coulnd't get API token from Reddit")
|
|
}
|
|
defer resp.Body.Close()
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
|
var r tokenResponse
|
|
json.Unmarshal(body, &r)
|
|
return r.AccessToken, nil
|
|
}
|