Remove default album info from image type
[platform/core/multimedia/libmedia-service.git] / plugin / media-ebook-plugin-epub.cpp
1 /*
2  * libmedia-service
3  *
4  * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "media-ebook-plugin-epub.h"
21
22 #include <dlog.h>
23 #include <glib.h>
24 #include <vector>
25
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29
30 #define LOG_TAG "MEDIA_SERVICE"
31
32 using namespace EBook;
33
34 Epub::Epub(std::string path, std::unique_ptr<IRunnable> runner)
35         : runner(std::move(runner))
36 {
37         if (path.empty()) {
38                 LOGE("invalid path");
39                 return;
40         }
41
42         LOGD("%s", path.c_str());
43
44         int err = 0;
45         z = zip_open(path.c_str(), ZIP_RDONLY, &err);
46         if (err != 0)
47                 LOGE("zip_open failed");
48 }
49
50 Epub::~Epub()
51 {
52         if (!z)
53                 return;
54
55         zip_close(z);
56         z = nullptr;
57 }
58
59 bool Epub::find()
60 {
61         zip_stat_t sb {};
62
63         int entry_len = zip_get_num_entries(z, ZIP_FL_UNCHANGED);
64         for (int i = 0; i < entry_len; i++) {
65                 if (!g_str_has_suffix(zip_get_name(z, i, ZIP_FL_ENC_GUESS), "html"))
66                         continue;
67
68                 if (zip_stat_index(z, i, 0, &sb) != 0)
69                         continue;
70
71                 zip_file_t *file = zip_fopen_index(z, i, 0);
72                 if (!file)
73                         continue;
74
75                 std::vector<char> file_buf(sb.size);
76
77                 zip_int64_t readn = zip_fread(file, file_buf.data(), sb.size);
78                 zip_fclose(file);
79
80                 if ((readn == static_cast<zip_int64_t>(sb.size)) &&
81                         htmlFind(file_buf.data(), sb.size))
82                         return true;
83         }
84
85         return false;
86 }
87
88 bool Epub::htmlFind(const char* html_buf, int buf_size)
89 {
90         htmlDocPtr doc = htmlReadMemory(html_buf, buf_size, "/", NULL,
91                                                                         HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);
92
93         if (!doc) {
94                 LOGE("htmlReadMemory failed");
95                 return false;
96         }
97
98         bool found = htmlNodeFindRecursive(xmlDocGetRootElement(doc));
99
100         xmlFreeDoc(doc);
101
102         return found;
103 }
104
105 bool Epub::htmlNodeFindRecursive(xmlNodePtr node)
106 {
107         for (xmlNodePtr cur = node; cur; cur = cur->next) {
108                 if (cur->type == XML_TEXT_NODE &&
109                         runner->run(reinterpret_cast<char*>(cur->content)))
110                         return true;
111
112                 if (htmlNodeFindRecursive(cur->children))
113                         return true;
114         }
115
116         return false;
117 }
118
119 void Epub::insert()
120 {
121         zip_stat_t sb {};
122
123         int entry_len = zip_get_num_entries(z, ZIP_FL_UNCHANGED);
124         for (int i = 0; i < entry_len; i++) {
125                 if (!g_str_has_suffix(zip_get_name(z, i, ZIP_FL_ENC_GUESS), "html"))
126                         continue;
127
128                 if (zip_stat_index(z, i, 0, &sb) != 0)
129                         continue;
130
131                 zip_file_t *file = zip_fopen_index(z, i, 0);
132                 if (!file)
133                         continue;
134
135                 std::vector<char> file_buf(sb.size);
136
137                 zip_int64_t readn = zip_fread(file, file_buf.data(), sb.size);
138                 zip_fclose(file);
139
140                 if (readn == static_cast<zip_int64_t>(sb.size))
141                         htmlInsert(file_buf.data(), sb.size);
142         }
143 }
144
145 void Epub::htmlInsert(const char* html_buf, int buf_size)
146 {
147         htmlDocPtr doc = htmlReadMemory(html_buf, buf_size, "/", NULL,
148                                                                         HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);
149
150         if (!doc) {
151                 LOGE("htmlReadMemory failed");
152                 return;
153         }
154
155         htmlNodeInsertRecursive(xmlDocGetRootElement(doc));
156
157         xmlFreeDoc(doc);
158 }
159
160 void Epub::htmlNodeInsertRecursive(xmlNodePtr node)
161 {
162         for (xmlNodePtr cur = node; cur; cur = cur->next) {
163                 if (cur->type == XML_TEXT_NODE)
164                         runner->run(reinterpret_cast<char*>(cur->content));
165
166                 htmlNodeInsertRecursive(cur->children);
167         }
168 }