alchemy-media 0.7.6 → 0.9.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/bootstrap.js +5 -148
- package/config/routes.js +92 -0
- package/config/settings.js +111 -0
- package/lib/media_types/image_media_type.js +53 -14
- package/lib/media_types/media_type.js +16 -5
- package/model/media_file_model.js +2 -2
- package/model/media_raw_model.js +27 -5
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
package/bootstrap.js
CHANGED
|
@@ -1,150 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Veronica = alchemy.use('veronica'),
|
|
3
|
-
fs = alchemy.use('fs');
|
|
4
|
-
|
|
5
|
-
// Define the default options
|
|
6
|
-
var options = {
|
|
7
|
-
|
|
8
|
-
// The path to use in the url
|
|
9
|
-
url: '/media/image',
|
|
10
|
-
|
|
11
|
-
// Where to store the files
|
|
12
|
-
path: path.resolve(PATH_ROOT, 'files'),
|
|
13
|
-
|
|
14
|
-
// Which hash function to use
|
|
15
|
-
hash: 'sha1',
|
|
16
|
-
|
|
17
|
-
// Enable webp
|
|
18
|
-
webp: true,
|
|
19
|
-
|
|
20
|
-
// Temporary map for intermediate file changes
|
|
21
|
-
scratch: path.resolve(PATH_TEMP, 'scratch'),
|
|
22
|
-
|
|
23
|
-
// The cache map for resized images & thumbnails
|
|
24
|
-
cache: path.resolve(PATH_TEMP, 'imagecache'),
|
|
25
|
-
|
|
26
|
-
// Path to fontawesome pro
|
|
27
|
-
fontawesome_pro: null,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Inject the user-overridden options
|
|
31
|
-
alchemy.plugins.media = Object.assign(options, alchemy.plugins.media);
|
|
32
|
-
|
|
33
|
-
// Find the paths to these binaries
|
|
34
|
-
options.convert = alchemy.findPathToBinarySync('convert', options.convert);
|
|
35
|
-
options.exiv2 = alchemy.findPathToBinarySync('exiv2', options.exiv2);
|
|
36
|
-
options.cwebp = alchemy.findPathToBinarySync('cwebp', options.cwebp);
|
|
37
|
-
|
|
38
|
-
// Make sure these folders exist
|
|
39
|
-
alchemy.createDir(options.scratch);
|
|
40
|
-
alchemy.createDir(options.cache);
|
|
41
|
-
|
|
42
|
-
// Create routes
|
|
43
|
-
Router.add({
|
|
44
|
-
name : 'MediaFile#serveStatic',
|
|
45
|
-
methods : ['get'],
|
|
46
|
-
can_be_postponed : false,
|
|
47
|
-
paths : /\/media\/static\/(.*)*/,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
Router.add({
|
|
51
|
-
name : 'MediaFile#image',
|
|
52
|
-
methods : ['get'],
|
|
53
|
-
can_be_postponed : false,
|
|
54
|
-
paths : options.url + '/{id}',
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// The prefix is added at the end of the route so it does not
|
|
58
|
-
// change the user's active_prefix
|
|
59
|
-
Router.add({
|
|
60
|
-
name : 'MediaFile#data',
|
|
61
|
-
methods : ['get'],
|
|
62
|
-
can_be_postponed : false,
|
|
63
|
-
paths : '/media/data/{prefix}/{id}',
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
Router.add({
|
|
67
|
-
name : 'MediaFile#info',
|
|
68
|
-
methods : ['get'],
|
|
69
|
-
can_be_postponed : false,
|
|
70
|
-
paths : '/media/info',
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
Router.add({
|
|
74
|
-
name : 'MediaFile#recordsource',
|
|
75
|
-
methods : ['get'],
|
|
76
|
-
can_be_postponed : false,
|
|
77
|
-
paths : '/media/recordsource',
|
|
78
|
-
permission : 'media.recordsource',
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Allow dummy extensions
|
|
82
|
-
Router.add({
|
|
83
|
-
name : 'Media#fileextension',
|
|
84
|
-
methods : ['get'],
|
|
85
|
-
can_be_postponed : false,
|
|
86
|
-
paths : '/media/file/{id}.{extension}',
|
|
87
|
-
handler : 'MediaFile#file'
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Allow direct file downloads
|
|
91
|
-
Router.add({
|
|
92
|
-
name : 'MediaFile#file',
|
|
93
|
-
methods : ['get'],
|
|
94
|
-
can_be_postponed : false,
|
|
95
|
-
paths : '/media/file/{id}',
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
Router.add({
|
|
99
|
-
name : 'MediaFile#downloadFile',
|
|
100
|
-
methods : ['get'],
|
|
101
|
-
can_be_postponed : false,
|
|
102
|
-
paths : '/media/download/{id}',
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
Router.add({
|
|
106
|
-
name : 'MediaFile#thumbnail',
|
|
107
|
-
methods : ['get'],
|
|
108
|
-
can_be_postponed : false,
|
|
109
|
-
paths : '/media/thumbnail/{id}',
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
Router.add({
|
|
113
|
-
name : 'MediaFile#placeholder',
|
|
114
|
-
methods : ['get'],
|
|
115
|
-
can_be_postponed : false,
|
|
116
|
-
paths : '/media/placeholder',
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
Router.add({
|
|
120
|
-
name : 'MediaFile#upload',
|
|
121
|
-
methods : ['post'],
|
|
122
|
-
can_be_postponed : false,
|
|
123
|
-
paths : '/media/upload',
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
Router.add({
|
|
127
|
-
name : 'MediaFile#uploadsingle',
|
|
128
|
-
methods : ['post'],
|
|
129
|
-
can_be_postponed : false,
|
|
130
|
-
paths : '/media/uploadsingle',
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
var profiles = alchemy.shared('Media.profiles');
|
|
134
|
-
|
|
135
|
-
// Create a new veronica instance
|
|
136
|
-
options.veronica = new Veronica({
|
|
137
|
-
cwebp: options.cwebp,
|
|
138
|
-
temp: options.scratch,
|
|
139
|
-
cache: options.cache
|
|
140
|
-
});
|
|
1
|
+
const profiles = alchemy.shared('Media.profiles');
|
|
141
2
|
|
|
142
3
|
alchemy.hawkejs.addRawHtml(`<script>document.cookie = 'mediaResolution=' + encodeURIComponent(JSON.stringify({width:Math.max(screen.availWidth||0, window.outerWidth||0) || 1024,height:Math.max(screen.availHeight||0, window.outerHeight||0) || 768,dpr:window.devicePixelRatio}))</script>`);
|
|
143
4
|
|
|
144
|
-
if (options.fontawesome_pro) {
|
|
145
|
-
alchemy.exposeStatic('fontawesome_pro', options.fontawesome_pro);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
5
|
/**
|
|
149
6
|
* Register a profile under the given name
|
|
150
7
|
*
|
|
@@ -155,11 +12,11 @@ if (options.fontawesome_pro) {
|
|
|
155
12
|
* @param {String} name
|
|
156
13
|
* @param {Object} settings
|
|
157
14
|
*/
|
|
158
|
-
|
|
15
|
+
Plugin.addProfile = function addProfile(name, settings) {
|
|
159
16
|
profiles[name] = settings;
|
|
160
17
|
};
|
|
161
18
|
|
|
162
19
|
// Add the thumbnail profile
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
20
|
+
Plugin.addProfile('thumbnail', {width: 100, height: 100});
|
|
21
|
+
Plugin.addProfile('pickerThumb', {width: 250, height: 250});
|
|
22
|
+
Plugin.addProfile('chimera-gallery', {width: 400, height: 400});
|
package/config/routes.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
let url_prefix = '/media/image';
|
|
2
|
+
|
|
3
|
+
// Create routes
|
|
4
|
+
Plugin.addRoute({
|
|
5
|
+
name : 'MediaFile#serveStatic',
|
|
6
|
+
methods : ['get'],
|
|
7
|
+
can_be_postponed : false,
|
|
8
|
+
paths : /\/media\/static\/(.*)*/,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
Plugin.addRoute({
|
|
12
|
+
name : 'MediaFile#image',
|
|
13
|
+
methods : ['get'],
|
|
14
|
+
can_be_postponed : false,
|
|
15
|
+
paths : url_prefix + '/{id}',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// The prefix is added at the end of the route so it does not
|
|
19
|
+
// change the user's active_prefix
|
|
20
|
+
Plugin.addRoute({
|
|
21
|
+
name : 'MediaFile#data',
|
|
22
|
+
methods : ['get'],
|
|
23
|
+
can_be_postponed : false,
|
|
24
|
+
paths : '/media/data/{prefix}/{id}',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
Plugin.addRoute({
|
|
28
|
+
name : 'MediaFile#info',
|
|
29
|
+
methods : ['get'],
|
|
30
|
+
can_be_postponed : false,
|
|
31
|
+
paths : '/media/info',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
Plugin.addRoute({
|
|
35
|
+
name : 'MediaFile#recordsource',
|
|
36
|
+
methods : ['get'],
|
|
37
|
+
can_be_postponed : false,
|
|
38
|
+
paths : '/media/recordsource',
|
|
39
|
+
permission : 'media.recordsource',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Allow dummy extensions
|
|
43
|
+
Plugin.addRoute({
|
|
44
|
+
name : 'Media#fileextension',
|
|
45
|
+
methods : ['get'],
|
|
46
|
+
can_be_postponed : false,
|
|
47
|
+
paths : '/media/file/{id}.{extension}',
|
|
48
|
+
handler : 'MediaFile#file'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Allow direct file downloads
|
|
52
|
+
Plugin.addRoute({
|
|
53
|
+
name : 'MediaFile#file',
|
|
54
|
+
methods : ['get'],
|
|
55
|
+
can_be_postponed : false,
|
|
56
|
+
paths : '/media/file/{id}',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
Plugin.addRoute({
|
|
60
|
+
name : 'MediaFile#downloadFile',
|
|
61
|
+
methods : ['get'],
|
|
62
|
+
can_be_postponed : false,
|
|
63
|
+
paths : '/media/download/{id}',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Plugin.addRoute({
|
|
67
|
+
name : 'MediaFile#thumbnail',
|
|
68
|
+
methods : ['get'],
|
|
69
|
+
can_be_postponed : false,
|
|
70
|
+
paths : '/media/thumbnail/{id}',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
Plugin.addRoute({
|
|
74
|
+
name : 'MediaFile#placeholder',
|
|
75
|
+
methods : ['get'],
|
|
76
|
+
can_be_postponed : false,
|
|
77
|
+
paths : '/media/placeholder',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
Plugin.addRoute({
|
|
81
|
+
name : 'MediaFile#upload',
|
|
82
|
+
methods : ['post'],
|
|
83
|
+
can_be_postponed : false,
|
|
84
|
+
paths : '/media/upload',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
Plugin.addRoute({
|
|
88
|
+
name : 'MediaFile#uploadsingle',
|
|
89
|
+
methods : ['post'],
|
|
90
|
+
can_be_postponed : false,
|
|
91
|
+
paths : '/media/uploadsingle',
|
|
92
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const libpath = require('path');
|
|
2
|
+
|
|
3
|
+
// system.plugins.media
|
|
4
|
+
const MEDIA_PLUGIN_GROUP = Plugin.getSettingsGroup();
|
|
5
|
+
|
|
6
|
+
MEDIA_PLUGIN_GROUP.addSetting('translatable', {
|
|
7
|
+
type : 'boolean',
|
|
8
|
+
default : false,
|
|
9
|
+
description : 'Should file title & alt fields be translatable?',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
MEDIA_PLUGIN_GROUP.addSetting('file_hash_algorithm', {
|
|
13
|
+
type : 'string',
|
|
14
|
+
default : 'sha1',
|
|
15
|
+
description : 'The default file hash method',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
MEDIA_PLUGIN_GROUP.addSetting('enable_webp', {
|
|
19
|
+
type : 'boolean',
|
|
20
|
+
default : true,
|
|
21
|
+
description : 'Serve webp images when possible',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
MEDIA_PLUGIN_GROUP.addSetting('file_storage_path', {
|
|
25
|
+
type : 'string',
|
|
26
|
+
default : libpath.resolve(PATH_ROOT, 'files'),
|
|
27
|
+
description : 'Where to store uploaded files',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
MEDIA_PLUGIN_GROUP.addSetting('scratch_path', {
|
|
31
|
+
type : 'string',
|
|
32
|
+
default : libpath.resolve(PATH_TEMP, 'scratch'),
|
|
33
|
+
description : 'Temporary map for intermediate file changes',
|
|
34
|
+
action : (value, value_instance) => {
|
|
35
|
+
|
|
36
|
+
if (value) {
|
|
37
|
+
alchemy.createDir(value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
createVeronicaInstance();
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
MEDIA_PLUGIN_GROUP.addSetting('cache_path', {
|
|
45
|
+
type : 'string',
|
|
46
|
+
default : libpath.resolve(PATH_TEMP, 'imagecache'),
|
|
47
|
+
description : 'The cache map for resized images & thumbnails',
|
|
48
|
+
action : (value, value_instance) => {
|
|
49
|
+
|
|
50
|
+
if (value) {
|
|
51
|
+
alchemy.createDir(value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
createVeronicaInstance();
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
MEDIA_PLUGIN_GROUP.addSetting('fontawesome_pro', {
|
|
59
|
+
type : 'string',
|
|
60
|
+
default : null,
|
|
61
|
+
description : 'The URL to fontawesome pro',
|
|
62
|
+
action : (value, value_instance) => {
|
|
63
|
+
alchemy.exposeStatic('fontawesome_pro', value);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
MEDIA_PLUGIN_GROUP.addSetting('max_page_width', {
|
|
68
|
+
type : 'integer',
|
|
69
|
+
default : null,
|
|
70
|
+
description : 'Limit the maximum allowed page width, used for image resizing',
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const BINARIES = MEDIA_PLUGIN_GROUP.createGroup('binaries');
|
|
74
|
+
|
|
75
|
+
BINARIES.addSetting('convert', {
|
|
76
|
+
type : 'string',
|
|
77
|
+
default : alchemy.findPathToBinarySync('convert'),
|
|
78
|
+
description : 'The path to the `convert` binary',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
BINARIES.addSetting('exiv2', {
|
|
82
|
+
type : 'string',
|
|
83
|
+
default : alchemy.findPathToBinarySync('exiv2'),
|
|
84
|
+
description : 'The path to the `exiv2` binary',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
BINARIES.addSetting('cwebp', {
|
|
88
|
+
type : 'string',
|
|
89
|
+
default : alchemy.findPathToBinarySync('cwebp'),
|
|
90
|
+
description : 'The path to the `cwebp` binary',
|
|
91
|
+
action : createVeronicaInstance,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Recreate the Veronica instance
|
|
96
|
+
*
|
|
97
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
98
|
+
* @since 0.9.0
|
|
99
|
+
* @version 0.9.0
|
|
100
|
+
*/
|
|
101
|
+
function createVeronicaInstance() {
|
|
102
|
+
|
|
103
|
+
let Veronica = alchemy.use('veronica');
|
|
104
|
+
const media = alchemy.settings.plugins.media;
|
|
105
|
+
|
|
106
|
+
alchemy.plugins.media.veronica = new Veronica({
|
|
107
|
+
cwebp : media.binaries.cwebp,
|
|
108
|
+
temp : media.scratch_path,
|
|
109
|
+
cache : media.cache_path,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
@@ -19,10 +19,6 @@ var exiv2 = alchemy.use('@11ways/exiv2'),
|
|
|
19
19
|
*/
|
|
20
20
|
const ImageMedia = Function.inherits('Alchemy.MediaType', 'ImageMediaType');
|
|
21
21
|
|
|
22
|
-
ImageMedia.setProperty('exivPath', alchemy.plugins.media.exiv2);
|
|
23
|
-
ImageMedia.setProperty('hashType', alchemy.plugins.media.hash);
|
|
24
|
-
ImageMedia.setProperty('veronica', alchemy.plugins.media.veronica);
|
|
25
|
-
|
|
26
22
|
ImageMedia.setProperty('typeMap', {
|
|
27
23
|
images: {
|
|
28
24
|
regex: /^image\//,
|
|
@@ -30,6 +26,45 @@ ImageMedia.setProperty('typeMap', {
|
|
|
30
26
|
}
|
|
31
27
|
});
|
|
32
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Add a property getter to the exiv binary
|
|
31
|
+
*
|
|
32
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
33
|
+
* @since 0.9.0
|
|
34
|
+
* @version 0.9.0
|
|
35
|
+
*
|
|
36
|
+
* @type {string}
|
|
37
|
+
*/
|
|
38
|
+
ImageMedia.setProperty(function exiv_path() {
|
|
39
|
+
return alchemy.settings.plugins.media.binaries.exiv2;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Add a property getter to the cwebp binary
|
|
44
|
+
*
|
|
45
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
46
|
+
* @since 0.9.0
|
|
47
|
+
* @version 0.9.0
|
|
48
|
+
*
|
|
49
|
+
* @type {string}
|
|
50
|
+
*/
|
|
51
|
+
ImageMedia.setProperty(function cwebp_path() {
|
|
52
|
+
return alchemy.settings.plugins.media.binaries.cwebp;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the hash algorithm
|
|
57
|
+
*
|
|
58
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
59
|
+
* @since 0.9.0
|
|
60
|
+
* @version 0.9.0
|
|
61
|
+
*
|
|
62
|
+
* @type {string}
|
|
63
|
+
*/
|
|
64
|
+
ImageMedia.setProperty(function hashType() {
|
|
65
|
+
return alchemy.settings.plugins.media.file_hash_algorithm;
|
|
66
|
+
});
|
|
67
|
+
|
|
33
68
|
/**
|
|
34
69
|
* Generate a thumbnail of this type
|
|
35
70
|
*
|
|
@@ -163,8 +198,8 @@ function getResizedDimension(query, type, resolution, dpr) {
|
|
|
163
198
|
}
|
|
164
199
|
|
|
165
200
|
// It's called "max_page_width", but height can also be checked against this
|
|
166
|
-
if (base_size > alchemy.plugins.media.max_page_width) {
|
|
167
|
-
base_size = alchemy.plugins.media.max_page_width;
|
|
201
|
+
if (base_size > alchemy.settings.plugins.media.max_page_width) {
|
|
202
|
+
base_size = alchemy.settings.plugins.media.max_page_width;
|
|
168
203
|
}
|
|
169
204
|
|
|
170
205
|
size = (base_size * percentage) / 100;
|
|
@@ -307,7 +342,9 @@ ImageMedia.setMethod(function serve(conduit, record, options) {
|
|
|
307
342
|
|
|
308
343
|
if (resizeOptions) {
|
|
309
344
|
|
|
310
|
-
|
|
345
|
+
const cwebp_path = this.cwebp_path;
|
|
346
|
+
|
|
347
|
+
if (this.supportsWebp(conduit) && cwebp_path) {
|
|
311
348
|
resizeOptions.type = 'webp';
|
|
312
349
|
}
|
|
313
350
|
|
|
@@ -440,11 +477,13 @@ ImageMedia.setMethod(function getSize(conduit, filePath, options, callback) {
|
|
|
440
477
|
|
|
441
478
|
tempPath = PATH_TEMP + '/' + alchemy.ObjectId() + '.webp';
|
|
442
479
|
|
|
443
|
-
|
|
480
|
+
const cwebp_path = this.cwebp_path;
|
|
481
|
+
|
|
482
|
+
if (!cwebp_path) {
|
|
444
483
|
return callback(new Error('Unable to get size: cwebp not found'));
|
|
445
484
|
}
|
|
446
485
|
|
|
447
|
-
child.exec(
|
|
486
|
+
child.exec(cwebp_path + ' ' + [resizeOptions, '-q 80', filePath, '-o', tempPath].join(' '), function(err, out) {
|
|
448
487
|
|
|
449
488
|
if (err) {
|
|
450
489
|
return callback(err);
|
|
@@ -560,7 +599,7 @@ ImageMedia.setMethod(function getMetadata(filePath, base, info, extra, callback)
|
|
|
560
599
|
return getInfo();
|
|
561
600
|
}
|
|
562
601
|
|
|
563
|
-
child.execFile(that.
|
|
602
|
+
child.execFile(that.exiv_path, ['rm', tempFile], function afterStrip(err) {
|
|
564
603
|
|
|
565
604
|
if (err) {
|
|
566
605
|
log.error('Error stripping metadata ', {err: err});
|
|
@@ -600,11 +639,11 @@ ImageMedia.setMethod(function getMetadata(filePath, base, info, extra, callback)
|
|
|
600
639
|
*
|
|
601
640
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
602
641
|
* @since 0.0.1
|
|
603
|
-
* @version 0.
|
|
642
|
+
* @version 0.9.0
|
|
604
643
|
*/
|
|
605
644
|
ImageMedia.setMethod(function resize(source, target, width, height, callback) {
|
|
606
645
|
|
|
607
|
-
|
|
646
|
+
let convertBin = alchemy.settings.plugins.media.convert;
|
|
608
647
|
|
|
609
648
|
child.execFile(convertBin, [source, '-resize', width + 'x' + height, target], function(err) {
|
|
610
649
|
callback(err);
|
|
@@ -616,7 +655,7 @@ ImageMedia.setMethod(function resize(source, target, width, height, callback) {
|
|
|
616
655
|
*
|
|
617
656
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
618
657
|
* @since 0.0.1
|
|
619
|
-
* @version 0.
|
|
658
|
+
* @version 0.9.0
|
|
620
659
|
*
|
|
621
660
|
* @param {String} filePath The path of the file to inspect
|
|
622
661
|
* @param {Function} callback
|
|
@@ -624,7 +663,7 @@ ImageMedia.setMethod(function resize(source, target, width, height, callback) {
|
|
|
624
663
|
ImageMedia.setMethod(function getImageInfo(filePath, callback) {
|
|
625
664
|
|
|
626
665
|
// Run exiv on the given file
|
|
627
|
-
child.execFile(this.
|
|
666
|
+
child.execFile(this.exiv_path, ['-pt', filePath], function afterStrip(err, out) {
|
|
628
667
|
|
|
629
668
|
var output,
|
|
630
669
|
lines,
|
|
@@ -22,8 +22,6 @@ MediaType = Function.inherits('Alchemy.Base', function MediaType(options) {
|
|
|
22
22
|
|
|
23
23
|
typeName = this.constructor.name.replace(/MediaType$/, '');
|
|
24
24
|
|
|
25
|
-
this.veronica = alchemy.plugins.media.veronica;
|
|
26
|
-
|
|
27
25
|
this.title = typeName || 'Media';
|
|
28
26
|
this.typeName = this.title.underscore();
|
|
29
27
|
this.options = options || {};
|
|
@@ -55,25 +53,38 @@ MediaType.makeAbstractClass();
|
|
|
55
53
|
*/
|
|
56
54
|
MediaType.startNewGroup();
|
|
57
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Get the veronica instance
|
|
58
|
+
*
|
|
59
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
60
|
+
* @since 0.9.0
|
|
61
|
+
* @version 0.9.0
|
|
62
|
+
*
|
|
63
|
+
* @type {Veronica}
|
|
64
|
+
*/
|
|
65
|
+
MediaType.setProperty(function veronica() {
|
|
66
|
+
return alchemy.plugins.media.veronica;
|
|
67
|
+
});
|
|
68
|
+
|
|
58
69
|
/**
|
|
59
70
|
* See if we can use webp
|
|
60
71
|
*
|
|
61
72
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
62
73
|
* @since 0.0.1
|
|
63
|
-
* @version 0.
|
|
74
|
+
* @version 0.9.0
|
|
64
75
|
*
|
|
65
76
|
* @param {Conduit} conduit
|
|
66
77
|
*/
|
|
67
78
|
MediaType.setMethod(function supportsWebp(conduit) {
|
|
68
79
|
|
|
69
|
-
|
|
80
|
+
let result = false,
|
|
70
81
|
has_webp_support,
|
|
71
82
|
uaString,
|
|
72
83
|
agent,
|
|
73
84
|
is;
|
|
74
85
|
|
|
75
86
|
// If webp has been disabled, return false
|
|
76
|
-
if (!alchemy.plugins.media.
|
|
87
|
+
if (!alchemy.settings.plugins.media.enable_webp) {
|
|
77
88
|
return false;
|
|
78
89
|
}
|
|
79
90
|
|
|
@@ -53,12 +53,12 @@ MediaFile.constitute(function addFields() {
|
|
|
53
53
|
this.addField('extra', 'Object');
|
|
54
54
|
|
|
55
55
|
this.addField('title', 'String', {
|
|
56
|
-
translatable : alchemy.plugins.media.translatable,
|
|
56
|
+
translatable : alchemy.settings.plugins.media.translatable,
|
|
57
57
|
description : 'The title of the file (will be used in the title attribute)',
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
this.addField('alt', 'String', {
|
|
61
|
-
translatable : alchemy.plugins.media.translatable,
|
|
61
|
+
translatable : alchemy.settings.plugins.media.translatable,
|
|
62
62
|
description : 'The alternative information of the file (will be used in the alt attribute)',
|
|
63
63
|
});
|
|
64
64
|
|
package/model/media_raw_model.js
CHANGED
|
@@ -41,10 +41,34 @@ MediaRaw.constitute(function addFields() {
|
|
|
41
41
|
this.addField('extra', 'Object');
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
MediaRaw.setProperty('basePath', alchemy.plugins.media.path);
|
|
45
|
-
MediaRaw.setProperty('hash', alchemy.plugins.media.hash);
|
|
46
44
|
MediaRaw.setProperty('types', alchemy.getClassGroup('media_type'));
|
|
47
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Get the hash algorithm
|
|
48
|
+
*
|
|
49
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
50
|
+
* @since 0.9.0
|
|
51
|
+
* @version 0.9.0
|
|
52
|
+
*
|
|
53
|
+
* @type {string}
|
|
54
|
+
*/
|
|
55
|
+
MediaRaw.setProperty(function hashType() {
|
|
56
|
+
return alchemy.settings.plugins.media.file_hash_algorithm;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get the base path
|
|
61
|
+
*
|
|
62
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
63
|
+
* @since 0.9.0
|
|
64
|
+
* @version 0.9.0
|
|
65
|
+
*
|
|
66
|
+
* @type {string}
|
|
67
|
+
*/
|
|
68
|
+
MediaRaw.setProperty(function basePath() {
|
|
69
|
+
return alchemy.settings.plugins.media.file_storage_path;
|
|
70
|
+
});
|
|
71
|
+
|
|
48
72
|
/**
|
|
49
73
|
* Path to this file
|
|
50
74
|
*
|
|
@@ -239,13 +263,11 @@ MediaRaw.setMethod(function addFile(file, options, callback) {
|
|
|
239
263
|
|
|
240
264
|
alchemy.getFileInfo(file, {hash: this.hashType}, function gotFileInfo(err, info) {
|
|
241
265
|
|
|
242
|
-
var type;
|
|
243
|
-
|
|
244
266
|
if (err) {
|
|
245
267
|
return callback(err);
|
|
246
268
|
}
|
|
247
269
|
|
|
248
|
-
type = that.MediaType.determineType(info.mimetype, options);
|
|
270
|
+
let type = that.MediaType.determineType(info.mimetype, options);
|
|
249
271
|
|
|
250
272
|
type.normalize(file, info, function afterNormalize(err, rawPath, rawInfo, rawExtra, extra) {
|
|
251
273
|
|
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy-media",
|
|
3
3
|
"description": "The media plugin for Alchemy",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0-alpha",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type" : "git",
|
|
7
7
|
"url" : "https://github.com/11ways/alchemy-media.git"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@11ways/exiv2" : "~0.
|
|
10
|
+
"@11ways/exiv2" : "~0.7.0",
|
|
11
11
|
"gm" : "~1.23.1",
|
|
12
12
|
"veronica" : "~0.2.2"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"alchemymvc" : ">=1.
|
|
15
|
+
"alchemymvc" : ">=1.4.0||>=1.4.0-alpha"
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"engines": {
|
|
19
|
-
"node" : ">=
|
|
19
|
+
"node" : ">=16.20.1"
|
|
20
20
|
}
|
|
21
21
|
}
|