mirror of
https://github.com/YGGverse/bdoku.git
synced 2026-03-31 17:55:36 +00:00
implement full-text search
This commit is contained in:
parent
b0bdce7d5b
commit
290320c081
3 changed files with 240 additions and 17 deletions
|
|
@ -1,13 +1,14 @@
|
||||||
{
|
{
|
||||||
"name": "yggverse/dokuwiki-gemini-server",
|
"name": "yggverse/dokuwiki-gemini-server",
|
||||||
"description": "DokuWiki bridge for Gemini Protocol",
|
"description": "DokuWiki bridge for Gemini Protocol",
|
||||||
"keywords": [ "yggverse", "gemini", "gemini-protocol", "gemini-server", "wiki", "dokuwiki", "bridge", "server" ],
|
"keywords": [ "yggverse", "gemini", "gemini-protocol", "gemini-server", "wiki", "dokuwiki", "manticore", "bridge", "server" ],
|
||||||
"homepage": "https://github.com/yggverse/dokuwiki-to-gemini",
|
"homepage": "https://github.com/yggverse/dokuwiki-to-gemini",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"yggverse/titan-ii": "^1.0",
|
"yggverse/titan-ii": "^1.0",
|
||||||
"yggverse/gemini": "dev-main",
|
"yggverse/gemini": "dev-main",
|
||||||
"yggverse/cache": "^0.4.0"
|
"yggverse/cache": "^0.4.0",
|
||||||
|
"manticoresoftware/manticoresearch-php": "^3.1"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,29 @@
|
||||||
"timeout":3600
|
"timeout":3600
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"manticore":
|
||||||
|
{
|
||||||
|
"server":
|
||||||
|
{
|
||||||
|
"host":"127.0.0.1",
|
||||||
|
"port":9308
|
||||||
|
},
|
||||||
|
"index":
|
||||||
|
{
|
||||||
|
"document":{
|
||||||
|
"name":"dokuwiki_gemini_server",
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"morphology":"stem_cz,stem_enru",
|
||||||
|
"index_exact_words":1,
|
||||||
|
"html_strip":1,
|
||||||
|
"min_word_len":3,
|
||||||
|
"min_prefix_len":3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extension":"txt"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dokuwiki":
|
"dokuwiki":
|
||||||
{
|
{
|
||||||
"uri":
|
"uri":
|
||||||
|
|
@ -34,6 +57,10 @@
|
||||||
"sections":"Sections",
|
"sections":"Sections",
|
||||||
"pages":"Pages",
|
"pages":"Pages",
|
||||||
"actions":"Actions",
|
"actions":"Actions",
|
||||||
|
"search":"Search",
|
||||||
|
"results":"Request results",
|
||||||
|
"found":"Found",
|
||||||
|
"nothing":"Nothing found by this request",
|
||||||
"main":"Main page",
|
"main":"Main page",
|
||||||
"source":"Source",
|
"source":"Source",
|
||||||
"welcome":"About",
|
"welcome":"About",
|
||||||
|
|
|
||||||
225
src/server.php
225
src/server.php
|
|
@ -69,6 +69,8 @@ $memory = new \Yggverse\Cache\Memory(
|
||||||
$config->memcached->server->timeout
|
$config->memcached->server->timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$memory->flush();
|
||||||
|
|
||||||
// Init filesystem
|
// Init filesystem
|
||||||
$filesystem = new \Yggverse\Gemini\Dokuwiki\Filesystem(
|
$filesystem = new \Yggverse\Gemini\Dokuwiki\Filesystem(
|
||||||
sprintf(
|
sprintf(
|
||||||
|
|
@ -85,6 +87,71 @@ $helper = new \Yggverse\Gemini\Dokuwiki\Helper(
|
||||||
$reader
|
$reader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Init search server
|
||||||
|
$manticore = new \Manticoresearch\Client(
|
||||||
|
[
|
||||||
|
'host' => $config->manticore->server->host,
|
||||||
|
'port' => $config->manticore->server->port,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Init search index
|
||||||
|
$index = $manticore->index(
|
||||||
|
$config->manticore->index->document->name
|
||||||
|
);
|
||||||
|
|
||||||
|
$index->drop(true);
|
||||||
|
$index->create(
|
||||||
|
[
|
||||||
|
'uri' =>
|
||||||
|
[
|
||||||
|
'type' => 'text'
|
||||||
|
],
|
||||||
|
'name' =>
|
||||||
|
[
|
||||||
|
'type' => 'text'
|
||||||
|
],
|
||||||
|
'data' =>
|
||||||
|
[
|
||||||
|
'type' => 'text'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
(array) $config->manticore->index->document->settings
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($filesystem->getList() as $path)
|
||||||
|
{
|
||||||
|
if (!str_ends_with($path, $config->manticore->index->extension))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($uri = $filesystem->getPageUriByPath($path))
|
||||||
|
{
|
||||||
|
if ($data = file_get_contents($path))
|
||||||
|
{
|
||||||
|
$gemini = $reader->toGemini(
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
$index->addDocument(
|
||||||
|
[
|
||||||
|
'uri' => $uri,
|
||||||
|
'name' => (string) $reader->getH1(
|
||||||
|
$gemini
|
||||||
|
),
|
||||||
|
'data' => (string) $reader->toGemini(
|
||||||
|
$gemini
|
||||||
|
)
|
||||||
|
],
|
||||||
|
crc32(
|
||||||
|
$uri
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Init server
|
// Init server
|
||||||
$server = new \Yggverse\TitanII\Server();
|
$server = new \Yggverse\TitanII\Server();
|
||||||
|
|
||||||
|
|
@ -101,6 +168,7 @@ $server->setHandler(
|
||||||
{
|
{
|
||||||
global $config;
|
global $config;
|
||||||
global $memory;
|
global $memory;
|
||||||
|
global $index;
|
||||||
global $filesystem;
|
global $filesystem;
|
||||||
global $reader;
|
global $reader;
|
||||||
global $helper;
|
global $helper;
|
||||||
|
|
@ -118,18 +186,135 @@ $server->setHandler(
|
||||||
// Route begin
|
// Route begin
|
||||||
switch ($request->getPath())
|
switch ($request->getPath())
|
||||||
{
|
{
|
||||||
// Static route here
|
// Static routes
|
||||||
case null:
|
case null:
|
||||||
case false:
|
case false:
|
||||||
case '':
|
case '':
|
||||||
|
|
||||||
// @TODO redirect to document root (/)
|
$response->setCode(
|
||||||
|
30
|
||||||
|
);
|
||||||
|
|
||||||
|
$response->setMeta(
|
||||||
|
sprintf(
|
||||||
|
'gemini://%s%s/',
|
||||||
|
$config->gemini->server->host,
|
||||||
|
$config->gemini->server->port == 1965 ? null : ':' . $config->gemini->server->port
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/search':
|
case '/search':
|
||||||
|
|
||||||
// @TODO implement search feature
|
// Search query request
|
||||||
|
if (empty($request->getQuery()))
|
||||||
|
{
|
||||||
|
$response->setMeta(
|
||||||
|
'text/plain'
|
||||||
|
);
|
||||||
|
|
||||||
|
$response->setCode(
|
||||||
|
10
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare query
|
||||||
|
$query = trim(
|
||||||
|
urldecode(
|
||||||
|
$request->getQuery()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Do search
|
||||||
|
$results = $index->search(
|
||||||
|
@\Manticoresearch\Utils::escape(
|
||||||
|
$query
|
||||||
|
)
|
||||||
|
)->get();
|
||||||
|
|
||||||
|
// Init page content
|
||||||
|
$lines = [
|
||||||
|
PHP_EOL
|
||||||
|
];
|
||||||
|
|
||||||
|
// Append page title
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'# %s - %s',
|
||||||
|
$config->string->search,
|
||||||
|
$query
|
||||||
|
);
|
||||||
|
|
||||||
|
// Append search results
|
||||||
|
if ($total = $results->getTotal())
|
||||||
|
{
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'%s: %d',
|
||||||
|
$config->string->found,
|
||||||
|
$total
|
||||||
|
);
|
||||||
|
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'## %s',
|
||||||
|
$config->string->results
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> /%s %s',
|
||||||
|
$result->get('uri'),
|
||||||
|
$result->get('name')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing found
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$lines[] = $config->string->nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append actions
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'## %s',
|
||||||
|
$config->string->actions
|
||||||
|
);
|
||||||
|
|
||||||
|
// Append search link
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> /search %s',
|
||||||
|
$config->string->search
|
||||||
|
);
|
||||||
|
|
||||||
|
// Append homepage link
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> / %s',
|
||||||
|
$config->string->main
|
||||||
|
);
|
||||||
|
|
||||||
|
// Append source link
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> %s %s',
|
||||||
|
$config->dokuwiki->url->source,
|
||||||
|
$config->string->source
|
||||||
|
);
|
||||||
|
|
||||||
|
// Append about info
|
||||||
|
$lines[] = $config->string->about;
|
||||||
|
|
||||||
|
$response->setContent(
|
||||||
|
implode(
|
||||||
|
PHP_EOL,
|
||||||
|
$lines
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -165,13 +350,13 @@ $server->setHandler(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Define index menu
|
// Define index menu
|
||||||
$index = [];
|
$menu = [];
|
||||||
|
|
||||||
// Append index sections
|
// Append index sections
|
||||||
if ($sections = $helper->getChildrenSectionLinksByUri($_uri))
|
if ($sections = $helper->getChildrenSectionLinksByUri($_uri))
|
||||||
{
|
{
|
||||||
// Append header
|
// Append header
|
||||||
$index[] = sprintf(
|
$menu[] = sprintf(
|
||||||
'### %s',
|
'### %s',
|
||||||
$config->string->sections
|
$config->string->sections
|
||||||
);
|
);
|
||||||
|
|
@ -179,7 +364,7 @@ $server->setHandler(
|
||||||
// Append sections
|
// Append sections
|
||||||
foreach ($sections as $section)
|
foreach ($sections as $section)
|
||||||
{
|
{
|
||||||
$index[] = $section;
|
$menu[] = $section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +372,7 @@ $server->setHandler(
|
||||||
if ($pages = $helper->getChildrenPageLinksByUri($_uri))
|
if ($pages = $helper->getChildrenPageLinksByUri($_uri))
|
||||||
{
|
{
|
||||||
// Append header
|
// Append header
|
||||||
$index[] = sprintf(
|
$menu[] = sprintf(
|
||||||
'### %s',
|
'### %s',
|
||||||
$config->string->pages
|
$config->string->pages
|
||||||
);
|
);
|
||||||
|
|
@ -195,18 +380,18 @@ $server->setHandler(
|
||||||
// Append pages
|
// Append pages
|
||||||
foreach ($pages as $page)
|
foreach ($pages as $page)
|
||||||
{
|
{
|
||||||
$index[] = $page;
|
$menu[] = $page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set macros value
|
// Set macros value
|
||||||
if ($index)
|
if ($menu)
|
||||||
{
|
{
|
||||||
$reader->setRule(
|
$reader->setRule(
|
||||||
'/\{\{indexmenu>:([^\}]+)\}\}/i',
|
'/\{\{indexmenu>:([^\}]+)\}\}/i',
|
||||||
implode(
|
implode(
|
||||||
PHP_EOL,
|
PHP_EOL,
|
||||||
$index
|
$menu
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -214,7 +399,7 @@ $server->setHandler(
|
||||||
'/\{\{indexmenu_n>[\d]+\}\}/i',
|
'/\{\{indexmenu_n>[\d]+\}\}/i',
|
||||||
implode(
|
implode(
|
||||||
PHP_EOL,
|
PHP_EOL,
|
||||||
$index
|
$menu
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -253,11 +438,15 @@ $server->setHandler(
|
||||||
$config->string->actions
|
$config->string->actions
|
||||||
);
|
);
|
||||||
|
|
||||||
// Append source and homepage link
|
// Append search link
|
||||||
$lines[] = sprintf(
|
$lines[] = sprintf(
|
||||||
'=> gemini://%s%s %s',
|
'=> /search %s',
|
||||||
$config->gemini->server->host,
|
$config->string->search
|
||||||
$config->gemini->server->port == 1965 ? null : ':' . $config->gemini->server->port,
|
);
|
||||||
|
|
||||||
|
// Append homepage link
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> / %s',
|
||||||
$config->string->main
|
$config->string->main
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -397,6 +586,12 @@ $server->setHandler(
|
||||||
$config->string->resources
|
$config->string->resources
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Append search link
|
||||||
|
$lines[] = sprintf(
|
||||||
|
'=> /search %s',
|
||||||
|
$config->string->search
|
||||||
|
);
|
||||||
|
|
||||||
// Append source link
|
// Append source link
|
||||||
$lines[] = sprintf(
|
$lines[] = sprintf(
|
||||||
'=> %s %s',
|
'=> %s %s',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue