Hellowlol HTPC-Manager fork support thread - Printable Version +- Kodi Community Forum (https://forum.kodi.tv) +-- Forum: Support (https://forum.kodi.tv/forumdisplay.php?fid=33) +--- Forum: Supplementary Tools for Kodi (https://forum.kodi.tv/forumdisplay.php?fid=116) +--- Thread: Hellowlol HTPC-Manager fork support thread (/showthread.php?tid=221715) |
RE: Hellowlol HTPC-Manager fork support thread - GTunney - 2016-04-15 Hi Hellowlol, I upgraded the Python on my NAS but I'm now getting cherrypy errors on start. Any suggestion what might be causing it? pyopenssl is deffo installed as sab, headphones, couch are all using the same instance of python. Code: 2016-04-15 21:06:09 :: root :: INFO :: Welcome to Hellowlol's HTPC Manager fork RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-04-16 No really, except from cherrypy failing to import cherrypy. Can you read the issue guidelines on github and open a new issue and I'll look into it. RE: Hellowlol HTPC-Manager fork support thread - GTunney - 2016-04-20 Hellow should it still display fanart in the background on the now playing window in Kodi? I'm now using the QNAP package http://forum.qnap.com/viewtopic.php?f=320&t=117760 with PIL embedded so would have thought this would work but I just get the grey background. Was just asking in case this feature was removed? RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-04-20 It seems I have disabled it. I can't remember why, I hust remember that. I added additional options regarding the background image. I can enable it again RE: Hellowlol HTPC-Manager fork support thread - GTunney - 2016-04-20 I thought it was a nice touch, would be good to have the option to enable / disable it. Where are the additional options? I don't seem to be able to spot them anywhere. Is this also the case for Movie info? I'm sure that had fanart as well. RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-04-20 Sorry, it wasn't that kind of options. It was related to the image how to manipulate it etc. it wasn't intended for public use so it only exist in the image function. It will be for anything that has fanart RE: Hellowlol HTPC-Manager fork support thread - GTunney - 2016-04-20 Ah ok, well it's up to you if you chose to enable it again. Would be nice to see it back. RE: Hellowlol HTPC-Manager fork support thread - krystyan - 2016-04-26 Hi How to add Jackett (https://github.com/Jackett/Jackett) Newznab (enable) API URL:http://ip:port/torznab/indexer-name not working RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-04-26 (2016-04-26, 17:58)krystyan Wrote: Hi Hi! It will not work. Jackett are for torrents. The newznab module is for nzbs. If you want to use torrents use the torrent module. I have only included trackers that has a api, the best public trackers and the best movie tracker and TV tracker is included but you need access to them. RE: Hellowlol HTPC-Manager fork support thread - krystyan - 2016-04-26 Ok. thx I added now in "Other apps" temporarily. RE: Hellowlol HTPC-Manager fork support thread - kevcompton - 2016-05-04 Hi, I have managed to get the tvheadend module working again with HTS Tvheadend 4.1-361~gd9cf931. Still needs a bit of tidying up but at least you can now connect, list recordings, set timers, delete recordings. Need to tidy up the channel list. Tried Private messaging hellow but wouldn't let me. Code is below (2 file changes). You will also have to uncomment of adding module in main code (Htpc.py). Hope this helps someone. Kevin tvheadend.py: #!/usr/bin/env python # -*- coding: utf-8 -*- import cherrypy import htpc import logging import urllib2 import urllib import base64 import json from cherrypy.lib.auth2 import require class TVHeadend(object): def __init__(self): self.logger = logging.getLogger('modules.tvheadend') htpc.MODULES.append({ 'name': 'TVHeadend', 'id': 'tvheadend', 'test': htpc.WEBDIR + 'TVHeadend/ping', 'fields': [ {'type': 'bool', 'label': 'Enable', 'name': 'tvheadend_enable'}, {'type': 'text', 'label': 'Menu name', 'name': 'tvheadend_name'}, {'type': 'text', 'label': 'IP / Host *', 'name': 'tvheadend_host'}, {'type': 'text', 'label': 'Port *', 'name': 'tvheadend_port'}, {'type': 'text', 'label': 'Username', 'name': 'tvheadend_username'}, {'type': 'password', 'label': 'Password', 'name': 'tvheadend_password'}, {'type': 'text', 'label': 'Reverse proxy link', 'placeholder': '', 'desc': 'Reverse proxy link, e.g. https://domain.com/tvh', 'name': 'tvheadend_reverse_proxy_link'}, ] }) @cherrypy.expose() @require() def index(self): return htpc.LOOKUP.get_template("tvheadend.html").render(scriptname="tvheadend", webinterface=self.webinterface()) def webinterface(self): ip = htpc.settings.get('tvheadend_host') port = htpc.settings.get('tvheadend_port') url = 'http://%s:%s/' % (ip, port) if htpc.settings.get('tvheadend_reverse_proxy_link'): url = htpc.settings.get('tvheadend_reverse_proxy_link') return url @cherrypy.expose() @require() @cherrypy.tools.json_out() def GetEPG(self, strLimit="300", strChannel=""): return self.fetch("api/epg/events/grid", {'limit': strLimit, 'start': "0", 'channel': strChannel }) @cherrypy.expose() @require() @cherrypy.tools.json_out() def GetChannels(self): return self.fetch("api/channel/grid", { 'dir': 'ASC', 'sort': 'tags', 'limit': 1000}) @cherrypy.expose() @require() @cherrypy.tools.json_out() def GetChannelTags(self): return self.fetch("api/channeltag/list", {'op': 'listTags'}) @cherrypy.expose() @require() @cherrypy.tools.json_out() def DVRAdd(self, strEventID=""): return self.fetch("api/dvr/entry/create_by_event", {'event_id': strEventID, 'config_uuid': ''}) @cherrypy.expose() @require() @cherrypy.tools.json_out() def DVRDel(self, strEntryID=""): return self.fetch("api/idnode/delete", {'uuid': strEntryID}) @cherrypy.expose() @require() @cherrypy.tools.json_out() def DVRList(self, strType=""): return self.fetch("api/dvr/entry/grid_" + strType, None) #return self.fetch("dvrlist_" + strType, None) def fetch(self, strQuery, rgpData): rgpHeaders = {} username = htpc.settings.get("tvheadend_username", "") password = htpc.settings.get("tvheadend_password", "") if username and password: rgpHeaders['Authorization'] = 'Basic %s' % base64.encodestring('%s:%s' % (username, password)).strip('\n') # Lame debug to get as much info as possible self.logger.debug('strQuery: %s' % strQuery) self.logger.debug('rgpData: %s' % rgpData) strResponse = None strData = None if rgpData is not None: strData = urllib.urlencode(rgpData) url = "http://%s:%s/%s" % (htpc.settings.get("tvheadend_host", ""), htpc.settings.get("tvheadend_port", ""), strQuery) self.logger.debug('url: %s' % url) self.logger.debug('encoded: %s' % strData) try: pRequest = urllib2.Request("http://%s:%s/%s" % (htpc.settings.get("tvheadend_host", ""), htpc.settings.get("tvheadend_port", ""), strQuery), data = strData, headers = rgpHeaders) strResponse = urllib2.urlopen(pRequest).read() return json.loads(strResponse) except Exception as e: self.logger.error('%s %s failed error: %s' % strQuery, rgpData, e) tvheadend.js: function parseJSON(strQuery, pCallback) { $(".spinner").show(); $.getJSON(WEBDIR + "tvheadend/" + strQuery, function (pResult) { if (pCallback == null) { $(".spinner").hide(); return; } pCallback(pResult); $(".spinner").hide(); }); } function convertTimestamp(nTimestamp) { var strDate = new Date(nTimestamp * 1000).toString(); return strDate.substring(0, strDate.indexOf(' GMT')); // Strip GMT crap } function showEPG(pChannel) { parseJSON("GetEPG/300/" + pChannel.uuid, function(pResult) { var strTable = $("<table>").addClass("table table-striped table-hover").append( $("<tr>").append("<th>Name</th>") .append("<th>Start</th>") .append("<th>End</th>") .append("<th>Actions</th>") ); $.each(pResult.entries, function(nIndex, pEntry) { strTable.append($("<tr>") .append($("<td>").text(pEntry.title)) .append($("<td>").text(convertTimestamp(pEntry.start))) .append($("<td>").text(convertTimestamp(pEntry.stop))) .append($("<td>") .append($("<a>").text("REC").click(function(pEvent) { pEvent.preventDefault(); parseJSON("DVRAdd/" + pEntry.eventId, null); })) )); }); showModal(pChannel.name, strTable, { /*'Watch' : function() { strTable.html("<video controls autoplay>" + "<source src=\"http://192.168.1.11:9981/stream/channel/" + pChannel.uuid + "\"></source>" + "</video>"); }*/ } ); }); } function getChannelTags() { parseJSON("GetChannelTags", function(pResult) { $.each(pResult.entries, function(nIndex, pEntry) { // Add nav tabs $(".nav.nav-tabs").append($("<li>") .append($("<a>") .attr("href", "#tag-" + pEntry.key) .attr("data-toggle", "tab") .text(pEntry.val))); // Add tab pane var strTabPane = $("<div>").attr("id", "tag-" + pEntry.key) .attr("class", "tab-pane"); $(".tab-content").append(strTabPane.append($("<ul>").attr("id", "tag-" + pEntry.key + "-grid").attr("class", "thumbnails"))); }); getChannels(); }); $(window).trigger("hashchange"); } function getChannels() { parseJSON("GetChannels", function(pResult) { $.each(pResult.entries, function(nIndex, pEntry) { var strHTML = $("<div>").attr("class", "channel"); var pHTMLEntry = null; if (pEntry.icon != undefined) { pHTMLEntry = $("<img>").attr("src", pEntry.icon); } else { pHTMLEntry = $("<a>").text(pEntry.name); } pHTMLEntry.click(function (pEvent) { showEPG(pEntry); }); strHTML.append(pHTMLEntry); $.each(pEntry.tags, function(nIndex, nTag) { $("#tag-" + nTag + "-grid").append($("<li>").append(strHTML)); }); }); }); } function parseRecordings(strType) { var strTable = $("<table>").attr("id", "recordings_" + strType) .attr("class", "recordingtable") .append($("<tr>") .append("<th>Channel</th>") .append("<th>Title</th>") .append("<th>Start</th>") .append("<th>End</th>") .append("<th>Status</th>") .append("<th>Actions</th>") ); parseJSON("DVRList/" + strType, function(pResult) { $.each(pResult.entries, function(nIndex, pEntry) { strTable.append($("<tr>").attr("id", "recording-" + pEntry.uuid) .append($("<td>").text(pEntry.channelname)) .append($("<td>").text(pEntry.disp_title)) .append($("<td>").text(convertTimestamp(pEntry.start))) .append($("<td>").text(convertTimestamp(pEntry.stop))) .append($("<td>").text(pEntry.status)) .append($("<td>").append($("<a>").text("DEL").click(function(pEvent) { pEvent.preventDefault(); parseJSON("DVRDel/" + pEntry.uuid, function(pResult) { if (pResult.success == 1) { $("#recording-" + pEntry.uuid).fadeOut(); } }); }))) ); }); }); $("#recordings").append("<h2>" + strType.charAt(0).toUpperCase() + strType.slice(1) + " recordings</h2>") .append(strTable); } function getRecordings() { parseRecordings("upcoming"); parseRecordings("finished"); } $(document).ready(function () { getChannelTags(); getChannels(); getRecordings(); }); RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-05-04 Thats awesome. Can you send a pr on github? What tvheadend version is this tested against? (2016-05-04, 10:11)kevcompton Wrote: Hi, RE: Hellowlol HTPC-Manager fork support thread - kevcompton - 2016-05-04 Thanks. Will do, haven't used GitHub much before but will do my best. Done some more testing since posting above, just need to figure out why channels are being duplicated. I'm running it on a ReadyNas box and the version of tvheadend is 4.1 RE: Hellowlol HTPC-Manager fork support thread - hellow - 2016-05-04 They are are being duplicated since you don't remove the old content but add new stuff. Try using $(selector).empty() RE: Hellowlol HTPC-Manager fork support thread - kevcompton - 2016-05-05 (2016-05-04, 17:45)hellow Wrote: They are are being duplicated since you don't remove the old content but add new stuff. Try using $(selector).empty() I've added the latest version to GitHub. Where would you put this code? The issue is for channels that appear in 2 groups eg both TV Channels and HDTV, so the channel gets processed twice (once per group) but should only appear once in each group. But this list is being repeat so you get channel 1, channel 2, channel 3, channel 1, channel 2, channel 3. The code that looks to be wrong is this: function getChannels() { parseJSON("GetChannels", function(pResult) { $.each(pResult.entries, function(nIndex, pEntry) { $.each(pEntry.tags, function(nIndex, nTag) { var strHTML = null; var strHTML = $("<div>").attr("class", "channel"); var pHTMLEntry = null; if (pEntry.icon != undefined) { pHTMLEntry = $("<img>").attr("src", pEntry.icon); } else { pHTMLEntry = $("<a>").text(pEntry.name); } pHTMLEntry.click(function (pEvent) { showEPG(pEntry); }); strHTML.append(pHTMLEntry); $("#tag-" + nTag + "-grid").append($("<li>").append(strHTML)); }); }); }); } |