Skip to content

Commit

Permalink
fix(slb-495): add standalone page drop functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dspachos committed Dec 18, 2024
1 parent 0d32f66 commit d793830
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function silverback_ai_import_form_alter(&$form, &$form_state, $form_id) {
* {@inheritdoc}
*/
function silverback_ai_import_form_node_page_split_form_alter(&$form, FormStateInterface $form_state, $form_id) {

$form['import'] = [
'#type' => 'details',
'#title' => t('Import content'),
Expand Down Expand Up @@ -75,7 +76,8 @@ function silverback_ai_import_form_node_page_split_form_alter(&$form, FormStateI
$form['import']['container_url']['url_value'] = [
'#type' => 'url',
'#title' => t('URL'),
'#maxlength' => 1024,
'#maxlength' => 2048,
'#size' => 128,
'#states' => [
'required' => [
'input[name="import_type"]' => ['value' => 'url'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,66 @@ public function sendOpenAiRequest(string $ast, string $type, string $template, s
return json_decode($responseBodyContents, TRUE, 512, JSON_THROW_ON_ERROR);
}

/**
* {Helper method}
*/
public function extractBaseDataFromMarkdown(string $markdown) {
// @todo Get some of these from settings
$model = $this->configFactory->get('silverback_image_ai.settings')->get('ai_model') ?: self::DEFAULT_AI_MODEL;

$prompt = <<<EOD
You are an expert Markdown data extraction assistant. Your task is to analyze and extract specific information from provided Markdown text.
Input Markdown Context:
$markdown
Follow these steps carefully:
1. Extract the following information from the markdown:
- Title
- Language (in language code format, e.g. EN, EL etc)
2. Format your output strictly as JSON using this template:
{
'title' : extracted_title,
'language' : extracted_langcode,
}
Rules:
- Only return the JSON output.
- The output should be valid JSON, not markdown.
- Ensure the language code adheres to ISO 639-1 format.
- Be precise and concise in extracting the required information.
EOD;

$payload = [
'model' => $model,
'messages' => [
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => $prompt,
],
],
],
],
];

try {
$response = $this->silverbackAiOpenaiHttpClient->post('chat/completions', [
'json' => $payload,
]);
}
catch (\Exception $e) {
throw new \Exception('HTTP request failed: ' . $e->getMessage());
}

$responseBodyContents = $response->getBody()->getContents();
return json_decode($responseBodyContents, TRUE, 512, JSON_THROW_ON_ERROR);
}

/**
* Retrieves a plugin instance that matches the specified chunk.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@

namespace Drupal\silverback_ai_import\Form;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\file\Entity\File;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;

/**
* Provides a Silverback Import AI form.
Expand All @@ -28,6 +34,8 @@ public function getFormId(): string {
*/
public function buildForm(array $form, FormStateInterface $form_state): array {

// End debug
// ---------------------.
$form['message'] = [
'#type' => 'item',
'#markup' => Markup::create('<em>Create content by importing either a file or an existing URL.</em>'),
Expand Down Expand Up @@ -88,53 +96,123 @@ public function buildForm(array $form, FormStateInterface $form_state): array {
$form['import']['container_url']['url_value'] = [
'#type' => 'url',
'#title' => $this->t('URL'),
'#maxlength' => 1024,
'#maxlength' => 2048,
'#size' => 128,
'#states' => [
'required' => [
'input[name="import_type"]' => ['value' => 'url'],
],
],
];

$form['actions']['submit']['#submit'][] = '_silverback_ai_import_form_submit';

// Better to have this unpublished originally, and then
// we will display a message to the user (esp. if there is AI content)
$form['moderation_state']['#access'] = FALSE;
$form['actions']['submit']['#value'] = t('Create');
$form['import']['container_output'] = [
'#type' => 'container',
];
$form['import']['container_output']['output'] = [
'#type' => 'item',
'#prefix' => '<div id="edit-output">',
'#suffix' => '</div>',
];

// $form['actions']['submit']['#submit'][] = '_silverback_ai_import_form_submit';
$form['actions'] = [
'#type' => 'actions',
'#states' => [
'visible' => [
'input[name="import_type"]' => ['value' => 'docx'],
],
],
'submit' => [
'#type' => 'submit',
'#value' => $this->t('Create'),
'#value' => $this->t('Process document'),
/* '#attributes' => [
'class' => [
'use-ajax-submit',
],
],
'#ajax' => [
'#progress_indicator' => 'throbber',
'#progress_message' => $this->t('Validating input'),
'callback' => '::myAjaxCallbackDocx',
'event' => 'click',
'wrapper' => 'edit-output',
], */
],
];

return $form;
}

/**
* The textbox with the selected text.
*/
public function myAjaxCallbackDocx(array &$form, FormStateInterface $form_state) {
$file = $form_state->getValue('file');

$response = new AjaxResponse();

$response->addCommand(new ReplaceCommand('#edit-output', '<div id="edit-output"><em>' . $this->t('Please upload a file') . '</em></div>'));
return $response;
}

/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
// @todo Validate the form here.
// Example:
// @code
// if (mb_strlen($form_state->getValue('message')) < 10) {
// $form_state->setErrorByName(
// 'message',
// $this->t('Message should be at least 10 characters.'),
// );
// }
// @endcode
$file = $form_state->getValue('file');
$type = $form_state->getValue('import_type');
if ($type == 'docx' && empty($file['uploaded_files'])) {
$form_state->setErrorByName('file', $this->t('Please upload a file to import.'));
}
}

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$this->messenger()->addStatus($this->t('The message has been sent.'));
$type = $form_state->getValue('import_type');
if ($type == 'docx') {
$file = $form_state->getValue('file');
$filepath = $file['uploaded_files'][0]['path'];
$directory = 'public://converted';
$file_system = \Drupal::service('file_system');
$file_system->prepareDirectory($directory, FileSystemInterface:: CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
$file_system->copy($filepath, $directory . '/' . basename($filepath), FileSystemInterface::EXISTS_REPLACE);

$file = File::create([
'filename' => basename($filepath),
'uri' => "{$directory}/" . basename($filepath),
'status' => NodeInterface::PUBLISHED,
'uid' => \Drupal::currentUser()->id() ?? 1,
]);

$file->setPermanent();
$file->save();

if ($file) {
$service = \Drupal::service('silverback_ai_import.content');
$ast = $service->getAstFromFilePath($file);

$markdown = file_get_contents($ast->outputDirectory . '/content.md');
$openai = \Drupal::service('silverback_ai_import.content');
$data = $openai->extractBaseDataFromMarkdown($markdown);
if (isset($data['choices'][0]['message']['content'])) {
$content = \Drupal::service('silverback_ai_import.batch.import');
$data = json_decode($data['choices'][0]['message']['content'], TRUE);
$entity = Node::create([
'type' => 'page',
'title' => $data['title'],
'langcode' => strtolower($data['language']),
]);
$entity->save();
$ast = $service->getAstFromFilePath($file);
$flatten = $service->flattenAst($ast->content);
$content->create($flatten, $entity);
$form_state->setRedirectUrl($entity->toUrl());
}
}
}

}

}

0 comments on commit d793830

Please sign in to comment.