Skip to content

Commit f71fa26

Browse files
committed
Implement MimeInfoEditor
1 parent d51803e commit f71fa26

File tree

5 files changed

+182
-1
lines changed

5 files changed

+182
-1
lines changed

src/libappimage/desktop_integration/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set(
44
integrator/Integrator.cpp
55
integrator/DesktopEntryEditError.h
66
integrator/DesktopEntryEditor.cpp
7-
)
7+
integrator/MimeInfoEditor.cpp integrator/MimeInfoEditor.h)
88

99
if(LIBAPPIMAGE_THUMBNAILER_ENABLED)
1010
list(APPEND appimage_desktop_integration_sources "Thumbnailer.cpp")
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// libraries
2+
#include <boost/property_tree/xml_parser.hpp>
3+
#include <boost/property_tree/ptree.hpp>
4+
#include <boost/algorithm/string.hpp>
5+
#include <iostream>
6+
7+
// local
8+
#include "utils/Logger.h"
9+
#include "MimeInfoEditor.h"
10+
11+
namespace appimage {
12+
namespace desktop_integration {
13+
namespace integrator {
14+
MimeInfoEditor::MimeInfoEditor(std::string data, std::string deployId)
15+
: data(std::move(data)), deployId(std::move(deployId)) {}
16+
17+
std::string MimeInfoEditor::edit() {
18+
std::stringstream in(data), out;
19+
20+
try {
21+
using boost::property_tree::ptree;
22+
23+
// populate tree structure pt
24+
ptree pt;
25+
read_xml(in, pt);
26+
27+
// traverse pt
28+
for (auto& node: pt.get_child("mime-info")) {
29+
if (node.first == "mime-type") {
30+
auto& subTree = node.second;
31+
// get original icon name from the icon entry
32+
std::string originalName = subTree.get<std::string>("icon.<xmlattr>.name", "");
33+
34+
// or fallback to the mime-type name
35+
if (originalName.empty()) {
36+
originalName = subTree.get<std::string>("<xmlattr>.type");
37+
boost::replace_all(originalName, "/", "-");
38+
}
39+
40+
std::string newIconName = originalName + "-" + deployId;
41+
42+
subTree.put("icon.<xmlattr>.name", newIconName);
43+
}
44+
}
45+
46+
write_xml(out, pt);
47+
} catch (const std::runtime_error& error) {
48+
appimage::utils::Logger::warning(std::string("Unable to edit MimeInfo: ") + error.what());
49+
return data;
50+
}
51+
52+
return out.str();
53+
}
54+
}
55+
}
56+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
// system
4+
#include <string>
5+
6+
namespace appimage {
7+
namespace desktop_integration {
8+
namespace integrator {
9+
/**
10+
* @brief Modifies MimeInfo files to be deployed.
11+
*
12+
*
13+
*/
14+
class MimeInfoEditor {
15+
public:
16+
/**
17+
* Create an editor instance to modify the
18+
* @param data
19+
* @param deployId
20+
*/
21+
MimeInfoEditor(std::string data, std::string deployId);
22+
23+
std::string edit();
24+
25+
private:
26+
std::string data;
27+
std::string deployId;
28+
};
29+
}
30+
}
31+
}

tests/libappimage/desktop_integration/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(
55

66
integrator/TestDesktopIntegration.cpp
77
integrator/TestDesktopEntryEditor.cpp
8+
integrator/TestMimeInfoEditor.cpp
89

910
$<TARGET_OBJECTS:core>
1011
$<TARGET_OBJECTS:appimage_utils>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//system
2+
#include <sstream>
3+
4+
// library
5+
#include <gtest/gtest.h>
6+
#include <XdgUtils/DesktopEntry/DesktopEntry.h>
7+
#include <boost/property_tree/xml_parser.hpp>
8+
#include <boost/property_tree/ptree.hpp>
9+
10+
// local
11+
#include <appimage/core/exceptions.h>
12+
#include "utils/hashlib.h"
13+
#include "integrator/MimeInfoEditor.h"
14+
15+
using namespace appimage::desktop_integration::integrator;
16+
using namespace appimage::utils;
17+
18+
class MimeInfoEditorTests : public ::testing::Test {
19+
protected:
20+
std::stringstream mimeInfo;
21+
std::stringstream mimeInfoWithIconEntry;
22+
std::stringstream expectedMimeInfo;
23+
protected:
24+
25+
void SetUp() override {
26+
mimeInfo << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
27+
"<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">\n"
28+
" <mime-type type=\"application/x-starbright-file\">\n"
29+
" <sub-class-of type=\"application/xml\"/>\n"
30+
" <comment>Starbright File</comment>\n"
31+
" <glob pattern=\"*.starb\"/>\n"
32+
" </mime-type>\n"
33+
"</mime-info>";
34+
35+
mimeInfoWithIconEntry
36+
<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
37+
"<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">\n"
38+
" <mime-type type=\"application/x-starbright-file\">\n"
39+
" <sub-class-of type=\"application/xml\"/>\n"
40+
" <comment>Starbright File</comment>\n"
41+
" <glob pattern=\"*.starb\"/>\n"
42+
" <icon name=\"application-x-starbright-file\"/>\n"
43+
" </mime-type>\n"
44+
"</mime-info>";
45+
46+
expectedMimeInfo
47+
<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
48+
"<mime-info xmlns=\"http://www.freedesktop.org/standards/shared-mime-info\">\n"
49+
" <mime-type type=\"application/x-starbright-file\">\n"
50+
" <sub-class-of type=\"application/xml\"/>\n"
51+
" <comment>Starbright File</comment>\n"
52+
" <glob pattern=\"*.starb\"/>\n"
53+
" <icon name=\"application-x-starbright-file-appimaged-d41d8cd98f00b204e9800998ecf8427e\"/>\n"
54+
" </mime-type>\n"
55+
"</mime-info>";
56+
}
57+
};
58+
59+
TEST_F(MimeInfoEditorTests, setIcon) {
60+
MimeInfoEditor editor(mimeInfo.str(), "appimaged-d41d8cd98f00b204e9800998ecf8427e");
61+
std::string result = editor.edit();
62+
63+
64+
using boost::property_tree::ptree;
65+
66+
std::stringstream resultStream(result);
67+
68+
// populate tree structure pt
69+
ptree resultPt, expectedPt;
70+
read_xml(resultStream, resultPt, boost::property_tree::xml_parser::trim_whitespace);
71+
read_xml(expectedMimeInfo, expectedPt, boost::property_tree::xml_parser::trim_whitespace);
72+
73+
74+
ASSERT_EQ(resultPt, expectedPt);
75+
}
76+
77+
TEST_F(MimeInfoEditorTests, updateIcon) {
78+
MimeInfoEditor editor(mimeInfoWithIconEntry.str(), "appimaged-d41d8cd98f00b204e9800998ecf8427e");
79+
std::string result = editor.edit();
80+
81+
82+
using boost::property_tree::ptree;
83+
84+
std::stringstream resultStream(result);
85+
86+
// populate tree structure pt
87+
ptree resultPt, expectedPt;
88+
read_xml(resultStream, resultPt, boost::property_tree::xml_parser::trim_whitespace);
89+
read_xml(expectedMimeInfo, expectedPt, boost::property_tree::xml_parser::trim_whitespace);
90+
91+
92+
ASSERT_EQ(resultPt, expectedPt);
93+
}

0 commit comments

Comments
 (0)