コード例 #1
0
ファイル: arte.py プロジェクト: Arkangel74/norre_kodi
def get_live_data(name):
    PLog('get_live_data:')

    import resources.lib.EPG as EPG
    rec = EPG.EPG(ID='ARTE', mode='OnlyNow')  # Daten holen
    PLog(len(rec))

    if len(rec) == 0:
        msg1 = 'Sender %s:' % name
        msg2 = 'keine EPG-Daten gefunden'
        MyDialog(msg1, msg2, '')
        return li

    title = 'Arte'
    summ = ''
    descr = ''
    vonbis = ''
    img = ''
    href = ''
    if len(rec) > 0:
        # href (PRG-Seite) hier n.b.
        img = rec[2]
        sname = rec[3]
        stime = rec[4]
        summ = rec[5]
        vonbis = rec[6]
        sname = unescape(sname)
        title = sname
        summ = unescape(summ)
        PLog("title: " + title)
        summ = "[B]LAUFENDE SENDUNG [COLOR red](%s Uhr)[/COLOR][/B]\n\n%s" % (
            vonbis, summ)
        title = sname
        try:  # 'list' object in summ möglich - Urs. n.b.
            descr = summ.replace('\n', '||')  # \n aus summ -> ||
        except Exception as exception:
            PLog(str(exception))
            descr = ''
        PLog(title)
        PLog(img)
        PLog(sname)
        PLog(stime)
        PLog(vonbis)

    zdf_streamlinks = ardundzdf.get_ZDFstreamlinks(skip_log=True)
    # Zeile zdf_streamlinks: "webtitle|href|thumb|tagline"
    for line in zdf_streamlinks:
        webtitle, href, thumb, tagline = line.split('|')
        # Bsp.: "ZDFneo " in "ZDFneo Livestream":
        if up_low('Arte ') in up_low(webtitle):  # Arte mit Blank!
            href = href
            break

    if href == '':
        PLog('%s: Streamlink fehlt' % 'Arte ')
    if img == '':
        img = thumb  # Fallback Senderlogo (+ in Main_arte)

    return title, summ, descr, vonbis, img, href
コード例 #2
0
def date_human(myformat, now=''):
    PLog("date_human:")

    if now == '':
        now = EPG.get_unixtime(onlynow=True)
    now = int(now)
    s = datetime.datetime.fromtimestamp(now)
    date_human = s.strftime(myformat)
    return date_human
コード例 #3
0
 def iterprogrammes(self):
     epg = self.getepg()
     # delete cache first
     cachefile = os.path.join(util.DICTSTORE, "EPG_%s" % epg)
     if os.path.exists(cachefile):
         os.remove(cachefile)
     for start, _url, icon, prog1, _hour, desc, _fromto, _dt, end in EPG.EPG(
             epg):
         prog = re.sub("\[.*?\]", "", prog1).split("|")[-1].strip()
         start = datetime.utcfromtimestamp(int(start)).replace(tzinfo=UTC)
         end = datetime.utcfromtimestamp(int(end)).replace(tzinfo=UTC)
         yield programme(prog, start, end, icon=icon, desc=desc)
コード例 #4
0
def test_jobs():
    PLog("test_jobs:")
    # "Das Erste|https://mcdn.daserste.de/daserste/de/master.m3u8"  - funkt. nicht
    mylist = [
        "Das Erste|https://derste247livede.akamaized.net/hls/live/658317/daserste_de/profile1/1.m3u8",
        "BR Fernsehen-Nord|http://brlive-lh.akamaihd.net/i/bfsnord_germany@119898/master.m3u8",
        "hr-fernsehen|https://hrlive1-lh.akamaihd.net/i/hr_fernsehen@75910/master.m3u8",
        "MDR Sachsen|https://mdrsnhls-lh.akamaihd.net/i/livetvmdrsachsen_de@513998/master.m3u8",
        "Radio Bremen|https://rbfs-lh.akamaihd.net/i/rb_fs@438960/master.m3u8",
        "NDR Niedersachsen|https://ndrfs-lh.akamaihd.net/i/ndrfs_nds@430233/master.m3u8",
        "NDR Hamburg|https://ndrfs-lh.akamaihd.net/i/ndrfs_hh@430231/master.m3u8",
        "SR Fernsehen|https://srlive24-lh.akamaihd.net/i/sr_universal02@107595/master.m3u8",
        "Tagesschau24|http://tagesschau-lh.akamaihd.net/i/tagesschau_1@119231/master.m3u8",
        "Deutsche Welle|https://dwstream72-lh.akamaihd.net/i/dwstream72_live@123556/master.m3u8",
        "One|http://onelivestream-lh.akamaihd.net/i/one_livestream@568814/master.m3u8",
    ]
    add_sec = 10

    now = EPG.get_unixtime(onlynow=True)
    now = int(now)
    end = now + 2 * add_sec
    now = now + add_sec

    job_list = []
    i = 0
    for item in mylist:
        i = i + 1
        sender, url = item.split('|')
        PLog("job %s" % str(i))
        end = now + 2 * add_sec
        now = now + add_sec
        title = "Testjob %s" % str(i)
        start_end = "%s|%s" % (str(now), str(end))
        descr = u"Debug: Jobliste mit ausgewählten Jobs, Startzeit: jetzt + 10 Sec., Aufnahmezeit 10 Sec. (Endzeit: Startzeit + 10 Sec.)"
        status = "waiting"
        pid = ''
        block = '4Yp2C09aF1k5YC3d'
        JobID = ''.join(random.choice(block)
                        for i in range(len(block)))  # 16 stel. Job-ID

        job = JOBLINE_TEMPL % (start_end, title, descr, sender, url, status,
                               pid, JobID)
        job_list.append(JOB_TEMPL % job)  # job -> Marker

    jobs = "\n".join(job_list)
    page = JOBLIST_TEMPL % jobs  # Jobliste -> Marker
    page = py2_encode(page)
    PLog(page[:80])

    err_msg = RSave(JOBFILE, page)  # Jobliste -> Livesystem
    return
コード例 #5
0
def Kika_Live():
	PLog('Kika_Live:')
	li = xbmcgui.ListItem()
	li = home(li, ID='Kinderprogramme')			# Home-Button
	
	import resources.lib.EPG as EPG
	zdf_streamlinks = ardundzdf.get_ZDFstreamlinks()
	# Zeile zdf_streamlinks: "webtitle|href|thumb|tagline"
	for line in zdf_streamlinks:
		webtitle, href, thumb, tagline = line.split('|')
		# Bsp.: "ZDFneo " in "ZDFneo Livestream":
		if up_low('KiKA ') in up_low(webtitle): 	# Sender mit Blank!
			m3u8link = href
			break
	if m3u8link == '':
		PLog('%s: Streamlink fehlt' % 'KiKA ')
	
	ID = 'KIKA'
	title = 'KIKA TV-Live'
	Merk = ''
	
	rec = EPG.EPG(ID=ID, mode='OnlyNow')		# Daten holen - nur aktuelle Sendung
	PLog(rec)	# bei Bedarf
	if len(rec) == 0:							# EPG-Satz leer?
		title = 'EPG nicht gefunden'
		summ = ''
		tagline = ''
	else:	
		href=rec[1]; img=rec[2]; sname=rec[3]; stime=rec[4]; summ=rec[5]; vonbis=rec[6]
		if img.find('http') == -1:	# Werbebilder today.de hier ohne http://
			img = R('tv-kika.png')
		title 	= sname.replace('JETZT', ID)		# JETZT durch Sender ersetzen
		# sctime 	= "[COLOR red] %s [/COLOR]" % stime			# Darstellung verschlechtert
		# sname 	= sname.replace(stime, sctime)
		tagline = 'Zeit: ' + vonbis
				
	title = unescape(title); title = repl_json_chars(title)
	summ = unescape(summ); summ = repl_json_chars(summ)
	PLog("title: " + title); PLog(summ)
	title=py2_encode(title); m3u8link=py2_encode(m3u8link);
	img=py2_encode(img); summ=py2_encode(summ);			
	fparams="&fparams={'path': '%s', 'title': '%s', 'thumb': '%s', 'descr': '%s', 'Merk': '%s'}" %\
		(quote(m3u8link), quote(title), quote(img), quote_plus(summ), Merk)
	addDir(li=li, label=title, action="dirList", dirID="ardundzdf.SenderLiveResolution", fanart=R('tv-EPG-all.png'), 
		thumb=img, fparams=fparams, summary=summ, tagline=tagline)

	xbmcplugin.endOfDirectory(HANDLE, cacheToDisc=True)
コード例 #6
0
def JobStop(sender, job_title, start_end, job_active, pid, JobID):
    PLog("JobStop:")
    PLog(pid)
    PLog(JobID)
    PLog(job_active), PLog(start_end)

    if sender:  # fehlt beim Recording
        msg1 = "%s: %s" % (sender, job_title)
    else:
        msg1 = job_title

    PLog("kill_pid: %s" % str(pid))
    os.kill(int(pid),
            signal.SIGTERM)  # auch Windows10 OK (aber Teilvideo beschäd.)

    icon = MSG_ICON
    xbmcgui.Dialog().notification("Jobliste:", u"Job wird gestoppt", icon,
                                  3000)

    now = EPG.get_unixtime(onlynow=True)
    jobs = ReadJobs()  # s. util
    newjob_list = []
    # newjob_list: Liste nach Änderungen
    job_title = py2_encode(job_title)
    # type kann vom code-Format in jobs abweichen
    for job in jobs:
        my_JobID = stringextract('<JobID>', '</JobID>', job)
        if JobID in my_JobID:  # sonst unverändert
            my_start_end = stringextract('<startend>', '</startend>', job)
            start, end = my_start_end.split('|')
            end = int(now) - 1  # end anpassen (Job abgelaufen)
            new_start_end = "%s|%d" % (start, end)
            job = job.replace(
                my_start_end,
                new_start_end)  # job: <startend></startend> ändern
            PLog(my_start_end)
            PLog(new_start_end)

        newjob_list.append(JOB_TEMPL % job)  # job -> Marker

    save_Joblist(jobs, newjob_list, "Jobliste:", "")  # ohne notification
    return
コード例 #7
0
def Kika_Live():
	PLog('Kika_Live')
	li = xbmcgui.ListItem()
	li = home(li, ID='Kinderprogramme')			# Home-Button
	
	import resources.lib.EPG as EPG
	m3u8link = 'https://kikade-lh.akamaihd.net/i/livetvkika_de@450035/master.m3u8'	# neu 07.12.2017
	
	ID = 'KIKA'
	title = 'KIKA TV-Live'
	Merk = ''
	
	rec = EPG.EPG(ID=ID, mode='OnlyNow')		# Daten holen - nur aktuelle Sendung
	PLog(rec)	# bei Bedarf
	if len(rec) == 0:							# EPG-Satz leer?
		title = 'EPG nicht gefunden'
		summ = ''
		tagline = ''
	else:	
		href=rec[1]; img=rec[2]; sname=rec[3]; stime=rec[4]; summ=rec[5]; vonbis=rec[6]
		if img.find('http') == -1:	# Werbebilder today.de hier ohne http://
			img = R('tv-kika.png')
		title 	= sname.replace('JETZT', ID)		# JETZT durch Sender ersetzen
		# sctime 	= "[COLOR red] %s [/COLOR]" % stime			# Darstellung verschlechtert
		# sname 	= sname.replace(stime, sctime)
		tagline = 'Zeit: ' + vonbis
				
	title = unescape(title); title = repl_json_chars(title)
	summ = unescape(summ); summ = repl_json_chars(summ)
	PLog("title: " + title); PLog(summ)
	title=py2_encode(title); m3u8link=py2_encode(m3u8link);
	img=py2_encode(img); summ=py2_encode(summ);			
	fparams="&fparams={'path': '%s', 'title': '%s', 'thumb': '%s', 'descr': '%s', 'Merk': '%s'}" %\
		(quote(m3u8link), quote(title), quote(img), quote_plus(summ), Merk)
	addDir(li=li, label=title, action="dirList", dirID="ardundzdf.SenderLiveResolution", fanart=R('tv-EPG-all.png'), 
		thumb=img, fparams=fparams, summary=summ, tagline=tagline)

	xbmcplugin.endOfDirectory(HANDLE, cacheToDisc=True)
コード例 #8
0
        tcont = re.sub("ADDON_PATH[\s\t]*?=[\s\t]*?SETTINGS.getAddonInfo.+?\n",
                       "ADDON_PATH = '%s'\n" % ardundzdf, tcont)
        tcont = re.sub(
            "USERDATA[\s\t]*?=[\s\t]*?xbmc.translatePath.+?\n",
            "USERDATA = '%s'\n" %
            os.path.join(addon.get_addondir("plugin.video.livestreams"), ""),
            tcont)
        tcont = re.sub("HANDLE[\s\t]*?=[\s\t]*?int.+?\n", "HANDLE = 1", tcont)
    with open(tfile, "w") as f:
        f.write(tcont)

from resources.lib import util
from resources.lib import EPG
util.check_DataStores()

e = EPG.EPG("ARD")


class multi():
    categories = ["Deutschland"]
    title = u"Das Erste"
    iconpath = os.path.join(ardundzdf, "resources", "images", "")
    usehlsproxy = False
    sender = "Das Erste"
    epg = None
    link = None

    def _link_epg(self):
        if not self.link or not self.epg:
            _, link, epg = util.get_playlist_img(self.sender)
        if not self.link:
コード例 #9
0
def JobMonitor():
    PLog("JobMonitor:")
    pre_rec = SETTINGS.getSetting(
        'pref_pre_rec')  # Vorlauf (Bsp. 00:15:00 = 15 Minuten)
    post_rec = SETTINGS.getSetting('pref_post_rec')  # Nachlauf (dto.)
    pre_rec = re.search('= (\d+) Min', pre_rec).group(1)
    post_rec = re.search('= (\d+) Min', post_rec).group(1)
    if pre_rec == '0':
        pre_rec = JOBDELAY  # Ausgleich Intervall

    if os.path.exists(JOB_STOP):  # Ruine?
        os.remove(JOB_STOP)

    old_age = 0
    if os.path.exists(JOBFILE):
        jobs = ReadJobs()  # s. util
        old_age = os.stat(
            JOBFILE).st_mtime  # Abgleich in Monitor (z.Z. n.verw.)
    else:
        jobs = []
    PLog("JOBFILE_old_age: %d" % old_age)

    i = 0
    monitor = xbmc.Monitor()
    while not monitor.abortRequested():
        i = i + 1
        PLog("Monitor_Lauf: %d" % i)

        if get_Setting('pref_epgRecord') == 'false':  # direkter Zugriff (s.o.)
            PLog("Monitor: pref_epgRecord false - stop")
            xbmcgui.Dialog().notification("Aufnahme-Monitor:", "gestoppt",
                                          MSG_ICON, 3000)
            break

        open(MONITOR_ALIVE,
             'w').close()  # Lebendsignal - Abgleich mtime in JobMain

        xbmc.sleep(JOBDELAY * 1000)  # Pause
        # xbmc.sleep(2000)	# Debug
        if os.path.exists(JOB_STOP):
            PLog("Monitor: JOB_STOP gefunden - stop")
            xbmcgui.Dialog().notification("Aufnahme-Monitor:", "gestoppt",
                                          MSG_ICON, 3000)
            break

        if os.path.exists(JOBFILE):  # bei jedem Durchgang neu einlesen
            jobs = ReadJobs()
        else:
            jobs = []

        now = EPG.get_unixtime(onlynow=True)
        now = int(now)
        now_human = date_human("%Y.%m.%d_%H:%M:%S", now='')  # Debug

        #---------------------------------------------------		# Schleife Jobliste
        PLog("scan_jobs:")
        newjob_list = []
        cnt = 0
        job_changed = False  # newjob_list: Liste nach Änderungen
        for cnt in range(len(jobs)):
            myjob = jobs[cnt]
            PLog(myjob[:80])
            status = stringextract('<status>', '</status>', myjob)
            PLog("scan_Job %d status: %s" % (cnt + 1, status))

            start_end = stringextract('<startend>', '</startend>', myjob)
            start, end = start_end.split('|')  # 1593627300|1593633300
            start = int(
                start) - int(pre_rec) * 60  # Vorlauf (Min -> Sek) abziehen
            end = int(
                end) + int(post_rec) * 60  # Nachlauf (Min -> Sek) aufschlagen
            start_human = date_human("%Y.%m.%d_%H:%M:%S", now=start)
            mydate = date_human(
                "%Y%m%d_%H%M%S",
                now=start)  # Zeitstempel für titel in LiveRecord
            end_human = date_human("%Y.%m.%d_%H:%M:%S", now=end)

            duration = end - start  # in Sekunden für ffmpeg
            diff = start - now
            vorz = ''
            if diff < 0:
                vorz = "minus "
            diff = seconds_translate(diff)

            laenge = ""
            PIDffmpeg = ''  # laenge entfällt hier
            # PLog("now %s, start %s, end %s" % (now, start, end))  # Debug
            PLog("now %s, start %s, end %s, start-now: %s" %
                 (now_human, start_human, end_human, diff))

            #---------------------------------------------------	# 1 Job -> Aufnahme
            if (now >= start and now <= end
                ) and status == 'waiting':  # Job ist aufnahmereif
                PLog("Job ready: " + start_end)
                duration = end - now  # Korrektur, falls start schon überschritten
                url = stringextract('<url>', '</url>', myjob)
                JobID = stringextract('<JobID>', '</JobID>', myjob)
                sender = stringextract('<sender>', '</sender>', myjob)
                title = stringextract('<title>', '</title>', myjob)
                title = "%s: %s" % (sender, title)  # Titel: Sender + Sendung
                descr = stringextract('<descr>', '</descr>', myjob)

                started = date_human("%Y.%M.D_%H:%M:%S", now=start)
                dfname = make_filenames(title.strip())  # Name aus Titel
                # Textdatei
                txttitle = "%s_%s" % (mydate, dfname
                                      )  # Zeitstempel wie inLiveRecord
                detailtxt = MakeDetailText(title=txttitle,
                                           thumb='',
                                           quality='Livestream',
                                           summary=descr,
                                           tagline='',
                                           url=url)
                detailtxt = py2_encode(detailtxt)
                txttitle = py2_encode(txttitle)
                storetxt = 'Details zur Aufnahme ' + txttitle + ':\r\n\r\n' + detailtxt
                dest_path = SETTINGS.getSetting('pref_download_path')
                textfile = txttitle + '.txt'

                dfname = dfname + '.mp4'  # LiveRecord ergänzt Zeitstempel
                textfile = py2_encode(textfile)
                pathtextfile = os.path.join(dest_path, textfile)
                storetxt = py2_encode(storetxt)
                RSave(pathtextfile, storetxt)  # Begleitext speichern

                # duration = "00:00:10"	# Debug: 10 Sec.
                PLog("Satz:")
                PLog(url)
                PLog(title)
                PLog(duration)
                PLog(detailtxt)
                PLog(started)

                myjob = myjob.replace('<status>waiting', '<status>gestartet')
                PLog("Job %d started" % cnt)
                job_changed = True

                PIDffmpeg = LiveRecord(url,
                                       title,
                                       duration,
                                       laenge='',
                                       epgJob=mydate,
                                       JobID=JobID)  # Aufnehmen
                myjob = myjob.replace('<pid></pid>',
                                      '<pid>%s</pid>' % PIDffmpeg)

            #---------------------------------------------------	# Job zurück in Liste
            jobs[cnt] = JOB_TEMPL % myjob  # Job -> Listenelement
            PLog("Job %d PIDffmpeg: %s" % (cnt + 1, PIDffmpeg))
            cnt = cnt + 1  # und nächster Job

        #---------------------------------------------------		# Jobliste speichern, falls geändert
        if job_changed:
            newjobs = "\n".join(jobs)
            page = JOBLIST_TEMPL % newjobs  # Jobliste -> Marker
            page = py2_encode(page)
            PLog(u"geänderte Jobliste speichern:")
            PLog(page[:80])
            open(JOBFILE_LOCK, 'w').close()  # Lock ein
            err_msg = RSave(JOBFILE, page)  # Jobliste speichern
            xbmc.sleep(500)
            if os.path.exists(JOBFILE_LOCK):  # Lock aus
                os.remove(JOBFILE_LOCK)

    if os.path.exists(MONITOR_ALIVE):  # Aufräumen nach Monitor-Ende
        os.remove(MONITOR_ALIVE)

    return
コード例 #10
0
def JobListe():  # Liste, Job-Status, Jobs löschen
    PLog("JobListe:")

    li = xbmcgui.ListItem()
    li = home(li, ID=NAME)  # Home-Button

    if os.path.exists(JOBFILE):
        jobs = ReadJobs()  # s. util
        if len(jobs) == 0:
            xbmcgui.Dialog().notification("Jobliste:",
                                          "keine Aufnahme-Jobs vorhanden",
                                          MSG_ICON, 3000)
    else:
        xbmcgui.Dialog().notification("Jobliste:", "nicht gefunden", MSG_ICON,
                                      3000)

    now = EPG.get_unixtime(onlynow=True)
    now = int(now)

    globFiles = "%s/ThreadKill_*" % ADDON_DATA  # KillFile-Ruinen löschen
    files = glob.glob(globFiles)
    if len(files) > 0:
        max_rec_time = 43200  # 12 Std. = max. Setting pref_LiveRecord_duration
        OldKillFile = files[
            0]  # 1 reicht, ev. Rest wird bei Folge-Calls abgeräumt
        if os.stat(OldKillFile).st_mtime < (
                now - max_rec_time):  # falls älter als max_rec_time
            PLog("entferne OldKillFile: %s" % OldKillFile)
            os.remove(OldKillFile)

    now_human = date_human("%d.%m.%Y, %H:%M", now='')
    pre_rec = SETTINGS.getSetting(
        'pref_pre_rec')  # Vorlauf (Bsp. 00:15:00 = 15 Minuten)
    post_rec = SETTINGS.getSetting('pref_post_rec')  # Nachlauf (dto.)
    pre_rec = re.search('= (\d+) Min', pre_rec).group(1)
    post_rec = re.search('= (\d+) Min', post_rec).group(1)
    anz_jobs = len(jobs)
    jobs.sort()

    for cnt in range(len(jobs)):
        myjob = jobs[cnt]
        PLog(myjob[:80])
        status = stringextract('<status>', '</status>', myjob)
        status_real = status  # wird aktualisiert s.u.
        PLog("JobListe_Job %d status: %s" % (cnt + 1, status))

        start_end = stringextract('<startend>', '</startend>', myjob)
        start, end = start_end.split('|')  # 1593627300|1593633300
        start = int(start)
        end = int(end)
        descr = stringextract('<descr>', '</descr>', myjob)
        PLog(descr)
        if "Recording Live" in descr == False:  # Vor- und Nachlauf entfallen
            pass
        else:
            start = int(
                start) - int(pre_rec) * 60  # Vorlauf (Min -> Sek) abziehen
            end = int(
                end) + int(post_rec) * 60  # Nachlauf (Min -> Sek) aufschlagen
        mydate = date_human("%Y%m%d_%H%M%S",
                            now=start)  # Zeitstempel für titel in LiveRecord
        start_human = date_human("%d.%m.%Y, %H:%M", now=start)
        end_human = date_human("%d.%m.%Y, %H:%M", now=end)

        pid = stringextract('<pid>', '</pid>', myjob)
        title = stringextract('<title>', '</title>', myjob)
        job_title = title  # Abgleich in JobRemove alt
        JobID = stringextract('<JobID>', '</JobID>',
                              myjob)  # Abgleich in JobRemove neu
        sender = stringextract('<sender>', '</sender>', myjob)
        dfname = title.strip()  # Recording Live: ohne Sender
        if sender:
            dfname = "%s: %s" % (sender, title
                                 )  # Titel: Sender + Sendung (mit Mark.)
        dfname = make_filenames(dfname.strip()) + ".mp4"  # Name aus Titel
        dfname = "%s_%s" % (mydate, dfname)  # wie LiveRecord
        dest_path = SETTINGS.getSetting('pref_download_path')
        video = os.path.join(dest_path, dfname)
        PLog("video: " + video)
        status_add = ""
        if os.path.exists(video):
            status_add = " | Video vorhanden: %s.." % dfname[:
                                                             28]  # für Infobereich begrenzen
        else:
            status_add = " | Video fehlt: %s.." % dfname[:28]  # dto.

        title = cleanmark(title)
        title = title.replace("JETZT: ", '')

        img = MSG_ICON  # rot
        PLog(" end %s, now %s" % (end, now))
        job_active = False
        if end < now:  # abgelaufen
            img = R("icon-record-grey.png")  # grau
            if status == "gestartet":
                status_real = "[B] Jobstatus: Aufnahme wurde gestartet [/B]" + status_add
            else:
                status_real = "[B] Jobstatus: Aufnahme wurde nicht gestartet [/B] - Ursache nicht bekannt"
        else:  # noch aktiv
            img = MSG_ICON  # grau
            job_active = True
            status_real = "Aufnahme geplant: %s" % start_human

        label = u'Job löschen: %s' % title
        if job_active:
            label = u'Job stoppen / löschen: %s' % title
        tag = u'Start: [B]%s[/B], Ende: [I][B]%s[/B][/I]' % (start_human,
                                                             end_human)
        tag = u'%s\n%s' % (tag, status_real)

        max_reclist = SETTINGS.getSetting('pref_max_reclist')
        summ = u'[B]Anzahl Jobs[/B] in der Aufnahmeliste: %s' % (anz_jobs)
        summ = u"%s\n[B]Settings[/B]:\n[B]max. Größe der Aufnahmeliste:[/B] %s Jobs," % (
            summ, max_reclist)
        summ = u"%s[B]Vorlauf:[/B] %s Min., [B]Nachlauf:[/B] %s Min." % (
            summ, pre_rec, post_rec)
        fparams="&fparams={'sender':'%s','job_title':'%s','start_end':'%s','job_active':'%s','pid':'%s','JobID':'%s'}" %\
         (sender, job_title, start_end, job_active, pid, JobID)
        addDir(li=li,
               label=label,
               action="dirList",
               dirID="resources.lib.epgRecord.JobRemove",
               fanart=R(ICON_DOWNL_DIR),
               thumb=img,
               fparams=fparams,
               tagline=tag,
               summary=summ)

    xbmcplugin.endOfDirectory(HANDLE, cacheToDisc=False)
コード例 #11
0
def JobMain(action,
            start_end='',
            title='',
            descr='',
            sender='',
            url='',
            setSetting='',
            PIDffmpeg=''):
    PLog("JobMain:")
    PLog(action)
    PLog(sender)
    PLog(title)
    PLog(descr)
    PLog(start_end)
    PLog(PIDffmpeg)

    # mythreads = threading.enumerate()								# liefert in Kodi nur MainThread
    status = os.path.exists(MONITOR_ALIVE)
    PLog("MONITOR_ALIVE pre: " + str(status))  # Eingangs-Status
    now = EPG.get_unixtime(onlynow=True)

    #------------------------
    if action == 'init':  # bei jedem Start ardundzdf.py
        if setSetting:  # Aufruf: DownloadTools
            SETTINGS.setSetting('pref_epgRecord', 'true')
            xbmcgui.Dialog().notification("Aufnahme-Monitor:",
                                          "Start veranlasst", MSG_ICON, 3000)
            xbmc.executebuiltin('Container.Refresh')
            return

        if os.path.exists(MONITOR_ALIVE):  # check Lebendsignal
            mtime = os.stat(MONITOR_ALIVE).st_mtime
            diff = int(now) - mtime
            PLog("now: %s, mtime: %d, diff: %d" % (now, mtime, diff))

            if diff > JOBDELAY:  # Monitor tot?
                PLog(
                    "alive_veraltet: force init")  # abhängig von JOBFILE, s.u.
                os.remove(MONITOR_ALIVE)
            else:
                PLog("alive_aktuell: return")
                return
        else:
            PLog("alive_fehlt: force init")  # dto.

        if check_file(JOBFILE) == False:  # JOBFILE leer/fehlt - kein Hindernis
            PLog("Aufnahmeliste leer")

        if os.path.exists(MONITOR_ALIVE) == False:  # JobMonitor läuft bereits?
            bg_thread = Thread(
                target=JobMonitor,  # sonst Thread JobMonitor starten
                args=())
            bg_thread.start()
            xbmcgui.Dialog().notification("Aufnahme-Monitor:", "gestartet",
                                          MSG_ICON, 3000)
        else:
            PLog("running - skip init")
        return

    #------------------------
    if action == 'stop':  # DownloadTools <-
        jobs = ReadJobs()  # s. util
        now = EPG.get_unixtime(onlynow=True)
        job_active = False
        PLog('Mark0')
        for job in jobs:
            start_end = stringextract('<startend>', '</startend>', job)
            start, end = start_end.split('|')  # 1593627300|1593633300
            if int(start) > int(now):
                job_active = True
                break

        if job_active:
            title = 'Aufnahme-Monitor stoppen'
            msg1 = "Mindestens ein Aufnahmejob ist noch aktiv!"
            msg2 = "Aufnahme-Monitor trotzdem stoppen?"
            ret = MyDialog(msg1=msg1,
                           msg2=msg2,
                           msg3='',
                           ok=False,
                           cancel='Abbruch',
                           yes='JA',
                           heading=title)
            if ret != 1:
                return

        open(JOB_STOP, 'w').close()  # STOPFILE anlegen
        SETTINGS.setSetting(
            'pref_epgRecord',
            'false')  # Setting muss manuell wieder eingeschaltet werden
        PLog("JOB_STOP set")  # Status
        xbmc.executebuiltin('Container.Refresh')
        xbmcgui.Dialog().notification("Aufnahme-Monitor:", "Stop veranlasst",
                                      MSG_ICON,
                                      3000)  # Notification im Monitor
        # test_jobs		# Debug
        return

    #------------------------
    # die für Recording Live (LiveRecord) erzeugten Jobs werden nicht im JobMonitor
    # 	abgearbeitet, sondern direkt in m3u8.Main_m3u8 - entfallen mit Ende des
    #   experimentellen m3u8-Aufnahmeverfahrens 30.08.2020
    if action == 'setjob':  # neuen Job an Aufnahmeliste anhängen + Bereinigung: Doppler
        # 	verhindern, Einträge auf pref_max_reclist beschränken
        title = cleanmark(title)  # Farbe/fett aus ProgramRecord
        block = '4Yp2C09aF1k5YC3d'
        JobID = ''.join(random.choice(block)
                        for i in range(len(block)))  # 16 stel. Job-ID
        if "Recording Live" in descr:  # Aufruf: LiveRecord, Start ohne EPG
            status = 'gestartet'  # -> <status>,  für JobMonitor tabu
            pid = "Thread_%s" % JobID  # -> KillFile (JobRemove) - wie JobMonitor
        else:
            status = 'waiting'
            if PIDffmpeg:  # Aufruf: LiveRecord via ffmpeg
                status = 'gestartet'  # -> <status>,  für JobMonitor tabu
            pid = PIDffmpeg  # aus LiveRecord direkt oder via JobMonitor

        job_line = JOBLINE_TEMPL % (start_end, title, descr, sender, url,
                                    status, pid, JobID)
        new_job = JOB_TEMPL % job_line
        PLog(new_job[:80])
        jobs = ReadJobs()  # s. util

        job_list = []
        cnt = 0  # Neubau Jobliste
        # Kontrolle erweitern, falls startend + sender nicht eindeutig genug:
        for job in jobs:
            list_startend = stringextract('<startend>', '</startend>', job)
            list_sender = stringextract('<sender>', '</sender>', job)
            if list_startend == start_end and list_sender == sender:  # Kontrolle Doppler
                msg1 = "%s: %s\nStart/Ende (Unix-Format): %s" % (sender, title,
                                                                 start_end)
                msg2 = "Sendung ist bereits in der Jobliste - Abbruch"
                MyDialog(msg1, msg2, '')
                PLog("%s\n%s" % (msg1, msg2))
                return  # alte Liste unverändert
            else:
                job_list.append(JOB_TEMPL % job)  # job -> Marker
                cnt = cnt + 1

        new_job = py2_encode(new_job)
        job_list.append(new_job)  # neuen Job anhängen
        maxlen = int(SETTINGS.getSetting('pref_max_reclist'))
        if len(job_list) > maxlen:
            while len(job_list) > maxlen:
                del job_list[0]  # 1. Satz entf.
                PLog('%d/%d, Job entfernt: %s' %
                     (maxlen, len(job_list), job_list[0]))
        jobs = "\n".join(job_list)
        page = JOBLIST_TEMPL % jobs  # Jobliste -> Marker
        page = py2_encode(page)
        PLog(page[:80])

        open(JOBFILE_LOCK, 'w').close()  # Lock ein
        err_msg = RSave(JOBFILE, page)  # Jobliste speichern
        if os.path.exists(JOBFILE_LOCK):  # Lock aus
            os.remove(JOBFILE_LOCK)

        xbmcgui.Dialog().notification("Aufnahme-Monitor:", "Job hinzugefügt",
                                      MSG_ICON, 3000)
        PLog("JobID: %s" % JobID)
        if "ffmpeg-recording" in descr:  # LiveRecord ffmpeg
            return JobID
        else:
            if os.path.exists(
                    MONITOR_ALIVE) == False:  # JobMonitor läuft bereits?
                bg_thread = Thread(
                    target=JobMonitor,  # sonst Thread JobMonitor starten
                    args=())
                bg_thread.start()
        return
    #------------------------
    if action == 'listJobs':  # Liste, Job-Status, Jobs löschen
        JobListe()
        return

    #------------------------
    if action == 'deljob':  # Job aus Aufnahmeliste entfernen
        JobRemove()
        return

    #------------------------
    if action == 'test_jobs':  # Testfunktion
        test_jobs()
        return