app

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2026 License: GPL-3.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TMDBFilmPathPrefix     = "https://www.themoviedb.org/movie/"
	PosterPathPrefix       = "https://image.tmdb.org/t/p/original/"
	LetterboxdIMDBRedirect = "https://www.letterboxd.com/tmdb/"

	DiscordRPCid = "1223146234538360906"
)
View Source
const (
	NumberOfStacks = 5
	StackSize      = 5
)
View Source
const (
	LatestSaveVersion = 0
)
View Source
const LetterboxdUrl = "https://letterboxd.com"
View Source
const Version = "v0.2.3"

Variables

View Source
var (
	Config    config
	ConfigErr error
)
View Source
var (
	ErrMissingPosterPath = errors.New("poster path is missing")
	ErrRetreivingPoster  = errors.New("could not retrieve poster")
)
View Source
var (
	ErrDuplicateList  = errors.New("duplicate list")
	ErrListEmpty      = errors.New("list is empty")
	ErrNoValidFilm    = errors.New("no valid film")
	ErrListNotTracked = errors.New("list not tracked")
)
View Source
var (
	ErrNotEnoughFilms = errors.New("not enough films in watchlist")
	ErrFilmNotFound   = errors.New("film not found")
)
View Source
var (
	ErrBadScrape  error = errors.New("bad scrape")
	ErrInvalidUrl error = errors.New("invalid url")
	ErrNotAFilm   error = errors.New("not a film")
)
View Source
var (
	TMDBClient *tmdb.Client = nil

	ErrNoAPI            = errors.New("could not connect to TMDB api")
	ErrFailedTMDBLookup = errors.New("failed TMDB lookup")
)
View Source
var NWDataPath string

Functions

func ConfigPath

func ConfigPath() string

Returns the expected config file path

func DownloadPoster

func DownloadPoster(fr FilmRecord) (string, error)

Downloads poster given a film record containing a PosterPath in its details. Returns the path the poster was saved to.

func GetUser

func GetUser(username *string, askUser func() string) error

Retrieve username if it has not been set using a variety of means. askUser is a function that can be used to ask the user in some way to enter their username if all else fails. GetUser also saves and loads most recently used username. Returns an error if no username can ultimately be retrieved.

func ReleaseYear

func ReleaseYear(mr tmdb.MovieResult) (int, error)

func ScrapeFilmID

func ScrapeFilmID(rawURL string) (id int, err error)

func SearchFilms

func SearchFilms(query string) ([]tmdb.MovieResult, error)

Queries TMDB for movies matching the given search string.

func TMDBFilm

func TMDBFilm(id int) (*tmdb.MovieDetails, error)

Types

type Application

type Application struct {
	Username     string      // username on letterboxd
	ApiKey       string      // TMDB api key
	ListHeaders  []*FilmList // lists that belong to user on letterboxd (without scrapped films)
	Watchlist    FilmsSet    // users letterboxd watchlist
	WatchedFilms FilmsSet    // users list of watched films on letterboxd

	NWQueue         NextWatch
	TrackedLists    map[string]*FilmList // lists tracked in this program; urls are keys
	FilmStore       FilmStore            // central structure that stores local film information
	UserDataChecked time.Time            // last time watchlist, watched films, etc. were checked

	// ----- tracked processes
	DiscordRPC DiscordRPC
}

func CreateApp

func CreateApp(username string) (*Application, error)

Create application on first startup, scrapping all user information.

func Load

func Load(username string) (*Application, error)

Creates application struct. First tries to load user from save file; otherwise, it creates new user and filmstore.

func (*Application) AddList

func (app *Application) AddList(filmList *FilmList) error

Saves list in map of list tracked by the user.

func (*Application) AddListFromUrl

func (app *Application) AddListFromUrl(url string) error

Starts tracking the list corresponding to the given url.

func (*Application) ApiInit

func (app *Application) ApiInit()

func (*Application) IsListTracked

func (app *Application) IsListTracked(url string) bool

Checks if list is traced by user.

func (*Application) MakeNextWatch

func (app *Application) MakeNextWatch() (NextWatch, error)

Create NextWatch queue data structure, selecting NumberOfStacks*StackSize+1 unwatched films from watchlist at random (the plus one is for the next pick at the top of the queue).

Returns an error if there is not enough unwatched films in the watchlist.

func (*Application) RefreshList

func (app *Application) RefreshList(filmList *FilmList) error

Rescrapes the list films and data from Letterboxd.

func (*Application) RemoveList

func (app *Application) RemoveList(filmList *FilmList) error

Remove list from the map of list traced by the user.

func (*Application) Save

func (app *Application) Save() error

Save application info to file

func (*Application) Shutdown

func (app *Application) Shutdown()

Run application shutdown tasks (e.g., write save).

func (*Application) StartDiscordRPC

func (app *Application) StartDiscordRPC(fr FilmRecord) error

func (*Application) StopDiscordRPC

func (app *Application) StopDiscordRPC()

func (*Application) UpdateUserData

func (app *Application) UpdateUserData(check bool) error

Updates all of the user's watchlist, watched films, and lists

Argument "check," when true, checks whether previous data has expired---if it has not, nothing is done.

type DiscordRPC

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

func (DiscordRPC) String

func (d DiscordRPC) String() string

func (DiscordRPC) Watching

func (d DiscordRPC) Watching() bool

type Film

type Film struct {
	LBxdID int    // letterboxd film id (used as unique identifier here)
	Url    string // letterboxd url
	Title  string // film title
	Year   uint   // release year
}

Struct storing data for film,

func (Film) String

func (f Film) String() string

type FilmList

type FilmList struct {
	Name     string  // name of list on letterboxd
	Desc     string  // description of list
	Url      string  // letterboxd list url
	NumFilms int     // number of films in list
	Ordered  bool    // is the list ordered
	NextFilm *Film   // the next film to be suggested
	Films    []*Film // films in list (can be nil)
	// contains filtered or unexported fields
}

Film list that user might track

func ScrapeFilmList

func ScrapeFilmList(rawURL string) (fl FilmList, err error)

Scraps list name, and film urls from list url.

The list name may be empty if it is not listed on the webpage (e.g., a watchlist).

func ScrapeUserLists added in v0.1.5

func ScrapeUserLists(username string) ([]*FilmList, error)

func (*FilmList) NextWatch

func (fl *FilmList) NextWatch() (Film, error)

Suggest next unwatched film to watch from list.

Returns NextFilm if it has not been watched and it has been set. Otherwise recalculate the next film to watch. If ordered, it is simply the first unwatched film; otherwise, list is shuffled and first unwatched film is selected.

If the list is empty, the function returns ErrListEmpty. If all the films are watched, then ErrNoValidFilm is returned.

func (*FilmList) ToggleOrdered

func (fl *FilmList) ToggleOrdered()

Changed Ordered status; clears NextFilm

type FilmRecord

type FilmRecord struct {
	Film
	TMDBID      int                // tmdb id number
	Details     *tmdb.MovieDetails // film details from tmdb
	ReleaseDate time.Time          // release date (according to tmdb)
	Watched     bool               // film is recorded as watched

	Checked time.Time // last time details were checked
	NRefs   uint      // number of list references
}

func (*FilmRecord) DirectorString added in v0.1.6

func (fd *FilmRecord) DirectorString() string

type FilmStore

type FilmStore struct {
	Films map[int]*FilmRecord // Film records index by letterboxd ids
}

Keeps track of all films that are currently in memory so we do not duplicate scraping TMDB ids and TMDB api calls.

func (*FilmStore) Clean

func (fs *FilmStore) Clean()

Clear film records that are either not referenced or too old.

func (*FilmStore) DeregisterList

func (fs *FilmStore) DeregisterList(filmList *FilmList)

Stop tracking list and decrement ref counts as necessary.

func (*FilmStore) DeregisterSet

func (fs *FilmStore) DeregisterSet(filmSet map[int]*Film)

Stop tracking set and decrement ref counts as necessary.

func (*FilmStore) Lookup

func (fs *FilmStore) Lookup(film Film) (*FilmRecord, error)

Get cached film record, retrieve if necessary

Returns error if it needs to retrieve details and fails.

func (*FilmStore) RegisterList

func (fs *FilmStore) RegisterList(filmList *FilmList)

Add film list to be tracked. Films in registered lists will be saved/stored in save data as long as they have references.

func (*FilmStore) RegisterSet

func (fs *FilmStore) RegisterSet(filmSet map[int]*Film)

Add film set to be tracked (such as watchlist or watched films). Films in registered set will be saved/stored in save data as long as they have references.

type FilmsSet

type FilmsSet map[int]*Film

func (FilmsSet) InSet

func (fs FilmsSet) InSet(film *Film) bool

type NextWatch

type NextWatch struct {
	Stacks [][]*Film
	// contains filtered or unexported fields
}

func (*NextWatch) ClearLastUpdated

func (nw *NextWatch) ClearLastUpdated()

func (*NextWatch) ContainsFilm

func (nw *NextWatch) ContainsFilm(film Film) bool

Checks if Next Watch queue contains a given film (by letterboxd id).

func (*NextWatch) DeleteFilm

func (nw *NextWatch) DeleteFilm(film Film) error

Remove stack from Next Watch queue from given stack and stack index.

func (*NextWatch) Full

func (nw *NextWatch) Full() bool

Checks if all stack positions have a film in them

func (*NextWatch) LastUpdated

func (nw *NextWatch) LastUpdated(i, j int) bool

func (*NextWatch) Positions

func (nw *NextWatch) Positions() iter.Seq2[int, int]

Iterator over valid i, j pairs in Stacks

func (*NextWatch) UpdateWatched

func (nw *NextWatch) UpdateWatched() error

Update Next Watch queue by removing watched films.

type Save

type Save struct {
	Application
	Version int // save version, if format changes are made this will be incremented
}

Jump to

Keyboard shortcuts

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