From 81797f66ca100a508240ce20bc9043a57d8a7721 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 12:20:20 -0600 Subject: [PATCH 01/17] splitting out the eraser model from the locator model, adding library type logic. --- cmd/main.go | 4 + pkg/eraser/eraser.go | 3 - pkg/locator/locator.go | 39 +++++++++ pkg/model/eraser_model.go | 140 ++++++++++++++++++++++++++++++++ pkg/model/locator_model.go | 159 ++++++------------------------------- 5 files changed, 207 insertions(+), 138 deletions(-) create mode 100644 pkg/model/eraser_model.go diff --git a/cmd/main.go b/cmd/main.go index bf25d95..d046b6f 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "log" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/communicator" @@ -37,6 +38,9 @@ func main() { log.Fatal(err) } + libraryType := locator.GetLibraryType(cfg, sectionID) + fmt.Println(libraryType) + ids, titles := locator.GetTitles(cfg, sectionID, days) if check { diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index c9a8f15..bc3e160 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -21,9 +21,6 @@ func LookupFileLocation(config config.Config, ids []int) []string { plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/?X-Plex-Token=", config.PlexToken) req, err := http.NewRequest(http.MethodGet, plexURL, nil) - if err != nil { - log.Fatal(err) - } httpClient := http.Client{} req.Header.Set("User-Agent", "Housekeeper") diff --git a/pkg/locator/locator.go b/pkg/locator/locator.go index ec17c05..be3f1f3 100644 --- a/pkg/locator/locator.go +++ b/pkg/locator/locator.go @@ -2,6 +2,7 @@ package locator import ( "encoding/json" + "encoding/xml" "fmt" "io/ioutil" "log" @@ -14,6 +15,44 @@ import ( "git.linuxrocker.com/mattburchett/Housekeeper/pkg/util" ) +// GetLibraryType checks to see what type the library is. +func GetLibraryType(config config.Config, sectionID int) string { + typeURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/sections/", sectionID, "/?X-Plex-Token=", config.PlexToken) + + req, err := http.NewRequest(http.MethodGet, typeURL, nil) + httpClient := http.Client{} + req.Header.Set("User-Agent", "Housekeeper") + + res, getErr := httpClient.Do(req) + if getErr != nil { + log.Fatal(getErr) + } + + body, readErr := ioutil.ReadAll(res.Body) + if readErr != nil { + log.Fatal(readErr) + } + + if err != nil { + log.Fatal(err) + } + + typeModel := model.XMLPlexLibraryType{} + xml.Unmarshal(body, &typeModel) + + var libraryType string + + if typeModel.Thumb == "/:/resources/movie.png" { + libraryType = "movie" + } else if typeModel.Thumb == "/:/resources/show.png" { + libraryType = "show" + } else { + log.Fatal("Unsupported library type found. This app only supports movies and shows.") + } + + return libraryType +} + // GetCount will gather a count of media in a specific library, required for GetTitles. func GetCount(config config.Config, sectionID int) int { countURL := fmt.Sprintf("%s%s%s%s%s%d", config.BaseURL, config.PlexPyContext, "/api/v2?apikey=", config.PlexPyAPIKey, "&cmd=get_library§ion_id=", sectionID) diff --git a/pkg/model/eraser_model.go b/pkg/model/eraser_model.go new file mode 100644 index 0000000..ed7e883 --- /dev/null +++ b/pkg/model/eraser_model.go @@ -0,0 +1,140 @@ +package model + +import "encoding/xml" + +// XMLPlexAPI - This is the XML version of the struct below it. +type XMLPlexAPI struct { + XMLName xml.Name `xml:"MediaContainer"` + Text string `xml:",chardata"` + Size string `xml:"size,attr"` + AllowSync string `xml:"allowSync,attr"` + Identifier string `xml:"identifier,attr"` + LibrarySectionID string `xml:"librarySectionID,attr"` + LibrarySectionTitle string `xml:"librarySectionTitle,attr"` + LibrarySectionUUID string `xml:"librarySectionUUID,attr"` + MediaTagPrefix string `xml:"mediaTagPrefix,attr"` + MediaTagVersion string `xml:"mediaTagVersion,attr"` + Video struct { + Text string `xml:",chardata"` + RatingKey string `xml:"ratingKey,attr"` + Key string `xml:"key,attr"` + GUID string `xml:"guid,attr"` + LibrarySectionTitle string `xml:"librarySectionTitle,attr"` + LibrarySectionID string `xml:"librarySectionID,attr"` + LibrarySectionKey string `xml:"librarySectionKey,attr"` + Studio string `xml:"studio,attr"` + Type string `xml:"type,attr"` + Title string `xml:"title,attr"` + ContentRating string `xml:"contentRating,attr"` + Summary string `xml:"summary,attr"` + Rating string `xml:"rating,attr"` + AudienceRating string `xml:"audienceRating,attr"` + Year string `xml:"year,attr"` + Tagline string `xml:"tagline,attr"` + Thumb string `xml:"thumb,attr"` + Art string `xml:"art,attr"` + Duration string `xml:"duration,attr"` + OriginallyAvailableAt string `xml:"originallyAvailableAt,attr"` + AddedAt string `xml:"addedAt,attr"` + UpdatedAt string `xml:"updatedAt,attr"` + AudienceRatingImage string `xml:"audienceRatingImage,attr"` + ChapterSource string `xml:"chapterSource,attr"` + PrimaryExtraKey string `xml:"primaryExtraKey,attr"` + RatingImage string `xml:"ratingImage,attr"` + Media struct { + Text string `xml:",chardata"` + VideoResolution string `xml:"videoResolution,attr"` + ID string `xml:"id,attr"` + Duration string `xml:"duration,attr"` + Bitrate string `xml:"bitrate,attr"` + Width string `xml:"width,attr"` + Height string `xml:"height,attr"` + AspectRatio string `xml:"aspectRatio,attr"` + AudioChannels string `xml:"audioChannels,attr"` + AudioCodec string `xml:"audioCodec,attr"` + VideoCodec string `xml:"videoCodec,attr"` + Container string `xml:"container,attr"` + VideoFrameRate string `xml:"videoFrameRate,attr"` + AudioProfile string `xml:"audioProfile,attr"` + VideoProfile string `xml:"videoProfile,attr"` + Part struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Key string `xml:"key,attr"` + Duration string `xml:"duration,attr"` + File string `xml:"file,attr"` + Size string `xml:"size,attr"` + AudioProfile string `xml:"audioProfile,attr"` + Container string `xml:"container,attr"` + VideoProfile string `xml:"videoProfile,attr"` + Stream []struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + StreamType string `xml:"streamType,attr"` + Default string `xml:"default,attr"` + Codec string `xml:"codec,attr"` + Index string `xml:"index,attr"` + Bitrate string `xml:"bitrate,attr"` + Language string `xml:"language,attr"` + LanguageCode string `xml:"languageCode,attr"` + BitDepth string `xml:"bitDepth,attr"` + ChromaLocation string `xml:"chromaLocation,attr"` + ChromaSubsampling string `xml:"chromaSubsampling,attr"` + FrameRate string `xml:"frameRate,attr"` + HasScalingMatrix string `xml:"hasScalingMatrix,attr"` + Height string `xml:"height,attr"` + Level string `xml:"level,attr"` + Profile string `xml:"profile,attr"` + RefFrames string `xml:"refFrames,attr"` + ScanType string `xml:"scanType,attr"` + Title string `xml:"title,attr"` + Width string `xml:"width,attr"` + DisplayTitle string `xml:"displayTitle,attr"` + Selected string `xml:"selected,attr"` + Channels string `xml:"channels,attr"` + AudioChannelLayout string `xml:"audioChannelLayout,attr"` + SamplingRate string `xml:"samplingRate,attr"` + Key string `xml:"key,attr"` + } `xml:"Stream"` + } `xml:"Part"` + } `xml:"Media"` + Genre []struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + } `xml:"Genre"` + Director struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + } `xml:"Director"` + Writer []struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + } `xml:"Writer"` + Producer []struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + } `xml:"Producer"` + Country struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + } `xml:"Country"` + Role []struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Filter string `xml:"filter,attr"` + Tag string `xml:"tag,attr"` + Role string `xml:"role,attr"` + Thumb string `xml:"thumb,attr"` + } `xml:"Role"` + } `xml:"Video"` +} diff --git a/pkg/model/locator_model.go b/pkg/model/locator_model.go index b8a0e44..b3308e7 100644 --- a/pkg/model/locator_model.go +++ b/pkg/model/locator_model.go @@ -63,139 +63,28 @@ type PlexPyMediaInfo struct { } `json:"response"` } -// XMLPlexAPI - This is the XML version of the struct below it. -type XMLPlexAPI struct { - XMLName xml.Name `xml:"MediaContainer"` - Text string `xml:",chardata"` - Size string `xml:"size,attr"` - AllowSync string `xml:"allowSync,attr"` - Identifier string `xml:"identifier,attr"` - LibrarySectionID string `xml:"librarySectionID,attr"` - LibrarySectionTitle string `xml:"librarySectionTitle,attr"` - LibrarySectionUUID string `xml:"librarySectionUUID,attr"` - MediaTagPrefix string `xml:"mediaTagPrefix,attr"` - MediaTagVersion string `xml:"mediaTagVersion,attr"` - Video struct { - Text string `xml:",chardata"` - RatingKey string `xml:"ratingKey,attr"` - Key string `xml:"key,attr"` - GUID string `xml:"guid,attr"` - LibrarySectionTitle string `xml:"librarySectionTitle,attr"` - LibrarySectionID string `xml:"librarySectionID,attr"` - LibrarySectionKey string `xml:"librarySectionKey,attr"` - Studio string `xml:"studio,attr"` - Type string `xml:"type,attr"` - Title string `xml:"title,attr"` - ContentRating string `xml:"contentRating,attr"` - Summary string `xml:"summary,attr"` - Rating string `xml:"rating,attr"` - AudienceRating string `xml:"audienceRating,attr"` - Year string `xml:"year,attr"` - Tagline string `xml:"tagline,attr"` - Thumb string `xml:"thumb,attr"` - Art string `xml:"art,attr"` - Duration string `xml:"duration,attr"` - OriginallyAvailableAt string `xml:"originallyAvailableAt,attr"` - AddedAt string `xml:"addedAt,attr"` - UpdatedAt string `xml:"updatedAt,attr"` - AudienceRatingImage string `xml:"audienceRatingImage,attr"` - ChapterSource string `xml:"chapterSource,attr"` - PrimaryExtraKey string `xml:"primaryExtraKey,attr"` - RatingImage string `xml:"ratingImage,attr"` - Media struct { - Text string `xml:",chardata"` - VideoResolution string `xml:"videoResolution,attr"` - ID string `xml:"id,attr"` - Duration string `xml:"duration,attr"` - Bitrate string `xml:"bitrate,attr"` - Width string `xml:"width,attr"` - Height string `xml:"height,attr"` - AspectRatio string `xml:"aspectRatio,attr"` - AudioChannels string `xml:"audioChannels,attr"` - AudioCodec string `xml:"audioCodec,attr"` - VideoCodec string `xml:"videoCodec,attr"` - Container string `xml:"container,attr"` - VideoFrameRate string `xml:"videoFrameRate,attr"` - AudioProfile string `xml:"audioProfile,attr"` - VideoProfile string `xml:"videoProfile,attr"` - Part struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Key string `xml:"key,attr"` - Duration string `xml:"duration,attr"` - File string `xml:"file,attr"` - Size string `xml:"size,attr"` - AudioProfile string `xml:"audioProfile,attr"` - Container string `xml:"container,attr"` - VideoProfile string `xml:"videoProfile,attr"` - Stream []struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - StreamType string `xml:"streamType,attr"` - Default string `xml:"default,attr"` - Codec string `xml:"codec,attr"` - Index string `xml:"index,attr"` - Bitrate string `xml:"bitrate,attr"` - Language string `xml:"language,attr"` - LanguageCode string `xml:"languageCode,attr"` - BitDepth string `xml:"bitDepth,attr"` - ChromaLocation string `xml:"chromaLocation,attr"` - ChromaSubsampling string `xml:"chromaSubsampling,attr"` - FrameRate string `xml:"frameRate,attr"` - HasScalingMatrix string `xml:"hasScalingMatrix,attr"` - Height string `xml:"height,attr"` - Level string `xml:"level,attr"` - Profile string `xml:"profile,attr"` - RefFrames string `xml:"refFrames,attr"` - ScanType string `xml:"scanType,attr"` - Title string `xml:"title,attr"` - Width string `xml:"width,attr"` - DisplayTitle string `xml:"displayTitle,attr"` - Selected string `xml:"selected,attr"` - Channels string `xml:"channels,attr"` - AudioChannelLayout string `xml:"audioChannelLayout,attr"` - SamplingRate string `xml:"samplingRate,attr"` - Key string `xml:"key,attr"` - } `xml:"Stream"` - } `xml:"Part"` - } `xml:"Media"` - Genre []struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - } `xml:"Genre"` - Director struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - } `xml:"Director"` - Writer []struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - } `xml:"Writer"` - Producer []struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - } `xml:"Producer"` - Country struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - } `xml:"Country"` - Role []struct { - Text string `xml:",chardata"` - ID string `xml:"id,attr"` - Filter string `xml:"filter,attr"` - Tag string `xml:"tag,attr"` - Role string `xml:"role,attr"` - Thumb string `xml:"thumb,attr"` - } `xml:"Role"` - } `xml:"Video"` +type XMLPlexLibraryType struct { + XMLName xml.Name `xml:"MediaContainer"` + Text string `xml:",chardata"` + Size string `xml:"size,attr"` + AllowSync string `xml:"allowSync,attr"` + Art string `xml:"art,attr"` + Content string `xml:"content,attr"` + Identifier string `xml:"identifier,attr"` + LibrarySectionID string `xml:"librarySectionID,attr"` + MediaTagPrefix string `xml:"mediaTagPrefix,attr"` + MediaTagVersion string `xml:"mediaTagVersion,attr"` + Nocache string `xml:"nocache,attr"` + Thumb string `xml:"thumb,attr"` + Title1 string `xml:"title1,attr"` + ViewGroup string `xml:"viewGroup,attr"` + ViewMode string `xml:"viewMode,attr"` + Directory []struct { + Text string `xml:",chardata"` + Key string `xml:"key,attr"` + Title string `xml:"title,attr"` + Secondary string `xml:"secondary,attr"` + Prompt string `xml:"prompt,attr"` + Search string `xml:"search,attr"` + } `xml:"Directory"` } From b6b5814588d8ea1cb6ffa3af7e18302db5f4672c Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 13:39:15 -0600 Subject: [PATCH 02/17] More tweaks --- cmd/main.go | 18 +++++++++++------- pkg/eraser/eraser.go | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index d046b6f..ba5923d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,7 +2,6 @@ package main import ( "flag" - "fmt" "log" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/communicator" @@ -39,7 +38,6 @@ func main() { } libraryType := locator.GetLibraryType(cfg, sectionID) - fmt.Println(libraryType) ids, titles := locator.GetTitles(cfg, sectionID, days) @@ -51,11 +49,17 @@ func main() { } if delete { - files := eraser.LookupFileLocation(cfg, ids) - err = eraser.DeleteMedia(delete, files) - if err != nil { - log.Println(err) + if libraryType == "movie" { + files := eraser.LookupFileLocation(cfg, ids) + err = eraser.DeleteMovies(delete, files) + if err != nil { + log.Println(err) + } + // } else if libraryType == "show" { + // err = eraser.DeleteTVShows() + // if err != nil { + // log.Println(err) + // } } } - } diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index bc3e160..0209faf 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -45,8 +45,8 @@ func LookupFileLocation(config config.Config, ids []int) []string { return fileList } -// DeleteMedia will actually perform the deletion. -func DeleteMedia(delete bool, files []string) error { +// DeleteMovies will actually perform the deletion. +func DeleteMovies(delete bool, files []string) error { var err error if delete { for _, i := range files { From b175b02b87a7ce21d76349deaa32f395e4b096ee Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 13:50:47 -0600 Subject: [PATCH 03/17] Test --- cmd/main.go | 12 ++--- pkg/eraser/eraser.go | 43 ++++++++++++++++-- pkg/model/eraser_model.go | 96 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 140 insertions(+), 11 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index ba5923d..c241282 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "log" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/communicator" @@ -48,18 +49,17 @@ func main() { } } + files := eraser.LookupTVFileLocation(cfg, ids) + fmt.Printf("%v\n", files) + if delete { if libraryType == "movie" { - files := eraser.LookupFileLocation(cfg, ids) + files := eraser.LookupMovieFileLocation(cfg, ids) err = eraser.DeleteMovies(delete, files) if err != nil { log.Println(err) } - // } else if libraryType == "show" { - // err = eraser.DeleteTVShows() - // if err != nil { - // log.Println(err) - // } + } else if libraryType == "show" { } } } diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 0209faf..ba40f0c 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -13,8 +13,8 @@ import ( "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" ) -// LookupFileLocation will gather a list of Information based on IDs returned by locator.GetTitles -func LookupFileLocation(config config.Config, ids []int) []string { +// LookupMovieFileLocation will gather a list of Information based on IDs returned by locator.GetTitles +func LookupMovieFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) for _, i := range ids { @@ -38,13 +38,50 @@ func LookupFileLocation(config config.Config, ids []int) []string { if err != nil { log.Fatal(err) } - plexModel := model.XMLPlexAPI{} + plexModel := model.XMLPlexMovieAPI{} xml.Unmarshal(body, &plexModel) fileList = append(fileList, filepath.Dir(plexModel.Video.Media.Part.File)) } return fileList } +// LookupTVFileLocation will gather a list of Information based on IDs returned by locator.GetTitles +func LookupTVFileLocation(config config.Config, ids []int) []string { + fileList := make([]string, 0) + + for _, i := range ids { + plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/?X-Plex-Token=", config.PlexToken) + + req, err := http.NewRequest(http.MethodGet, plexURL, nil) + + httpClient := http.Client{} + req.Header.Set("User-Agent", "Housekeeper") + + res, getErr := httpClient.Do(req) + if getErr != nil { + log.Fatal(getErr) + } + + body, readErr := ioutil.ReadAll(res.Body) + if readErr != nil { + log.Fatal(readErr) + } + + if err != nil { + log.Fatal(err) + } + plexModel := model.XMLPlexTVAPI{} + xml.Unmarshal(body, &plexModel) + + plexTV := plexModel.Video + + for _, i := range plexTV { + fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + } + } + return fileList +} + // DeleteMovies will actually perform the deletion. func DeleteMovies(delete bool, files []string) error { var err error diff --git a/pkg/model/eraser_model.go b/pkg/model/eraser_model.go index ed7e883..a79a5f1 100644 --- a/pkg/model/eraser_model.go +++ b/pkg/model/eraser_model.go @@ -2,8 +2,8 @@ package model import "encoding/xml" -// XMLPlexAPI - This is the XML version of the struct below it. -type XMLPlexAPI struct { +// XMLPlexMovieAPI - This is the XML version of the Library. +type XMLPlexMovieAPI struct { XMLName xml.Name `xml:"MediaContainer"` Text string `xml:",chardata"` Size string `xml:"size,attr"` @@ -138,3 +138,95 @@ type XMLPlexAPI struct { } `xml:"Role"` } `xml:"Video"` } + +// XMLPlexTVAPI - This is the XML version of the Library. +type XMLPlexTVAPI struct { + XMLName xml.Name `xml:"MediaContainer"` + Text string `xml:",chardata"` + Size string `xml:"size,attr"` + AllowSync string `xml:"allowSync,attr"` + Art string `xml:"art,attr"` + Banner string `xml:"banner,attr"` + Identifier string `xml:"identifier,attr"` + Key string `xml:"key,attr"` + LibrarySectionID string `xml:"librarySectionID,attr"` + LibrarySectionTitle string `xml:"librarySectionTitle,attr"` + LibrarySectionUUID string `xml:"librarySectionUUID,attr"` + MediaTagPrefix string `xml:"mediaTagPrefix,attr"` + MediaTagVersion string `xml:"mediaTagVersion,attr"` + MixedParents string `xml:"mixedParents,attr"` + Nocache string `xml:"nocache,attr"` + ParentIndex string `xml:"parentIndex,attr"` + ParentTitle string `xml:"parentTitle,attr"` + ParentYear string `xml:"parentYear,attr"` + Theme string `xml:"theme,attr"` + Title1 string `xml:"title1,attr"` + Title2 string `xml:"title2,attr"` + ViewGroup string `xml:"viewGroup,attr"` + ViewMode string `xml:"viewMode,attr"` + Video []struct { + Text string `xml:",chardata"` + RatingKey string `xml:"ratingKey,attr"` + Key string `xml:"key,attr"` + ParentRatingKey string `xml:"parentRatingKey,attr"` + GrandparentRatingKey string `xml:"grandparentRatingKey,attr"` + Studio string `xml:"studio,attr"` + Type string `xml:"type,attr"` + Title string `xml:"title,attr"` + GrandparentKey string `xml:"grandparentKey,attr"` + ParentKey string `xml:"parentKey,attr"` + GrandparentTitle string `xml:"grandparentTitle,attr"` + ParentTitle string `xml:"parentTitle,attr"` + ContentRating string `xml:"contentRating,attr"` + Summary string `xml:"summary,attr"` + Index string `xml:"index,attr"` + ParentIndex string `xml:"parentIndex,attr"` + Rating string `xml:"rating,attr"` + Year string `xml:"year,attr"` + Thumb string `xml:"thumb,attr"` + Art string `xml:"art,attr"` + ParentThumb string `xml:"parentThumb,attr"` + GrandparentThumb string `xml:"grandparentThumb,attr"` + GrandparentArt string `xml:"grandparentArt,attr"` + GrandparentTheme string `xml:"grandparentTheme,attr"` + Duration string `xml:"duration,attr"` + OriginallyAvailableAt string `xml:"originallyAvailableAt,attr"` + AddedAt string `xml:"addedAt,attr"` + UpdatedAt string `xml:"updatedAt,attr"` + TitleSort string `xml:"titleSort,attr"` + Media struct { + Text string `xml:",chardata"` + VideoResolution string `xml:"videoResolution,attr"` + ID string `xml:"id,attr"` + Duration string `xml:"duration,attr"` + Bitrate string `xml:"bitrate,attr"` + Width string `xml:"width,attr"` + Height string `xml:"height,attr"` + AspectRatio string `xml:"aspectRatio,attr"` + AudioChannels string `xml:"audioChannels,attr"` + AudioCodec string `xml:"audioCodec,attr"` + VideoCodec string `xml:"videoCodec,attr"` + Container string `xml:"container,attr"` + VideoFrameRate string `xml:"videoFrameRate,attr"` + VideoProfile string `xml:"videoProfile,attr"` + Part struct { + Text string `xml:",chardata"` + ID string `xml:"id,attr"` + Key string `xml:"key,attr"` + Duration string `xml:"duration,attr"` + File string `xml:"file,attr"` + Size string `xml:"size,attr"` + Container string `xml:"container,attr"` + VideoProfile string `xml:"videoProfile,attr"` + } `xml:"Part"` + } `xml:"Media"` + Director struct { + Text string `xml:",chardata"` + Tag string `xml:"tag,attr"` + } `xml:"Director"` + Writer []struct { + Text string `xml:",chardata"` + Tag string `xml:"tag,attr"` + } `xml:"Writer"` + } `xml:"Video"` +} From 91c22140822861bd112a389a56bfb0c299b4ec36 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 13:51:47 -0600 Subject: [PATCH 04/17] blah --- pkg/eraser/eraser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index ba40f0c..56c6f33 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -50,7 +50,7 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) for _, i := range ids { - plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/?X-Plex-Token=", config.PlexToken) + plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/allLeaves/?X-Plex-Token=", config.PlexToken) req, err := http.NewRequest(http.MethodGet, plexURL, nil) From 8997e6ae1ace11b29bf51b019acf1520d8b6e6c6 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:05:51 -0600 Subject: [PATCH 05/17] test --- pkg/eraser/eraser.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 56c6f33..ece7b99 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "path/filepath" + "sort" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/config" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" @@ -76,7 +77,10 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + count := sort.SearchStrings(fileList, i.Media.Part.File) + if count == 0 { + fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + } } } return fileList From 8330101154fd49f5202bfe42d279a61a926e9436 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:14:40 -0600 Subject: [PATCH 06/17] test --- pkg/eraser/eraser.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index ece7b99..9f2c335 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -8,7 +8,6 @@ import ( "net/http" "os" "path/filepath" - "sort" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/config" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" @@ -49,6 +48,7 @@ func LookupMovieFileLocation(config config.Config, ids []int) []string { // LookupTVFileLocation will gather a list of Information based on IDs returned by locator.GetTitles func LookupTVFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) + results := make([]string, 0) for _, i := range ids { plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/allLeaves/?X-Plex-Token=", config.PlexToken) @@ -77,13 +77,25 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - count := sort.SearchStrings(fileList, i.Media.Part.File) - if count == 0 { - fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + } + + for _, v := range fileList { + if !isValueInList(v, fileList) { + results = append(results, v) } } } - return fileList + return results +} + +func isValueInList(value string, list []string) bool { + for _, v := range list { + if v == value { + return true + } + } + return false } // DeleteMovies will actually perform the deletion. From bba80e30050659de4143309c625e17d9e3119d4b Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:16:38 -0600 Subject: [PATCH 07/17] test --- pkg/eraser/eraser.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 9f2c335..126e8da 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -81,7 +81,8 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { } for _, v := range fileList { - if !isValueInList(v, fileList) { + bool := isValueInList(v, fileList) + if !bool { results = append(results, v) } } From 267a891e4de1f8e2fedf970b8084f75134f4a14f Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:16:50 -0600 Subject: [PATCH 08/17] test --- pkg/eraser/eraser.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 126e8da..01b4d38 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -81,8 +81,8 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { } for _, v := range fileList { - bool := isValueInList(v, fileList) - if !bool { + boolean := isValueInList(v, fileList) + if !boolean { results = append(results, v) } } From 31dc49eae4940546f5ff1fc44f1b237121ae8a57 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:20:34 -0600 Subject: [PATCH 09/17] test --- pkg/eraser/eraser.go | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 01b4d38..317b2a1 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -11,6 +11,7 @@ import ( "git.linuxrocker.com/mattburchett/Housekeeper/pkg/config" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" + "github.com/forestgiant/sliceutil" ) // LookupMovieFileLocation will gather a list of Information based on IDs returned by locator.GetTitles @@ -48,7 +49,6 @@ func LookupMovieFileLocation(config config.Config, ids []int) []string { // LookupTVFileLocation will gather a list of Information based on IDs returned by locator.GetTitles func LookupTVFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) - results := make([]string, 0) for _, i := range ids { plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/allLeaves/?X-Plex-Token=", config.PlexToken) @@ -77,17 +77,13 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) - } - - for _, v := range fileList { - boolean := isValueInList(v, fileList) - if !boolean { - results = append(results, v) + if sliceutil.Contains(fileList, i) { + fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) } } + } - return results + return fileList } func isValueInList(value string, list []string) bool { From f890d7f0eedce2f90f84ebdd05e77eeb3e48cef1 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:21:03 -0600 Subject: [PATCH 10/17] Oops, typo. --- pkg/eraser/eraser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 317b2a1..e080559 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -77,7 +77,7 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - if sliceutil.Contains(fileList, i) { + if !sliceutil.Contains(fileList, i) { fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) } } From b86a80b00130923397ceee9a9fb842c495990ecc Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:22:05 -0600 Subject: [PATCH 11/17] Another Typo --- pkg/eraser/eraser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index e080559..48befa6 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -77,7 +77,7 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - if !sliceutil.Contains(fileList, i) { + if !sliceutil.Contains(fileList, i.Media.Part.File) { fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) } } From 7c2af867b0a8f3288bbf9480de5d24d0d76f74cb Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:23:03 -0600 Subject: [PATCH 12/17] test --- pkg/eraser/eraser.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 48befa6..afe99e6 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -77,7 +77,9 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - if !sliceutil.Contains(fileList, i.Media.Part.File) { + if sliceutil.Contains(fileList, i.Media.Part.File) { + fmt.Println("Already exists.") + } else { fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) } } From cbafaa57818da8a88117a9c376e8a15d27978dd9 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:26:47 -0600 Subject: [PATCH 13/17] test --- pkg/eraser/eraser.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index afe99e6..c539304 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -11,7 +11,6 @@ import ( "git.linuxrocker.com/mattburchett/Housekeeper/pkg/config" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" - "github.com/forestgiant/sliceutil" ) // LookupMovieFileLocation will gather a list of Information based on IDs returned by locator.GetTitles @@ -49,6 +48,7 @@ func LookupMovieFileLocation(config config.Config, ids []int) []string { // LookupTVFileLocation will gather a list of Information based on IDs returned by locator.GetTitles func LookupTVFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) + m := make(map[string]bool) for _, i := range ids { plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/allLeaves/?X-Plex-Token=", config.PlexToken) @@ -77,9 +77,9 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { plexTV := plexModel.Video for _, i := range plexTV { - if sliceutil.Contains(fileList, i.Media.Part.File) { - fmt.Println("Already exists.") - } else { + f := i.Media.Part.File + if _, ok := m[f]; !ok { + m[f] = true fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) } } From 0a8b11e1545fc17a491932d0ed425ec0c14a6202 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:28:37 -0600 Subject: [PATCH 14/17] test --- pkg/eraser/eraser.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index c539304..e4d77c5 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -75,12 +75,16 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { xml.Unmarshal(body, &plexModel) plexTV := plexModel.Video + results := make([]string, 0) for _, i := range plexTV { - f := i.Media.Part.File - if _, ok := m[f]; !ok { - m[f] = true - fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) + } + + for _, r := range fileList { + if _, ok := m[r]; !ok { + m[r] = true + results = append(results, r) } } From b0d51ad15eeb15ab1e6bc829fd6e66576f549254 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:28:51 -0600 Subject: [PATCH 15/17] fixing return --- pkg/eraser/eraser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index e4d77c5..4e80b72 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -89,7 +89,7 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { } } - return fileList + return results } func isValueInList(value string, list []string) bool { From 9cfd5c427493e40542195f2e1ac79024af52ca7e Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 14:29:14 -0600 Subject: [PATCH 16/17] fixing --- pkg/eraser/eraser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 4e80b72..1f790b8 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -49,6 +49,7 @@ func LookupMovieFileLocation(config config.Config, ids []int) []string { func LookupTVFileLocation(config config.Config, ids []int) []string { fileList := make([]string, 0) m := make(map[string]bool) + results := make([]string, 0) for _, i := range ids { plexURL := fmt.Sprintf("%s:%d%s%d%s%s", config.PlexHost, config.PlexPort, "/library/metadata/", i, "/allLeaves/?X-Plex-Token=", config.PlexToken) @@ -75,7 +76,6 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { xml.Unmarshal(body, &plexModel) plexTV := plexModel.Video - results := make([]string, 0) for _, i := range plexTV { fileList = append(fileList, filepath.Dir(filepath.Dir(i.Media.Part.File))) From f381b5421e45c4892352a1c38cd9cd99da4f4587 Mon Sep 17 00:00:00 2001 From: Matt Burchett Date: Tue, 20 Nov 2018 17:07:22 -0600 Subject: [PATCH 17/17] Cleanup --- cmd/main.go | 11 ++++++----- pkg/eraser/eraser.go | 13 ++----------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index c241282..483e209 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,7 +2,6 @@ package main import ( "flag" - "fmt" "log" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/communicator" @@ -49,17 +48,19 @@ func main() { } } - files := eraser.LookupTVFileLocation(cfg, ids) - fmt.Printf("%v\n", files) - if delete { if libraryType == "movie" { files := eraser.LookupMovieFileLocation(cfg, ids) - err = eraser.DeleteMovies(delete, files) + err = eraser.DeleteFiles(delete, files) if err != nil { log.Println(err) } } else if libraryType == "show" { + files := eraser.LookupTVFileLocation(cfg, ids) + err = eraser.DeleteFiles(delete, files) + if err != nil { + log.Println(err) + } } } } diff --git a/pkg/eraser/eraser.go b/pkg/eraser/eraser.go index 1f790b8..197e24c 100644 --- a/pkg/eraser/eraser.go +++ b/pkg/eraser/eraser.go @@ -92,17 +92,8 @@ func LookupTVFileLocation(config config.Config, ids []int) []string { return results } -func isValueInList(value string, list []string) bool { - for _, v := range list { - if v == value { - return true - } - } - return false -} - -// DeleteMovies will actually perform the deletion. -func DeleteMovies(delete bool, files []string) error { +// DeleteFiles will actually perform the deletion. +func DeleteFiles(delete bool, files []string) error { var err error if delete { for _, i := range files {