Example #1
0
func ShowEpisodePlay(ctx *gin.Context) {
	tmdbId := ctx.Params.ByName("showId")
	showId, _ := strconv.Atoi(tmdbId)
	seasonNumber, _ := strconv.Atoi(ctx.Params.ByName("season"))
	episodeNumber, _ := strconv.Atoi(ctx.Params.ByName("episode"))

	show := tmdb.GetShow(showId, "")
	episode := tmdb.GetEpisode(showId, seasonNumber, episodeNumber, "")

	runtime := 45
	if len(show.EpisodeRunTime) > 0 {
		runtime = show.EpisodeRunTime[len(show.EpisodeRunTime)-1]
	}

	torrents, err := showEpisodeLinks(showId, seasonNumber, episodeNumber)
	if err != nil {
		ctx.Error(err)
		return
	}

	if len(torrents) == 0 {
		xbmc.Notify("Quasar", "LOCALIZE[30205]", config.AddonIcon())
		return
	}

	AddToTorrentsMap(strconv.Itoa(episode.Id), torrents[0])

	rUrl := UrlQuery(UrlForXBMC("/play"), "uri", torrents[0].Magnet(),
		"tmdb", strconv.Itoa(episode.Id),
		"type", "episode",
		"runtime", strconv.Itoa(runtime))
	ctx.Redirect(302, rUrl)
}
Example #2
0
func Lookup(ctx *gin.Context) {
	var db DataBase

	LibraryPath := config.Get().LibraryPath
	DBPath := filepath.Join(LibraryPath, fmt.Sprintf("%s.json", DBName))

	if _, err := os.Stat(DBPath); err == nil {
		file, err := ioutil.ReadFile(DBPath)
		if err != nil {
			ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
			ctx.JSON(200, gin.H{
				"success": false,
			})
			return
		}
		json.Unmarshal(file, &db)
	}

	Movies := make([]*Item, 0, len(db.Movies))
	Shows := make([]*Item, 0, len(db.Shows))

	for i := 0; i < len(db.Movies); i++ {
		movie := tmdb.GetMovieById(db.Movies[i], "en")
		Movies = append(Movies, &Item{
			Id:       db.Movies[i],
			Title:    movie.OriginalTitle,
			Year:     strings.Split(movie.ReleaseDate, "-")[0],
			Overview: movie.Overview,
			Poster:   tmdb.ImageURL(movie.PosterPath, "w500"),
		})
	}

	for i := 0; i < len(db.Shows); i++ {
		showId, _ := strconv.Atoi(db.Shows[i])
		show := tmdb.GetShow(showId, "en")
		if show == nil {
			ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
			ctx.JSON(200, gin.H{
				"success": false,
			})
			return
		}
		Shows = append(Shows, &Item{
			Id:       db.Shows[i],
			Title:    show.Name,
			Year:     strings.Split(show.FirstAirDate, "-")[0],
			Overview: show.Overview,
			Poster:   tmdb.ImageURL(show.PosterPath, "w500"),
		})
	}

	ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*")
	ctx.JSON(200, gin.H{
		"success": true,
		"results": gin.H{
			"movies": Movies,
			"shows":  Shows,
		},
	})
}
Example #3
0
func ShowEpisodes(ctx *gin.Context) {
	showId, _ := strconv.Atoi(ctx.Params.ByName("showId"))
	seasonNumber, _ := strconv.Atoi(ctx.Params.ByName("season"))
	language := config.Get().Language
	show := tmdb.GetShow(showId, language)
	season := tmdb.GetSeason(showId, seasonNumber, language)
	items := season.Episodes.ToListItems(show, season)

	for _, item := range items {
		playUrl := UrlForXBMC("/show/%d/season/%d/episode/%d/play",
			show.Id,
			seasonNumber,
			item.Info.Episode,
		)
		episodeLinksUrl := UrlForXBMC("/show/%d/season/%d/episode/%d/links",
			show.Id,
			seasonNumber,
			item.Info.Episode,
		)
		if config.Get().ChooseStreamAuto == true {
			item.Path = playUrl
		} else {
			item.Path = episodeLinksUrl
		}
		item.ContextMenu = [][]string{
			[]string{"LOCALIZE[30202]", fmt.Sprintf("XBMC.PlayMedia(%s)", episodeLinksUrl)},
			[]string{"LOCALIZE[30023]", fmt.Sprintf("XBMC.PlayMedia(%s)", playUrl)},
			[]string{"LOCALIZE[30203]", "XBMC.Action(Info)"},
			[]string{"LOCALIZE[30037]", fmt.Sprintf("XBMC.RunPlugin(%s)", UrlForXBMC("/setviewmode/episodes"))},
		}
		item.IsPlayable = true
	}

	ctx.JSON(200, xbmc.NewView("episodes", items))
}
Example #4
0
func RemoveShow(ctx *gin.Context) {
	LibraryPath := config.Get().LibraryPath
	ShowsLibraryPath := filepath.Join(LibraryPath, "Shows")
	DBPath := filepath.Join(LibraryPath, fmt.Sprintf("%s.json", DBName))
	showId := ctx.Params.ByName("showId")
	Id, _ := strconv.Atoi(showId)
	show := tmdb.GetShow(Id, "en")
	if show == nil {
		ctx.String(404, "")
		return
	}
	ShowStrm := toFileName(fmt.Sprintf("%s (%s)", show.Name, strings.Split(show.FirstAirDate, "-")[0]))
	ShowPath := filepath.Join(ShowsLibraryPath, ShowStrm)

	if err := RemoveFromJsonDB(DBPath, showId, LShow); err != nil {
		libraryLog.Error("Unable to remove show from db")
		ctx.String(404, "")
		return
	}

	if err := os.RemoveAll(ShowPath); err != nil {
		libraryLog.Error("Unable to remove show folder")
		ctx.String(404, "")
		return
	}

	xbmc.Notify("Quasar", "LOCALIZE[30222]", config.AddonIcon())
	ctx.String(200, "")
	xbmc.VideoLibraryClean()
	ClearCache(ctx)
	xbmc.Refresh()
	libraryLog.Notice("Show removed")
}
Example #5
0
func ProviderGetEpisode(ctx *gin.Context) {
	provider := ctx.Params.ByName("provider")
	showId, _ := strconv.Atoi(ctx.Params.ByName("showId"))
	seasonNumber, _ := strconv.Atoi(ctx.Params.ByName("season"))
	episodeNumber, _ := strconv.Atoi(ctx.Params.ByName("episode"))

	log.Println("Searching links for TMDB Id:", showId)

	show := tmdb.GetShow(showId, "en")
	season := tmdb.GetSeason(showId, seasonNumber, "en")
	if season == nil {
		ctx.Error(errors.New(fmt.Sprintf("Unable to get season %d", seasonNumber)))
		return
	}
	episode := season.Episodes[episodeNumber-1]

	log.Printf("Resolved %s to %s", showId, show.Name)

	searcher := providers.NewAddonSearcher(provider)
	torrents := searcher.SearchEpisodeLinks(show, episode)
	if ctx.Request.URL.Query().Get("resolve") == "true" {
		for _, torrent := range torrents {
			torrent.Resolve()
		}
	}
	data, err := json.MarshalIndent(providerDebugResponse{
		Payload: searcher.GetEpisodeSearchObject(show, episode),
		Results: torrents,
	}, "", "    ")
	if err != nil {
		xbmc.AddonFailure(provider)
		ctx.Error(err)
	}
	ctx.Data(200, "application/json", data)
}
Example #6
0
func WriteShowStrm(showId string, ShowsLibraryPath string) error {
	Id, _ := strconv.Atoi(showId)
	show := tmdb.GetShow(Id, "en")
	if show == nil {
		return errors.New("Unable to get Show")
	}
	ShowStrm := toFileName(fmt.Sprintf("%s (%s)", show.Name, strings.Split(show.FirstAirDate, "-")[0]))
	ShowPath := filepath.Join(ShowsLibraryPath, ShowStrm)

	if _, err := os.Stat(ShowPath); os.IsNotExist(err) {
		if err := os.Mkdir(ShowPath, 0755); err != nil {
			libraryLog.Error("Unable to create path for Show")
			return err
		}
	}

	now := time.Now().UTC()
	addSpecials := config.Get().AddSpecials

	for _, season := range show.Seasons {
		if season.EpisodeCount == 0 {
			continue
		}
		firstAired, _ := time.Parse("2006-01-02", show.FirstAirDate)
		if firstAired.After(now) {
			continue
		}
		if addSpecials == false && season.Season == 0 {
			continue
		}

		episodes := tmdb.GetSeason(Id, season.Season, "en").Episodes

		for _, episode := range episodes {
			if episode.AirDate == "" {
				continue
			}
			firstAired, _ := time.Parse("2006-01-02", episode.AirDate)
			if firstAired.After(now) {
				continue
			}

			EpisodeStrmPath := filepath.Join(ShowPath, fmt.Sprintf("%s S%02dE%02d.strm", ShowStrm, season.Season, episode.EpisodeNumber))
			playLink := UrlForXBMC("/library/play/show/%d/season/%d/episode/%d", Id, season.Season, episode.EpisodeNumber)
			if err := ioutil.WriteFile(EpisodeStrmPath, []byte(playLink), 0644); err != nil {
				libraryLog.Error("Unable to write to strm file for episode")
				return err
			}
		}
	}

	return nil
}
Example #7
0
func (as *AddonSearcher) GetEpisodeSearchObject(show *tvdb.Show, episode *tvdb.Episode) *EpisodeSearchObject {
	seriesName := show.SeriesName
	absoluteNumber := 0
	tmdbFindResults := tmdb.Find(strconv.Itoa(show.Id), "tvdb_id")

	// FIXME: This can crash
	if tmdbFindResults != nil {
		var tmdbShow *tmdb.Show
		for _, result := range tmdbFindResults.TVResults {
			tmdbShow = tmdb.GetShow(result.Id, "en")
			break
		}
		if tmdbShow != nil {
			seriesName = tmdbShow.Name
		}
		// is this an anime?
		countryIsJP := false
		for _, country := range tmdbShow.OriginCountry {
			if country == "JP" {
				countryIsJP = true
				break
			}
		}
		genreIsAnim := false
		for _, genre := range tmdbShow.Genres {
			if genre.Name == "Animation" {
				genreIsAnim = true
				break
			}
		}
		if countryIsJP && genreIsAnim {
			absoluteNumber = episode.AbsoluteNumber
		}
	}

	return &EpisodeSearchObject{
		IMDBId:         show.ImdbId,
		TVDBId:         show.Id,
		Title:          NormalizeTitle(seriesName),
		Season:         episode.SeasonNumber,
		Episode:        episode.EpisodeNumber,
		AbsoluteNumber: absoluteNumber,
	}
}
Example #8
0
func ShowSeasons(ctx *gin.Context) {
	showId, _ := strconv.Atoi(ctx.Params.ByName("showId"))

	show := tmdb.GetShow(showId, config.Get().Language)

	items := show.Seasons.ToListItems(show)
	reversedItems := make(xbmc.ListItems, 0)
	for i := len(items) - 1; i >= 0; i-- {
		item := items[i]
		item.Path = UrlForXBMC("/show/%d/season/%d/episodes", show.Id, item.Info.Season)
		item.ContextMenu = [][]string{
			[]string{"LOCALIZE[30036]", fmt.Sprintf("XBMC.RunPlugin(%s)", UrlForXBMC("/setviewmode/seasons"))},
		}
		reversedItems = append(reversedItems, item)
	}
	// xbmc.ListItems always returns false to Less() so that order is unchanged

	ctx.JSON(200, xbmc.NewView("seasons", reversedItems))
}
Example #9
0
func showSeasonLinks(showId int, seasonNumber int) ([]*bittorrent.Torrent, error) {
	log.Println("Searching links for TMDB Id:", showId)

	show := tmdb.GetShow(showId, config.Get().Language)
	season := tmdb.GetSeason(showId, seasonNumber, config.Get().Language)
	if season == nil {
		return nil, errors.New("Unable to find season")
	}

	log.Printf("Resolved %d to %s", showId, show.Name)

	if torrents := InTorrentsMap(strconv.Itoa(season.Id)); len(torrents) > 0 {
		return torrents, nil
	}

	searchers := providers.GetSeasonSearchers()
	if len(searchers) == 0 {
		xbmc.Notify("Quasar", "LOCALIZE[30204]", config.AddonIcon())
	}

	return providers.SearchSeason(searchers, show, season), nil
}
Example #10
0
func showEpisodeLinks(showId int, seasonNumber int, episodeNumber int) ([]*bittorrent.Torrent, string, error) {
	log.Println("Searching links for TMDB Id:", showId)

	show := tmdb.GetShow(showId, config.Get().Language)
	season := tmdb.GetSeason(showId, seasonNumber, config.Get().Language)
	if season == nil {
		return nil, "", errors.New("Unable to find season")
	}

	episode := season.Episodes[episodeNumber-1]

	log.Printf("Resolved %d to %s", showId, show.Name)

	searchers := providers.GetEpisodeSearchers()
	if len(searchers) == 0 {
		xbmc.Notify("Quasar", "LOCALIZE[30204]", config.AddonIcon())
	}

	longName := fmt.Sprintf("%s S%02dE%02d", show.Name, seasonNumber, episodeNumber)

	return providers.SearchEpisode(searchers, show, episode), longName, nil
}
Example #11
0
func ShowEpisodeLinks(ctx *gin.Context) {
	tmdbId := ctx.Params.ByName("showId")
	showId, _ := strconv.Atoi(tmdbId)
	seasonNumber, _ := strconv.Atoi(ctx.Params.ByName("season"))
	episodeNumber, _ := strconv.Atoi(ctx.Params.ByName("episode"))

	show := tmdb.GetShow(showId, "")
	episode := tmdb.GetEpisode(showId, seasonNumber, episodeNumber, "")
	longName := fmt.Sprintf("%s S%02dE%02d", show.Name, seasonNumber, episodeNumber)

	runtime := 45
	if len(show.EpisodeRunTime) > 0 {
		runtime = show.EpisodeRunTime[len(show.EpisodeRunTime)-1]
	}

	torrents, err := showEpisodeLinks(showId, seasonNumber, episodeNumber)
	if err != nil {
		ctx.Error(err)
		return
	}

	if len(torrents) == 0 {
		xbmc.Notify("Quasar", "LOCALIZE[30205]", config.AddonIcon())
		return
	}

	choices := make([]string, 0, len(torrents))
	for _, torrent := range torrents {
		resolution := ""
		if torrent.Resolution > 0 {
			resolution = fmt.Sprintf("[B][COLOR %s]%s[/COLOR][/B] ", bittorrent.Colors[torrent.Resolution], bittorrent.Resolutions[torrent.Resolution])
		}

		info := make([]string, 0)
		if torrent.Size != "" {
			info = append(info, fmt.Sprintf("[B][%s][/B]", torrent.Size))
		}
		if torrent.RipType > 0 {
			info = append(info, bittorrent.Rips[torrent.RipType])
		}
		if torrent.VideoCodec > 0 {
			info = append(info, bittorrent.Codecs[torrent.VideoCodec])
		}
		if torrent.AudioCodec > 0 {
			info = append(info, bittorrent.Codecs[torrent.AudioCodec])
		}
		if torrent.Provider != "" {
			info = append(info, fmt.Sprintf(" - [B]%s[/B]", torrent.Provider))
		}

		multi := ""
		if torrent.Multi {
			multi = "\nmulti"
		}

		label := fmt.Sprintf("%s(%d / %d) %s\n%s\n%s%s",
			resolution,
			torrent.Seeds,
			torrent.Peers,
			strings.Join(info, " "),
			torrent.Name,
			torrent.Icon,
			multi,
		)
		choices = append(choices, label)
	}

	choice := xbmc.ListDialogLarge("LOCALIZE[30228]", longName, choices...)
	if choice >= 0 {
		AddToTorrentsMap(strconv.Itoa(episode.Id), torrents[choice])

		rUrl := UrlQuery(
			UrlForXBMC("/play"), "uri", torrents[choice].Magnet(),
			"tmdb", strconv.Itoa(episode.Id),
			"type", "episode",
			"runtime", strconv.Itoa(runtime))
		ctx.Redirect(302, rUrl)
	}
}