pp

package module
v0.0.0-...-be20f81 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2020 License: AGPL-3.0 Imports: 19 Imported by: 0

README

Private Podcast (pp)

Private Podcast is a simple application to serve podcast episodes from a S3 bucket with Google login.

Building and Running

If you have the latest go toolchain installed running go build ./cmd should be enough. To run the application you'll need to set the AWS environmental variables in addition to the configuration provided and documented on the CLI (see cmd/main.go for the variables and their documentation). The AWS variables that are usually needed are AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, the region should be the region of the S3 bucket.

Database

This application requires a Postgres database, by default it connects to a local database. To run a local database for testing you can use docker run -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=pp -p 5432:5432 -it postgres:12.

S3 Bucket

NEVER change the key (name/path) of a podcast in S3, otherwise its GUID will also change, meaning that some podcast applications might show that particular episode multiple times. If you need to rename an episode you can add a metadata title (metadata with key of x-amx-meta-title in the S3 Console) to it. Publishing date cannot be changed currently.

All podcasts in the S3 bucket should be placed in the root, have a .mp3 prefix, and start with the publishing date in YYYY-MM-DD format. For example, a file named 2020-01-27 Hello World!.mp3 will be parsed as podcast episode that was released on the 27th of January in 2020, with a title and description of Hello World!. All files which can't be parsed are skipped.

To add a description to a podcast, another file can be added with .txt suffix. It's name must otherwise be exactly equal, e.g. in the example above the file would be named 2020-01-27 Hello World!.mp3.txt.

License

pp - Private Podcast feed with Single Sign-On
Copyright (C) 2020  Maximilian Remming

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

Documentation

Index

Constants

View Source
const SecretSizeBytes = 36

SecretSizeBytes is the size of the secret in bytes, it should be a multiple of 12 to make sure it's encoded nicely in base64.

Variables

This section is empty.

Functions

func GenerateSecret

func GenerateSecret() string

GenerateSecret generates `SecretSizeBytes` bytes of secure randomness and encodes it with URL safe base64.

Types

type Auth

type Auth interface {
	HandleAuth(http.ResponseWriter, *http.Request, Storage, bool) error
}

type AuthGoogle

type AuthGoogle struct {
	// contains filtered or unexported fields
}

func NewAuthGoogle

func NewAuthGoogle(clientID, clientSecret, authURL string) AuthGoogle

func (AuthGoogle) HandleAuth

func (a AuthGoogle) HandleAuth(w http.ResponseWriter, r *http.Request, storage Storage, noSecureCookie bool) error

type Backend

type Backend interface {
	ListPodcasts() ([]Podcast, error)
	GetPodcast(key string) (Podcast, error)
}

type BackendS3

type BackendS3 struct {
	// contains filtered or unexported fields
}

func NewBackendS3

func NewBackendS3(bucket, logo string) BackendS3
func (b BackendS3) GetLogo() (io.ReadCloser, error)

func (BackendS3) GetPodcast

func (b BackendS3) GetPodcast(key string) (Podcast, error)

func (BackendS3) ListPodcasts

func (b BackendS3) ListPodcasts() ([]Podcast, error)

type Podcast

type Podcast interface {
	Details() PodcastDetails
	HandlePodcast(http.ResponseWriter, *http.Request) error
}

type PodcastDetails

type PodcastDetails struct {
	Key         string
	Title       string
	Published   time.Time
	Size        int64
	Description string
}

type PodcastS3

type PodcastS3 struct {
	// contains filtered or unexported fields
}

func (PodcastS3) Details

func (p PodcastS3) Details() PodcastDetails

func (PodcastS3) HandlePodcast

func (p PodcastS3) HandlePodcast(w http.ResponseWriter, r *http.Request) error

type Storage

type Storage interface {
	Init() error
	CreateUser(userID string) (string, error)
	ValidSecret(secret string) (bool, error)
	LogFeed(secret, referer, userAgent string) error
	LogPodcast(secret, key, referer, userAgent string) error
}

type StoragePostgres

type StoragePostgres struct {
	// contains filtered or unexported fields
}

func NewStoragePostgres

func NewStoragePostgres(connectionString string) (StoragePostgres, error)

func (StoragePostgres) CreateUser

func (s StoragePostgres) CreateUser(userID string) (string, error)

func (StoragePostgres) Init

func (s StoragePostgres) Init() error

func (StoragePostgres) LogFeed

func (s StoragePostgres) LogFeed(secret, referer, userAgent string) error

func (StoragePostgres) LogPodcast

func (s StoragePostgres) LogPodcast(secret, key, referer, userAgent string) error

func (StoragePostgres) ValidSecret

func (s StoragePostgres) ValidSecret(secret string) (bool, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL