Skip to content

Commit dbcdd3a

Browse files
committed
feat: Generate images
1 parent 2f7add3 commit dbcdd3a

File tree

14 files changed

+630
-12
lines changed

14 files changed

+630
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
core/components/modai/vendor
2+
_packages

_build/gpm.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: modAI
2-
version: 1.0.0-pl
2+
version: 0.0.2-alpha
33
lowCaseName: modai
44
namespace: modAI
55
author: 'John Peca'
@@ -45,3 +45,17 @@ systemSettings:
4545
area: prompt
4646
type: 'textarea'
4747
value: "- You are a SEO expert\n- Your task is to generate SEO description from the content provided by the user\n- Description can't exceed 155 characters\n- Don't use any HTML or markdown tags"
48+
49+
- key: vision.model
50+
area: vision
51+
value: gpt-4o-mini
52+
- key: vision.prompt
53+
area: vision
54+
value: "What is in this image?"
55+
56+
- key: image.model
57+
area: image
58+
value: dall-e-3
59+
- key: image.size
60+
area: image
61+
value: "1024x1024"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
use xPDO\Transport\xPDOTransport;
3+
4+
/**
5+
* Include bootstrap when installing the package
6+
*
7+
* THIS RESOLVER IS AUTOMATICALLY GENERATED, NO CHANGES WILL APPLY
8+
*
9+
* @package modai
10+
* @subpackage build
11+
*
12+
* @var \MODX\Revolution\modNamespace $object
13+
* @var \MODX\Revolution\modX $modx
14+
* @var array $options
15+
*/
16+
17+
$modx =& $object->xpdo;
18+
if ($options[xPDOTransport::PACKAGE_ACTION] !== xPDOTransport::ACTION_INSTALL) return true;
19+
20+
$bootstrap = $object->getCorePath() . 'bootstrap.php';
21+
if (file_exists($bootstrap)) {
22+
$namespace = $object->toArray();
23+
$namespace['path'] = $object->getCorePath();
24+
$namespace['assets_path'] = $object->getAssetsPath();
25+
26+
require $object->getCorePath() . 'bootstrap.php';
27+
}
28+
29+
return true;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
use xPDO\Transport\xPDOTransport;
3+
4+
/**
5+
* Handle relation between elements and property sets
6+
*
7+
* THIS RESOLVER IS AUTOMATICALLY GENERATED, NO CHANGES WILL APPLY
8+
*
9+
* @package modai
10+
* @subpackage build
11+
*
12+
* @var \MODX\Revolution\modCategory $object
13+
* @var \MODX\Revolution\modX $modx
14+
* @var array $options
15+
* @var array $fileMeta
16+
*/
17+
18+
$modx =& $object->xpdo;
19+
if ($options[xPDOTransport::PACKAGE_ACTION] === xPDOTransport::ACTION_UNINSTALL) return true;
20+
21+
$propertySetsCache = [];
22+
23+
$elementClasses = [
24+
'snippets' => 'MODX\\Revolution\\modSnippet',
25+
'chunks' => 'MODX\\Revolution\\modChunk',
26+
'templates' => 'MODX\\Revolution\\modTemplate',
27+
'plugins' => 'MODX\\Revolution\\modPlugin',
28+
];
29+
30+
foreach ($elementClasses as $type => $elementClass) {
31+
if (isset($fileMeta[$type]) && is_array($fileMeta[$type])) {
32+
foreach ($fileMeta[$type] as $elementName => $propertySets) {
33+
$nameColumn = $type === 'templates' ? 'templatename' : 'name';
34+
/** @var \MODX\Revolution\modElement $element */
35+
$element = $modx->getObject($elementClass, [$nameColumn => $elementName]);
36+
if (!$element) continue;
37+
38+
if (empty($propertySets)) {
39+
$modx->removeCollection(\MODX\Revolution\modElementPropertySet::class, ['element' => $element->id, 'element_class' => $elementClass]);
40+
continue;
41+
}
42+
43+
if (!is_array($propertySets)) continue;
44+
45+
foreach ($propertySets as $propertySetName) {
46+
if (!isset($propertySetsCache[$propertySetName])) {
47+
/** @var \MODX\Revolution\modPropertySet $propertySet */
48+
$propertySet = $modx->getObject(\MODX\Revolution\modPropertySet::class, ['name' => $propertySetName]);
49+
if (!$propertySet) continue;
50+
51+
$propertySetsCache[$propertySetName] = $propertySet->id;
52+
}
53+
54+
$elementPropertySet = $modx->getObject(\MODX\Revolution\modElementPropertySet::class, ['element' => $element->id, 'element_class' => $elementClass, 'property_set' => $propertySetsCache[$propertySetName]]);
55+
if ($elementPropertySet) continue;
56+
57+
$elementPropertySet = $modx->newObject(\MODX\Revolution\modElementPropertySet::class);
58+
$elementPropertySet->set('element', $element->id);
59+
$elementPropertySet->set('element_class', $elementClass);
60+
$elementPropertySet->set('property_set', $propertySetsCache[$propertySetName]);
61+
$elementPropertySet->save();
62+
}
63+
}
64+
}
65+
}
66+
67+
return true;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
*
4+
* THIS RESOLVER IS AUTOMATICALLY GENERATED, NO CHANGES WILL APPLY
5+
*
6+
* @package modai
7+
* @subpackage build
8+
*
9+
* @var \xPDO\Transport\xPDOTransport $transport
10+
* @var array $object
11+
* @var array $options
12+
*/
13+
14+
use Fred\Model\FredThemedTemplate;
15+
use Fred\Model\FredBlueprint;
16+
use Fred\Model\FredTheme;
17+
use xPDO\Transport\xPDOTransport;
18+
use MODX\Revolution\modSystemSetting;
19+
use xPDO\xPDO;
20+
use xPDO\Cache\xPDOCacheManager;
21+
22+
if ($options[xPDOTransport::PACKAGE_ACTION] === xPDOTransport::ACTION_UNINSTALL) {
23+
return true;
24+
}
25+
26+
$modx =& $transport->xpdo;
27+
28+
$modx->getCacheManager();
29+
$modx->cacheManager->refresh();
30+
31+
$config = $modx->cacheManager->get('config', [
32+
xPDO::OPT_CACHE_KEY => $modx->getOption('cache_system_settings_key', null, 'system_settings'),
33+
xPDO::OPT_CACHE_HANDLER => $modx->getOption('cache_system_settings_handler', null, $modx->getOption(xPDO::OPT_CACHE_HANDLER)),
34+
xPDO::OPT_CACHE_FORMAT => (integer) $modx->getOption('cache_system_settings_format', null, $modx->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)),
35+
]);
36+
37+
if (empty($config)) {
38+
$config = $modx->cacheManager->generateConfig();
39+
}
40+
41+
if (empty($config)) {
42+
$config = [];
43+
if (!$settings = $modx->getCollection(modSystemSetting::class)) {
44+
return;
45+
}
46+
/** @var modSystemSetting $setting */
47+
foreach ($settings as $setting) {
48+
$config[$setting->get('key')]= $setting->get('value');
49+
}
50+
}
51+
52+
$modx->config = array_merge($modx->config, $config);
53+
$modx->_systemConfig = $modx->config;

assets/components/modai/js/mgr/autosummary.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,27 @@ Ext.onReady(function() {
7474
}
7575
};
7676

77-
const createGenerateButton = (field, fieldName) => {
77+
const createWantEl = () => {
7878
const wandEl = document.createElement('span');
7979
wandEl.style.cursor = 'pointer';
8080
wandEl.style.marginLeft = '5px';
8181
wandEl.style.verticalAlign = 'middle';
8282
wandEl.style.fontSize = '24px';
8383
wandEl.innerText = '🪄'
8484

85+
return wandEl;
86+
}
87+
88+
const createGenerateButton = (field, fieldName) => {
89+
const wandEl = createWantEl();
8590

8691
wandEl.addEventListener('click', () => {
8792
Ext.Msg.wait('Generating ...', 'Please wait');
8893

8994
MODx.Ajax.request({
9095
url: MODx.config.connector_url,
9196
params: {
92-
action: 'modAI\\Processors\\Prompt\\Generate',
97+
action: 'modAI\\Processors\\Prompt\\Text',
9398
id: MODx.request.id,
9499
field: fieldName
95100
},
@@ -185,6 +190,74 @@ Ext.onReady(function() {
185190
field.label.appendChild(wrapper);
186191
}
187192

193+
const attachImagePlus = () => {
194+
document.querySelectorAll('.imageplus-panel-input').forEach((el) => {
195+
const imagePlus = Ext.getCmp(el.firstChild.id);
196+
197+
const imageWand = createWantEl();
198+
imageWand.addEventListener('click', () => {
199+
const createColumn = MODx.load({
200+
xtype: 'modai-window-image_prompt',
201+
title: 'Image',
202+
record: {
203+
resource: MODx.request.id,
204+
prompt: Ext.getCmp('modx-resource-introtext').getValue(),
205+
},
206+
listeners: {
207+
'success': {fn:function(res) {
208+
imagePlus.imageBrowser.setValue(res.a.result.object.url);
209+
imagePlus.onImageChange(res.a.result.object.url)
210+
},scope:this}
211+
}
212+
});
213+
214+
createColumn.show();
215+
});
216+
217+
const altTextWand = createWantEl();
218+
altTextWand.addEventListener('click', () => {
219+
const imgElement = imagePlus.imagePreview.el.dom;
220+
221+
const canvas = document.createElement('canvas');
222+
const ctx = canvas.getContext('2d');
223+
224+
canvas.width = imgElement.width;
225+
canvas.height = imgElement.height;
226+
227+
ctx.drawImage(imgElement, 0, 0);
228+
229+
const base64Data = canvas.toDataURL('image/png');
230+
231+
Ext.Msg.wait('Generating ...', 'Please wait');
232+
233+
MODx.Ajax.request({
234+
url: MODx.config.connector_url,
235+
params: {
236+
action: 'modAI\\Processors\\Prompt\\Vision',
237+
image: base64Data
238+
},
239+
listeners: {
240+
success: {
241+
fn: (r) => {
242+
imagePlus.items.items[1].items.items[1].items.items[0].setValue(r.object.content);
243+
Ext.Msg.hide();
244+
}
245+
},
246+
failure: {
247+
fn: function() {
248+
console.log('fail');
249+
} ,
250+
scope: this
251+
}
252+
}
253+
});
254+
});
255+
256+
imagePlus.items.items[0].el.dom.appendChild(imageWand);
257+
imagePlus.items.items[1].items.items[1].el.dom.appendChild(altTextWand);
258+
})
259+
};
260+
188261
Ext.defer(function() {
189262
attach('modx-resource-pagetitle', 'pagetitle');
190263

@@ -196,5 +269,7 @@ Ext.onReady(function() {
196269
attach('modx-resource-description', 'description');
197270
attach('seosuite-description', 'description');
198271

272+
attachImagePlus();
273+
199274
}, 500);
200275
});

0 commit comments

Comments
 (0)