teleportal: Many ukrainian shows

This commit is contained in:
CakesTwix 2024-02-17 15:19:59 +02:00
parent 297bb51623
commit a709aa7c28
Signed by: CakesTwix
GPG key ID: 7B11051D5CE19825
9 changed files with 375 additions and 0 deletions

View file

@ -0,0 +1,29 @@
// use an integer for version numbers
version = 1
dependencies{
implementation("com.google.code.gson:gson:2.9.0")
}
cloudstream {
language = "uk"
// All of these properties are optional, you can safely remove them
description = "Telepotral - Серіали. шоу, Док. фільми"
authors = listOf("CakesTwix")
/**
* Status int as the following:
* 0: Down
* 1: Ok
* 2: Slow
* 3: Beta only
* */
status = 1 // will be 3 if unspecified
tvTypes = listOf(
"Series",
"Movie",
)
iconUrl = "https://www.google.com/s2/favicons?domain=teleportal.ua&sz=%size%"
}

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.lagradost"/>

View file

@ -0,0 +1,166 @@
package com.lagradost
import com.google.gson.Gson
import com.lagradost.cloudstream3.DubStatus
import com.lagradost.cloudstream3.Episode
import com.lagradost.cloudstream3.HomePageResponse
import com.lagradost.cloudstream3.LoadResponse
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.MainPageRequest
import com.lagradost.cloudstream3.SearchResponse
import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.TvType
import com.lagradost.cloudstream3.addEpisodes
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mainPageOf
import com.lagradost.cloudstream3.newAnimeLoadResponse
import com.lagradost.cloudstream3.newAnimeSearchResponse
import com.lagradost.cloudstream3.newHomePageResponse
import com.lagradost.cloudstream3.newMovieLoadResponse
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.M3u8Helper
import com.lagradost.models.Media
import com.lagradost.models.MediaShows
import com.lagradost.models.SeasonModel
import com.lagradost.models.TitleShows
import com.lagradost.models.VideoPlayer
class TeleportalProvider : MainAPI() {
// Basic Info
override var mainUrl = "https://teleportal.ua"
override var name = "Teleportal"
override val hasMainPage = true
override var lang = "uk"
override val hasDownloadSupport = true
override val supportedTypes = setOf(
TvType.TvSeries,
TvType.Movie,
)
private val apiUrl = "https://tp-back.starlight.digital"
private val findUrl = "$apiUrl/ua/live-search?q="
private val playerUrl = "https://vcms-api2.starlight.digital/player-api/"
// Sections
override val mainPage = mainPageOf(
"$apiUrl/ua/serials" to "Серіали",
"$apiUrl/ua/show" to "Шоу",
"$apiUrl/ua/documentaries" to "Документальні фільми",
)
override suspend fun getMainPage(
page: Int,
request: MainPageRequest
): HomePageResponse {
// Movies
if(request.data.substringAfterLast("/") == "documentaries"){
val homeList = Gson().fromJson(app.get(request.data).text, Media::class.java).items.map{
newAnimeSearchResponse(it.title, "$apiUrl/ua${it.videoSlug}", TvType.TvSeries) {
this.posterUrl = "$mainUrl${it.image}"
}
}
return newHomePageResponse(request.name, homeList)
}
// Shows
else {
val homeList = Gson().fromJson(app.get(request.data).text, MediaShows::class.java).items.map{
newAnimeSearchResponse(it.name, "$apiUrl/ua/${request.data.substringAfterLast("/")}/${it.channelSlug}/${it.projectSlug}", TvType.TvSeries) {
this.posterUrl = "$mainUrl${it.image}"
}
}
return newHomePageResponse(request.name, homeList)
}
}
override suspend fun search(query: String): List<SearchResponse> {
return app.get("$findUrl$query&page=1").parsedSafe<Media>()!!.items.map{
newAnimeSearchResponse(it.title, "$apiUrl${it.videoSlug}", TvType.TvSeries) {
this.posterUrl = "$mainUrl${it.image}"
}
}
}
// Detailed information
override suspend fun load(url: String): LoadResponse {
//val title = app.get(url).parsedSafe<TitleShows>()!!
val title = Gson().fromJson(app.get(url).text, TitleShows::class.java)
val tvType = when(title.typeSlug){
"show" -> TvType.TvSeries
"series" -> TvType.TvSeries
"serials" -> TvType.TvSeries
else -> TvType.Movie
}
val episodes = mutableListOf<Episode>()
if (tvType == TvType.TvSeries){
title.seasons.map{
val season = Gson().fromJson(app.get("$url/${it.seasonSlug}").text, SeasonModel::class.java)
if(season.seasonGallery.items.isNullOrEmpty()) return@map
season.seasonGallery.items.forEach { episode ->
episodes.add(
Episode(
"$url/${it.seasonSlug}/${episode.videoSlug}",
episode.title,
extractIntFromString(season.seasonTitle),
extractIntFromString(episode.seriesTitle),
"$mainUrl${episode.image}",
description = episode.tizer,
)
)
}
}
return newAnimeLoadResponse(
title.title,
"$mainUrl${title.projectSlug}",
tvType,
) {
this.posterUrl = "$mainUrl${title.image}"
this.plot = title.description
addEpisodes(DubStatus.Dubbed, episodes)
}
}
return newMovieLoadResponse(title.title, url, TvType.Movie, "$apiUrl/ua/${title.typeSlug}/${title.channelSlug}/${title.videoSlug}") {
this.posterUrl = "$mainUrl${title.image}"
this.plot = title.description
}
}
// It works when I click to view the series
override suspend fun loadLinks(
data: String,
isCasting: Boolean,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
): Boolean {
// Log.d("CakesTwix-Debug", data)
val videoHash = Gson().fromJson(app.get(data).text, TitleShows::class.java).hash
// Log.d("CakesTwix-Debug", "$playerUrl$videoHash?referer=https://teleportal.ua/")
val video = Gson().fromJson(app.get("$playerUrl$videoHash?referer=https://teleportal.ua/").text, VideoPlayer::class.java).video[0]
// Log.d("CakesTwix-Debug", video.toString())
if(video.mediaHlsNoAdv.isNullOrEmpty()) return false
// Log.d("CakesTwix-Debug", video.mediaHlsNoAdv)
M3u8Helper.generateM3u8(
source = video.projectName,
streamUrl = video.mediaHlsNoAdv,
referer = mainUrl
).forEach(callback)
return true
}
private fun extractIntFromString(string: String): Int? {
val value = Regex("(\\d+)").findAll(string).lastOrNull() ?: return null
if(value.value[0].toString() == "0"){
return value.value.drop(1).toIntOrNull()
}
return value.value.toIntOrNull()
}
}

View file

@ -0,0 +1,13 @@
package com.lagradost
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
import com.lagradost.cloudstream3.plugins.Plugin
import android.content.Context
@CloudstreamPlugin
class TeleportalProviderPlugin: Plugin() {
override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(TeleportalProvider())
}
}

View file

@ -0,0 +1,23 @@
package com.lagradost.models
data class Media(
val galleryName : String,
val typeSlug : String,
val seoTitle : String,
val seoDescription : String,
val seoKeywords : String,
val channels : List<String>,
val items : List<Items>
)
data class Items (
val title : String,
val tizer : String,
val image : String,
val imageMob : String,
val videoSlug : String,
val seriesTitle : String,
)

View file

@ -0,0 +1,30 @@
package com.lagradost.models
data class MediaShows (
val galleryName : String,
val typeSlug : String,
val seoTitle : String,
val seoDescription : String,
val seoKeywords : String,
val channels : List<Channels>,
val items : List<ItemsShows>
)
data class Channels (
val title : String,
val channelSlug : String,
val seoTitle : String,
val seoDescription : String,
val seoKeywords : String
)
data class ItemsShows (
val name : String,
val image : String,
val imageMob : String,
val channelSlug : String,
val projectSlug : String
)

View file

@ -0,0 +1,36 @@
package com.lagradost.models
data class SeasonModel (
val id : Int,
val seoTitle : String,
val seoDescription : String,
val seoKeywords : String,
val typeTitle : String,
val channelTitle : String,
val channelImage : String,
val sortableCompilations : String,
val projectTitle : String,
val seasonTitle : String,
val age : String,
val image : String,
val imageTab : String,
val imageMob : String,
val logoImage : String,
val description : String,
val typeSlug : String,
val channelSlug : String,
val projectSlug : String,
val seasonSlug : String,
val personPage : Boolean,
// val persons : List<Persons>,
val seasons : List<Seasons>,
val seasonGallery : SeasonGallery,
)
data class SeasonGallery (
val title : String,
val seasonSlug : String,
val items : List<Items>
)

View file

@ -0,0 +1,27 @@
package com.lagradost.models
data class TitleShows (
val id : Int,
val typeTitle : String,
val title : String,
val image : String,
val imageTab : String,
val imageMob : String,
val logoImage : String,
val description : String,
val typeSlug : String,
val channelSlug : String,
val projectSlug : String,
val videoSlug : String,
val seasons : List<Seasons>,
val video : String,
val hash : String,
)
data class Seasons (
val id : Int,
val title : String,
val seasonSlug : String
)

View file

@ -0,0 +1,49 @@
package com.lagradost.models
data class VideoPlayer (
val version : String,
val type : String,
val poster : String,
val posterMob : String,
val name : String,
val video : List<Video>
)
data class Video (
val vcmsId : Int,
val hash : String,
val channel : String,
val channel_domain : String,
val project_id : String,
val projectName : String,
val seasonName : String,
val releaseName : String,
val year_of_production : Int,
val countries_of_production : List<String>,
val content_language : List<String>,
val publishDate : String,
val date_of_broadcast : String,
val time_upload_video : String,
val cache_time : String,
val current_time : String,
val videoAccessible : Boolean,
val videoAccessible_type : String,
val autoplay : Boolean,
val showadv : Boolean,
val anons : Boolean,
val program : String,
val name : String,
val duration : Int,
val poster : String,
val projectPostURL : String,
val preview_url : String,
val tt : String,
val plug_type : String,
val canonicalPageUrl : String,
val media : List<Media>,
val mediaHls : String,
val mediaHlsNoAdv : String,
val availableHls : Int
)