mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
feat(metadata): abstract metadata loader
This commit is contained in:
parent
77c919f7dd
commit
6bbb4d9971
|
@ -363,6 +363,7 @@ HEADERS += \
|
|||
src/keyboardstate.hh \
|
||||
src/langcoder.hh \
|
||||
src/language.hh \
|
||||
src/metadata.hh \
|
||||
src/multimediaaudioplayer.hh \
|
||||
src/parsecmdline.hh \
|
||||
src/resourceschemehandler.hh \
|
||||
|
@ -485,6 +486,7 @@ SOURCES += \
|
|||
src/langcoder.cc \
|
||||
src/language.cc \
|
||||
src/main.cc \
|
||||
src/metadata.cc \
|
||||
src/multimediaaudioplayer.cc \
|
||||
src/parsecmdline.cc \
|
||||
src/resourceschemehandler.cc \
|
||||
|
|
33
src/metadata.cc
Normal file
33
src/metadata.cc
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "metadata.hh"
|
||||
#include "toml.hpp"
|
||||
#include <QDebug>
|
||||
|
||||
std::optional< Metadata::result > Metadata::load( std::string_view filepath )
|
||||
{
|
||||
// by default, the optional will be initialized as std::nullopt
|
||||
Metadata::result result{};
|
||||
toml::table tbl;
|
||||
|
||||
try {
|
||||
tbl = toml::parse_file( filepath );
|
||||
}
|
||||
catch ( toml::parse_error & e ) {
|
||||
qWarning()<< "Failed to load metadata: " << QString::fromUtf8(filepath.data(),filepath.size())
|
||||
<< "Reason:" << e.what();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if ( toml::array * categories = tbl.get_as< toml::array >( "categories" ) ) {
|
||||
// result.categories is an optional, it exists, but the vector does not, so we have to create one here
|
||||
result.categories.emplace();
|
||||
for ( auto & el : *categories ) {
|
||||
if ( el.is_string() ) {
|
||||
result.categories.value().emplace_back( std::move( *el.value_exact< std::string >() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.name = tbl[ "metadata" ][ "name" ].value_exact< std::string >();
|
||||
return result;
|
||||
}
|
19
src/metadata.hh
Normal file
19
src/metadata.hh
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include <QStringView>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace Metadata {
|
||||
|
||||
/**
|
||||
* Represent the metadata.toml beside the dictionary files
|
||||
*/
|
||||
struct result
|
||||
{
|
||||
std::optional< std::vector< std::string > > categories;
|
||||
std::optional< std::string > name;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::optional< Metadata::result > load( std::string_view filepath );
|
||||
|
||||
} // namespace Metadata
|
|
@ -7,7 +7,7 @@
|
|||
#include "config.hh"
|
||||
#include "langcoder.hh"
|
||||
#include "language.hh"
|
||||
#include "toml.hpp"
|
||||
#include "metadata.hh"
|
||||
|
||||
//#include "initializing.hh"
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
|||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <QMap>
|
||||
#include <QMultiMap>
|
||||
#include <QVector>
|
||||
#include <QFileInfo>
|
||||
#include <QFileDialog>
|
||||
|
@ -904,30 +903,16 @@ void DictGroupsWidget::groupsByMetadata()
|
|||
continue;
|
||||
|
||||
auto filePath = Utils::Path::combine( baseDir, "metadata.toml" );
|
||||
if ( !QFile::exists( filePath ) ) {
|
||||
qDebug() << "the dictionary folder:" << baseDir << " contain no metadata.toml";
|
||||
|
||||
auto dictMetaData = Metadata::load( filePath.toStdString() );
|
||||
if ( dictMetaData && dictMetaData->categories ) {
|
||||
for ( const auto & category : dictMetaData->categories.value() ) {
|
||||
auto group = QString::fromStdString( category ).trimmed();
|
||||
if ( group.isEmpty() ) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
auto config = toml::parse_file( filePath.toStdString() );
|
||||
|
||||
toml::array * categories = config.get_as< toml::array >( "category" );
|
||||
if ( !categories ) {
|
||||
continue;
|
||||
}
|
||||
categories->for_each( [ &groupToDicts, &dict ]( auto && elem ) {
|
||||
if ( elem.is_string() ) {
|
||||
auto group = QString::fromStdString( elem.as_string()->get() ).trimmed();
|
||||
|
||||
if ( group.isEmpty() )
|
||||
return;
|
||||
|
||||
groupToDicts.insert( group, dict );
|
||||
}
|
||||
} );
|
||||
}
|
||||
catch ( toml::parse_error & e ) {
|
||||
qWarning() << "can not open the metadata.toml" << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ The `metadata.toml` should be placed beside dictionary files. One `metadata.toml
|
|||
The metadata file uses [TOML](https://toml.io) format.
|
||||
|
||||
```toml
|
||||
category = [ "English", "Russian", "Chinese" ]
|
||||
categories = [ "English", "Russian", "Chinese" ]
|
||||
|
||||
# the following fields have not supported yet.
|
||||
[metadata]
|
||||
|
@ -108,12 +108,12 @@ For example,
|
|||
|
||||
The content of the metadata `(A)` is
|
||||
```toml
|
||||
category = ["en-zh", "汉英词典"]
|
||||
categories = ["en-zh", "汉英词典"]
|
||||
```
|
||||
|
||||
The content of the metadata `(B)` is
|
||||
```toml
|
||||
category = ["图片词典", "en-zh", "汉英词典"]
|
||||
categories = ["图片词典", "en-zh", "汉英词典"]
|
||||
```
|
||||
|
||||
The structure above will be auto grouped into three groups:
|
||||
|
|
Loading…
Reference in a new issue