Skip to content

Thursday, 11 August 2022

This week I have published several new versions of my music applications:

The first two applications, kmetronome and kmidimon, are now over fifteen years old and are only available for Linux. These two new versions are simply bug fixes, with no new features. But it is interesting to note that in FlatHub they are already based on Qt6 and supporting both Wayland and X11, although the packages in AppImage format still use Qt5. The chances of finding these applications in the official repositories of Linux distributions are slim. In fact, kmidimon was removed from the official Debian repositories with some lame excuse, and it is unlikely to be included again. I can't do anything about it, so please: direct complaints where they belong. Or use the new available distribution formats or the unofficial repositories, like Debian Multimedia, which includes the three mentioned applications and many others.

The other app, dmidiplayer, is much newer and cross-platform. It is the successor to Kmid2, the KDE karaoke application that I rewrote many years ago. In this new version the most remarkable new feature is the persistent configuration of the songs. This is a feature that was already present in the old Kmid2 and that allows you to store the tempo, general volume, pitch transposition, and MIDI channel settings for each song, which will be applied when it is played again in the future. The other novelty is the individual volume adjustment for each MIDI channel, something that was not possible in Kmid2.

After all these years, it is curious that it is still possible to find Kmid2 in one distribution: Fedora, despite being a Qt4/KDE4 application. So a functional comparison of both applications is not only possible, but easy to do. In my opinion, with this version dmidiplayer has reached parity in terms of functionality with Kmid2. On the other hand, the new architecture has allowed the application to be available on other Unixes (such as FreeBSD) in addition to Linux, macOS, and Windows.

I guess the next app to get updates will be VMPK. There is no forecast yet of the changes it will bring, but there is a recurring request that I will not do: MIDI Jack support. This is not to say that it is not possible to use Jack MIDI with VMPK, because in fact there is an utility called 'a2jmidid' that serves as a translation layer between applications using the ALSA Sequencer and Jack MIDI. On the other hand, for VMPK to use new native backends it is only necessary to implement Drumstick::RT plugins. And this can be done by any interested developer, and then independently distribute the out-of-tree plugins. I've opened a discussion on GitHub about this. Anyone interested, please read and ask your questions there.

Tuesday, 9 August 2022

Purpose

The major purpose of the mid-term evaluation during the Google Summer of Code program is to ensure the contributor’s progress for their committed timeline for both coding and communication.

My progress till mid-term

During the coding period, I started with “ten’s complement,” and after a thorough discussion among the mentors, we decided to divide the activity into three sub-activities. The details for all the sub-activities can be found here.
At the time of mid-term evaluation, all these three sub-activities were half-functional, the improvements were left, but the basic functioning and the dataset for level 1 of all the activities were present. Although, I was one week late to my timeline, which I proposed. I planned to complete “ten’s complement” by mid-term. I’ve added the to-do for this activity under the task. (here)
But one thing I realized, and my mentors told me too, is that the small things require more time. One of the reasons why I was unable to complete the activity before mid-term was the incorrect estimation of time and work. And initially, the college was going to open a month later, but it started in the month of July itself. Due to this, I couldn’t provide much time for a few days.

Improving myself

After the mid-term evaluation, I prepared another timeline consisting of the remaining tasks and time left, as advised by the mentors. An updated timeline would help both of us, mentors and me. Through this, my progress during the remaining weeks can be measured. I try to have daily interaction with the mentors, and I’ll be publishing more blogs to increase communication with the whole community as well.
Also, I am allocating more time to the remaining task and increasing the contributing pace to catch up to the timeline and complete all the tasks before the final evaluation.

Monday, 8 August 2022

Seventh week

In the seventh week, I will implement the OcrTesseract Engine, an internal object, which handles the input scanned document image, get optional tesseract values from the dialog and release the OCR output text and the text file.

figure1

The detailed architecture of this object is shown in the following :

figure1

It implements a function runOcrProcess() that uses Tesseract CLI, a command line program that accepts text input to execute operating system functions. This function returns the type enum state of a process and saves the results are saved in member variables as well :

ValueDescription
PROCESS_COMPLETEAll stages done.
PROCESS_FAILEDA failure happen while processing.
PROCESS_CANCELEDUser has canceled processing.

Eighth week

This week, I started implementing the backend part, an internal multi-thread to manage the batch processing and Data object delivery to send from backend to frontend.

Text Converter Thread Management

This plugin will use an internal multi-thread for OCR processing images. Classes in this part will be implemented based on existing objects to manage and chain threads in digikam. The idea is inspired by using QThreadPool and QRunnable. Existing threads can be reused for new tasks, and QThreadPool is a collection of reusable QThreads.

The part TextConverterActionThread manages the functioning of TextConverterTask. Concretely, TextConverterActionThread manages the instantiations of TextConverterTask.

Each Text Converter Task will initialize one Ocr Tesseract engine object to manage one URL of an image.

The purpose is to allow each OCR image process to run in parallel and stop properly. The run() method of object TextConverterTask is a virtual method that will be reimplemented to facilitate advanced thread management. Here is the architecture of this part:

figure1

Here is a sequence diagram representing the communication between GUI and with backend interface.

figure1

When the user clicks on the button “Start OCR”, the object TextConverterThread instantiates objects TextConverterTask and sets up Tesseract options from the dialog to them. By receiving the signal “clicked” from the dialog button, TextConverterTask creates an OCR engine to control the image’s Url. When the process is finished, all the necessaire outputs are set on the widget list of pictures and text editor.

The most important part is how to deliver the output and set them up on the dialog interface. For this problem, I implement a class Text Converter Data containing the status of a process, the destination path of an output file, and the recognized text extracted from the image. Output data is transferred to the dialog through two signals :

signalStarting(TextConverterActionData), signalFinished(TextConverterActionData)

figure1

In the next few weeks, I will:

  • Implement the functionalities of storing OCR result.
  • Polish and re-implement code if necessary.

Main commits

Saturday, 6 August 2022

Are you the C++ experienced reader to solve the following challenge?

Given a class C (edit: covered by binary compatibility needs) with the overloaded methods foo() and foo(A a):

    class C
    {
    public:
        void foo();
        void foo(A a);
    };

Now you want to add an overload, to serve further use-cases as requested by API consumers, and going for another overload matches your API guidelines :

        void foo(B b);

But there is existing consumer code, making use of C++17, which calls

    C c;
    c.foo({});

So the new overload will not be source-compatible and break existing code, due to the ambiguity whether {} should be turned into an instance of A or B.

What could be done about this?

The goals here would be:

  1. to enable API consumers to write code which works as if there are the two old and the one new overloads declared
  2. any calls using the {} expression as argument are resolved to a method which emits a compiler warning to avoid that ambiguous argument and which on any next compatibility breaking occasion can be simply removed

While asking around, some approaches have been proposed, but so far none could satisfy the second goal, catching existing ambiguous argument expressions to hint API consumers to adapt them.

Would you have an idea?

Edit: Note that we cannot change A or B (might be types/classes from elsewhere), and only can add new API to C, due to binary compatibility needs.

Edit: On a second thought, similar problems also exist before C++17 already when an argument has a type which can be implicitly converted both to A and B, by implicit constructors or type operator methods.

Hello and welcome to my second GSOC update! I think I these last few weeks have been really productive in fixing some issues with my code and getting some direction in the next steps for my project. If you remember last time we had just figured out how to get the SVG option to appear in Krita so we can start testing out saving a test SVG file. We were getting a few errors actually trying to use that option and save the file but those should be all fixed now.

Firstly we were getting a Permission denied: Krita is not allowed to read the file. error when actually trying to save with SVG. At first I thought this was due to how I was trying to use the svgWriter class. The svgWriter assumes that we are only getting to export one layer (the current one) so I thought by trying to save in the context of the whole file, that was tripping it up somehow. After doing some investigation and tracing all the steps in the code this didn’t seem to be the issue.

Hmmmm alright so since my intitial assumption was incorrect lets try starting from the beginning with whats actually producing this error? Well turns out it is from the fail of the check !io->isReadable(). Is this the correct way to check if a file is readable? Well comparing to the check used in an example commit (from amyspark) it seems to use a different method to check if the file is writeable KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(io->isWritable(), ImportExportCodes::NoAccessToWrite);. Thats interesting, lets try commenting our check and see if the file gets created or Krita crashes, either way we’ll get some valuable information. After trying that it the file gets created! An empty file but thats exactly what we expected. Now we’ll replace my incorrect check with the right one.

Next step is get the boilerplate SVG file context written to our empty file. After some investigation it seems like all of the SVG writer code does get executed properly and it does try to write to the file but something is missing. Even when passing the same layer contents to svgWriter it still doesn’t write to that file. Well to make a long story short it turns out you have to actually pass your IO device if you want to actually write to it/use it. After changing my code to pass the current QIODevice it was properly writing to the file!

After figuring out those issues I had a discussion with Wolthera around the next steps for my project. We talked about how I was going to traverse the layers of the Krita file as I was writing to my SVG file. At first I thinking about writing entirely new code, reading the document, and going through layer by layer but then Wolthera introduced me to the intended way to do this process. Namely, by making an implementation for the KisNodeVisitor class that would handle traversing the layers. Instead of trying to re-invent the wheel I can use the standard way Krita accesses file. I started working on that implementation late last week so I’m still figuring out all the details on how it works. Hopefully I’ll be able to talk about my making that next week.

Thanks for tuning in!

Friday, 5 August 2022

Let’s go for my web review for the week 2022-31.


How far can you go by train in 5h?

Tags: tech, train, map

Very cool map. Definitely useful tool to push for more train use.

https://chronotrains-eu.vercel.app/


Remote attestation is coming back. How much freedom will it take? – Gabriel Sieben

Tags: tech, microsoft, vendor-lockin, surveillance, security

Palladium is coming back and it’s not good news in my opinion.

https://gabrielsieben.tech/2022/07/29/remote-assertion-is-coming-back-how-much-freedom-will-it-take/


How Tor is fighting—and beating—Russian censorship | Ars Technica

Tags: tech, tor, security, censorship

It’s nice to see Tor is still winning even in difficult countries.

https://arstechnica.com/information-technology/2022/07/how-tor-is-fighting-and-beating-russian-censorship/


The OG Social Network: Other People’s Websites - Jim Nielsen’s Blog

Tags: tech, google, search, attention-economy, advertisement, open-access, web

The paradox of how walled gardens could kill search engines in the end. I’m not too concerned for Google in practice though, it’s been a long time since it’s an ad agency and not a search engine, and they’ll always have something to advertise…

https://blog.jim-nielsen.com/2022/other-peoples-websites/


Use One Big Server - Speculative Branches

Tags: tech, infrastructure, cloud, services

This is definitely a good musing on when not to go for “cloudy architectures”. Most often people don’t really need it, this needs to be properly thought out for each project. There are costs involved which you might not make sense to pay for in your context.

https://specbranch.com/posts/one-big-server/


The Slotted Counter Pattern

Tags: tech, design, databases

Nice little database pattern to avoid row contention with counters.

https://planetscale.com/blog/the-slotted-counter-pattern


Manifold

Tags: tech, java

This looks like an interesting set of extensions for Java projects. Unsure if it’s been properly battle tested yet. Likely need that before being really advisable.

http://manifold.systems/


Unlocking type-safety superpowers in Typescript with nominal and refinement types

Tags: tech, typescript, type-systems

That’s an intersecting Typescript pattern to get to nominal and refinement types despite the fact they lack from the language.

https://zackoverflow.dev/writing/nominal-and-refinement-types-typescript



Bye for now!

While testing my merge request, Tobias spotted that NeoChat was making multiple requests to the /hierarchy API endpoint. The requests were actually being spammed to the server.

So I was suggested to separate the Space hierarchy caching functionality to a separate class itself.

The work was mostly about refactoring. Code was already existing in a different class. I moved it to the new SpaceHierarchyCache class and edited it to glue in properly.

getRoomListForSpace() in SpaceHierarchyCache accepts a space id, and returns a list of rooms id that belong to the space. This function is exposed in QML and used to populate SortFilterRoomListModel:: m_activeSpaceRooms whenever user clicks a Space icon.

Rest of the implementation is mostly similar to what was earlier scattered through SortFilterRoomListModel.

The code is currently on a separate branch on my fork so that my mentors can check if it looks and works right. If they say its fine, I'll add the code to my open merge request.

PS. Its my birthday today :)

Thursday, 4 August 2022

I’ve gotten annoyed with the inability to manage system files so I’ve made a KIO worker that enables Dolphin to view and edit files as root.

This is dolphin viewing the system root with administrative access.

The way this works is actually fairly exciting. It’s pulling off worker chaining: The admin worker itself contains gloriously little logic, all it does is translate all worker calls to dbus calls, and those dbus calls go out to a privileged polkit helper. The polkit helper then translates the URIs from admin:///foo to file:///foo and uses the regular KIO API to recreate the request in root-scope. KIO then, behind the scenes, acts just like it would in dolphin proper, using the existing file worker code to execute the file operations.

The advantages are amazing! It’s fairly little actual code (albeit a lot of boilerplate). Since it’s an ordinary worker on the Dolphin side we can expect all file operations to just work™ because really admin:// is just like trash:// or desktop://. Because ultimately the file worker is actually in charge of doing the work, all things are generally expected to work (it’s the same code that powers regular file operations).

Disadvantageously it’s a fair large portal into root-scope, meaning the worker should really only be used in trusted environments (e.g. with only sandboxed applications on the system ;)). Even with polkit guarding the entrance, once you have given permissions you have to trust the application (e.g. dolphin) to not get exploited.

“But why a dedicated worker instead of integrated polkit support in the file worker?” Why, I’m glad you asked! Integrated polkit support sounds simple but is really rocket science. For example there is currently no good architectural way to “catch” operations that had gone wrong - you try to copy a file to `/srv` and that fails with 🤖PERMISSION DENIED🤖 but there is no consistent way to then go “well, let’s retry this entire operation with privileges then” so without huge code refactoring first, we’d end up tucking fallback logic onto every which error scenario… it’s messy and also easy to miss or mess up edge cases. There are also user experience problems. You’d not want to have every internal operation require dedicated permission, so you kind of have to bundle them up and then request permission for the bundle; but how do you know when a bundle is complete? It’s really frightfully complicated.

In conclusion admin:// is awesome today. Maybe one day integrated polkit will also be awesome.

Reviews and testing appreciated https://invent.kde.org/sitter/kio-admin (mind the readme - this currently wants some patching elsewhere in the stack).

The process of selecting the new KDE Goals is ongoing, and after finishing the submission stage we now have 11 proposals.

As you might see in the workboard, they are in the “Not ready for voting” column. This is because even though they have successfully been created according to the template, there is still much to do before the voting starts.

Right now we are in the Refinement stage, which lasts until August 27th. But what is the purpose of this stage?

The point is to shape each proposal into its best possible version. This is the moment to work on the proposal with a larger audience, seek feedback and gather people that would be interested in participating in the Goal.

Konqi is ready to work on stuff.

I encourage everyone in the community – newcomers and veterans – to look through the proposals and voice your opinions. If you find a proposal that you like and needs some work, be sure to suggest changes. You can help refine any number of proposals. If you want to show support for a Goal proposal in a visible way, each entry should have a “Interest” section at the bottom – you can add your name there.

Some things to consider when refining the Goals:

  • The name of the Goal should be attractive, not very long, and clearly state what is it about. It will be easier to vote for a Goal that has clear steps of how it will be achieved. The more concrete plan is formulated, the better it will look.
  • Ambitious Goals are good, but keep them in the realm of possibility. A selected Goal will be in focus for the community for ~2 years, the community expects major parts of the Goal to be completed in that time AND visible progress to be made on an ongoing basis.
  • And of course, the Goal needs to serve the KDE community :)

With all of that in mind, I again encourage you to look at the current proposals and start refining!

Sunday, 31 July 2022

Second issue about the progress on rolisteam.

1. Mindmap

When I wrote down a story for a TTRPG game, I always find useful to draw an interaction diagram. It’s the best way to get an overview of the story really quickly. First, it was on blocknotes, then I wish for a better tool and I designed it.

For a overnight game, this is how a mindmap looks: image

Now, we decided to add this rmindmap into rolisteam. The original tool has received several versions and implementation about diagram style and technology.

Adding QML mindmap into rolisteam

Let’s talk about technical aspect here. The main difference between the stand-alone version and the mindmap inside rolisteam is that in rolisteam, some components have to follow some APi.

image

Basically, MediaControllerBase is the low-level api that every media controller shares. You share an image on rolisteam, there is an ImageController which extends from MediaControllerBase. And it is the case for every media: Charactersheet, virtual map, Notes…

MediaControllerBase stores all data required for identifying the media (Uuid, name…) and it also stored data to describe the permission context: the owner, the gamemaster, and does this controller is a remote version or the original one.

Then, you have the MindMapControllerBase which provided the mindmap API, such as adding nodes, links, packages, remove them, manage the selection and so on. This code is mainly from the original stand-alone software rmindmap.

Then, the last layer: MindMapController. This class takes in charge any specific behaviour or feature for mindmap into rolisteam. The mindmap is the second media to have a permission selector. Users will be able to share in read-only mode or read-write mode to everyone or to some selected people.

Features:

  • Add node
  • Customize node: text, description, tags and style
  • Add picture to node (drag and drop or contextual menu)
  • Default style
  • Editable link label
  • (Activate/Disactive) Automatic spacing
  • Add Packages
  • Dark mode
  • Realtime small view, the visible part on the mindmap is marked with a blue rectangle
  • Export in png
  • hide/show link label
  • Search for node based on tags, name or description
  • Show/Hide children node
  • Reparenting
  • Add link
  • Undo/Redo
  • Zoom in/out
  • Automatic save

Demo: From nothing

image

Demo: The big one

image

2. Image in instant messaging

We implement a small feature on the instant messaging. If you copy/paste a link to image. The url is replaced by the image.

image

Other urls (to website or other kind of format), the link is clickable.

3. Upnp class

Some users have difficulties to configure their network device at home to host games.
Then, we create a simple QObject to open network port and forward it to the rolisteam server. In rolisteam, the object will only be used on server side.

You can find the implementation here It is already integrated into rolisteam. Some improvements can be done, of course. But it works on our side. Feel free to test it on your side and give us feedback.
There is a unit test to run. The unit test does exactly what we are doing in rolisteam.

4. Translation scripts for KDE

As you may know, rolisteam is now part of KDE. We are trying to enjoy that new status. One way to do it, it’s to change the way rolisteam is translated. The KDE project has huge translation team and they are really efficient.
On project side, when you want your application to be translated. You have to provide a script that extract all texts. We made this script for DiceParser, and it is now ready for rolisteam.

5. Work for August

  • Finish Mindmap
  • keep working on Vectorial map
  • See network status for mindmap and vectorial map