gjs/gnome-shell-extension: прочитать удаленное jpg-изображение с URL-адреса и установить в качестве значка

Я пытаюсь улучшить расширение gnome-shell, разрешив извлечение удаленного изображения (jpg) и установив его в качестве значка для определенного виджета.

Вот что я получил до сих пор, но это не работает из-за несоответствия типа данных:

// allow remote album art url
const GdkPixbuf = imports.gi.GdkPixbuf;
const Soup = imports.gi.Soup;
const _httpSession = new Soup.SessionAsync();
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
function getAlbumArt(url, callback) {
    var request = Soup.Message.new('GET', url);
    _httpSession.queue_message(request, function(_httpSession, message) {
        if (message.status_code !== 200) {
          callback(message.status_code, null);
          return;
        } else {
          var albumart = request.response_body_data;
          // this line gives error message:
          // JS ERROR: Error: Expected type guint8 for Argument 'data' 
          // but got type 'object'
          // getAlbumArt/<@~/.local/share/gnome-shell/extensions
          // /[email protected]/streamMenu.js:42
          var icon = GdkPixbuf.Pixbuf.new_from_inline(albumart, true);
          callback(null, icon);
        };
    });

Вот обратный вызов:

....
            log('try retrieve albumart: ' + filePath);
            if(GLib.file_test(iconPath, GLib.FileTest.EXISTS)){
                let file = Gio.File.new_for_path(iconPath)
                let icon = new Gio.FileIcon({file:file});
                this._albumArt.gicon = icon;
            } else if (filePath.indexOf('http') == 0) {
                log('try retrieve from url: ' + filePath);
                getAlbumArt(filePath, function(code, icon){
                    if (code) {
                        this._albumArt.gicon = icon;
                    } else {
                        this._albumArt.hide();
                    }
                });
            }

....

Мой вопрос: как проанализировать ответ, который представляет собой изображение jpg, чтобы я мог установить с ним значок виджета? Большое спасибо!


person Jerry Ma    schedule 07.04.2016    source источник
comment
Просто удачная догадка, но это var albumart = request.response_body_data; или var albumart = message.response_body.data; с точкой вместо подчеркивания?   -  person L-Ray    schedule 07.04.2016
comment
Спасибо за предложение, и я действительно попробовал: response_body.data возвращает изображение в виде строки Unicode, как указано в сообщении об ошибке.   -  person Jerry Ma    schedule 09.04.2016
comment
Возможно, имеет смысл также использовать roojs.org /seed/gir-1.2-gtk-3.0/seed/Soup.RequestFile.html вместо Soup.Message.New?   -  person L-Ray    schedule 09.04.2016


Ответы (2)


Я смог добиться этого, просто выполнив:

const St = imports.gi.St;
const Gio = imports.gi.Gio;
// ...

this.icon = new St.Icon()

// ...
let url = 'https://some.url'
let icon = Gio.icon_new_for_string(url);
this.icon.set_gicon(icon);

И он автоматически загрузит его.

Я часами боролся с этой проблемой, пока наконец не нашел способ сделать это с локальным кешем изображений (загрузив изображение и сохранив его в значках/папке). Затем я попробовал этот подход для развлечения (просто чтобы посмотреть, что произойдет, ожидая, что он с треском провалится), и знаете что? Это просто сработало. Это нигде не упоминается в очень скудной документации, которую мне удалось найти.

person Juan Casilla    schedule 29.03.2020

Для тех, у кого все еще есть такая же проблема, вот мое решение:

_httpSession.queue_message(request, function(_httpSession, message) {
    
    let buffer = message.response_body.flatten();
    let bytes = buffer.get_data();
    let gicon = Gio.BytesIcon.new(bytes);

    // your code here

});
person Pikachunakapika    schedule 11.10.2020