TSmedia addons development - mfaraj - 06-12-2020
Here all technical data will be discussed regarding development of TSmedia and addons.
wTSmedia:
wTSmedia is windows tool to create and debug TSmedia addons.
wTSmedia is portable application runs in windows 64bit and 32bit systems.
download from [Only registered and activated users can see links You are not allowed to view links. Register or Login to view.] and extract to any folder without spaces.
requirements:
python 2.7-[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
optional:
vlc -[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
potplayer-[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
node.js-[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
peerflix-[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
The following video demonstrates the basic use of wTSmedia
[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
RE: TSmedia addons development - mfaraj - 06-12-2020
Install external python package for wTSmedia
download and xtract the package from the net
[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
after extraction of the package to known location
from wTSmedia-menu developers
RE: TSmedia addons development - frank087234 - 06-12-2020
@mfaraj
warning: GMP or MPIR library not found; Not building Crypto.PublicKey._fastmath.
building 'Crypto.Random.OSRNG.winrandom' extension
error: Microsoft Visual C++ 9.0 is required. Get it from [Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
RE: TSmedia addons development - mfaraj - 06-12-2020
Install python 2.7 for 64 bit system
[Only registered and activated users can see links You are not allowed to view links. Register or Login to view.]
and try again
RE: TSmedia addons development - mfaraj - 06-17-2020
Writing TSmedia addon
TSmedia addon code and directory structure based on kodi addons with significant modification to make it more simpler and appropriate for enigma2.
Writing addon for TSmedia is very simple with less code lines than any other similar host code for any iptv stream application.
will not go through the basic of python,a lot of tutorial available on the internet for who interested.
fist step to create TSmedia addon by help of wTSmedia.
just go to menu addon and select create new addon
default template appears,all needed to fill the required fields and follow the steps to create the addon.
Now the addon is created and the default py module is ready for editing and adding your code.
new addon template
PHP Code: # -*- coding: utf8 -*- import urllib,urllib2,re,sys,os from iTools import CBaseAddonClass,printD,printE
########################################## class myaddon(CBaseAddonClass): def __init__(self): CBaseAddonClass.__init__(self,{'cookie':'myaddon.cookie'}) self.USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0' self.MAIN_URL ="http://myaddon.com" self.HEADER = {'User-Agent': self.USER_AGENT, 'DNT':'1', 'Accept': 'text/html', 'Accept-Encoding':'gzip, deflate', 'Referer':self.getMainUrl(), 'Origin':self.getMainUrl()} self.AJAX_HEADER = dict(self.HEADER) self.AJAX_HEADER.update( {'X-Requested-With': 'XMLHttpRequest', 'Accept-Encoding':'gzip, deflate', 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8', 'Accept':'application/json, text/javascript, */*; q=0.01'} ) self.cacheLinks = {} self.defaultParams = {'header':self.HEADER, 'raw_post_data':True, 'use_cookie': True, 'load_cookie': True, 'save_cookie': True, 'cookiefile': self.COOKIE_FILE} def showmenu(self): self.addDir('search','https://yts.lt/api/v2/list_movies.json?limit=50&sort_by=date_added&quality=all&genre=all',103,'img/search.png','',1,searchall=True) self.addDir('Most Downloads','https://yts.lt/api/v2/list_movies.json?limit=50&sort_by=date_added&quality=all&genre=all',100,'img/1.png','',1) self.addDir('Recent','https://yts.lt/api/v2/list_movies.json?limit=50&sort_by=download_count&quality=all&genre=all',100,'img/2.png','',1) self.addDir('Top rated','https://yts.lt/api/v2/list_movies.json?limit=50&sort_by=rating&quality=all&genre=all',100,'img/3.png','',1) self.addDir('Most liked','https://yts.lt/api/v2/list_movies.json?limit=50&sort_by=like_count&quality=all&genre=all',100,'img/4.png','',1)
def search_103(self,name,sterm,page): surl='https://m2.arabseed.net/?s=' if page>1: url_page='https://m2.arabseed.net/page/%s/?s=%s'%(str(page),sterm) else: url_page=surl+sterm ################################################################## data=self.getcfPage(url_page) if data is None: return print "data",data #data=self.getDM(data,'ti-video-library','class="pagination"',False) blocks=data.split('class="BlockItem ISMovie"') i=0 print "blocks",len(blocks) blocks.pop(0) print "block",blocks[0] for block in blocks: regx='''href="(.*?)"''' href=self.getSM(block,regx) regx='''data-src="(.*?)"''' image=self.getSM(block,regx) regx='''title="(.*?)"''' title=self.getSM(block,regx) regx='''<div class="Rate">imdb <em>(.*?)</em></div>''' rating=self.getSM(block,regx) if rating!='': title=title+"("+rating+")" regx='''<p>(.*?)</p>''' desc=self.getSM(block,regx) title=title.replace("’"," ") title=self.colorize(title,"green") if 'مسلسل' in title: mode=201 else: mode=1 try:self.addDir(title,href,mode,image,name,1,True,desc=desc) except:pass if len(blocks)>22: self.addDir("next page",sterm,103,'img/next.png','',str(page+1),dialog='nsearch')
def getmovies_100(self,name,url,page): if page>1: #http://arabseed.net/cat_film/%D8%A7%D9%81%D9%84%D8%A7%D9%85-%D8%A7%D8%AC%D9%86%D8%A8%D9%8A/page/2/ url_page=url+"?page="+str(page) else: url_page=url data=self.getcfPage(url_page) if data is None: return #data=self.getDM(data,'ti-video-library','class="pagination"',False) blocks=data.split('class="BlockItem ISMovie"') i=0 blocks.pop(0) print "block",blocks[0] for block in blocks: regx='''href="(.*?)"''' href=self.getSM(block,regx) regx='''data-src="(.*?)"''' image=self.getSM(block,regx) regx='''title="(.*?)"''' title=self.getSM(block,regx) regx='''<div class="Rate">imdb <em>(.*?)</em></div>''' rating=self.getSM(block,regx) if rating!='': title=title+"("+rating+")" regx='''<p>(.*?)</p>''' desc=self.getSM(block,regx) title=title.replace("’"," ") title=self.colorize(title,"green") try:self.addDir(title,href,1,image,name,1,True,desc=desc) except:pass if len(blocks)>22: self.addDir("next page",url,100,'img/next.png','',str(page+1))
###############################################series def getseries_200(self,name,url,page): if page>1: #http://arabseed.net/cat_film/%D8%A7%D9%81%D9%84%D8%A7%D9%85-%D8%A7%D8%AC%D9%86%D8%A8%D9%8A/page/2/ url_page=url+"?page="+str(page) else: url_page=url data=self.getPage(url_page) if data is None: return blocks=data.split('class="BlockItem ISMovie"') i=0 blocks.pop(0) print "block",blocks[0] for block in blocks: regx='''href="(.*?)"''' href=self.getSM(block,regx) regx='''data-src="(.*?)"''' image=self.getSM(block,regx) regx='''title="(.*?)"''' title=self.getSM(block,regx) regx='''<div class="Rate">imdb <em>(.*?)</em></div>''' rating=self.getSM(block,regx) if rating!='': title=title+"("+rating+")" regx='''<p>(.*?)</p>''' desc=self.getSM(block,regx) title=self.colorize(title,"green") if 'كامل' in title: continue title=title.replace("’"," ") try:self.addDir(title,href,201,image,name,1,True,desc=desc) except:pass if len(blocks)>22: self.addDir("next page",url,200,'img/next.png','',str(page+1)) ###############################################series def getepisode_201(self,name,url,image,page,extra,desc=''): self.addDir(name,url,1,image,name,1,extra=extra,desc=desc,dialog='servers') self.addDir("حلقات اخرى",url,202,image,name,1,extra=extra,desc=desc,dialog='servers') def getepisodes_202(self,name,url,image,page,extra): print '**************////////////////////////*******************//////////////////' data=self.getPage(url) #if 'class="BlockItem ISMovie"' in data: #self.getepisodes_203( name,url,image,page,extra) #return extra,desc,img=self.metaData(url='',data=data,image=image) regx1='''<li class="keywordsLi"><a href="(.*?)">.*?</a>''' regx='''<a href="(.*?)" class="content-box ">\s(.*?)<span>(.*?)</span>''' blocks=data.split('episode-block box-11x1') blocks.pop(0) for block in blocks: href=self.getSM(block,'href="(.*?)"') episode="episode"+"-"+self.getSM(block,'<span>(.*?)</span>') self.addDir(episode,href,1,image,name,1,extra=extra,desc=desc,dialog='servers') def getepisodes_203(self,name,url,image,page,extra): if page>1: #http://arabseed.net/cat_film/%D8%A7%D9%81%D9%84%D8%A7%D9%85-%D8%A7%D8%AC%D9%86%D8%A8%D9%8A/page/2/ url_page=url+"?page="+str(page) else: url_page=url data=self.getPage(url_page) if data is None: return blocks=data.split('class="BlockItem ISMovie"') i=0 blocks.pop(0) print "block",blocks[0] for block in blocks: regx='''href="(.*?)"''' href=self.getSM(block,regx) regx='''data-src="(.*?)"''' image=self.getSM(block,regx) regx='''title="(.*?)"''' title=self.getSM(block,regx) regx='''<div class="Rate">imdb <em>(.*?)</em></div>''' rating=self.getSM(block,regx) if rating!='': title=title+"("+rating+")" regx='''<p>(.*?)</p>''' desc=self.getSM(block,regx) title=self.colorize(title,"green") try:self.addDir(title,href,202,image,name,1,True,desc=desc) except:pass if len(blocks)>22: self.addDir("next page",url,200,'img/next.png','',str(page+1)) #######################################host resolving def metaData(self,data='',extra={},image='',url='',desc='',show='movie'): if show=='tv': self.metaDataTV(url=url,image=image,data=data,desc=desc,extra=extra) return regx='''<i class="fa fa-fw fa-star"></i>(.*?)</span>''' rating=self.getSM(data,regx) extra['rating']=rating
year=self.getDM(data,'<span>تاريخ الاصدار','</li>') extra['year']=self.cleanhtml(year) country=self.getDM(data,'<span>الدولة','</li>') extra['country']=self.cleanhtml(country) language=self.getDM(data,'<span>اللغة','</li>') extra['language']=self.cleanhtml(language) duration=self.getDM(data,'<span>مدة العرض','</li>') extra['duration']=self.cleanhtml(duration) regx='''<a href="https://arabseed.net/altsnyf/(.*?)" )"''' pg=self.getSM(data,regx) pg=self.cleanhtml(pg) extra['pg']=pg regx='''<span>النوع"''' genre=self.getDM(data,'<span>النوع','</li>') genre=self.cleanhtml(genre,withSpace=True) extra['genre']=str(genre) regx='''href="https://arabseed.net/quality/(.*?)"''' quality=self.getDM(data,'<span>الجودة','</li>') extra['quality']=self.cleanhtml(quality) regx='''<meta name="description" content="(.*?)" />''' desc=self.getDM(data,'"description": "','",') desc=self.cleanhtml(desc) poster=self.getDM(data,'"thumbnailUrl": "','"') if poster!='': image=poster
return extra,desc,image def getservers_1(self,name,url,img,extra): print '7777777777777777777777777777',url data=self.getPage(url) extra,desc,img=self.metaData(data=data,extra=extra,image=img) from arabseed import get_arabseed_Servers servers=get_arabseed_Servers(url) for server,href in servers: if not 'arabseed' in href and not 'mixdrop' in href: server,image,supported=self.getDomain(href) self.addDir(server,href,3,img,name,1,extra=extra,dialog='servers',desc=desc) return
def getservers_2(self,name,url,img,extra,desc):# get server arabseed.me if 'arabseed' in url : data=self.getPage(url) regx='''<source src="(.+?)"''' hrefs=re.findall(regx,data, re.M|re.I) for href in hrefs: print '***************************href__*****************',href self.addDir('arabseed'+"-"+name,href,0,img,name,1,extra=extra,dialog='servers',desc=desc)
else: self.resolvehost(name,url) def resolve_host(self,name,url): self.resolvehost(name,url)#### def run(self,params={}): url=None name=None mode=None page=1 name=params.get("name",'') url=params.get("url",'') try:mode=int(params.get("mode",None)) except:mode=None image=params.get("image",'') section=params.get("section",'') page=int(params.get("page",1)) extra=params.get("extra",{}) desc=params.get("desc",'') show=params.get("show",'') ##menu and tools if mode==None: self.showmenu() ##hosts elif mode==1: self.getservers_1(name,url,image,extra) elif mode==2: self.resolve_host(name,url) elif mode==3: self.getservers_2(name,url,image,extra,desc) elif mode==103: sterm = self.getsearchtext() self.search_103("Search",sterm,page) ###movies elif mode==100: self.getmovies_100(name,url,page) elif mode==101: self.years_101() elif mode==102: self.getA_Z_102('movies') ###series elif mode==200: self.getseries_200(name,url,page) elif mode==201: self.getepisode_201(name,url,image,page,extra) elif mode==202: self.getepisodes_202(name,url,image,page,extra) return self.endDir() def start(params={}): addon=myaddon() return addon.run(params)
to continue...
Many built in functions are available to write complete addon for TSmedia.
addDir:
One of the most important function and needed to store data collected from the execution of the addon to be sent to the TSmedia to processes the data and display and on TV screen.
addDir accepts many arguments.
basic arguments are title,url,mode,image,category,page,maintitle
all are self explanatory but some words about mode and maintitle.
mode :
used to direct the next execution of the addon and takes any integer value,some values are reserved to do certain actions
0 means play the link
-1 display error message
-10 no action,used for markers
-7 used for torrent links
103 for search
maintitle :
accepts two boolean values default False and the other True
suppose we have this branch as example movies>divergent 2014>server1>link1
in this case the title of the link player by the player will be link1,also the title used by imdb engine and subssupport is link1,to make movie divergent instead we should use maintitle True with the addDir passing the movie title,at least one calling addDir function should include maintitle equal True else TSmedia processing will be disrupted,commonly we use maintitle=True with listing of movies and series
other some non-basic arguments: all these should be used as key-value arguments extra=extra
extra is dictionary to hold not basic data like movie imdb_id,trailer,language.....
show accepts two values movie,tv
dialog:
dialog argument is important and some common useage
dialog="search" to display search virtual keybaord
dialog="setup" and dialog="login" to display the addon settings screen
dialog="torrentLink" to display the torrent info in special screen
dialog="servers" if we want to display data as in following screen
other addDir arguements are raely used and mentioned in the file iTools in the TSmedia/scripts/script.module.main/lib
getPage(baseUrl, addParams = {}, post_data = None,cloudflare=False):
getPage used to get the data from internet website.This function is well-built to handle ssl verification and timeout.
getPage acts in get and post mode.
getPage accepts 4 arguments arguments
url:link to the website
addParams: to pass header parameters dictionary,getPage by defualt use the self.HEADER defined in the __ini__ function of the addon.
post_data :to pass other params dictionary and if this argument filled the getPage function will use post mode automatically
cloudflare=default False and if site protected by cloudflare we use cloudflare=True
getSM(data,regx):
wrapper for re.findall to find single match for given regular expression,the value of this function will give empty match in failure and not error of index out of range
getMM(data,regx):
[b]same as getSM but to get list of multiple matches[/b]
[b]getDM(data,marker1,marker2)
to get data between two markers ,we use it when we cannot use regular expression
example: getDM(data,"data_source",">")
we can use with cleanhtml to clear html tags and to get text only
getDomain(url)
to get the domain name of the link,also return the image assigned to the domain and if supprted by TSmedia or not
server,image,supported=getDomain(url)
cleanhtml(data):
to clean data from html tags and return text.
resolvehost(name,url):
analyze the server link to direct link to read by the players.
getsearchtext()
to get the search term entered by the user
many other helpful functions are available in
the file iTools in the TSmedia/scripts/script.module.main/lib
colorize(text,'green'):
to colorize the text between brackets with selected color
as example
divergent(2019) appear like this when use this function
divergent(2019)
to continue
management of addon settings
RE: TSmedia addons development - mfaraj - 06-18-2020
Management of addon settings:
TSmedia addon settings do not use enigma config system as other plugins as TSmedia addon is platform independent,so we have to use local sources to store settings.TSmedia uses xml method as fastest and flexible method to do that.
settings stored in the file settings.xml in addon path/resources directory and developer can edit manually and the user can edit by TSmedia
attached typical example of settings.xml which cover all we need for TSmedia
PHP Code: <settings>
<category label="settings"> <setting label="settings" /> <setting default="OFF" id="kidsmode" label="kids mode" type="labelenum" values="OFF|ON" /> <setting default="1" id="sortmedia" label="Sort media" type="enum" values="Trending|Popular|Top Rated|Recently Added|New" /> <setting default="3" id="mediagenre" label="Media genre" type="enum" values="All|action|adventure|animation|biography|comedy|crime|documentary|drama|family|fantasy|game-show|history|horror|music|musical|mystery|romance|sci-fi|short|sport|thriller|war|western" /> <setting default="0" id="addonlanguage" label="addon language" type="enum" values="Arabic|English|French|German|Italian|Spanish" /> <setting default="false" id="needslogin" label="Needs login" type="bool" values="" /> <setting default="mfaraj57" id="username" label="user name" type="text" values="" /> <setting default="drtgyu7" id="password" label="Password" type="text" values="" /> <setting default="mfaraj57@gmail.com" id="email" label="Your email" type="text" values="" /> </category> </settings>
The components of the settings file row include
default:this is the value read by the addon with given id.
id:unique for each type of setting.
label:describe the setting item,appears as first row in TSmedia when run settings screen
values: include different values for given id.
type:type of the setting item,we usually use 4 types text,bool,labelenum,enum
text type returns text
bool type returns true,false
labelenum returns the value selected example OFF or ON in our settings file
enum return the index of selected value 0,1,2...
The following code used to manage settings and retrieve settings values.
PHP Code: from iTools import Addon settings= Addon(id='science/testsettings') value = settings.getSetting(id) print "id",value print "value",value
attached settings addon to test different addons values
to continue
images management
RE: TSmedia addons development - mfaraj - 06-19-2020
Addon images and fanart:
addon images downloaded directly form the source usually except for the main menu items of the addon,the images of main menu items stored in the /img directory in the addon path
to simplify adding posters for main menu items we use wTSmedia
open the addon
browse the item we want to assign the poster to it
on the poster double clikc,the poster save in the /img directory with name index of the item.png as in the following picture will be save as 2.png
the posters names in code of main menu should be edited in sequence
Fanart.jpg:
background image for the addon and dimension should be 1920*1080 to fit for full hd skin
but sometimes the image is too light and interfere with the color of the movies titles and make them difficult to read,to dim and darken the fanart image we use wTSmedia addon menu-draken fanart
three values available
sometimes the addon increased in size due to adding of the image,i usually use [Only registered and activated users can see links You are not allowed to view links. Register or Login to view.] application to reduce the size and dimension of the images with losing the quality
RE: TSmedia addons development - mfaraj - 06-19-2020
Addon params
addon param and addon.xml control the appearance,behavior and reaction of the addon wiith TSmedia.
Many params are available but not necessory to write then in Param file in the addon path,any param not mentioned TSmedia will consider the default value for it.
the basic params which should b written in the Param file
PHP Code: ##params## plugin_title==YTS YIFY plugin_id==ytslt section==movies subsection==general group==movies rating==5 version==1.0.8 provider==TSmedia Team Support yassinov.com
The other optional params are
PHP Code: textsize==20 textcolor==#00ffe875 infobar_forecolor==#000080 infobar_color==#00ffe875 baseurl== https://yts.lt/ style==thumbnails fanart==True mediatype==torrents downloadimage_by==thread autonext==False metadata==False subtitle==False player=="exteplayer3"
all are known except
mediatype: take values video(default),audio,picture,youtube,torrent
downloadimage_by:takes values thread(default),cfthread(for cloudflare protected images),twisted
autonext:play the next item in players automatically used mainly fro youtube clips,default False
metadata:usaully the addon display automatically the imdb data for the movie if the imdb_id is available ,but if we want TSmedia to display metadate(genre,language,country..) extracted from the source we put metadata==True default is False
subtitle:also TSmedia download subtitle and play it automatically for given movie if imdb_id is available,to make this possible we put subtitle==True default is False
player:some links in some addons played by specific player
player takes two value exteplayer3 and systemPlayer default is systemPlayer
available tools in wTSmedia-addon menu(edit params,addon settings) to help in making Param file and addon,xml
Web scraping:
means extracting data from the source and process it to be read by the local application.
Basic knowledge of regular expression is needed and ability to analyze the source by the browsers(firefox,chrome) from the development tools.
the best way to learn this by studying any known addon and looking for the code how do this task.
with time the process will be easy and interesting.
END
RE: TSmedia addons development - taplu - 05-22-2021
How can I download wTSmedia, the link does not working, Thanks
RE: TSmedia addons development - emadsaead - 09-26-2021
(06-19-2020, 08:24 AM)mfaraj Wrote: You are not allowed to view links. Register or Login to view.Addon params
addon param and addon.xml control the appearance,behavior and reaction of the addon wiith TSmedia.
Many params are available but not necessory to write then in Param file in the addon path,any param not mentioned TSmedia will consider the default value for it.
the basic params which should b written in the Param file
PHP Code: ##params## plugin_title==YTS YIFY plugin_id==ytslt section==movies subsection==general group==movies rating==5 version==1.0.8 provider==TSmedia Team Support yassinov.com
The other optional params are
PHP Code: textsize==20 textcolor==#00ffe875 infobar_forecolor==#000080 infobar_color==#00ffe875 baseurl== https://yts.lt/ style==thumbnails fanart==True mediatype==torrents downloadimage_by==thread autonext==False metadata==False subtitle==False player=="exteplayer3"
all are known except
mediatype: take values video(default),audio,picture,youtube,torrent
downloadimage_by:takes values thread(default),cfthread(for cloudflare protected images),twisted
autonext:play the next item in players automatically used mainly fro youtube clips,default False
metadata:usaully the addon display automatically the imdb data for the movie if the imdb_id is available ,but if we want TSmedia to display metadate(genre,language,country..) extracted from the source we put metadata==True default is False
subtitle:also TSmedia download subtitle and play it automatically for given movie if imdb_id is available,to make this possible we put subtitle==True default is False
player:some links in some addons played by specific player
player takes two value exteplayer3 and systemPlayer default is systemPlayer
available tools in wTSmedia-addon menu(edit params,addon settings) to help in making Param file and addon,xml
Web scraping:
means extracting data from the source and process it to be read by the local application.
Basic knowledge of regular expression is needed and ability to analyze the source by the browsers(firefox,chrome) from the development tools.
the best way to learn this by studying any known addon and looking for the code how do this task.
with time the process will be easy and interesting.
END
great works thanks
|