Adding support to look the first image of the

manga...
This commit is contained in:
sergiotarxz 2021-11-15 22:26:20 +01:00
parent d91cd296a9
commit 490af0a0db
12 changed files with 184 additions and 9 deletions

View File

@ -5,6 +5,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <openmg/manga.h> #include <openmg/manga.h>
#include <openmg/chapter.h>
G_BEGIN_DECLS; G_BEGIN_DECLS;
@ -32,5 +33,7 @@ mg_backend_readmng_get_featured_manga (MgBackendReadmng *self);
void void
mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self, mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
MgManga *manga); MgManga *manga);
GListModel *
mg_backend_readmng_get_chapter_images (MgBackendReadmng *self, MgMangaChapter *chapter);
G_END_DECLS G_END_DECLS

View File

@ -12,5 +12,7 @@ mg_manga_chapter_new (const char *const title,
const char *const url); const char *const url);
char * char *
mg_manga_chapter_get_title (MgMangaChapter *self); mg_manga_chapter_get_title (MgMangaChapter *self);
char *
mg_manga_chapter_get_url (MgMangaChapter *self);
G_END_DECLS G_END_DECLS

View File

@ -0,0 +1,6 @@
#pragma once
#include <adwaita.h>
void
setup_chapter_view (MgMangaChapter *chapter, AdwLeaflet *views_leaflet);

View File

@ -1,4 +1,7 @@
#include <gtk/gtk.h>
#include <adwaita.h>
#include <openmg/manga.h> #include <openmg/manga.h>
GtkBox * GtkBox *
create_detail_view (MgManga *manga); create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet);

View File

@ -1,5 +1,9 @@
#pragma once
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <adwaita.h>
#include <openmg/manga.h> #include <openmg/manga.h>
GtkListView * GtkListView *
create_list_view_chapters (MgManga *manga); create_list_view_chapters (MgManga *manga, AdwLeaflet *views_leaflet);

View File

@ -12,6 +12,7 @@ openmgdeps = [
] ]
sources = [ sources = [
'src/view/chapter_view.c',
'src/view/list_view_chapter.c', 'src/view/list_view_chapter.c',
'src/view/picture.c', 'src/view/picture.c',
'src/util/gobject_utility_extensions.c', 'src/util/gobject_utility_extensions.c',

View File

@ -1,3 +1,4 @@
#include <gtk/gtk.h>
#include <libxml/HTMLparser.h> #include <libxml/HTMLparser.h>
#include <openmg/backend/readmng.h> #include <openmg/backend/readmng.h>
@ -57,6 +58,12 @@ static MgMangaChapter *
mg_backend_readmng_loop_li_chapter ( mg_backend_readmng_loop_li_chapter (
MgBackendReadmng *self, MgBackendReadmng *self,
xmlNodePtr li); xmlNodePtr li);
static GListModel *
mg_backend_readmng_parse_page (MgBackendReadmng *self,
xmlDocPtr html_document);
static xmlDocPtr
mg_backend_readmng_fetch_page_url (MgBackendReadmng *self,
MgMangaChapter *chapter);
static GListStore * static GListStore *
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self, mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
xmlDocPtr html_document_details); xmlDocPtr html_document_details);
@ -147,6 +154,67 @@ mg_backend_readmng_get_property (GObject *object,
} }
} }
GListModel *
mg_backend_readmng_get_chapter_images (MgBackendReadmng *self, MgMangaChapter *chapter) {
GListModel *images;
xmlDocPtr html_document;
html_document = mg_backend_readmng_fetch_page_url (self, chapter);
images = mg_backend_readmng_parse_page (self, html_document);
xmlFreeDoc (html_document);
return images;
}
static GListModel *
mg_backend_readmng_parse_page (MgBackendReadmng *self,
xmlDocPtr html_document) {
GListModel *images = G_LIST_MODEL
(gtk_string_list_new (NULL));
MgUtilXML *xml_utils = self->xml_utils;
xmlXPathObjectPtr xpath_result = NULL;
xmlNodeSetPtr node_set = NULL;
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
html_document, "//img[@class]");
node_set = xpath_result->nodesetval;
if (!node_set) {
fprintf(stderr, "No match for images.\n");
return images;
}
for (int i = 0; i < node_set->nodeNr; i++) {
xmlNodePtr node = node_set->nodeTab[i];
const char *image_url = mg_util_xml_get_attr (xml_utils, node, "src");
gtk_string_list_append (GTK_STRING_LIST (images), (void *)image_url);
}
return images;
}
static xmlDocPtr
mg_backend_readmng_fetch_page_url (MgBackendReadmng *self,
MgMangaChapter *chapter) {
size_t response_len = 0;
MgUtilSoup *util_soup = mg_util_soup_new ();
char *url = mg_manga_chapter_get_url (chapter);
size_t concat_all_pages_len;
char *concated_url;
concat_all_pages_len = snprintf (NULL, 0, "%s/all-pages", url);
concated_url = g_malloc
(sizeof *concated_url * (concat_all_pages_len + 1));
snprintf (concated_url, concat_all_pages_len + 1,
"%s/all-pages", url);
const char *html_response = mg_util_soup_get_request (util_soup, concated_url,
&response_len);
return htmlReadMemory (html_response, response_len,
NULL, NULL,
HTML_PARSE_RECOVER | HTML_PARSE_NODEFDTD
| HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING );
}
GListStore * GListStore *
mg_backend_readmng_get_featured_manga (MgBackendReadmng *self) { mg_backend_readmng_get_featured_manga (MgBackendReadmng *self) {
GListStore *mangas; GListStore *mangas;
@ -178,7 +246,7 @@ mg_backend_readmng_retrieve_manga_details (MgBackendReadmng *self,
xml_utils = self->xml_utils; xml_utils = self->xml_utils;
html_document = mg_backend_readmng_fetch_xml_details (self, html_document = mg_backend_readmng_fetch_xml_details (self,
manga); manga);
xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils, xpath_result = mg_util_xml_get_nodes_xpath_expression (xml_utils,
html_document, "//li[@class]"); html_document, "//li[@class]");
node_set = xpath_result->nodesetval; node_set = xpath_result->nodesetval;
@ -205,7 +273,7 @@ cleanup_mg_backend_readmng_retrieve_manga_details:
static GListStore * static GListStore *
mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self, mg_backend_readmng_recover_chapter_list (MgBackendReadmng *self,
xmlDocPtr html_document_details) { xmlDocPtr html_document_details) {
MgUtilXML *xml_utils = self->xml_utils; MgUtilXML *xml_utils = self->xml_utils;
xmlXPathObjectPtr xpath_result = NULL; xmlXPathObjectPtr xpath_result = NULL;
xmlNodeSetPtr node_set = NULL; xmlNodeSetPtr node_set = NULL;
xmlNodePtr *uls = NULL; xmlNodePtr *uls = NULL;

View File

@ -160,3 +160,11 @@ mg_manga_chapter_get_title (MgMangaChapter *self) {
g_object_get_property (G_OBJECT (self), "title", &value); g_object_get_property (G_OBJECT (self), "title", &value);
return g_value_dup_string (&value); return g_value_dup_string (&value);
} }
char *
mg_manga_chapter_get_url (MgMangaChapter *self) {
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (self), "url", &value);
return g_value_dup_string (&value);
}

64
src/view/chapter_view.c Normal file
View File

@ -0,0 +1,64 @@
#include <gtk/gtk.h>
#include <openmg/chapter.h>
#include <openmg/view/chapter_view.h>
#include <openmg/view/picture.h>
#include <openmg/util/gobject_utility_extensions.h>
#include <openmg/util/string.h>
#include <openmg/backend/readmng.h>
static void
fire_zoom (GtkGestureZoom *zoom,
gdouble scale,
gpointer user_data);
typedef struct {
guint current_page;
GListModel *pages;
GtkPicture *current_picture;
} ChapterVisorData;
void
setup_chapter_view (MgMangaChapter *chapter, AdwLeaflet *views_leaflet) {
MgBackendReadmng *readmng = mg_backend_readmng_new ();
MgUtilString *string_util = mg_util_string_new ();
GtkBox *chapter_view_container = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
GtkScrolledWindow *zoomable_picture_container = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new ());
GtkGesture *zoom_controller = gtk_gesture_zoom_new ();
GListModel *pages = mg_backend_readmng_get_chapter_images (readmng, chapter);
ChapterVisorData *chapter_visor_data = g_malloc (sizeof *chapter_visor_data);
GtkPicture *current_picture;
chapter_visor_data->current_page = 0;
chapter_visor_data->pages = pages;
const char *url_image_not_owned =
gtk_string_list_get_string (GTK_STRING_LIST
(pages), 0);
char *url_image = mg_util_string_alloc_string (string_util, strlen (url_image_not_owned));
mg_util_string_copy_substring (string_util,
url_image_not_owned, url_image,
strlen(url_image_not_owned) + 1, 0,
strlen (url_image_not_owned));
current_picture = create_picture_from_url
(url_image, 200);
g_object_set_property_int (G_OBJECT (current_picture), "vexpand", 1);
g_object_set_property_int (G_OBJECT (current_picture), "hexpand", 1);
chapter_visor_data->current_picture =
current_picture;
gtk_scrolled_window_set_child (zoomable_picture_container, GTK_WIDGET (current_picture));
gtk_widget_add_controller (GTK_WIDGET (zoomable_picture_container),
GTK_EVENT_CONTROLLER (zoom_controller));
g_signal_connect (G_OBJECT (zoom_controller), "scale-changed", G_CALLBACK (fire_zoom), NULL);
gtk_box_append (chapter_view_container, GTK_WIDGET (zoomable_picture_container));
adw_leaflet_append (views_leaflet, GTK_WIDGET (chapter_view_container));
adw_leaflet_navigate (views_leaflet, ADW_NAVIGATION_DIRECTION_FORWARD);
}
static void
fire_zoom (GtkGestureZoom *zoom,
gdouble scale,
gpointer user_data) {
// Do something.
}

View File

@ -48,7 +48,7 @@ toggle_folded (GtkButton *toggle_folded_button,
} }
GtkBox * GtkBox *
create_detail_view (MgManga *manga) { create_detail_view (MgManga *manga, AdwLeaflet *views_leaflet) {
MgBackendReadmng *readmng = mg_backend_readmng_new (); MgBackendReadmng *readmng = mg_backend_readmng_new ();
GtkWidget *scroll; GtkWidget *scroll;
GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0)); GtkBox *detail_view = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
@ -73,7 +73,7 @@ create_detail_view (MgManga *manga) {
g_object_set_property_int (G_OBJECT (scroll), "vexpand", 1); g_object_set_property_int (G_OBJECT (scroll), "vexpand", 1);
mg_backend_readmng_retrieve_manga_details (readmng, manga); mg_backend_readmng_retrieve_manga_details (readmng, manga);
chapter_list = create_list_view_chapters (manga); chapter_list = create_list_view_chapters (manga, views_leaflet);
g_signal_connect (G_OBJECT (toggle_folded_button), "clicked", G_CALLBACK (toggle_folded), foldable_manga_data); g_signal_connect (G_OBJECT (toggle_folded_button), "clicked", G_CALLBACK (toggle_folded), foldable_manga_data);

View File

@ -4,14 +4,17 @@
#include <openmg/chapter.h> #include <openmg/chapter.h>
#include <openmg/backend/readmng.h> #include <openmg/backend/readmng.h>
#include <openmg/view/list_view_chapter.h> #include <openmg/view/list_view_chapter.h>
#include <openmg/view/chapter_view.h>
static void
activate_chapter (GtkListView *list_view, guint position, gpointer user_data);
static void static void
setup_list_view_chapter_list (GtkSignalListItemFactory *factory, setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
GtkListItem *list_item, GtkListItem *list_item,
gpointer user_data); gpointer user_data);
GtkListView * GtkListView *
create_list_view_chapters (MgManga *manga) { create_list_view_chapters (MgManga *manga, AdwLeaflet *views_leaflet) {
GListStore *manga_chapter_list = NULL; GListStore *manga_chapter_list = NULL;
GtkListView *list_view_chapters = NULL; GtkListView *list_view_chapters = NULL;
GtkSingleSelection *selection = NULL; GtkSingleSelection *selection = NULL;
@ -28,6 +31,9 @@ create_list_view_chapters (MgManga *manga) {
list_view_chapters = GTK_LIST_VIEW (gtk_list_view_new (GTK_SELECTION_MODEL (selection), list_view_chapters = GTK_LIST_VIEW (gtk_list_view_new (GTK_SELECTION_MODEL (selection),
factory)); factory));
gtk_list_view_set_single_click_activate (list_view_chapters, 1);
g_signal_connect (G_OBJECT (list_view_chapters), "activate",
G_CALLBACK (activate_chapter), views_leaflet);
return list_view_chapters; return list_view_chapters;
} }
@ -47,3 +53,13 @@ setup_list_view_chapter_list (GtkSignalListItemFactory *factory,
gtk_box_append (box, GTK_WIDGET (title)); gtk_box_append (box, GTK_WIDGET (title));
gtk_list_item_set_child (list_item, GTK_WIDGET (box)); gtk_list_item_set_child (list_item, GTK_WIDGET (box));
} }
static void
activate_chapter (GtkListView *list_view, guint position, gpointer user_data) {
GtkSingleSelection *selection = GTK_SINGLE_SELECTION
(gtk_list_view_get_model (list_view));
GListModel *chapters = gtk_single_selection_get_model (selection);
MgMangaChapter *chapter = MG_MANGA_CHAPTER (g_list_model_get_item (chapters, position));
AdwLeaflet *views_leaflet = ADW_LEAFLET (user_data);
setup_chapter_view (chapter, views_leaflet);
}

View File

@ -39,7 +39,7 @@ manga_selected (GtkListView *list_view,
ADW_NAVIGATION_DIRECTION_FORWARD); ADW_NAVIGATION_DIRECTION_FORWARD);
} }
GtkBox *detail_view = create_detail_view (manga); GtkBox *detail_view = create_detail_view (manga, views_leaflet);
adw_leaflet_append (views_leaflet, GTK_WIDGET (detail_view)); adw_leaflet_append (views_leaflet, GTK_WIDGET (detail_view));
adw_leaflet_navigate (views_leaflet, ADW_NAVIGATION_DIRECTION_FORWARD); adw_leaflet_navigate (views_leaflet, ADW_NAVIGATION_DIRECTION_FORWARD);
} }