diff --git a/config.json b/config.json index 2c77afc..3910412 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,9 @@ { "baseURL": "http://dvr.linuxrocker.com", "plexPyContext": "/plexpy", - "plexPyAPIKey": "6b707d0439a2449a9bcaed8c6f042de0" + "plexPyAPIKey": "6b707d0439a2449a9bcaed8c6f042de0", + "plexToken": "K1WCALqRK5HVzSQ1J3bM", + "plexHost": "http://172.19.0.105", + "plexPort": 32400, + "telegramToken": "568753422:AAEpsvhrB4RQA4QGEFwutFmTFkE_zjjzHSQ" } \ No newline at end of file diff --git a/pkg/communicator/communicator.go b/pkg/communicator/communicator.go new file mode 100644 index 0000000..211f475 --- /dev/null +++ b/pkg/communicator/communicator.go @@ -0,0 +1 @@ +package communicator diff --git a/pkg/config/config.go b/pkg/config/config.go index 0d49006..9cc6711 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -12,6 +12,10 @@ type Config struct { BaseURL string `json:"baseURL"` PlexPyContext string `json:"plexPyContext"` PlexPyAPIKey string `json:"plexPyAPIKey"` + PlexToken string `json:"plexToken"` + PlexHost string `json:"plexHost"` + PlexPort int `json:"plexPort"` + TelegramToken string `json:"telegramToken"` } //GetConfig gets the configuration values for the api using the file in the supplied configPath. diff --git a/pkg/locator/locator.go b/pkg/locator/locator.go index 40c43ac..b81ea6c 100644 --- a/pkg/locator/locator.go +++ b/pkg/locator/locator.go @@ -2,11 +2,14 @@ package locator import ( "encoding/json" + "encoding/xml" "fmt" "io/ioutil" "log" "net/http" + "sort" "strconv" + "strings" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/config" "git.linuxrocker.com/mattburchett/Housekeeper/pkg/model" @@ -45,7 +48,7 @@ func GetCount(config config.Config, sectionID int) int { } // GetTitles will gather a list of information from the media in the library, based on the previous count. -func GetTitles(config config.Config, sectionID int, days int) string { +func GetTitles(config config.Config, sectionID int, days int) { count := GetCount(config, sectionID) titlesURL := fmt.Sprintf("%s%s%s%s%s%d%s%d", config.BaseURL, config.PlexPyContext, "/api/v2?apikey=", config.PlexPyAPIKey, "&cmd=get_library_media_info§ion_id=", sectionID, "&order_column=last_played&refresh=true&order_dir=asc&length=", count) @@ -75,13 +78,19 @@ func GetTitles(config config.Config, sectionID int, days int) string { } data := titleModel.Response.Data.Data - // titles := make([]string, 0) + titles := make([]string, 0) + ids := make([]int, 0) epoch := util.SubtractedEpoch(days) for _, i := range data { if i.LastPlayed < epoch { - fmt.Println(i.Title) + titles = append(titles, i.Title) + strirk, err := strconv.Atoi(i.RatingKey) + if err != nil { + log.Fatal(err) + } + ids = append(ids, strirk) } if i.LastPlayed < 0 { stri, err := strconv.Atoi(i.AddedAt) @@ -89,11 +98,57 @@ func GetTitles(config config.Config, sectionID int, days int) string { log.Fatal(err) } if int64(stri) < epoch { - fmt.Println(i.Title) + titles = append(titles, i.Title) + strirk, err := strconv.Atoi(i.RatingKey) + if err != nil { + log.Fatal(err) + } + ids = append(ids, strirk) } } } + sort.Strings(titles) - return string(epoch) + LookupFileLocation(config, ids) + + return +} + +func LookupFileLocation(config config.Config, ids []int) { + // fileLocations := 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) + if err != nil { + log.Fatal(err) + } + + 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.XMLPlexAPI{} + xml.Unmarshal(body, &plexModel) + + fileList := strings.Split(plexModel.Video.Media.Part.File, "/") + + fmt.Printf("/%v/%v/%v/%v/%v\n", fileList[1], fileList[2], fileList[3], fileList[4], fileList[5]) + } + + // http://172.19.0.105:32400/library/metadata/9/?X-Plex-Token=K1WCALqRK5HVzSQ1J3bM } diff --git a/pkg/model/locator_model.go b/pkg/model/locator_model.go index e0ce729..807a355 100644 --- a/pkg/model/locator_model.go +++ b/pkg/model/locator_model.go @@ -1,5 +1,7 @@ package model +import "encoding/xml" + // PlexPyLibraryInfo will gather all the library related info. We really just need the count from this... type PlexPyLibraryInfo struct { Response struct { @@ -60,3 +62,267 @@ type PlexPyMediaInfo struct { Result string `json:"result"` } `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"` +} + +// PlexAPI - This contains the information returned from Plex's API +type PlexAPI struct { + MediaContainer struct { + Video struct { + Media struct { + Part struct { + Stream []struct { + ID string `json:"_id"` + StreamType string `json:"_streamType"` + Default string `json:"_default,omitempty"` + Codec string `json:"_codec"` + Index string `json:"_index,omitempty"` + Bitrate string `json:"_bitrate,omitempty"` + Language string `json:"_language"` + LanguageCode string `json:"_languageCode"` + BitDepth string `json:"_bitDepth,omitempty"` + ChromaLocation string `json:"_chromaLocation,omitempty"` + ChromaSubsampling string `json:"_chromaSubsampling,omitempty"` + FrameRate string `json:"_frameRate,omitempty"` + HasScalingMatrix string `json:"_hasScalingMatrix,omitempty"` + Height string `json:"_height,omitempty"` + Level string `json:"_level,omitempty"` + Profile string `json:"_profile,omitempty"` + RefFrames string `json:"_refFrames,omitempty"` + ScanType string `json:"_scanType,omitempty"` + Title string `json:"_title,omitempty"` + Width string `json:"_width,omitempty"` + DisplayTitle string `json:"_displayTitle"` + Selected string `json:"_selected,omitempty"` + Channels string `json:"_channels,omitempty"` + AudioChannelLayout string `json:"_audioChannelLayout,omitempty"` + SamplingRate string `json:"_samplingRate,omitempty"` + Key string `json:"_key,omitempty"` + } `json:"Stream"` + ID string `json:"_id"` + Key string `json:"_key"` + Duration string `json:"_duration"` + File string `json:"_file"` + Size string `json:"_size"` + AudioProfile string `json:"_audioProfile"` + Container string `json:"_container"` + VideoProfile string `json:"_videoProfile"` + } `json:"Part"` + VideoResolution string `json:"_videoResolution"` + ID string `json:"_id"` + Duration string `json:"_duration"` + Bitrate string `json:"_bitrate"` + Width string `json:"_width"` + Height string `json:"_height"` + AspectRatio string `json:"_aspectRatio"` + AudioChannels string `json:"_audioChannels"` + AudioCodec string `json:"_audioCodec"` + VideoCodec string `json:"_videoCodec"` + Container string `json:"_container"` + VideoFrameRate string `json:"_videoFrameRate"` + AudioProfile string `json:"_audioProfile"` + VideoProfile string `json:"_videoProfile"` + } `json:"Media"` + Genre []struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + } `json:"Genre"` + Director struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + } `json:"Director"` + Writer []struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + } `json:"Writer"` + Producer []struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + } `json:"Producer"` + Country struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + } `json:"Country"` + Role []struct { + ID string `json:"_id"` + Filter string `json:"_filter"` + Tag string `json:"_tag"` + Role string `json:"_role"` + Thumb string `json:"_thumb"` + } `json:"Role"` + RatingKey string `json:"_ratingKey"` + Key string `json:"_key"` + GUID string `json:"_guid"` + LibrarySectionTitle string `json:"_librarySectionTitle"` + LibrarySectionID string `json:"_librarySectionID"` + LibrarySectionKey string `json:"_librarySectionKey"` + Studio string `json:"_studio"` + Type string `json:"_type"` + Title string `json:"_title"` + ContentRating string `json:"_contentRating"` + Summary string `json:"_summary"` + Rating string `json:"_rating"` + AudienceRating string `json:"_audienceRating"` + Year string `json:"_year"` + Tagline string `json:"_tagline"` + Thumb string `json:"_thumb"` + Art string `json:"_art"` + Duration string `json:"_duration"` + OriginallyAvailableAt string `json:"_originallyAvailableAt"` + AddedAt string `json:"_addedAt"` + UpdatedAt string `json:"_updatedAt"` + AudienceRatingImage string `json:"_audienceRatingImage"` + ChapterSource string `json:"_chapterSource"` + PrimaryExtraKey string `json:"_primaryExtraKey"` + RatingImage string `json:"_ratingImage"` + } `json:"Video"` + Size string `json:"_size"` + AllowSync string `json:"_allowSync"` + Identifier string `json:"_identifier"` + LibrarySectionID string `json:"_librarySectionID"` + LibrarySectionTitle string `json:"_librarySectionTitle"` + LibrarySectionUUID string `json:"_librarySectionUUID"` + MediaTagPrefix string `json:"_mediaTagPrefix"` + MediaTagVersion string `json:"_mediaTagVersion"` + } `json:"MediaContainer"` +}