diff --git a/apiGo/api/TVShows.go b/apiGo/api/TVShows.go index 573459c..d536938 100644 --- a/apiGo/api/TVShows.go +++ b/apiGo/api/TVShows.go @@ -72,4 +72,21 @@ WHERE tvshow_episodes.id=%d`, le.ID) return jsonify(ret) }) + + var rtn struct { + Id int + } + AddHandler("readThumbnail", TVShowNode, &rtn, func() []byte { + var pic []byte + + query := fmt.Sprintf("SELECT thumbnail FROM tvshow WHERE id=%d", rtn.Id) + + err := database.QueryRow(query).Scan(&pic) + if err != nil { + fmt.Printf("the thumbnail of movie id %d couldn't be found", rtn.Id) + return nil + } + + return pic + }) } diff --git a/apiGo/api/Video.go b/apiGo/api/Video.go index e2e7391..9ddca40 100644 --- a/apiGo/api/Video.go +++ b/apiGo/api/Video.go @@ -44,7 +44,7 @@ func getVideoHandlers() { AddHandler("readThumbnail", VideoNode, &rtn, func() []byte { var pic []byte - query := fmt.Sprintf("SELECT thumbnail FROM videos WHERE movie_id='%d'", rtn.Movieid) + query := fmt.Sprintf("SELECT thumbnail FROM videos WHERE movie_id=%d", rtn.Movieid) err := database.QueryRow(query).Scan(&pic) if err != nil { diff --git a/apiGo/main.go b/apiGo/main.go index 0b52cb2..1c46361 100644 --- a/apiGo/main.go +++ b/apiGo/main.go @@ -9,12 +9,15 @@ import ( "openmediacenter/apiGo/database" "openmediacenter/apiGo/static" "openmediacenter/apiGo/videoparser" + "openmediacenter/apiGo/videoparser/tmdb" ) func main() { fmt.Println("init OpenMediaCenter server") port := 8081 + tmdb.SearchTVShow("Arrow") + db, verbose, pathPrefix := handleCommandLineArguments() // todo some verbosity logger or sth diff --git a/apiGo/videoparser/ReIndexTVShows.go b/apiGo/videoparser/ReIndexTVShows.go index efb70f6..7b7392e 100644 --- a/apiGo/videoparser/ReIndexTVShows.go +++ b/apiGo/videoparser/ReIndexTVShows.go @@ -4,6 +4,7 @@ import ( "fmt" "openmediacenter/apiGo/api/types" "openmediacenter/apiGo/database" + "openmediacenter/apiGo/videoparser/tmdb" "regexp" "strconv" "strings" @@ -23,8 +24,8 @@ func startTVShowReindex(files []Show, sett types.SettingsType) { } func insertEpisodesIfNotExisting(show Show) { - query := fmt.Sprintf("SELECT tvshow_episodes.name, season, episode FROM tvshow_episodes JOIN tvshow t on t.id = tvshow_episodes.tvshow_id WHERE t.name='%s'", show.Name) - rows := database.Query(query) + query := "SELECT tvshow_episodes.name, season, episode FROM tvshow_episodes JOIN tvshow t on t.id = tvshow_episodes.tvshow_id WHERE t.name=?" + rows := database.Query(query, show.Name) var dbepisodes []string for rows.Next() { @@ -47,7 +48,7 @@ func insertEpisodesIfNotExisting(show Show) { } fmt.Println("diff is...") - fmt.Println(diff) + fmt.Println(len(diff)) } func insertEpisode(path string, ShowName string) { @@ -55,21 +56,27 @@ func insertEpisode(path string, ShowName string) { episodeRegex := regexp.MustCompile("E[0-9][0-9]") matchENDPattern := regexp.MustCompile(" S[0-9][0-9]E[0-9][0-9].+$") - seasonStr := seasonRegex.FindString(path)[1:] - episodeStr := episodeRegex.FindString(path)[1:] + seasonStr := seasonRegex.FindString(path) + episodeStr := episodeRegex.FindString(path) extString := matchENDPattern.FindString(path) + // handle invalid matches + if len(seasonStr) != 3 || len(episodeStr) != 3 || len(extString) < 8 { + fmt.Printf("Error inserting episode: %s -- %s/%s/%s\n", path, seasonStr, episodeStr, extString) + return + } + name := strings.TrimSuffix(path, extString) - season, err := strconv.ParseInt(seasonStr, 10, 8) - episode, err := strconv.ParseInt(episodeStr, 10, 8) + season, err := strconv.ParseInt(seasonStr[1:], 10, 8) + episode, err := strconv.ParseInt(episodeStr[1:], 10, 8) if err != nil { fmt.Println(err.Error()) } - query := fmt.Sprintf(` + query := ` INSERT INTO tvshow_episodes (name, season, poster, tvshow_id, episode, filename) -VALUES ('%s', %d, '%s', (SELECT tvshow.id FROM tvshow WHERE tvshow.name='%s'), %d, '%s')`, name, season, "", ShowName, episode, path) - err = database.Edit(query) +VALUES (?, ?, ?, (SELECT tvshow.id FROM tvshow WHERE tvshow.name=?), ?, ?)` + err = database.Edit(query, name, season, "", ShowName, episode, path) if err != nil { fmt.Println(err.Error()) } @@ -99,10 +106,18 @@ func insertShowIfNotExisting(show Show, allShows *[]string) { } } - // todo load tmdb pic + // insert empty thubnail if tmdb fails + thubnail := "" + + // load tmdb infos + tmdbInfo := tmdb.SearchTVShow(show.Name) + if tmdbInfo != nil { + thubnail = tmdbInfo.Thumbnail + } + // currently the foldernamme == name which mustn't necessarily be - query := fmt.Sprintf("INSERT INTO tvshow (name, thumbnail, foldername) VALUES ('%s', '%s', '%s')", show.Name, "", show.Name) - err := database.Edit(query) + query := "INSERT INTO tvshow (name, thumbnail, foldername) VALUES (?, ?, ?)" + err := database.Edit(query, show.Name, thubnail, show.Name) if err != nil { fmt.Println(err.Error()) } diff --git a/apiGo/videoparser/tmdb/TMDBApi.go b/apiGo/videoparser/tmdb/TMDBApi.go index 2a81d4c..659adc3 100644 --- a/apiGo/videoparser/tmdb/TMDBApi.go +++ b/apiGo/videoparser/tmdb/TMDBApi.go @@ -21,6 +21,12 @@ type VideoTMDB struct { GenreIds []int } +type TVShowTMDB struct { + Thumbnail string + Overview string + GenreIds []int +} + type tmdbVidResult struct { Poster_path string Adult bool @@ -89,7 +95,7 @@ func SearchVideo(MovieName string, year int) *VideoTMDB { // continue label cont: - thumbnail := fetchPoster(tmdbVid) + thumbnail := fetchPoster(tmdbVid.Poster_path) result := VideoTMDB{ Thumbnail: *thumbnail, @@ -101,8 +107,64 @@ cont: return &result } -func fetchPoster(vid tmdbVidResult) *string { - url := fmt.Sprintf("%s%s", pictureBase, vid.Poster_path) +type tmdbTvResult struct { + PosterPath string `json:"poster_path"` + Popularity int `json:"popularity"` + Id int `json:"id"` + BackdropPath string `json:"backdrop_path"` + VoteAverage int `json:"vote_average"` + Overview string `json:"overview"` + FirstAirDate string `json:"first_air_date"` + OriginCountry []string `json:"origin_country"` + GenreIds []int `json:"genre_ids"` + OriginalLanguage string `json:"original_language"` + VoteCount int `json:"vote_count"` + Name string `json:"name"` + OriginalName string `json:"original_name"` +} + +func SearchTVShow(Name string) *TVShowTMDB { + fmt.Printf("Searching TMDB for: TVShow: %s\n", Name) + queryURL := fmt.Sprintf("%ssearch/tv?api_key=%s&query=%s", baseUrl, apiKey, url.QueryEscape(Name)) + resp, err := http.Get(queryURL) + if err != nil { + fmt.Println(err.Error()) + return nil + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println(err.Error()) + return nil + } + + var t struct { + Results []tmdbTvResult `json:"results"` + } + err = json.Unmarshal(body, &t) + + fmt.Println(len(t.Results)) + + if len(t.Results) == 0 { + return nil + } + + res := TVShowTMDB{ + Thumbnail: "", + Overview: t.Results[0].Overview, + GenreIds: t.Results[0].GenreIds, + } + + thumbnail := fetchPoster(t.Results[0].PosterPath) + if thumbnail != nil { + res.Thumbnail = *thumbnail + } + + return &res +} + +func fetchPoster(posterPath string) *string { + url := fmt.Sprintf("%s%s", pictureBase, posterPath) resp, err := http.Get(url) if err != nil { diff --git a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf index 8ee1e5f..cbdb815 100755 --- a/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf +++ b/deb/OpenMediaCenter/etc/nginx/sites-available/OpenMediaCenter.conf @@ -16,4 +16,11 @@ server { location ~* ^/(api/|token) { proxy_pass http://127.0.0.1:8081; } + location /subscribe { + proxy_pass http://127.0.0.1:8081; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } } diff --git a/src/elements/DynamicContentContainer/DynamicContentContainer.tsx b/src/elements/DynamicContentContainer/DynamicContentContainer.tsx index 4b19b99..e83cebd 100644 --- a/src/elements/DynamicContentContainer/DynamicContentContainer.tsx +++ b/src/elements/DynamicContentContainer/DynamicContentContainer.tsx @@ -19,6 +19,12 @@ class DynamicContentContainer extends React.Component, state> { // stores current index of loaded elements loadindex: number = 0; + readonly InitialLoadNR = this.props.initialLoadNr + ? this.props.initialLoadNr === -1 + ? this.props.data.length + : this.props.initialLoadNr + : 16; + constructor(props: Props) { super(props); @@ -30,14 +36,14 @@ class DynamicContentContainer extends React.Component, state> { componentDidMount(): void { document.addEventListener('scroll', this.trackScrolling); - this.loadPreviewBlock(this.props.initialLoadNr ? this.props.initialLoadNr : 16); + this.loadPreviewBlock(this.InitialLoadNR); } componentDidUpdate(prevProps: Props): void { // when source props change force update! if (prevProps.data.length !== this.props.data.length) { this.clean(); - this.loadPreviewBlock(this.props.initialLoadNr ? this.props.initialLoadNr : 16); + this.loadPreviewBlock(this.InitialLoadNR); } } diff --git a/src/pages/TVShowPage/EpisodePage.tsx b/src/pages/TVShowPage/EpisodePage.tsx index 56f3aca..be58dcc 100644 --- a/src/pages/TVShowPage/EpisodePage.tsx +++ b/src/pages/TVShowPage/EpisodePage.tsx @@ -42,6 +42,7 @@ class EpisodePage extends React.Component { } data={this.episodes} + initialLoadNr={-1} /> ); diff --git a/src/pages/TVShowPage/TVShowPage.tsx b/src/pages/TVShowPage/TVShowPage.tsx index 18273aa..fa005c6 100644 --- a/src/pages/TVShowPage/TVShowPage.tsx +++ b/src/pages/TVShowPage/TVShowPage.tsx @@ -1,6 +1,6 @@ import React from 'react'; import Preview from '../../elements/Preview/Preview'; -import {APINode, callAPI} from '../../utils/Api'; +import {APINode, callAPI, callAPIPlain} from '../../utils/Api'; import {TVShow} from '../../types/ApiTypes'; import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer'; import {Route, Switch, useRouteMatch} from 'react-router-dom'; @@ -33,11 +33,21 @@ class TVShowPage extends React.Component { callback('')} + picLoader={(callback: (pic: string) => void): void => { + callAPIPlain( + APINode.TVShow, + { + action: 'readThumbnail', + Id: elem.Id + }, + (result) => callback(result) + ); + }} linkPath={'/tvshows/' + elem.Id} /> )} data={this.state.loading ? [] : this.data} + initialLoadNr={20} /> ); }