mirror of
https://github.com/gmemstr/pogo.git
synced 2024-09-20 01:31:09 +01:00
Change of name! + better skeleton custom.css
This commit is contained in:
parent
0a20d53655
commit
41dcc302c3
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -20,3 +20,5 @@ podcasts/
|
||||||
feed\.rss
|
feed\.rss
|
||||||
|
|
||||||
assets/static/custom\.css
|
assets/static/custom\.css
|
||||||
|
|
||||||
|
config\.json
|
17
Dockerfile
17
Dockerfile
|
@ -2,16 +2,17 @@
|
||||||
FROM golang:latest
|
FROM golang:latest
|
||||||
|
|
||||||
# Set working directory
|
# Set working directory
|
||||||
WORKDIR /WhiteRabbit
|
WORKDIR /POGO
|
||||||
|
|
||||||
# Add source to container so we can build
|
# Add source to container so we can build
|
||||||
ADD . /WhiteRabbit
|
ADD . /POGO
|
||||||
|
|
||||||
# 1. Install make & co.
|
# 1. Install make and dependencies
|
||||||
# 2. Install project dependencies
|
# 2. Install Go dependencies
|
||||||
# 3. Build binary and move to parent directory
|
# 3. Build named Linux binary and allow execution
|
||||||
# 4. Create podcast directory
|
# 4. List directory structure (for debugging really)\
|
||||||
# 5. Generate basic skeleton files
|
# 5. Make empty podcast direcory
|
||||||
|
# 6. Create empty feed files
|
||||||
RUN apt update; apt install build-essential -y && \
|
RUN apt update; apt install build-essential -y && \
|
||||||
make install && \
|
make install && \
|
||||||
make linux && chmod +x whiterabbit && \
|
make linux && chmod +x whiterabbit && \
|
||||||
|
@ -21,4 +22,4 @@ RUN apt update; apt install build-essential -y && \
|
||||||
|
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
CMD ./whiterabbit
|
CMD ./pogoapp
|
6
Makefile
6
Makefile
|
@ -2,10 +2,10 @@ all:
|
||||||
go build src/webserver.go src/admin.go src/generate_rss.go
|
go build src/webserver.go src/admin.go src/generate_rss.go
|
||||||
|
|
||||||
windows: src/admin.go src/webserver.go src/generate_rss.go
|
windows: src/admin.go src/webserver.go src/generate_rss.go
|
||||||
go build -o whiterabbit.exe src/webserver.go src/admin.go src/generate_rss.go
|
go build -o pogoapp.exe src/webserver.go src/admin.go src/generate_rss.go
|
||||||
|
|
||||||
linux: src/admin.go src/webserver.go src/generate_rss.go
|
linux: src/admin.go src/webserver.go src/generate_rss.go
|
||||||
go build -o whiterabbit src/webserver.go src/admin.go src/generate_rss.go
|
go build -o pogoapp src/webserver.go src/admin.go src/generate_rss.go
|
||||||
|
|
||||||
install:
|
install:
|
||||||
go get github.com/gmemstr/feeds
|
go get github.com/gmemstr/feeds
|
||||||
|
@ -18,4 +18,4 @@ docker:
|
||||||
|
|
||||||
and run:
|
and run:
|
||||||
go build src/webserver.go src/admin.go src/generate_rss.go
|
go build src/webserver.go src/admin.go src/generate_rss.go
|
||||||
./webserver.exe
|
./pogoapp.exe
|
61
README.md
61
README.md
|
@ -1,26 +1,25 @@
|
||||||
# white rabbit
|
# Pogo
|
||||||
|
Podcast RSS feed generator and CMS in Go.
|
||||||
|
---
|
||||||
|
|
||||||
[![gitgalaxy](https://img.shields.io/badge/website-gitgalaxy.com-blue.svg)](https://gitgalaxy.com) [![shield](https://img.shields.io/badge/live-podcast.gitgalaxy.com-green.svg)](https://podcast.gitgalaxy.com) [![follow](https://img.shields.io/twitter/follow/gitgalaxy.svg?style=social&label=Follow)](https://twitter.com/gitgalaxy)
|
[![gitgalaxy](https://img.shields.io/badge/website-gitgalaxy.com-blue.svg)](https://gitgalaxy.com) [![shield](https://img.shields.io/badge/live-podcast.gitgalaxy.com-green.svg)](https://podcast.gitgalaxy.com) [![follow](https://img.shields.io/twitter/follow/gitgalaxy.svg?style=social&label=Follow)](https://twitter.com/gitgalaxy)
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
podcast rss generator and cms in golang
|
To produce a product that is easy to deploy and easier to use when hosting a podcast from ones own servers.
|
||||||
|
|
||||||
## goal
|
## Features
|
||||||
|
|
||||||
to produce a product that is easy to deploy and easier to use when hosting a podcast from ones own servers.
|
* Auto-generate rss feed
|
||||||
|
* Basic frontend for listening to episodes
|
||||||
|
* Flat-file directory structure
|
||||||
|
* Human readable files
|
||||||
|
* Self publishing interface w/ password protection
|
||||||
|
* Custom CSS and themeing capabilities
|
||||||
|
* JSON feed generation for easier parsing
|
||||||
|
* Docker support
|
||||||
|
|
||||||
## features
|
## Requirements
|
||||||
|
|
||||||
* auto-generate rss feed
|
|
||||||
* flat-file directory structure
|
|
||||||
* human readable files
|
|
||||||
* self publishing interface w/ password protection
|
|
||||||
* basic frontend for listening to episodes
|
|
||||||
* custom css and themeing capabilities
|
|
||||||
* json feed generation for easier parsing
|
|
||||||
* docker support
|
|
||||||
|
|
||||||
## requirements
|
|
||||||
|
|
||||||
[github.com/gmemstr/feeds](https://github.com/gmemstr/feeds) _this branch contains some fixes for "podcast specific" tags_
|
[github.com/gmemstr/feeds](https://github.com/gmemstr/feeds) _this branch contains some fixes for "podcast specific" tags_
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ to produce a product that is easy to deploy and easier to use when hosting a pod
|
||||||
|
|
||||||
[github.com/gorilla/mux](https://github.com/gorilla/mux)
|
[github.com/gorilla/mux](https://github.com/gorilla/mux)
|
||||||
|
|
||||||
## building
|
## Building
|
||||||
|
|
||||||
```
|
```
|
||||||
make install
|
make install
|
||||||
|
@ -38,6 +37,16 @@ make
|
||||||
./webserver
|
./webserver
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Makefile
|
||||||
|
|
||||||
|
There are several commands in the Makefile, for various reasons (commands are preceded by the `make` command).
|
||||||
|
|
||||||
|
* `all` - also works by just running `make`, compiles go code to executable
|
||||||
|
* `windows` - creates named compiled .exe (pogoapp.exe)
|
||||||
|
* `linux` - creates named compiled binary (pogoapp)
|
||||||
|
* `install` - installs go dependencies
|
||||||
|
* `docker` - build docker image for running elsewhere
|
||||||
|
* `and run` - build and run the executable (remove .exe in file for \*nix)
|
||||||
|
|
||||||
**non-make**
|
**non-make**
|
||||||
```
|
```
|
||||||
|
@ -49,22 +58,12 @@ go build webserver.go generate_rss.go admin.go
|
||||||
./webserver
|
./webserver
|
||||||
```
|
```
|
||||||
|
|
||||||
## file format
|
## File format
|
||||||
|
|
||||||
white rabbit uses a flat file structure for managing podcast episodes. as such, files have a special naming convention.
|
Pogo uses a flat file structure for managing podcast episodes. as such, files have a special naming convention.
|
||||||
|
|
||||||
for podcast audio files, filenames take the form of YEAR-MONTH-DAY followed by the title. The two values are
|
For podcast audio files, filenames take the form of YEAR-MONTH-DAY followed by the title. The two values are
|
||||||
seperated by underscores (`YYYY-MM-DD_TITLE.mp3`).
|
seperated by underscores (`YYYY-MM-DD_TITLE.mp3`).
|
||||||
|
|
||||||
shownote fils are markdown formatted and simply append `_SHOWNOTES.md` to the existing filename (sans .mp3 of course).
|
Shownote fils are markdown formatted and simply append `_SHOWNOTES.md` to the existing filename (sans .mp3 of course).
|
||||||
|
|
||||||
### Makefile
|
|
||||||
|
|
||||||
there are several commands in the Makefile, for various reasons. (commands are preceded by the `make` command)
|
|
||||||
|
|
||||||
* `all` - also works by just running `make`, compiles go code to executable
|
|
||||||
* `windows` - creates named compiled .exe
|
|
||||||
* `linux` - creates named compiled binary
|
|
||||||
* `install` - installs go dependencies
|
|
||||||
* `docker` - build docker image for running elsewhere
|
|
||||||
* `and run` - build and run the executable (remove .exe in file for \*nix)
|
|
|
@ -2,13 +2,13 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>WR Publish</title>
|
<title>Pogo Publish</title>
|
||||||
<link rel="stylesheet" href="/assets/styles.css">
|
<link rel="stylesheet" href="/assets/styles.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="admin">
|
<div class="admin">
|
||||||
<h1>White Rabbit Publish</h1>
|
<h1>Pogo Publish</h1>
|
||||||
|
|
||||||
<form enctype="multipart/form-data" action="/admin/publish" method="post">
|
<form enctype="multipart/form-data" action="/admin/publish" method="post">
|
||||||
<label for="title">Episode Title</label>
|
<label for="title">Episode Title</label>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<p>White Rabbit licensed under the GPLv3</p>
|
<p>Pogo licensed under the GPLv3</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<p>White Rabbit licensed under the GPLv3 | <a href="/rss">RSS Feed</a>
|
<p>Pogo licensed under the GPLv3 | <a href="/rss">RSS Feed</a>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -60,7 +60,7 @@ func CreateEpisode(w http.ResponseWriter, r *http.Request) {
|
||||||
err := ioutil.WriteFile("./podcasts/" + shownotes, []byte(description), 0644)
|
err := ioutil.WriteFile("./podcasts/" + shownotes, []byte(description), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte("<script>window.location = '/admin#failed';</script>"))
|
w.Write([]byte("<script>window.location = '/admin#failed';</script>"))
|
||||||
panic(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
file, handler, err := r.FormFile("file")
|
file, handler, err := r.FormFile("file")
|
||||||
|
|
|
@ -48,6 +48,10 @@ func watch() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
err = watcher.Add("config.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +71,10 @@ func generate_rss() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
podcasturl := viper.GetString("PodcastUrl")
|
||||||
feed := &feeds.Feed{
|
feed := &feeds.Feed{
|
||||||
Title: viper.GetString("Name"),
|
Title: viper.GetString("Name"),
|
||||||
Link: &feeds.Link{Href: viper.GetString("PodcastUrl")},
|
Link: &feeds.Link{Href: podcasturl},
|
||||||
Description: viper.GetString("Description"),
|
Description: viper.GetString("Description"),
|
||||||
Author: &feeds.Author{Name: viper.GetString("Host"), Email:viper.GetString("Email")},
|
Author: &feeds.Author{Name: viper.GetString("Host"), Email:viper.GetString("Email")},
|
||||||
Created: now,
|
Created: now,
|
||||||
|
@ -90,11 +95,12 @@ func generate_rss() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
size := fmt.Sprintf("%d", file.Size())
|
size := fmt.Sprintf("%d", file.Size())
|
||||||
|
link := podcasturl + "/download/" + file.Name()
|
||||||
feed.Add (
|
feed.Add (
|
||||||
&feeds.Item{
|
&feeds.Item{
|
||||||
Title: title,
|
Title: title,
|
||||||
Link: &feeds.Link{Href: viper.GetString("PodcastUrl") + "/download/" + file.Name(), Length: size, Type: "audio/mpeg"},
|
Link: &feeds.Link{Href: link, Length: size, Type: "audio/mpeg"},
|
||||||
Enclosure: &feeds.Enclosure{Url: viper.GetString("PodcastUrl") + "/download/" + file.Name(), Length: size, Type: "audio/mpeg"},
|
Enclosure: &feeds.Enclosure{Url: link, Length: size, Type: "audio/mpeg"},
|
||||||
Description: string(description),
|
Description: string(description),
|
||||||
Author: &feeds.Author{Name: viper.GetString("Host"), Email: viper.GetString("Email")},
|
Author: &feeds.Author{Name: viper.GetString("Host"), Email: viper.GetString("Email")},
|
||||||
Created: date,
|
Created: date,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* webserver.go
|
/* webserver.go
|
||||||
*
|
*
|
||||||
* This is the webserver handler for White Rabbit, and handles
|
* This is the webserver handler for Pogo, and handles
|
||||||
* all incoming connections, including authentication.
|
* all incoming connections, including authentication.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authenticate user using basic webserver authentication
|
// Authenticate user using basic webserver authentication
|
||||||
|
// @TODO: Replace this with a different for of _more secure_
|
||||||
|
// authentication that we can POST to instead.
|
||||||
/*
|
/*
|
||||||
* Code from stackoverflow by user Timmmm
|
* Code from stackoverflow by user Timmmm
|
||||||
* https://stackoverflow.com/questions/21936332/idiomatic-way-of-requiring-http-basic-auth-in-go/39591234#39591234
|
* https://stackoverflow.com/questions/21936332/idiomatic-way-of-requiring-http-basic-auth-in-go/39591234#39591234
|
||||||
|
@ -63,7 +65,7 @@ func BasicAuth(handler http.HandlerFunc,) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
username := viper.GetString("AdminUsername")
|
username := viper.GetString("AdminUsername")
|
||||||
password := viper.GetString("AdminPassword")
|
password := viper.GetString("AdminPassword")
|
||||||
realm := "Login to White Rabbit admin interface"
|
realm := "Login to Pogo admin interface"
|
||||||
user, pass, ok := r.BasicAuth()
|
user, pass, ok := r.BasicAuth()
|
||||||
|
|
||||||
if !ok || subtle.ConstantTimeCompare([]byte(user), []byte(username)) != 1 || subtle.ConstantTimeCompare([]byte(pass), []byte(password)) != 1 {
|
if !ok || subtle.ConstantTimeCompare([]byte(user), []byte(username)) != 1 || subtle.ConstantTimeCompare([]byte(pass), []byte(password)) != 1 {
|
||||||
|
@ -123,5 +125,6 @@ func main() {
|
||||||
r.HandleFunc("/admin/css", BasicAuth(CustomCss))
|
r.HandleFunc("/admin/css", BasicAuth(CustomCss))
|
||||||
|
|
||||||
// We're live!
|
// We're live!
|
||||||
|
fmt.Println("Listening on port :8000")
|
||||||
log.Fatal(http.ListenAndServe(":8000", r))
|
log.Fatal(http.ListenAndServe(":8000", r))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue