Explorar o código

Merge with LMS OTA proxy

Sebastien %!s(int64=4) %!d(string=hai) anos
pai
achega
4444fed343
Modificáronse 22 ficheiros con 273 adicións e 11 borrados
  1. 3 3
      README.md
  2. 4 1
      components/wifi-manager/webapp/mock/status.json
  3. 23 2
      components/wifi-manager/webapp/src/js/custom.js
  4. 3 3
      components/wifi-manager/webapp/webapp.cmake
  5. 27 0
      components/wifi-manager/webapp/webpack.c
  6. 57 0
      components/wifi-manager/webapp/webpack.h
  7. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/favicon-32x32.png
  8. 0 0
      components/wifi-manager/webapp/webpack/dist/index.html
  9. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/index.html.br
  10. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/index.html.gz
  11. 0 0
      components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js
  12. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js.br
  13. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js.gz
  14. 7 0
      components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js
  15. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js.br
  16. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js.gz
  17. 1 0
      components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js
  18. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js.br
  19. BIN=BIN
      components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js.gz
  20. 1 1
      components/wifi-manager/webapp/webpack/webpack.dev.js
  21. 146 1
      plugin/SqueezeESP32/Plugin.pm
  22. 1 0
      server_certs/getcert.sh

+ 3 - 3
README.md

@@ -13,7 +13,7 @@ But squeezelite-esp32 is highly extensible and you can add
 
 - Buttons and Rotary Encoder and map/combine them to various functions (play, pause, volume, next ...)
 - IR receiver (no pullup resistor or capacitor needed, just the 38kHz receiver)
-- Monochrome, GrayScale or Color displays using SPI or I2S (supported drivers are SH1106, SSD1306, SSD1322, SSD1326/7, SSD1351, ST7735, ST7789 and IL9341).
+- Monochrome, GrayScale or Color displays using SPI or I2C (supported drivers are SH1106, SSD1306, SSD1322, SSD1326/7, SSD1351, ST7735, ST7789 and ILI9341).
 
 Other features include
 
@@ -172,7 +172,7 @@ Ground -------------------------- coax signal ground
 The NVS parameter "display_config" sets the parameters for an optional display. Syntax is
 ```
 I2C,width=<pixels>,height=<pixels>[address=<i2c_address>][,reset=<gpio>][,HFlip][,VFlip][driver=SSD1306|SSD1326[:1|4]|SSD1327|SH1106]
-SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,back=<gpio>][,reset=<gpio>][,speed=<speed>][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789[,rotate]]
+SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,back=<gpio>][,reset=<gpio>][,speed=<speed>][,HFlip][,VFlip][driver=SSD1306|SSD1322|SSD1326[:1|4]|SSD1327|SH1106|SSD1675|ST7735|ST7789|ILI9341[:16|18][,rotate]]
 ```
 - back: a LED backlight used by some older devices (ST7735). It is PWM controlled for brightness
 - reset: some display have a reset pin that is should normally be pulled up if unused
@@ -188,7 +188,7 @@ SPI,width=<pixels>,height=<pixels>,cs=<gpio>[,back=<gpio>][,reset=<gpio>][,speed
 - SSD1675 is an e-ink paper and is experimental as e-ink is really not suitable for LMS du to its very low refresh rate
 - ST7735 is a 128x160 65k color SPI [here](https://www.waveshare.com/product/displays/lcd-oled/lcd-oled-3/1.8inch-lcd-module.htm). This needs a backlight control
 - ST7789 is a 240x320 65k (262k not enabled) color SPI [here](https://www.waveshare.com/product/displays/lcd-oled/lcd-oled-3/2inch-lcd-module.htm). It also exist with 240x240 displays. See **rotate** for use in portrait mode
-- IL9341 is another 240x320 65k (262k capable) color SPI. I've not used it much, the driver it has been provided by one external contributor to the project
+- ILI9341 is another 240x320 65k (262k capable) color SPI. I've not used it much, the driver it has been provided by one external contributor to the project
 
 To use the display on LMS, add repository https://raw.githubusercontent.com/sle118/squeezelite-esp32/master/plugin/repo.xml. You will then be able to tweak how the vu-meter and spectrum analyzer are displayed, as well as size of artwork. You can also install the excellent plugin "Music Information Screen" which is super useful to tweak the layout.
 

+ 4 - 1
components/wifi-manager/webapp/mock/status.json

@@ -14,5 +14,8 @@
 	"ssid": "MyTestSSID",
 	"ip": "192.168.10.225",
 	"netmask": "255.255.255.0",
-	"gw": "192.168.10.1"
+	"gw": "192.168.10.1",
+	"lms_cport": 9090,
+	"lms_port": 9000,
+	"lms_ip": "127.0.0.1"
 }

+ 23 - 2
components/wifi-manager/webapp/src/js/custom.js

@@ -550,6 +550,7 @@ let project_name=versionName;
 let btSinkNamesOptSel='#cfg-audio-bt_source-sink_name';
 let ConnectedToSSID={};
 let ConnectingToSSID={};
+let lmsBaseUrl;
 const ConnectingToActions = {
   'CONN' : 0,'MAN' : 1,'STS' : 2,
 }
@@ -1315,8 +1316,7 @@ $(document).ready(function() {
 
 // eslint-disable-next-line no-unused-vars
 window.setURL = function(button) {
-  const url = button.dataset.url;
-  $('#fwurl').val(url);
+  let url = button.dataset.url;
 
   $('[data-url^="http"]')
     .addClass('btn-success')
@@ -1324,6 +1324,13 @@ window.setURL = function(button) {
   $('[data-url="' + url + '"]')
     .addClass('btn-danger')
     .removeClass('btn-success');
+
+  // if user can proxy download through LMS, modify the URL
+  if (lmsBaseUrl) {
+    url = url.replace(/.*\/download\//, lmsBaseUrl + '/plugins/SqueezeESP32/firmware/');
+  }
+
+  $('#fwurl').val(url);
 }
 
 // function performConnect(conntype) {
@@ -1763,6 +1770,20 @@ function checkStatus() {
     } else {
       $('#battery').hide();
     }
+
+    if (typeof lmsBaseUrl == "undefined" && data.lms_ip && data.lms_port) {
+      const baseUrl = 'http://' + data.lms_ip + ':' + data.lms_port;
+      $.ajax({
+        url: baseUrl + '/plugins/SqueezeESP32/firmware/-99', 
+        error: function() {
+          // define the value, so we don't check it any more.
+          lmsBaseUrl = '';
+        },
+        success: function() {
+          lmsBaseUrl = baseUrl;
+        }
+      });
+    }
     
     $('#o_jack').attr('display', Number(data.Jack) ? 'inline' : 'none');
     blockAjax = false;

+ 3 - 3
components/wifi-manager/webapp/webapp.cmake

@@ -1,5 +1,5 @@
 target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/favicon-32x32.png BINARY)
 target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/index.html.gz BINARY)
-target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/index.31a52e.bundle.js.gz BINARY)
-target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/node-modules.31a52e.bundle.js.gz BINARY)
-target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/runtime.31a52e.bundle.js.gz BINARY)
+target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/index.0b6890.bundle.js.gz BINARY)
+target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/node-modules.0b6890.bundle.js.gz BINARY)
+target_add_binary_data( __idf_wifi-manager ./webapp/webpack/dist/js/runtime.0b6890.bundle.js.gz BINARY)

+ 27 - 0
components/wifi-manager/webapp/webpack.c

@@ -4,6 +4,7 @@ extern const uint8_t _favicon_32x32_png_start[] asm("_binary_favicon_32x32_png_s
 extern const uint8_t _favicon_32x32_png_end[] asm("_binary_favicon_32x32_png_end");
 extern const uint8_t _index_html_gz_start[] asm("_binary_index_html_gz_start");
 extern const uint8_t _index_html_gz_end[] asm("_binary_index_html_gz_end");
+<<<<<<< HEAD
 extern const uint8_t _index_31a52e_bundle_js_gz_start[] asm("_binary_index_31a52e_bundle_js_gz_start");
 extern const uint8_t _index_31a52e_bundle_js_gz_end[] asm("_binary_index_31a52e_bundle_js_gz_end");
 extern const uint8_t _node_modules_31a52e_bundle_js_gz_start[] asm("_binary_node_modules_31a52e_bundle_js_gz_start");
@@ -16,19 +17,45 @@ const char * resource_lookups[] = {
 	"/js/index.31a52e.bundle.js.gz",
 	"/js/node-modules.31a52e.bundle.js.gz",
 	"/js/runtime.31a52e.bundle.js.gz",
+=======
+extern const uint8_t _index_0b6890_bundle_js_gz_start[] asm("_binary_index_0b6890_bundle_js_gz_start");
+extern const uint8_t _index_0b6890_bundle_js_gz_end[] asm("_binary_index_0b6890_bundle_js_gz_end");
+extern const uint8_t _node_modules_0b6890_bundle_js_gz_start[] asm("_binary_node_modules_0b6890_bundle_js_gz_start");
+extern const uint8_t _node_modules_0b6890_bundle_js_gz_end[] asm("_binary_node_modules_0b6890_bundle_js_gz_end");
+extern const uint8_t _runtime_0b6890_bundle_js_gz_start[] asm("_binary_runtime_0b6890_bundle_js_gz_start");
+extern const uint8_t _runtime_0b6890_bundle_js_gz_end[] asm("_binary_runtime_0b6890_bundle_js_gz_end");
+const char * resource_lookups[] = {
+	"/dist/favicon-32x32.png",
+	"/dist/index.html.gz",
+	"/js/index.0b6890.bundle.js.gz",
+	"/js/node-modules.0b6890.bundle.js.gz",
+	"/js/runtime.0b6890.bundle.js.gz",
+>>>>>>> master-cmake
 ""
 };
 const uint8_t * resource_map_start[] = {
 	_favicon_32x32_png_start,
 	_index_html_gz_start,
+<<<<<<< HEAD
 	_index_31a52e_bundle_js_gz_start,
 	_node_modules_31a52e_bundle_js_gz_start,
 	_runtime_31a52e_bundle_js_gz_start
+=======
+	_index_0b6890_bundle_js_gz_start,
+	_node_modules_0b6890_bundle_js_gz_start,
+	_runtime_0b6890_bundle_js_gz_start
+>>>>>>> master-cmake
 };
 const uint8_t * resource_map_end[] = {
 	_favicon_32x32_png_end,
 	_index_html_gz_end,
+<<<<<<< HEAD
 	_index_31a52e_bundle_js_gz_end,
 	_node_modules_31a52e_bundle_js_gz_end,
 	_runtime_31a52e_bundle_js_gz_end
+=======
+	_index_0b6890_bundle_js_gz_end,
+	_node_modules_0b6890_bundle_js_gz_end,
+	_runtime_0b6890_bundle_js_gz_end
+>>>>>>> master-cmake
 };

+ 57 - 0
components/wifi-manager/webapp/webpack.h

@@ -1,5 +1,6 @@
 /***********************************
 webpack_headers
+<<<<<<< HEAD
 Hash: 31a52ecfe661f5a02717
 Version: webpack 4.44.2
 Time: 6575ms
@@ -38,11 +39,52 @@ Entrypoint index [big] = ./js/runtime.31a52e.bundle.js ./js/node-modules.31a52e.
 [37] ./src/index.ts + 1 modules 59.9 KiB {0} [built]
      | ./src/index.ts 1.36 KiB [built]
      | ./src/js/custom.js 58.4 KiB [built]
+=======
+Hash: 0b6890f4337e767921f7
+Version: webpack 4.46.0
+Time: 273269ms
+Built at: 2021-04-03 1:28:56
+                                Asset       Size  Chunks                                Chunk Names
+          ./js/index.0b6890.bundle.js    231 KiB       0  [emitted] [immutable]         index
+       ./js/index.0b6890.bundle.js.br   31.5 KiB          [emitted]                     
+       ./js/index.0b6890.bundle.js.gz   41.1 KiB          [emitted]                     
+   ./js/node-modules.0b6890.bundle.js    266 KiB       1  [emitted] [immutable]  [big]  node-modules
+./js/node-modules.0b6890.bundle.js.br   76.3 KiB          [emitted]                     
+./js/node-modules.0b6890.bundle.js.gz   88.7 KiB          [emitted]                     
+        ./js/runtime.0b6890.bundle.js   1.46 KiB       2  [emitted] [immutable]         runtime
+     ./js/runtime.0b6890.bundle.js.br  644 bytes          [emitted]                     
+     ./js/runtime.0b6890.bundle.js.gz  722 bytes          [emitted]                     
+                    favicon-32x32.png  634 bytes          [emitted]                     
+                           index.html   19.5 KiB          [emitted]                     
+                        index.html.br   4.48 KiB          [emitted]                     
+                        index.html.gz   5.46 KiB          [emitted]                     
+                           sprite.svg    4.4 KiB          [emitted]                     
+                        sprite.svg.br  912 bytes          [emitted]                     
+Entrypoint index [big] = ./js/runtime.0b6890.bundle.js ./js/node-modules.0b6890.bundle.js ./js/index.0b6890.bundle.js
+ [6] ./node_modules/bootstrap/dist/js/bootstrap-exposed.js 437 bytes {1} [built]
+[11] ./src/sass/main.scss 1.55 KiB {0} [built]
+[16] ./node_modules/remixicon/icons/Device/signal-wifi-fill.svg 323 bytes {1} [built]
+[17] ./node_modules/remixicon/icons/Device/signal-wifi-3-fill.svg 327 bytes {1} [built]
+[18] ./node_modules/remixicon/icons/Device/signal-wifi-2-fill.svg 327 bytes {1} [built]
+[19] ./node_modules/remixicon/icons/Device/signal-wifi-1-fill.svg 327 bytes {1} [built]
+[20] ./node_modules/remixicon/icons/Device/signal-wifi-line.svg 323 bytes {1} [built]
+[21] ./node_modules/remixicon/icons/Device/battery-line.svg 315 bytes {1} [built]
+[22] ./node_modules/remixicon/icons/Device/battery-low-line.svg 323 bytes {1} [built]
+[23] ./node_modules/remixicon/icons/Device/battery-fill.svg 315 bytes {1} [built]
+[24] ./node_modules/remixicon/icons/Media/headphone-fill.svg 318 bytes {1} [built]
+[25] ./node_modules/remixicon/icons/Device/device-recover-fill.svg 329 bytes {1} [built]
+[26] ./node_modules/remixicon/icons/Device/bluetooth-fill.svg 319 bytes {1} [built]
+[27] ./node_modules/remixicon/icons/Device/bluetooth-connect-fill.svg 335 bytes {1} [built]
+[37] ./src/index.ts + 1 modules 53.3 KiB {0} [built]
+     | ./src/index.ts 1.36 KiB [built]
+     | ./src/js/custom.js 51.8 KiB [built]
+>>>>>>> master-cmake
     + 23 hidden modules
 
 WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
 This can impact web performance.
 Assets: 
+<<<<<<< HEAD
   ./js/node-modules.31a52e.bundle.js (265 KiB)
 
 WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
@@ -51,6 +93,16 @@ Entrypoints:
       ./js/runtime.31a52e.bundle.js
       ./js/node-modules.31a52e.bundle.js
       ./js/index.31a52e.bundle.js
+=======
+  ./js/node-modules.0b6890.bundle.js (266 KiB)
+
+WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
+Entrypoints:
+  index (499 KiB)
+      ./js/runtime.0b6890.bundle.js
+      ./js/node-modules.0b6890.bundle.js
+      ./js/index.0b6890.bundle.js
+>>>>>>> master-cmake
 
 
 WARNING in webpack performance recommendations: 
@@ -60,8 +112,13 @@ Child html-webpack-plugin for "index.html":
          Asset     Size  Chunks  Chunk Names
     index.html  558 KiB       0  
     Entrypoint undefined = index.html
+<<<<<<< HEAD
     [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.ejs 23.7 KiB {0} [built]
     [1] ./node_modules/lodash/lodash.js 530 KiB {0} [built]
+=======
+    [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.ejs 20.3 KiB {0} [built]
+    [1] ./node_modules/lodash/lodash.js 531 KiB {0} [built]
+>>>>>>> master-cmake
     [2] (webpack)/buildin/global.js 472 bytes {0} [built]
     [3] (webpack)/buildin/module.js 497 bytes {0} [built]
 ***********************************/

BIN=BIN
components/wifi-manager/webapp/webpack/dist/favicon-32x32.png


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
components/wifi-manager/webapp/webpack/dist/index.html


BIN=BIN
components/wifi-manager/webapp/webpack/dist/index.html.br


BIN=BIN
components/wifi-manager/webapp/webpack/dist/index.html.gz


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js


BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js.br


BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/index.0b6890.bundle.js.gz


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 0
components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js


BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js.br


BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/node-modules.0b6890.bundle.js.gz


+ 1 - 0
components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js

@@ -0,0 +1 @@
+!function(e){function r(r){for(var n,l,f=r[0],i=r[1],a=r[2],c=0,s=[];c<f.length;c++)l=f[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,f=1;f<t.length;f++){var i=t[f];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={2:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="";var f=window.webpackJsonp=window.webpackJsonp||[],i=f.push.bind(f);f.push=r,f=f.slice();for(var a=0;a<f.length;a++)r(f[a]);var p=i;t()}([]);

BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js.br


BIN=BIN
components/wifi-manager/webapp/webpack/dist/js/runtime.0b6890.bundle.js.gz


+ 1 - 1
components/wifi-manager/webapp/webpack/webpack.dev.js

@@ -111,7 +111,7 @@ module.exports = merge(common, {
         contentBase: path.join(__dirname, 'dist'),
         publicPath: '/',
         port: 9100,
-        host: 'desktop-n8u8515',//your ip address
+        host: '127.0.0.1',//your ip address
         disableHostCheck: true,
         headers: {'Access-Control-Allow-Origin': '*',
     'Accept-Encoding': 'identity'},

+ 146 - 1
plugin/SqueezeESP32/Plugin.pm

@@ -3,6 +3,9 @@ package Plugins::SqueezeESP32::Plugin;
 use strict;
 
 use base qw(Slim::Plugin::Base);
+use File::Basename qw(basename);
+use File::Spec::Functions qw(catfile);
+use JSON::XS::VersionOneAndTwo;
 
 use Slim::Utils::Prefs;
 use Slim::Utils::Log;
@@ -16,6 +19,12 @@ my $log = Slim::Utils::Log->addLogCategory({
 	'description'  => 'PLUGIN_SQUEEZEESP32',
 });
 
+use constant GITHUB_ASSET_URI => "https://api.github.com/repos/sle118/squeezelite-esp32/releases/assets/";
+use constant GITHUB_DOWNLOAD_URI => "https://github.com/sle118/squeezelite-esp32/releases/download/";
+my $FW_DOWNLOAD_ID_REGEX = qr|plugins/SqueezeESP32/firmware/(-?\d+)|;
+my $FW_DOWNLOAD_REGEX = qr|plugins/SqueezeESP32/firmware/([-a-z0-9-/.]+\.bin)$|i;
+my $FW_FILENAME_REGEX = qr/^squeezelite-esp32-.*\.bin(\.tmp)?$/;
+
 # migrate 'eq' pref, as that's a reserved word and could cause problems in the future
 $prefs->migrateClient(1, sub {
 	my ($cprefs, $client) = @_;
@@ -48,7 +57,7 @@ sub initPlugin {
 	$class->SUPER::initPlugin(@_);
 	# no name can be a subset of others due to a bug in addPlayerClass
 	Slim::Networking::Slimproto::addPlayerClass($class, 100, 'squeezeesp32-basic', { client => 'Plugins::SqueezeESP32::Player', display => 'Plugins::SqueezeESP32::Graphics' });
-	Slim::Networking::Slimproto::addPlayerClass($class, 101, 'squeezeesp32-graphic', { client => 'Plugins::SqueezeESP32::Player', display => 'Slim::Display::NoDisplay' });		
+	Slim::Networking::Slimproto::addPlayerClass($class, 101, 'squeezeesp32-graphic', { client => 'Plugins::SqueezeESP32::Player', display => 'Slim::Display::NoDisplay' });
 	main::INFOLOG && $log->is_info && $log->info("Added class 100 and 101 for SqueezeESP32");
 
 	# register a command to set the EQ - without saving the values! Send params as single comma separated list of values
@@ -58,6 +67,9 @@ sub initPlugin {
 	Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['newmetadata'] ] );
 	Slim::Control::Request::subscribe( sub { onNotification(@_) }, [ ['playlist'], ['open', 'newsong'] ]);
 	Slim::Control::Request::subscribe( \&onStopClear, [ ['playlist'], ['stop', 'clear'] ]);
+
+	Slim::Web::Pages->addRawFunction($FW_DOWNLOAD_ID_REGEX, \&handleFirmwareDownload);
+	Slim::Web::Pages->addRawFunction($FW_DOWNLOAD_REGEX, \&handleFirmwareDownloadDirect);
 }
 
 sub onStopClear {
@@ -99,4 +111,137 @@ sub setEQ {
 	$client->send_equalizer(\@eqParams);
 }
 
+sub handleFirmwareDownload {
+	my ($httpClient, $response) = @_;
+
+	my $request = $response->request;
+
+	my $_errorDownloading = sub {
+		_errorDownloading($httpClient, $response, @_);
+	};
+
+	my $id;
+	if (!defined $request || !(($id) = $request->uri =~ $FW_DOWNLOAD_ID_REGEX)) {
+		return $_errorDownloading->(undef, 'Invalid request', $request->uri, 400);
+	}
+
+	# this is the magic number used on the client to figure out whether the plugin does support download proxying
+	if ($id == -99) {
+		$response->code(204);
+		$response->header('Access-Control-Allow-Origin' => '*');
+
+		$httpClient->send_response($response);
+		return Slim::Web::HTTP::closeHTTPSocket($httpClient);
+	}
+
+	Slim::Networking::SimpleAsyncHTTP->new(
+		sub {
+			my $http = shift;
+			my $content = eval { from_json( $http->content ) };
+
+			if (!$content || !ref $content) {
+				$@ && $log->error("Failed to parse response: $@");
+				return $_errorDownloading->($http);
+			}
+			elsif (!$content->{browser_download_url} || !$content->{name}) {
+				return $_errorDownloading->($http, 'No download URL found');
+			}
+
+			downloadAndStreamFirmware($httpClient, $response, $content->{browser_download_url}, $content->{name});
+		},
+		$_errorDownloading,
+		{
+			timeout => 10,
+			cache => 1,
+			expires => 86400
+		}
+	)->get(GITHUB_ASSET_URI . $id);
+
+	return;
+}
+
+sub handleFirmwareDownloadDirect {
+	my ($httpClient, $response) = @_;
+
+	my $request = $response->request;
+
+	my $_errorDownloading = sub {
+		_errorDownloading($httpClient, $response, @_);
+	};
+
+	my $path;
+	if (!defined $request || !(($path) = $request->uri =~ $FW_DOWNLOAD_REGEX)) {
+		return $_errorDownloading->(undef, 'Invalid request', $request->uri, 400);
+	}
+
+	main::INFOLOG && $log->is_info && $log->info("Requesting firmware from: $path");
+
+	downloadAndStreamFirmware($httpClient, $response, GITHUB_DOWNLOAD_URI . $path);
+}
+
+sub downloadAndStreamFirmware {
+	my ($httpClient, $response, $url, $name) = @_;
+
+	my $_errorDownloading = sub {
+		_errorDownloading($httpClient, $response, @_);
+	};
+
+	$name ||= basename($url);
+
+	if ($name !~ $FW_FILENAME_REGEX) {
+		return $_errorDownloading->(undef, 'Unexpected firmware image name: ' . $name, $url, 400);
+	}
+
+	my $updatesDir = Slim::Utils::OSDetect::dirsFor('updates');
+	my $firmwareFile = catfile($updatesDir, $name);
+	Slim::Utils::Misc::deleteFiles($updatesDir, $FW_FILENAME_REGEX, $firmwareFile);
+
+	if (-f $firmwareFile) {
+		main::INFOLOG && $log->is_info && $log->info("Found cached firmware version");
+		$response->code(200);
+		return Slim::Web::HTTP::sendStreamingFile($httpClient, $response, 'application/octet-stream', $firmwareFile, undef, 1);
+	}
+
+	Slim::Networking::SimpleAsyncHTTP->new(
+		sub {
+			my $http = shift;
+
+			if ($http->code != 200 || !-e "$firmwareFile.tmp") {
+				return $_errorDownloading->($http, $http->mess);
+			}
+
+			rename "$firmwareFile.tmp", $firmwareFile or return $_errorDownloading->($http, "Unable to rename temporary $firmwareFile file" );
+
+			$response->code(200);
+			Slim::Web::HTTP::sendStreamingFile($httpClient, $response, 'application/octet-stream', $firmwareFile, undef, 1);
+		},
+		$_errorDownloading,
+		{
+			saveAs => "$firmwareFile.tmp",
+		}
+	)->get($url);
+
+	return;
+}
+
+sub _errorDownloading {
+	my ($httpClient, $response, $http, $error, $url, $code) = @_;
+
+	$error ||= ($http && $http->error) || 'unknown error';
+	$url   ||= ($http && $http->url) || 'no URL';
+	$code  ||= ($http && $http->code) || 500;
+
+	$log->error(sprintf("Failed to get data from Github: %s (%s)", $error || $http->error, $url));
+
+	$response->headers->remove_content_headers;
+	$response->code($code);
+	$response->content_type('text/plain');
+	$response->header('Connection' => 'close');
+	$response->content('');
+
+	$httpClient->send_response($response);
+	Slim::Web::HTTP::closeHTTPSocket($httpClient);
+};
+
+
 1;

+ 1 - 0
server_certs/getcert.sh

@@ -45,3 +45,4 @@ get_all_pem github.com github-com
 get_all_pem s3.amazonaws.com s3-amazon-com
 get_all_pem github-releases.githubusercontent.com githubusercontent-com
 cat *.pem >github.pem 
+

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio