From 215563d862ae3472e5a31fcebde8edb1d1bf912a Mon Sep 17 00:00:00 2001 From: sergiotarxz Date: Sat, 30 Oct 2021 04:02:10 +0200 Subject: [PATCH] Changing to leaflet and adding support for manga id recovery. --- include/manga.h | 2 ++ include/openmg/manga.h | 3 ++- manga.c | 34 ++++++++++++++++++++++++++++++++++ src/backend/readmng.c | 39 +++++++++++++++++++++++++++++++++------ src/manga.c | 32 +++++++++++++++++++++++++++++--- src/view/main_view.c | 11 +++++------ 6 files changed, 105 insertions(+), 16 deletions(-) diff --git a/include/manga.h b/include/manga.h index da8b553..20064d0 100644 --- a/include/manga.h +++ b/include/manga.h @@ -57,3 +57,5 @@ loop_search_class (const xmlNodePtr node, xmlNodePtr *nodes, const char * class, size_t *len); char * copy_binary_data (const char *input, size_t size); +char * +match_1 (char *re_str, char *subject); diff --git a/include/openmg/manga.h b/include/openmg/manga.h index 4196b48..519973f 100644 --- a/include/openmg/manga.h +++ b/include/openmg/manga.h @@ -14,7 +14,8 @@ 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); -MgManga *mg_manga_new (const char *const image_url, const char *const title); +MgManga *mg_manga_new (const char *const image_url, const char *const title, const char *const id); G_END_DECLS diff --git a/manga.c b/manga.c index 6f43d92..36daf50 100644 --- a/manga.c +++ b/manga.c @@ -94,6 +94,9 @@ print_debug_nodes (const xmlDocPtr html_document, char * get_attr (xmlNodePtr const node, const char *attr_name) { char *return_value = NULL; + if (!node) { + return NULL; + } for (xmlAttr *attr = node->properties; attr; attr=attr->next) { if (!xmlStrcmp(attr->name, (const xmlChar *) attr_name) && attr->children && attr->children->content) { @@ -270,3 +273,34 @@ loop_search_class (const xmlNodePtr node, xmlNodePtr *nodes, g_free (content); return nodes; } + +char * +match_1 (char *re_str, char *subject) { + pcre2_code *re; + pcre2_match_data *match_data; + + char *return_value; + int regex_compile_error; + int rc; + size_t len_match = 0; + + return_value = NULL; + PCRE2_SIZE error_offset; + re = pcre2_compile ((PCRE2_SPTR8) re_str, strlen (re_str), 0, + ®ex_compile_error, &error_offset, NULL); + match_data = pcre2_match_data_create_from_pattern (re, NULL); + if (!subject) { + goto cleanup_match; + } + rc = pcre2_match (re, (PCRE2_SPTR8) subject, strlen (subject), + 0, 0, match_data, NULL); + if (rc < 0 ) { + goto cleanup_match; + } + pcre2_substring_get_bynumber (match_data, 1, (PCRE2_UCHAR8**) + &return_value, &len_match); +cleanup_match: + pcre2_match_data_free (match_data); + pcre2_code_free (re); + return return_value; +} diff --git a/src/backend/readmng.c b/src/backend/readmng.c index 21933df..c7e3247 100644 --- a/src/backend/readmng.c +++ b/src/backend/readmng.c @@ -69,9 +69,14 @@ mg_backend_readmng_init (MgBackendReadmng *self) { } } -const char * +char * mg_backend_readmng_get_base_url (MgBackendReadmng *self) { - return self->base_url; + GValue value = G_VALUE_INIT; + g_value_init (&value, G_TYPE_STRING); + g_object_get_property (G_OBJECT (self), + "base_url", + &value); + return g_value_dup_string (&value); } void @@ -150,6 +155,7 @@ mg_backend_readmng_parse_main_page (MgBackendReadmng *self, const xmlDocPtr html size_t li_len = 0; li = mg_backend_readmng_retrieve_li_slides (self, slides, &li_len); + print_debug_nodes (html_document, li, li_len); for (int i = 0; ichildren; child; child = child->next) { + if (!strcmp((char *)child->name, "a")) { + return child; + } + } + return NULL; +} + +static char * +mg_backend_get_id_manga_link (MgBackendReadmng *self, xmlNodePtr a) { + char *re_str = "readmng\\.com/([^/]+)"; + return match_1 (re_str, get_attr (a, "href")); +} + static void mg_backend_readmng_extract_manga_info_from_current_li (MgBackendReadmng *self, - GListStore *mangas, xmlNodePtr current_li) { + GListStore *mangas, xmlNodePtr current_li) { xmlNodePtr thumbnail = mg_backend_readmng_retrieve_thumbnail_from_li (self, current_li); xmlNodePtr title = mg_backend_readmng_retrieve_title_from_li (self, current_li); + xmlNodePtr a = mg_backend_readmng_find_a_link_chapter (self, current_li); xmlNodePtr img; + char *id_manga = NULL; - if (thumbnail && title && (img = mg_backend_readmng_retrieve_img_from_thumbnail (self, thumbnail))) { - g_list_store_append (mangas, mg_manga_new (get_attr (img, "src"), - (char *)xmlNodeGetContent (title))); + + if (thumbnail && title && (img = mg_backend_readmng_retrieve_img_from_thumbnail (self, thumbnail)) + && a && (id_manga = mg_backend_get_id_manga_link (self, a))) { + g_list_store_append (mangas, + mg_manga_new (get_attr (img, "src"), (char *)xmlNodeGetContent (title), id_manga)); } } diff --git a/src/manga.c b/src/manga.c index ce7a7eb..943d7c3 100644 --- a/src/manga.c +++ b/src/manga.c @@ -7,6 +7,7 @@ struct _MgManga { GObject parent_instance; char *image_url; char *title; + char *id; }; G_DEFINE_TYPE (MgManga, mg_manga, G_TYPE_OBJECT) @@ -14,6 +15,7 @@ G_DEFINE_TYPE (MgManga, mg_manga, G_TYPE_OBJECT) typedef enum { MG_MANGA_IMAGE_URL = 1, MG_MANGA_TITLE, + MG_MANGA_ID, MG_MANGA_N_PROPERTIES } MgMangaProperties; @@ -46,6 +48,11 @@ mg_manga_class_init (MgMangaClass *class) { "Title of the manga.", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + manga_properties[MG_MANGA_ID] = g_param_spec_string ("id", + "Id", + "Id of the manga", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); g_object_class_install_properties (object_class, MG_MANGA_N_PROPERTIES, @@ -57,7 +64,17 @@ mg_manga_init (MgManga *self) { } char * -mg_manga_get_image_url(MgManga *self) { +mg_manga_get_id (MgManga *self) { + GValue value = G_VALUE_INIT; + g_value_init (&value, G_TYPE_STRING); + g_object_get_property (G_OBJECT (self), + "id", + &value); + return g_value_dup_string (&value); +} + +char * +mg_manga_get_image_url (MgManga *self) { GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_object_get_property (G_OBJECT (self), @@ -67,7 +84,7 @@ mg_manga_get_image_url(MgManga *self) { } char * -mg_manga_get_title(MgManga *self) { +mg_manga_get_title (MgManga *self) { GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_object_get_property (G_OBJECT (self), @@ -91,6 +108,10 @@ mg_manga_set_property (GObject *object, g_free (self->title); self->title = g_value_dup_string (value); break; + case MG_MANGA_ID: + g_free (self->id); + self->id = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -110,6 +131,9 @@ mg_manga_get_property (GObject *object, case MG_MANGA_TITLE: g_value_set_string (value, self->title); break; + case MG_MANGA_ID: + g_value_set_string (value, self->id); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -117,12 +141,14 @@ mg_manga_get_property (GObject *object, } MgManga * -mg_manga_new (const char *const image_url, const char *const title) { +mg_manga_new (const char *const image_url, const char *const title, const char *id) { MgManga *self = NULL; self = (MG_MANGA) (g_object_new (MG_TYPE_MANGA, NULL)); self->image_url = alloc_string (strlen (image_url)); self->title = alloc_string (strlen (title)); + self->id = alloc_string (strlen (id)); copy_substring (image_url, self->image_url, strlen(image_url) + 1, 0, strlen (image_url)); copy_substring (title, self->title, strlen(title) + 1, 0, strlen (title)); + copy_substring (id, self->id, strlen(id) + 1, 0, strlen (id)); return self; } diff --git a/src/view/main_view.c b/src/view/main_view.c index daae9cb..c2ca3d3 100644 --- a/src/view/main_view.c +++ b/src/view/main_view.c @@ -26,7 +26,7 @@ activate (AdwApplication *app, MgBackendReadmng *readmng = mg_backend_readmng_new (); GtkListView *list_view; GtkWidget *scroll; - AdwViewStack *views_stack = ADW_VIEW_STACK (adw_view_stack_new ()); + AdwLeaflet *views_leaflet = ADW_LEAFLET (adw_leaflet_new ()); create_headerbar (box); @@ -38,12 +38,11 @@ activate (AdwApplication *app, gtk_widget_set_vexpand (scroll, 1); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scroll), GTK_WIDGET (list_view)); - adw_view_stack_add_named (views_stack, scroll, "manga-list"); - adw_view_stack_set_visible_child_name (views_stack, "manga-list"); - AdwViewStackPage *page = adw_view_stack_get_page (views_stack, scroll); - adw_view_stack_page_set_title (page, "Manga List"); + adw_leaflet_append (views_leaflet, scroll); + adw_leaflet_set_can_unfold (views_leaflet, false); +// adw_leaflet_set_visible_child (views_leaflet, scroll); - gtk_box_append (box, GTK_WIDGET (views_stack)); + gtk_box_append (box, GTK_WIDGET (views_leaflet)); gtk_widget_show (window); }