initial working commit

This commit is contained in:
Rudis Muiznieks 2023-09-25 16:45:49 -05:00
commit a3a9bbb511
Signed by: rudism
GPG key ID: CABF2F86EF7884F9
6 changed files with 200 additions and 0 deletions

View file

@ -0,0 +1,48 @@
<?php
class FreshExtension_kagiSummarizer_Controller extends Minz_ActionController {
public function summarizeAction() {
$this->view->_layout(false);
$kagi_token = FreshRSS_Context::$user_conf->kagi_token;
if ($kagi_token === null || trim($kagi_token) ==='') {
echo json_encode(array(
'response' => array(
'output_text' => _t('ext.kagiSummarizer.ui.no_token_configured'),
'error' => 'configuration'),
'status' => 200));
return;
}
$entry_id = Minz_Request::param('id');
$entry_dao = FreshRSS_Factory::createEntryDao();
$entry = $entry_dao->searchById($entry_id);
if ($entry === null) {
echo json_encode(array('status' => 404));
return;
}
$entry_link = urlencode($entry->link());
$url = 'https://kagi.com/mother/summary_labs?summary_type=summary&url=' . $entry_link;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=UTF-8',
'Authorization: ' . $kagi_token
));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
$response = curl_exec($curl);
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$response_body = substr($response, $header_size);
echo json_encode(array(
'response' => json_decode($response_body),
'status' => curl_getinfo($curl, CURLINFO_HTTP_CODE)
));
}
}

19
configure.phtml Normal file
View file

@ -0,0 +1,19 @@
<?php
$kagi_token = FreshRSS_Context::$user_conf->kagi_token;
?>
<form action="<?php echo _url('extension', 'configure', 'e', urlencode($this->getName())); ?>" method="post">
<input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" />
<p><?php echo _t('ext.kagiSummarizer.configure.kagi_token_help'); ?></p>
<div class="form-group">
<label class="group-name" for="kagi_token"><?php echo _t('ext.kagiSummarizer.configure.kagi_token'); ?></label>
<div class="group-controls">
<input type="text" name="kagi_token" id="kagi_token" value="<?php echo $kagi_token; ?>">
</div>
</div>
<div class="form-group form-actions">
<div class="group-controls">
<button type="submit" class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button>
</div>
</div>
</form>

36
extension.php Normal file
View file

@ -0,0 +1,36 @@
<?php
class KagiSummarizerExtension extends Minz_Extension {
public function init() {
$this->registerTranslates();
$this->registerHook('entry_before_display', [$this, 'addSummarizeButton']);
Minz_View::appendScript($this->getFileUrl('script.js', 'js'), false, false, false);
$this->registerController('kagiSummarizer');
}
public function handleConfigureAction() {
$this->registerTranslates();
if (Minz_Request::isPost()) {
$kagi_token = Minz_Request::param('kagi_token', '');
$prefix = 'https://kagi.com/search?token=';
if (substr($kagi_token, 0, strlen($prefix)) == $prefix) {
$kagi_token = substr($kagi_token, strlen($prefix));
}
FreshRSS_Context::$user_conf->kagi_token = $kagi_token;
FreshRSS_Context::$user_conf->save();
}
}
public function addSummarizeButton(FreshRSS_Entry $entry): FreshRSS_Entry {
$this->registerTranslates();
$url = Minz_Url::display(array(
'c' => 'kagiSummarizer',
'a' => 'summarize',
'params' => array(
'id' => $entry->id()
)));
$entry->_content('<p class="kagi-summary"><a data-loading="' . htmlspecialchars(_t('ext.kagiSummarizer.ui.loading_summary')) . '" data-error="' . htmlspecialchars(_t('ext.kagiSummarizer.ui.error')) . '" class="btn" href="' . $url .'">' . _t('ext.kagiSummarizer.ui.summarize_button') . '</a></p>' . $entry->content());
return $entry;
}
}

16
i18n/en/ext.php Normal file
View file

@ -0,0 +1,16 @@
<?php
return array(
'kagiSummarizer' => array(
'configure' => array(
'kagi_token' => 'Kagi Token',
'kagi_token_help' => 'Copy and paste the "Session Link" from your <a href="https://kagi.com/settings?p=user_details" target="_blank">Kagi Account</a> settings.'
),
'ui' => array(
'summarize_button' => 'Summarize',
'loading_summary' => 'Loading summary...',
'error' => 'Error retrieving summary.',
'no_token_configured' => 'No Kagi token configured.'
)
)
);

8
metadata.json Normal file
View file

@ -0,0 +1,8 @@
{
"name": "Kagi Summarizer",
"author": "Rudis Muiznieks",
"description": "Add a button to summarize articles with the Kagi Universal Summarizer.",
"version": 0.1,
"entrypoint": "KagiSummarizer",
"type": "user"
}

73
static/script.js Normal file
View file

@ -0,0 +1,73 @@
if (document.readyState && document.readyState !== 'loading') {
configureSummarizeButtons();
} else {
document.addEventListener('DOMContentLoaded', configureSummarizeButtons, false);
}
function configureSummarizeButtons() {
document.getElementById('global').addEventListener('click', function(e) {
for (var target = e.target; target && target != this; target = target.parentNode) {
if (target.matches('.kagi-summary a.btn')) {
e.preventDefault();
e.stopPropagation();
if (target.href) {
summarizeButtonClick(target);
}
break;
}
}
}, false);
}
function summarizeButtonClick(button) {
var url = button.href;
var loadingMsg = button.dataset.loading;
var errorMsg = button.dataset.error;
var container = button.parentNode;
container.classList.add('alert');
container.classList.add('alert-warn');
container.innerHTML = loadingMsg;
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.responseType = 'json';
request.onload = function(e) {
if (this.status != 200) {
return request.onerror(e);
}
var response = xmlHttpRequestJson(this);
if (!response) {
return request.onerror(e);
}
if (response.status !== 200 || !response.response || !response.response.output_text) {
return request.onerror(e);
}
if (response.response.error) {
container.classList.remove('alert-warn');
container.classList.add('alert-error');
} else {
container.classList.remove('alert-warn');
container.classList.add('alert-success');
}
container.innerHTML = response.response.output_text;
}
request.onerror = function(e) {
badAjax(this.status == 403);
container.classList.remove('alert-warn');
container.classList.add('alert-error');
container.innerHTML = errorMsg;
}
request.setRequestHeader('Content-Type', 'application/json');
request.send(JSON.stringify({
ajax: true,
_csrf: context.csrf
}));
}