Adding support for retrieving a manga description.

This commit is contained in:
sergiotarxz 2021-11-04 00:00:00 +01:00
parent 553c545e2d
commit af0aab72b8
5 changed files with 165 additions and 17 deletions

View File

@ -29,4 +29,8 @@ mg_backend_readmng_new (void);
GListStore *
mg_backend_readmng_get_featured_manga (MgBackendReadmng *self);
void
mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
MgManga *manga);
G_END_DECLS

View File

@ -6,9 +6,22 @@ G_BEGIN_DECLS;
#define MG_TYPE_MANGA mg_manga_get_type()
G_DECLARE_FINAL_TYPE (MgManga, mg_manga, MG, MANGA, GObject)
char *mg_manga_get_image_url(MgManga *mg_manga);
char *mg_manga_get_title(MgManga *mg_manga);
char *mg_manga_get_id(MgManga *mg_manga);
char *
mg_manga_get_image_url (MgManga *mg_manga);
char *
mg_manga_get_title (MgManga *mg_manga);
char *
mg_manga_get_id (MgManga *mg_manga);
char *
mg_manga_get_id (MgManga *mg_manga);
char *
mg_manga_get_description (MgManga *mg_manga);
void
mg_manga_set_description (MgManga *mg_manga, const char *description);
int
mg_manga_has_details (MgManga *self);
void
mg_manga_details_recovered (MgManga *self);
MgManga *mg_manga_new (const char *const image_url, const char *const title, const char *const id);

View File

@ -1,9 +1,12 @@
#include <libxml/HTMLparser.h>
#include <openmg/backend/readmng.h>
#include <openmg/util/soup.h>
#include <openmg/util/regex.h>
#include <openmg/util/xml.h>
#include <openmg/util/string.h>
#include <openmg/manga.h>
typedef enum {
@ -41,6 +44,9 @@ mg_backend_readmng_class_init (MgBackendReadmngClass *class) {
mg_backend_readmng_properties);
}
static xmlDocPtr
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
MgManga *manga);
static xmlNodePtr
mg_backend_readmng_retrieve_img_from_thumbnail (MgBackendReadmng *self, xmlNodePtr thumbnail);
static xmlNodePtr
@ -125,6 +131,70 @@ mg_backend_readmng_get_featured_manga (MgBackendReadmng *self) {
}
void
mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
MgManga *manga) {
MgUtilXML *xml_utils;
xmlDocPtr html_document;
xmlNodePtr *movie_detail = NULL;
xmlXPathObjectPtr xpath_result = NULL;
xmlNodeSetPtr node_set = NULL;
size_t movie_detail_len = 0;
if (mg_manga_has_details (manga)) {
return;
}
xml_utils = mg_util_xml_new ();
html_document = mg_backend_readmng_fetch_xml_details (self,
manga);
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
html_document, "//li[@class]");
node_set = xpath_result->nodesetval;
if (!node_set) {
fprintf(stderr, "No match\n");
return;
}
for (int i = 0; i < node_set->nodeNr; i++) {
xmlNodePtr node = node_set->nodeTab[i];
movie_detail = mg_util_xml_loop_search_class (xml_utils,
node, movie_detail, "movie-detail", &movie_detail_len);
}
if (movie_detail) {
mg_manga_set_description (manga,
(char *) xmlNodeGetContent (movie_detail[0]));
}
mg_manga_details_recovered (manga);
}
static xmlDocPtr
mg_backend_readmng_fetch_xml_details (MgBackendReadmng *self,
MgManga *manga) {
MgUtilSoup *util_soup;
MgUtilString *string_util;
char *request_url;
char *manga_id;
size_t request_url_len;
size_t response_len = 0;
util_soup = mg_util_soup_new ();
string_util = mg_util_string_new ();
manga_id = mg_manga_get_id (manga);
request_url_len = snprintf ( NULL, 0, "%s/%s/", self->base_url, manga_id);
request_url = mg_util_string_alloc_string (string_util, request_url_len);
snprintf ( request_url, request_url_len+1, "%s/%s/", self->base_url, manga_id);
char *html_response = mg_util_soup_get_request (util_soup,
request_url, &response_len);
return htmlReadMemory (html_response, response_len, NULL, NULL,
HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD
| HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING );
}
static xmlDocPtr
mg_backend_readmng_fetch_xml_main_page (MgBackendReadmng *self) {
size_t size_response_text = 0;

View File

@ -8,6 +8,8 @@ struct _MgManga {
char *image_url;
char *title;
char *id;
char *description;
int has_details;
};
G_DEFINE_TYPE (MgManga, mg_manga, G_TYPE_OBJECT)
@ -16,6 +18,7 @@ typedef enum {
MG_MANGA_IMAGE_URL = 1,
MG_MANGA_TITLE,
MG_MANGA_ID,
MG_MANGA_DESCRIPTION,
MG_MANGA_N_PROPERTIES
} MgMangaProperties;
@ -50,9 +53,15 @@ mg_manga_class_init (MgMangaClass *class) {
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
manga_properties[MG_MANGA_ID] = g_param_spec_string ("id",
"Id",
"Id of the manga",
"Id of the manga.",
NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
manga_properties[MG_MANGA_DESCRIPTION] = g_param_spec_string (
"description",
"Description",
"Description of the manga.",
NULL,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class,
MG_MANGA_N_PROPERTIES,
@ -61,6 +70,17 @@ mg_manga_class_init (MgMangaClass *class) {
static void
mg_manga_init (MgManga *self) {
self->has_details = 0;
}
int
mg_manga_has_details (MgManga *self) {
return self->has_details;
}
void
mg_manga_details_recovered (MgManga *self) {
self->has_details = 1;
}
char *
@ -93,6 +113,24 @@ mg_manga_get_title (MgManga *self) {
return g_value_dup_string (&value);
}
char *
mg_manga_get_description (MgManga *self) {
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (self),
"description",
&value);
return g_value_dup_string (&value);
}
void
mg_manga_set_description (MgManga *self, const char *description) {
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_STRING);
g_value_set_string (&value, description);
g_object_set_property (G_OBJECT (self), "description", &value);
}
static void
mg_manga_set_property (GObject *object,
guint property_id,
@ -112,6 +150,10 @@ mg_manga_set_property (GObject *object,
g_free (self->id);
self->id = g_value_dup_string (value);
break;
case MG_MANGA_DESCRIPTION:
g_free (self->description);
self->description = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -134,6 +176,9 @@ mg_manga_get_property (GObject *object,
case MG_MANGA_ID:
g_value_set_string (value, self->id);
break;
case MG_MANGA_DESCRIPTION:
g_value_set_string (value, self->description);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;

View File

@ -3,6 +3,8 @@
#include <openmg/manga.h>
#include <openmg/backend/readmng.h>
#include <openmg/util/xml.h>
#include <openmg/view/picture.h>
@ -10,19 +12,33 @@
GtkBox *
create_detail_view (MgManga *manga) {
MgBackendReadmng *readmng = mg_backend_readmng_new ();
GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
GtkBox *descriptive_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
GtkBox *avatar_title_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
MgUtilXML *xml_util = mg_util_xml_new ();
GtkLabel *manga_title = NULL;
GtkLabel *manga_description = NULL;
GtkPicture *manga_image = create_picture_from_url (
mg_manga_get_image_url(manga), 200);
char *title_text = mg_util_xml_get_title_text (
xml_util, mg_manga_get_title (manga));
char *description_text;
mg_backend_readmng_retrieve_manga_details (readmng, manga);
description_text = mg_manga_get_description (manga);
manga_title = GTK_LABEL (gtk_label_new (title_text));
manga_description = GTK_LABEL (gtk_label_new (description_text));
gtk_label_set_wrap (manga_title, 1);
gtk_label_set_wrap (manga_description, 1);
gtk_label_set_use_markup (GTK_LABEL (manga_title), 1);
gtk_box_append (descriptive_box, GTK_WIDGET (manga_image));
gtk_box_append (descriptive_box, GTK_WIDGET (manga_title));
gtk_box_append (detail_view, GTK_WIDGET (descriptive_box));
gtk_box_append (avatar_title_box, GTK_WIDGET (manga_image));
gtk_box_append (avatar_title_box, GTK_WIDGET (manga_title));
gtk_box_append (detail_view, GTK_WIDGET (avatar_title_box));
gtk_box_append (detail_view, GTK_WIDGET (manga_description));
return detail_view;
}