浏览代码

dev: DRY base64 app icons from streams

KernelDeimos 4 月之前
父节点
当前提交
63401f2c83

+ 1 - 8
src/backend/src/helpers.js

@@ -1539,14 +1539,7 @@ async function get_taskbar_items(user, { icon_size, no_icons } = {}) {
                 size: icon_size,
             });
 
-            if ( icon_result.data_url ) {
-                item.icon = icon_result.data_url;
-            } else {
-                const buffer = await stream_to_buffer(icon_result.stream);
-                const resp_data_url = `data:${icon_result.mime};base64,${buffer.toString('base64')}`;
-                
-                item.icon = resp_data_url;
-            }
+            item.icon = await icon_result.get_data_url();
         }
 
         // add to final object

+ 7 - 1
src/backend/src/modules/apps/AppIconService.js

@@ -10,6 +10,7 @@ const BaseService = require("../../services/BaseService.js");
 const ICON_SIZES = [16,32,64,128,256,512];
 
 const DEFAULT_APP_ICON = require('./default-app-icon.js');
+const IconResult = require("./lib/IconResult.js");
 
 /**
  * AppIconService handles icon generation and serving for apps.
@@ -95,7 +96,12 @@ class AppIconService extends BaseService {
         }));
     }
 
-    async get_icon_stream ({ app_icon, app_uid, size, tries = 0 }) {
+    async get_icon_stream (params) {
+        const result = await this.get_icon_stream_(params);
+        return new IconResult(result);
+    }
+
+    async get_icon_stream_ ({ app_icon, app_uid, size, tries = 0 }) {
         // If there is an icon provided, and it's an SVG, we'll just return it
         if ( app_icon ) {
             const [metadata, data] = app_icon.split(',');

+ 27 - 0
src/backend/src/modules/apps/lib/IconResult.js

@@ -0,0 +1,27 @@
+const { stream_to_buffer } = require("../../../util/streamutil");
+
+module.exports = class IconResult {
+    constructor (o) {
+        Object.assign(this, o);
+    }
+
+    async get_data_url () {
+        if ( this.data_url ) {
+            return this.data_url;
+        } else {
+            try {
+                const buffer = await stream_to_buffer(this.stream);
+                return `data:${this.mime};base64,${buffer.toString('base64')}`;
+            } catch (e) {
+                const svc_error = Context.get(undefined, {
+                    allow_fallback: true,
+                }).get('services').get('error');
+                svc_error.report('IconResult:get_data_url', {
+                    source: e,
+                });
+                // TODO: broken image icon here
+                return `data:image/png;base64,${Buffer.from([]).toString('base64')}`;
+            }
+        }
+    }
+};

+ 2 - 5
src/backend/src/om/entitystorage/AppES.js

@@ -314,15 +314,12 @@ class AppES extends BaseES {
             if ( icon_size ) {
                 const svc_appIcon = this.context.get('services').get('app-icon');
                 try {
-                    const { stream, mime } = await svc_appIcon.get_icon_stream({
+                    const icon_result = await svc_appIcon.get_icon_stream({
                         app_uid: await entity.get('uid'),
                         app_icon: await entity.get('icon'),
                         size: icon_size,
                     });
-                    if ( ! stream ) throw Error('no stream');
-                    const buffer = await stream_to_buffer(stream);
-                    const data_url = `data:${mime};base64,${buffer.toString('base64')}`;
-                    await entity.set('icon', data_url);
+                    await entity.set('icon', await icon_result.get_data_url());
                 } catch (e) {
                     const svc_error = this.context.get('services').get('error-service');
                     svc_error.report('AppES:read_transform', { source: e });

+ 1 - 16
src/backend/src/routers/get-launch-apps.js

@@ -33,22 +33,7 @@ const iconify_apps = async (context, { apps, size }) => {
             size: size,
         });
 
-        if ( icon_result.data_url ) {
-            app.icon = icon_result.data_url;
-            return app;
-        }
-
-        try {
-            const buffer = await stream_to_buffer(icon_result.stream);
-            const resp_data_url = `data:${icon_result.mime};base64,${buffer.toString('base64')}`;
-            
-            app.icon = resp_data_url;
-        } catch (e) {
-            const svc_error = context.services.get('error');
-            svc_error.report('get-launch-apps:icon-stream', {
-                source: e,
-            });
-        }
+        app.icon = await icon_result.get_data_url();
         return app;
     }));
 }