• The forum software that supports hummy.tv has been upgraded to XenForo 2.3!

    Please bear with us as we continue to tweak things, and feel free to post any questions, issues or suggestions in the upgrade thread.

[webif] Web Interface 1.4.x

Status
Not open for further replies.
Is this not a perennial problem for anyone who likes to impose their own local CSS (and a reason for not bothering)?
 
That's a change that came in with webif 1.2.7 back in February 2016. Links on the main menu go through the /go/ route so that plugins can re-route requests or add their own. Nothing has changed there recently.

Is it the trailing ? on the final URL that's causing you problems? That's only the query string so should be the same as the first URL.
 
That's a change that came in with webif 1.2.7 back in February 2016. Links on the main menu go through the /go/ route so that plugins can re-route requests or add their own. Nothing has changed there recently.
Well, it's only made itself known this week.
Is it the trailing ? on the final URL that's causing you problems? That's only the query string so should be the same as the first URL.
Fixed it.
Changed the "Applies to" dropdown from "URL" to "URLs starting with".

Thanks for your reply.
 
Feature request: on the media management pages, for all files ticked provide a multi-file download option.
 
As reported by @Raydon and Matthew, there's a problem with Opt+ menu commands applied to recordings with '&' in the pathname.

At /mod/lib/jim/cgi.tcl line 70, query parameters are extracted as below and inserted into a tcl dict used by cgi_get:
Code:
        set pairs [split $input &]
Filenames, and in fact all externally supplied parameter values, need to be encoded in the HTTP request (eg & -> %26) and then decoded after splitting the query parameters.
Looking at /mod/webif/html/browse/script.js l.428
Code:
var menuclick = function(action, el, pos)                                
{                                                                        
        var file = $(el).parent().prevAll('a.bf').last().attr('file');   
        var efile = encodeURIComponent(file);                            
...
        switch (action)                                                        
        {                                                                      
...
            default:                                                          
                if (plugins.menu[action])                                     
                        plugins.menu[action](file);                           
                else                                                          
                        alert('Unhandled action: ' + action);                  
                break;                                                        
        }
}
Then in (eg) /mod/webif/plugin/sidecar/browse.js:
Code:
...
// Action taken when 'sidecar' action clicked on native recording.
plugins.menu.sidecar = function(file) {                           
        window.location = '/plugin/sidecar/web/?file=' + file;
...
Shouldn't the various .?menuclick() functions in /mod/webif/html/browse/script.js pass encodeURIComponent(file) rather than file? Or are plugins at fault for not calling encodeURIComponent() on the filename passed to them?

When I make the former set of changes, I'm able to invoke DecryptAds 'Run Analysis Now' successfully on a file with '&' in either its base name or its folder name, although strangely I had to do
Code:
chmod +x /mod/webif/plugin/detectads/web/runnow.jim
to avoid a "server error" response.

After thinking about this again, I think it's down to the plugins. There's no suggestion that the file parameter of the various plugin APIs is anything other than a system file name, so a plugin that wants to use it as part of a URI ought to sanitise it first, as below:
Code:
...
// Action taken when [whichever plugin] action clicked on native recording.
plugins.menu.whichever = function(file) {                           
        window.location = '/plugin/whichever/web/?file=' + encodeURIComponent(file);
...
What do affected WebIf/plugin authors (looks like WebIf, Sweeper? Sidecar, DetectAds) think?
 
Last edited:
Searches for CRIDs with '/' characters in them (as used these days by the BBC) don't work via items on the WebIf's Scheduled Events page.
Here's a fix:
Diff:
humax /mnt/hd2/mod/webif/html/sched/rpc # diff info.jim~ info.jim
--- info.jim~
+++ info.jim
@@ -68,7 +68,7 @@
        </tr>
"

-set crid [join [lrange [split [$event get szCRID] /] 1 end]]
+set crid [join [lrange [split [$event get szCRID] /] 1 end] /]
if {$crid != ""} {
        puts "<tr><th>"
        if {[$event isseries]} { puts "Series" } else { puts "Event" }
@@ -88,7 +88,7 @@
                set ev [string range $ev 1 end]
                if {$flag} { puts "<br>" }
                incr flag
-               set crid [join [lrange [split $ev /] 1 end]]
+               set crid [join [lrange [split $ev /] 1 end] /]
                puts -nonewline "<a href=/cgi-bin/epg/search.jim?"
                puts "crid=/$crid>
                    <img border=0 src=/images/421_1_00_CH_Title_2R_Arrow.png

Somewhere there's also a case-sensitivity problem as I've got things like /M/ABCDE in my database, whereas the current EPG has them as /m/ABCDE. The Humax seemingly doesn't care about this, but the WebIf's CRID search does.
 
Slight tweak to the WebIF Schedule Backup/Restore page please:

Select an existing backup to view, and the radio button for it resets. That means, having viewed it, in order to actually restore it (or delete it) the radio button has to be selected again (with the risk you select the wrong one by accident). Is it easy to make the radio buttons sticky, so they persist beyond the view operation?
 
Slight tweak to the WebIF Schedule Backup/Restore page please:
...
It's not completely obvious, but as I also wanted this improvement I had a look.

I added a 'Close View' button to the Backup/Restore display webif/html/sched/backup/index.jim and script changes webif/html/sched/backup/script.js to show/hide the new button and reselect the viewed item together with enabled Restore and Delete buttons after clicking 'View' (alternatively, you could morph the View button).

Like this:
Code:
--- index.jim.org
+++ index.jim
@@ -51,6 +51,7 @@
        <button id=restore_button disabled>Restore Backup</button>
        <button id=delete_button disabled>Delete Backup</button>
        <button id=view_button disabled>View Backup</button>
+       <button id=close_view_button disabled>Close View</button>
        <br>
        <div id=restore_working class=va style="display: none;">
                <img class=va src=/img/spin.gif>&nbsp;
[And this:
code=webif/html/sched/backup/script.js ]
--- script.js.org
+++ script.js
@@ -1,8 +1,9 @@

-function refresh_backup_files()
+function refresh_backup_files(viewedItemVal)
{
- $('#restore_button,#delete_button,#view_button')
+ $('#restore_button,#delete_button,#view_button,#close_view_button')
.button('option', 'disabled', true);
+ $('#close_view_button').hide();
$('#backup_files').load('backup/files.jim', function() {
$('input.restore').change(function() {
$('#restore_button,#delete_button,#view_button')
@@ -10,6 +11,20 @@
.button('option', 'disabled', false);
});
});
  • if (viewedItemVal) {
  • var itm=$('input.restore[value="'+viewedItemVal+'"]');
  • if (itm) {
  • itm.attr('checked',true);
  • $('#restore_button,#delete_button')
  • .removeAttr('disabled')
  • .button('option', 'disabled', false);
  • }
  • $('#close_view_button')
  • .removeAttr('disabled')
  • .button('option', 'disabled', false)
  • .show();
  • }
}

function backup_loaded()
@@ -19,6 +34,7 @@
$('#restore_button').button({icons: {primary: "ui-icon-play"}});
$('#delete_button').button({icons: {primary: "ui-icon-trash"}});
$('#view_button').button({icons: {primary: "ui-icon-script"}});
+$('#close_view_button').button({icons: {primary: "ui-icon-script"}});

refresh_backup_files();

@@ -49,9 +65,13 @@
$('#backup_results').load('backup/view.jim?' +
$('input.restore').serialize(), function() {
$('#backup_results').slideDown(function() {
- refresh_backup_files();
+ refresh_backup_files(backup);
});
});
+});
+$('#close_view_button').click(function() {
  • $('#backup_results').slideUp();
  • refresh_backup_files();
});
$('#restore_button').click(function() {
var backup = $('input.restore:checked').val();
[/code]

The jQuery $() function essentially maps over the results of the DOM function document.querySelectorAll(), which
returns a list of HTML elements matching a specified CSS selector. Each item in the backup list is an <input> element with class restore whose value is the name displayed next to the radio button. Thus the item being viewed can be found using a CSS attribute selector input.restore[value=selectedItemValue].

After further testing I see that there is a race condition in the original modified script, which normally (eg, when not running in the debugger) led to the selected backup item being cleared while displaying its view. This resulted from me Doing It Wrong.

The relevant hacks need to be applied in the jQuery completion callback function, the second parameter passed to the load method when loading the backup list. By doing it right, selection of a different backup while displaying the view of a backup can also be handled (closes the view), and the backup selection is retained as long as it makes sense and isn't changed.

Instead, like this:
Code:
--- script.js.org
+++ script.js
@@ -1,14 +1,37 @@
 
-function refresh_backup_files()
+function refresh_backup_files(viewing)
 {
-       $('#restore_button,#delete_button,#view_button')
+       $('#restore_button,#delete_button,#view_button,#close_view_button')
            .button('option', 'disabled', true);
+        $('#close_view_button').hide();
+       var backup=$('input.restore:checked').val();
        $('#backup_files').load('backup/files.jim', function() {
-               $('input.restore').change(function() {
+               if (backup) backup=$('input.restore[value="'+backup+'"]').val();
+               if (!backup) {
+                   $('input.restore').change(function() {
                        $('#restore_button,#delete_button,#view_button')
                            .removeAttr('disabled')
                            .button('option', 'disabled', false);
-               });
+                   });
+               } else {
+                   $('input.restore[value="'+backup+'"]').prop('checked',true);
+                   $('#restore_button,#delete_button')
+                       .removeAttr('disabled')
+                       .button('option', 'disabled', false);
+               }
+               if (viewing) {
+                    $('#close_view_button')
+                        .removeAttr('disabled')
+                        .button('option', 'disabled', false)
+                        .show();
+                   $('input.restore').change(function() {
+                        $('#close_view_button').click();
+                   });
+                } else if (backup) {
+                   $('#view_button')
+                       .removeAttr('disabled')
+                       .button('option', 'disabled', false);
+               }
        });
 }
 
@@ -19,6 +42,7 @@
 $('#restore_button').button({icons: {primary: "ui-icon-play"}});
 $('#delete_button').button({icons: {primary: "ui-icon-trash"}});
 $('#view_button').button({icons: {primary: "ui-icon-script"}});
+$('#close_view_button').button({icons: {primary: "ui-icon-script"}});
 
 refresh_backup_files();
 
@@ -49,9 +73,13 @@
        $('#backup_results').load('backup/view.jim?' +
            $('input.restore').serialize(), function() {
                $('#backup_results').slideDown(function() {
-                       refresh_backup_files();
+                       refresh_backup_files(true);
                });
        });
+});
+$('#close_view_button').click(function() {
+        $('#backup_results').slideUp();
+        refresh_backup_files();
 });
 $('#restore_button').click(function() {
        var backup = $('input.restore:checked').val();
Update: following a random reset, I can confirm that actually restoring a selected backup from its view works as desired.
 
Last edited:
I've just gone to the WebIf for the first time in a couple of days and the Browse function is only showing the first file in each folder.
There are no tool buttons underneath the file list either (e.g Cut, Copy, Delete etc.).

I've tried re-starting the machine, installing package updates (which included WebIf and I did another re-start) and run fix-flash-packages diagnostic.
If I go to FileEditor and click Open I can browse the My Video folder and see the files in the correct place.
They also appear and play correctly on the TV. It appears as though the page just stops after the first file is found.

Any suggestions as to what else to try?
 
I think the last entry is


24/mod/webif/lib/queue.class:210: Error: no such table: queue
25in procedure 'entry' called at file "/mod/webif/html/browse/index.jim", line 330
26in procedure 'queue' called at file "/mod/webif/html/browse/index.jim", line 215
27at file "/mod/webif/lib/queue.class", line 210

So a missing table sounds like the likely cause. I don't know where it's missing from or how to get it back though.
 
Last edited:
I'm experiencing a problem at the moment whereby the webif repeatedly asks me to provide my user ID and password, at apparently random intervals during a session. I always provide the requested credentials, and tick the "remember" checkbox, but it never seems to be satisfied.

Any ideas?
 
Status
Not open for further replies.
Back
Top