luci2: move most RPC proxy function declarations into the views using them to reduce...
[project/luci2/ui.git] / luci2 / htdocs / luci2 / view / system.software.js
index 7526e01986b150be78133ed6e677fcedbac41a57..7aed31c6768617a87980fff416fd93a6513d4c26 100644 (file)
@@ -1,7 +1,123 @@
 L.ui.view.extend({
+       title: L.tr('Package management'),
+
+       opkg: {
+               updateLists: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'update',
+                       expect: { '': { } }
+               }),
+
+               _allPackages: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'list',
+                       params: [ 'offset', 'limit', 'pattern' ],
+                       expect: { '': { } }
+               }),
+
+               _installedPackages: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'list_installed',
+                       params: [ 'offset', 'limit', 'pattern' ],
+                       expect: { '': { } }
+               }),
+
+               _findPackages: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'find',
+                       params: [ 'offset', 'limit', 'pattern' ],
+                       expect: { '': { } }
+               }),
+
+               _fetchPackages: function(action, offset, limit, pattern)
+               {
+                       var packages = [ ];
+
+                       return action(offset, limit, pattern).then(function(list) {
+                               if (!list.total || !list.packages)
+                                       return { length: 0, total: 0 };
+
+                               packages.push.apply(packages, list.packages);
+                               packages.total = list.total;
+
+                               if (limit <= 0)
+                                       limit = list.total;
+
+                               if (packages.length >= limit)
+                                       return packages;
+
+                               L.rpc.batch();
+
+                               for (var i = offset + packages.length; i < limit; i += 100)
+                                       action(i, (Math.min(i + 100, limit) % 100) || 100, pattern);
+
+                               return L.rpc.flush();
+                       }).then(function(lists) {
+                               for (var i = 0; i < lists.length; i++)
+                               {
+                                       if (!lists[i].total || !lists[i].packages)
+                                               continue;
+
+                                       packages.push.apply(packages, lists[i].packages);
+                                       packages.total = lists[i].total;
+                               }
+
+                               return packages;
+                       });
+               },
+
+               listPackages: function(offset, limit, pattern)
+               {
+                       return this._fetchPackages(this._allPackages, offset, limit, pattern);
+               },
+
+               installedPackages: function(offset, limit, pattern)
+               {
+                       return this._fetchPackages(this._installedPackages, offset, limit, pattern);
+               },
+
+               findPackages: function(offset, limit, pattern)
+               {
+                       return this._fetchPackages(this._findPackages, offset, limit, pattern);
+               },
+
+               installPackage: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'install',
+                       params: [ 'package' ],
+                       expect: { '': { } }
+               }),
+
+               removePackage: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'remove',
+                       params: [ 'package' ],
+                       expect: { '': { } }
+               }),
+
+               getConfig: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'config_get',
+                       expect: { config: '' }
+               }),
+
+               setConfig: L.rpc.declare({
+                       object: 'luci2.opkg',
+                       method: 'config_set',
+                       params: [ 'data' ]
+               }),
+
+               isInstalled: function(pkg)
+               {
+                       return this._installedPackages(0, 1, pkg).then(function(list) {
+                               return (!isNaN(list.total) && list.total > 0);
+                       });
+               }
+       },
+
        updateDiskSpace: function()
        {
-               return L.system.getInfo(function(info) {
+               return L.system.getDiskInfo().then(function(info) {
                        $('#package_space').empty().append(
                                new L.ui.progress({
                                        value:  info.root.used / 1024,
@@ -11,26 +127,22 @@ L.ui.view.extend({
                });
        },
 
-       installRemovePackage: function(name)
+       installRemovePackage: function(pkgname, installed)
        {
-               if (typeof(name) != 'string')
-                       name = undefined;
-
-               var pkgname   = (name || this.getAttribute('name')).replace(/^.*\//, '');
-               var installed = name ? false : !!this.getAttribute('installed');
-               var action    = installed ? L.opkg.removePackage : L.opkg.installPackage;
-               var title     = (installed ? L.tr('Removing package "%s" …') : L.tr('Installing package "%s" …')).format(pkgname);
-               var confirm   = (installed ? L.tr('Really remove package "%h" ?') : L.tr('Really install package "%h" ?')).format(pkgname);
-
                var self = this;
 
+               var dspname   = pkgname.replace(/^.+\//, '');
+               var action    = installed ? self.opkg.removePackage : self.opkg.installPackage;
+               var title     = (installed ? L.tr('Removing package "%s" …') : L.tr('Installing package "%s" …')).format(dspname);
+               var confirm   = (installed ? L.tr('Really remove package "%h" ?') : L.tr('Really install package "%h" ?')).format(dspname);
+
                L.ui.dialog(title, confirm, {
                        style:   'confirm',
                        confirm: function() {
                                L.ui.dialog(title, L.tr('Waiting for package manager …'), { style: 'wait' });
 
-                               action(name || pkgname).then(function(res) {
-                                       self.fetchInstalledList().then(function() { return fetchPackageList(); }).then(function() {
+                               action.call(self.opkg, pkgname).then(function(res) {
+                                       self.fetchInstalledList().then(function() { return self.fetchPackageList(); }).then(function() {
                                                var output = [ ];
 
                                                if (res.stdout)
@@ -54,11 +166,11 @@ L.ui.view.extend({
        fetchInstalledList: function()
        {
                var self = this;
-               return L.opkg.installedPackages(0, 0, '*', function(list) {
+               return self.opkg.installedPackages(0, 0, '*').then(function(list) {
                        self.installedList = { };
                        for (var i = 0; i < list.length; i++)
                                self.installedList[list[i][0]] = true;
-               })
+               });
        },
 
        fetchPackageList: function(offset, interactive)
@@ -69,19 +181,21 @@ L.ui.view.extend({
                if (typeof(offset) == 'undefined')
                        offset = parseInt($('#package_filter').attr('offset')) || 0;
 
+               var self = this;
+
                var pattern = $('#package_filter').val() || '';
                var action;
 
                if (pattern.length)
                {
-                       action = $('#package_which').prop('checked') ? L.opkg.installedPackages : L.opkg.findPackages;
+                       action = $('#package_which').prop('checked') ? self.opkg.installedPackages : self.opkg.findPackages;
                        pattern = '*' + pattern + '*';
 
                        $('#package_filter').next().attr('src', L.globals.resource + '/icons/cbi/remove.gif');
                }
                else
                {
-                       action = $('#package_which').prop('checked') ? L.opkg.installedPackages : L.opkg.listPackages;
+                       action = $('#package_which').prop('checked') ? self.opkg.installedPackages : self.opkg.listPackages;
                        pattern = '*';
 
                        $('#package_filter').next().attr('src', L.globals.resource + '/icons/cbi/find.gif');
@@ -90,9 +204,8 @@ L.ui.view.extend({
                $('#package_filter').attr('offset', offset);
 
                var install_disabled = $('#package_install').attr('disabled');
-               var self = this;
 
-               return action(offset, 100, pattern, function(list) {
+               return action.call(self.opkg, offset, 100, pattern).then(function(list) {
                        var packageTable = new L.ui.table({
                                placeholder: L.tr('No matching packages found.'),
                                columns: [ {
@@ -113,15 +226,14 @@ L.ui.view.extend({
                                        width:   '120px',
                                        format: function(v, n) {
                                                var inst = self.installedList[list[n][0]];
-                                               return $('<button />')
+                                               return L.ui.button(inst ? L.trc('Package state', 'Installed') : L.trc('Package state', 'Not installed'), inst ? 'success' : 'danger')
                                                        .css('width', '100%')
                                                        .attr('disabled', install_disabled)
-                                                       .attr('name', list[n][0])
+                                                       .attr('pkgname', list[n][0])
                                                        .attr('installed', inst)
-                                                       .addClass('cbi-button')
-                                                       .addClass(inst ? 'cbi-button-apply' : 'cbi-button-reset')
-                                                       .text(inst ? L.trc('Package state', 'Installed') : L.trc('Package state', 'Not installed'))
-                                                       .click(self.installRemovePackage);
+                                                       .click(function() {
+                                                               self.installRemovePackage(this.getAttribute('pkgname'), this.getAttribute('installed') == 'true');
+                                                       });
                                        }
                                } ]
                        });
@@ -133,21 +245,21 @@ L.ui.view.extend({
                                $('#package_prev')
                                        .attr('offset', offset - 100)
                                        .attr('disabled', false)
-                                       .val('« %d - %d'.format(offset - 100 + 1, offset));
+                                       .text('« %d - %d'.format(offset - 100 + 1, offset));
                        else
                                $('#package_prev')
                                        .attr('disabled', true)
-                                       .val('« %d - %d'.format(1, Math.min(100, list.total)));
+                                       .text('« %d - %d'.format(1, Math.min(100, list.total)));
 
                        if ((offset + 100) < list.total)
                                $('#package_next')
                                        .attr('offset', offset + 100)
                                        .attr('disabled', false)
-                                       .val('%d - %d »'.format(offset + 100 + 1, Math.min(offset + 200, list.total)));
+                                       .text('%d - %d »'.format(offset + 100 + 1, Math.min(offset + 200, list.total)));
                        else
                                $('#package_next')
                                        .attr('disabled', true)
-                                       .val('%d - %d »'.format(list.total - (list.total % 100) + 1, list.total));
+                                       .text('%d - %d »'.format(list.total - (list.total % 100) + 1, list.total));
 
                        if (interactive)
                                L.ui.loading(false);
@@ -162,17 +274,17 @@ L.ui.view.extend({
                $('#package_update, #package_url, #package_install').attr('disabled', !this.options.acls.software);
 
                return $.when(
-                       L.opkg.getConfig(function(config) {
-                               $('textarea')
+                       self.opkg.getConfig().then(function(config) {
+                               $('#config textarea')
                                        .attr('rows', (config.match(/\n/g) || [ ]).length + 1)
                                        .val(config);
 
-                               $('input.cbi-button-save')
+                               $('#config button')
                                        .click(function() {
-                                               var data = ($('textarea').val() || '').replace(/\r/g, '').replace(/\n?$/, '\n');
+                                               var data = ($('#config textarea').val() || '').replace(/\r/g, '').replace(/\n?$/, '\n');
                                                L.ui.loading(true);
-                                               L.opkg.setConfig(data, function() {
-                                                       $('textarea')
+                                               self.opkg.setConfig(data).then(function() {
+                                                       $('#config textarea')
                                                                .attr('rows', (data.match(/\n/g) || [ ]).length + 1)
                                                                .val(data);
 
@@ -183,8 +295,6 @@ L.ui.view.extend({
                        self.fetchInstalledList(),
                        self.updateDiskSpace()
                ).then(function() {
-                       $('#tabs').show().tabs();
-
                        $('#package_prev, #package_next').click(function(ev) {
                                if (!this.getAttribute('disabled'))
                                {
@@ -194,9 +304,7 @@ L.ui.view.extend({
                        });
 
                        $('#package_filter').next().click(function(ev) {
-                               if (this.getAttribute('src').indexOf('remove.gif') > -1)
-                                       $('#package_filter').val('');
-
+                               $('#package_filter').val('');
                                self.fetchPackageList(0, true);
                        });
 
@@ -221,18 +329,18 @@ L.ui.view.extend({
                                ev.preventDefault();
 
                                if (this.value)
-                                       self.installRemovePackage(this.value);
+                                       self.installRemovePackage(this.value, false);
                        });
 
                        $('#package_install').click(function(ev) {
                                var name = $('#package_url').val();
                                if (name)
-                                       self.installRemovePackage(name);
+                                       self.installRemovePackage(name, false);
                        });
 
                        $('#package_update').click(function(ev) {
                                L.ui.dialog(L.tr('Updating package lists'), L.tr('Waiting for package manager …'), { style: 'wait' });
-                               L.opkg.updateLists(function(res) {
+                               self.opkg.updateLists().then(function(res) {
                                        var output = [ ];
 
                                        if (res.stdout)