forked from sergiotarxz/mangareader
Changing to leaflet and adding support for manga id recovery.
This commit is contained in:
parent
f4c9ed4f3a
commit
215563d862
@ -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);
|
||||
|
@ -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
|
||||
|
34
manga.c
34
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;
|
||||
}
|
||||
|
@ -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; i<li_len; i++) {
|
||||
xmlNodePtr current_li = li[i];
|
||||
mg_backend_readmng_extract_manga_info_from_current_li (self,
|
||||
@ -226,17 +232,38 @@ mg_backend_readmng_retrieve_title_from_li (MgBackendReadmng *self, xmlNodePtr li
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
mg_backend_readmng_find_a_link_chapter (MgBackendReadmng *self,
|
||||
xmlNodePtr current_li) {
|
||||
for (xmlNodePtr child = current_li->children; 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) {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
32
src/manga.c
32
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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user