Google Summer of Code 2014 came to an end… — August 17, 2014

Google Summer of Code 2014 came to an end…

… but my involvement in GNOME has just started!

Google Summer of Code was an incredible experience, and I would like to give special thanks to Google for the sponsorship. This was a great opportunity to finally get involved in the FOSS world, and to start contributing to GNOME. My mentor, Cosimo Cecchi was a great support, helper, and teacher, so thank you Cosimo for your time, patience and knowledge transfer.

Project description

As a reminder, my project for GNOME is to develop an application for reading eBooks, titled ‘GNOME Books’. The main focus during this phase of Books development was to get the most of the functionality in the Read Mode. The first format which was chosen to support was EPUB, as it is a very popular standard among eBooks. The core application code itself is designed to have a formal separation of backend and frontend logic. The backend, so called GNOME Books Library is focused on providing the core object model & operation, and the interaction with the external libraries like epub.js. The frontend, or GJS Books Application builds on this backend, to produce a GTK based user interface.

Architecture

For the easier understanding of the following text the image below is showing the main components of the GNOME Books Application with the libraries.

Books Diagram
Application structure

Implementation details

GNOME BOOKS LIBRARY

EPUB is based on familiar technologies like XML, CSS, and XHTML. It is well known that browsers have built in mechanism for parsing (HTML, XML, CSS, JavaScript), text and graphics rendering, image decoding, etc. Those are the reasons for the Books Read Mode to use WebKit WebView to present the EPUB contents. Rendering EPUB documents is done with the JavaScript library, epub.js [1], which is included in the project as a sub-module. Books Library main purpose is to handle the interaction between epub.js and WebKit JS, while exposing the common API. Besides that it implements the functionality for the URI scheme, navigation control, linking, event handling, etc.

INTROSPECTION

Application Books is using the latest GNOME 3.0 technologies, so it is written in a very special JavaScript binding for GNOME, so called GJS. GObject introspection is used as a convenient bridge between the two worlds, C and JavaScript.

GJS BOOKS APPLICATION

GJS Books application is based on GtkApplication class which handles aspects of GTK+ application. It exports actions and menus, and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of the application.

By using introspected library application can load and render the eBook and present it in the window, with the WebKit WebView. Some extra functionality which is implemented is controlling the Read Mode.

BUILD SYSTEM

It was difficult to build the application ‘manually’ as it’s complexity reached a certain size. At that point I started learning about an awesome build system, autotools aka the GNU build system. After producing autotools and getting the project build it was much easier to continue the development.

Screenshots

GNOME_Books

Application’s state

You can get the code from the git repository [2]. Open the README file and follow the instructions.

There is an example eBook which is going to be loaded by clicking Load Book button. When the mouse is moved navigation controls will show up, and allow you to change the pages. You can also jump to other chapters by clicking Contents button in the navigation bar. This is the temporary look of the application. Later on, the buttons in the top panel are going to be removed, and displaced.

The development is still in the progress, so there is many new features coming up soon.

Future plans

End of the Google Summer of Code does not mean the end of the project. There is many more ideas left to realize. Below is the list of the next steps:

  • Solution to the asynchronous bug for the interaction between the WebKit JS and the Promise RSVP library used by ePub.js
  • Overview mode and integration with GNOME Documents
  • GNOME Books integration with an existing store
  • GNOME Books design

Very interesting parts of the GNOME Books development are in front of us. I will continue updating You about new features and hopefully, very soon, we are going to have a new application in GNOME.

“Grain by grain – a loaf; stone by stone – a palace.”
– George Bernard Shaw

[1] epub.js: https://github.com/futurepress/epub.js/
[2] Git repository: https://github.com/martamilakovic/gnome-books

GSOC REPORT #5 — August 13, 2014

GSOC REPORT #5

Here is a short status of the work done from the previous report. So let’s not waste too many word…

As mentioned in the previous report GNOME Books Library exposes WebKit WebView and the functionality needed for the interaction with epub.js. There are some new features. The library implements navigation bar and page controlling (total number of pages, status of the current page) as well as table of contents (links to the book chapters).

While working on the interaction between WebKit and epub.js certain issues are present. Epub.js uses RSVP.js, tools for organizing asynchronous code, by using Promises. There is no such functionality in WebKit, which causes a bad interaction between the WebKit JS execution and the epub.js. Because of that some extra steps in the user interaction were added, such as buttons to Load Table of Contents and Load Page Number. This should be further discussed and improved, so the user can achieve it’s task in the least number of steps.

Google Summer of Code is close to it’s end. An overview post with the pictures of the work done during GSoC is on it’s way… stay tuned ;).

GSOC REPORT #4 — July 22, 2014

GSOC REPORT #4

Looking behind my back, a very interesting part is done. Let me tell you what I did during this period and what is coming.

After the basis have been set the real work has started. GNOME Books is going to be a “two level” application, as it is going to use two different levels and languages, C for the core functionality and JavaScript as managed runtime. To make a bridge between those two worlds the code has to be written using GObject convention.  The application can be divided in two parts:

  1. A library for handling interaction with the WebKit WebView, which could be called GNOME Books Library,
  2. GNOME JS application.

GNOME BOOKS LIBRARY

To expose a common API from a C library to GJS the code had to be “introspected”. GObject introspection is a middleware layer between C libraries (using GObject) and language bindings, in this case JavaScript. The C library is being scanned at compile time, followed by the generation of a metadata file. At runtime, language bindings are reading metadata and automatically providing bindings to call into the C library.

The C library is exposing “controller” object with the methods which are calling into the WebKit WebView. WebKit View is then calling JS functions to execute the method.

The most challenging aspect was building the whole thing. The best supported build system is the autotools aka the GNU build system, with autoconfautomake and libtool.

The structure of the project at this point can be seen below.

.
├── autogen.sh
├── configure.ac
├── COPYING
├── Makefile.am
├── src
│   ├── lib
│   │   ├── gb-webview.c
│   │   ├── gb-webview.h
│   │   ├── gb-resources.c
│   │   ├── gb-resources.xml
│   ├── Makefile-js.am
│   ├── Makefile-lib.am
│   ├── Makefile.am
│   ├── application.js
│   ├── mainWindow.js
│   ├── main.js
│   └── webView.js
└── README.md

GJS BOOKS APPLICATION

GJS Books application is based on GtkApplication class which handles aspects of GTK+ application. It exports actions and menus and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of the application.

By using introspected library application can load and render the book and present it in the window, with the WebKit WebView. Some extra functionality which is implemented is controlling the reading more.

GIT REPOSITORY

The repository of the GNOME Books application can be found on github [1].

GUADEC 2014

I am very glad to say that I’ll attend this years edition of GUADEC in Strasbourg, France. As a participant of Google Summer of Code I will give a short introduction of my application during the interns’ lightning talks session.

guadec-2014-badge-large

NEXT STEPS

  • Add more functionality in the library to navigate the book
  • Integrate Books application with the document discovery part that Documents partly does

[1] github repository of the GNOME Books application: https://github.com/martamilakovic/gnome-books/tree/master

GSOC REPORT #3 — June 28, 2014

GSOC REPORT #3

This report is important because basis are now lined up and the process of building the application can start.

“LAST” TOUCH TO THE URI SCHEME

As the previous report said URI schemes are promising, now I can confirm that statement. The whole idea about URI schemes is pretty simple. By registering one I’m able to load epub.js library which renders the content of the .ePub eBook by loading local files such as html, css, images, etc. Using URI scheme I have successfully overcome the cross origin issue. A small problem which was described in the previous post was actually solved by defining the correct path of the eBook. A relative path to the unpacked eBook is given to epub.js, which builds the absolute path. It does that simply by getting current location of the document. Having this information all the relative links within the book are detected and replaced with the absolute path. This way the requests are made with the registered URI scheme. This should also be used for loading .epub file, as epub.js supports unpacking.

APPLICATION STRUCTURE

The overall look over the application structure will be explain, but further improvements and details will be given later on as this is still in the working state.

Application GNOME Books is going to have a WebKit view, subclass that loads epub.js. This class needs to expose “controller” object with the methods to control the interaction. The methods are used for loading an eBook file, controlling the reading mode (next page, previous page, pagination, etc). The WebKit view would then call JS functions to execute methods.

INTERACTION EPUB.JS <-> WEBKIT

To manage the interaction between epub.js and WebKit view I have started by asynchronously running a script in the context of the current page. To be able to run scripts WebKitWebSettings:enable-javascript has to be set to TRUE. As an example a method for loading .epub book is shown in the code below.

static void
load_book ()
{
  gchar* load_command = "var Book = ePub('/epub.js/reader/the-lifestone/', { width: 400, height: 600, spreads : false });";
  webkit_web_view_run_javascript (WEBKIT_WEB_VIEW(webView), load_command, NULL, NULL, NULL);
}

NEXT STEPS

  • Build the “controller” – used for the interaction with application
  • Application structure
GSOC REPORT #2 — June 16, 2014

GSOC REPORT #2

I’m going to tell you briefly about the work and other stuff that happened from the previous report. Lets see…

URI SCHEMES

In the previous report I wrote about the challenge which I had to overcome, and that is a need to run a server, by using the library epub.js. Without a server there was a cross origin issue because of “cross-domain” requests JavaScript makes to access the files. Therefore I made some research about URI schemes, and implemented a possibile solution.

As an introduction to it I would like to give you an overview of the test application’s flow, and how epub.js is being used. To follow my words look at the flow chart below. At the beginning (1) WebKitWebView has to be created. Next, the WebKitWebContext is being created and scheme is registered in Context (2). When a URI request with scheme is made in the WebKitWebContext the registered callback will be called. A callback function is opening the file (3) and it starts reading through the file (4). This is .html file, which is predefined and it is used to structure the ebook viewer, to preload epub.js library and to start rendering eBook. Interaction with the WebKit View and epub.js is being done by the JavaScript in this file. From there on epub.js starts rendering an eBook by HTTP “GET” request (5,6). At this point I used URI scheme for cross domain requests. The files that are being accessed are from the .epub format, such as .xhtml, .ncx, .css, .jpg. The problem is that in this files new HTTP requests are made for the style-sheets and pictures. The solution to this could be to redirect requests to use registered URI scheme.

As a conclusion I can say that this method is promising, and at this point I’m able to read an eBook in the .epub format without running the server, but some more improvements have to be done in order to show pictures and to apply the styles from the style-sheets.

GITHUB REPOSITORY

The repository of the test application can be found on github [1].

NEXT STEPS

  • Finish the URI scheme
  • Manage the interaction between library and WebKit
  • Application structure

Croatian Linux Users’ Convention

Last week I received an email from Marina Zhurakhinskaya. She invited me to join Croatia’s biggest and oldest FLOSS conference DORS/CLUC as a speaker in the round table panel on topic “Women in FLOSS technology world” together with Jasna Benčić, Elizabeth Krumbach Joseph, Ana Mandić, and Lucija Pilić. I was very excited about this opportunity and I gladly accepted the call. Today was the first day of the conference, and our round table took place too. We talked about different experiences of the girls in the FLOSS world and in IT in general, we also discussed how to encourage women to involve more in this exciting world, and we promoted different opportunities that are out there.

FlowChart URI scheme
Flow Chart of the test application with the URI scheme

[1] github repository of the test application: https://github.com/martamilakovic/gnome-books

GSoC Report #1 — June 3, 2014

GSoC Report #1

Two weeks of GSoC are behind our backs. From the very first day I have really dived deep into the code and had a lot of fun with it. Here is the first report of my work.

I’m really thankful for the feedback and comments you all gave me. As the whole idea is still in the development phase and nothing is strictly defined I considered some of your comments. I’m going to list the things that slightly changed from the initial proposal:

  • ‘Read mode’ vs ‘Preview mode’ – The mode in which user will be able to read the eBook will be called the ‘Read mode’, as it better describes its purpose.
  • DRM issue – For the begging it would be good to support listing and reading of DRM-free eBooks. Later on, one way to handle the DRM issue might be to authorize ‘GNOME Books’ application using an ID, but this could be further evaluated because there is also a clash of principles of DRM and freedom.
  • ‘GNOME Books’ integration with an existing store – a big plus would be to integrate ‘GNOME Books’ with different eBook stores. Defining a plugin API for eBook store fronts would probably be something that could be developed later on. For the begging it would be good to choose one store and try to integrate it with GNOME. Good online eBook store is Smashwords, and there is also Project Gutenberg.

EPUB.JS vs LIBGEPUB

Epub.js is a JavaScript library for rendering EPUB documents in the browser. Epub.js provides an interface for common eBook functions (such as rendering, persistence and pagination). While libgepub is a very simple GObject based library with only the core functionality needed to open an archive files and read HTML documents. Because epub.js provides most of the features for rendering .epub files I decided to look into it, and tried to build a simple application.

TEST APPLICATION DEVELOPED IN C

To start up I decided to make a test application in C, using GTK and WebKit. I’m using WebKit2 to load the library epub.js and render the eBook. WebKit is a huge project, and I’m just staring to discover all the functionality it provides. Using WebKit to present the eBook in the ePub format  has a big advantage, because it can interpret HTML, CSS and JavaScript, so there is no need to develop the backed for that interpretation.

At this point I came across an interesting fact.  To locally run epub.js through WebKit I had to run node.js server (or any http simple server) to avoid cross origin requests, because epub.js needs to access the local files using JavaScript. I’m still working on this, implementing some around solutions to the problem.

A very nice feature that comes with the WebKit is Inspector, the excellent debugger. You can use the property to turn on enable-developer-extras. This will cause “Inspect Element” to be added to the WebKit’s context menu.

The test application can render an an eBook in the .epub file format using epub.js and show it in the WebKit View. The screenshot of the test application can be seen on the Figure 1.

NEXT STEPS

  • Start a git repository
  • Port the test application to gjs
  • Overcome the cross origin issue with the URI schemes

gnome-books-Ctest

Figure 1: Screenshot of the test application