Tuesday, August 03, 2021

Your Hot New Stuff Here

KNewStuff, our Framework designed to make it as easy as possible for people to Get Hot New Stuff for whatever app they're running, and for the people who make those apps to add that same functionality to the apps, has for some time suggested that the KDE Store has the ability to accept uploading of content directly from the application. Unfortunately, due to the way this was originally built (which was essentially built around the idea that People Are Nice) turned out to be a fairly effective vector for spam and malicious content.

The result of this is that for several years, while KNewStuff has had an implementation of the OCS Content Create functionality, there is no serverside implementation which supports it as it stands. Which is a shame, especially when, while we may not be able to do it through the API because people are, apparently, sometimes Not Nice, what we can do instead is make it easier for people who are nice to learn how to add their own stuff to those listings.

Quickly Now!

How about that discoverability, eh?
 

Enter NewStuff.UploadPage and a few little hooks scattered through the rest of the Framework, such as a context action in NewStuff.Page which pushes an UploadPage to the page stack, and a reimplemented KNS3::UploadDialog which wraps up the QtQuick based UploadPage in a dialog, so those who use the existing dialog don't end up without functionality. This was added from the merge request right over here, if you would like to see what the process looked like.

How about using a Dialog? Even More Discoverable-er!

Some Side Effects

While working on this innocent seeming bit of stuff, i ran into few little things that needed to be done first. Of course, i could have hacked this and just Made It Work, but also that is not what we do in KDE.

The first, probably smallest thing is that this inherently shows up in our mobile apps, because it's now a part of both Page and Dialog now. Not that there's a problem with people finding their way to the store and uploading things there, but if we catch just a couple of people who would have otherwise not uploaded their stuff for the rest of the world to see, well, i'll chalk that down as a win :D

As for more technical things, the way in which one would get a list of the providers known to a KNewStuffCore::Engine was previously all manner of awkward, and really does not fit into how a modern Qt application works (that is, you'd call one function to get some string IDs, then you'd call another function to get each provider, and there was no good way to keep track of what might happen if another got added late, and so on). So, we now have a little model, KNSCore::ProvidersModel, which handles this, and just gives you a list of all the Providers known to an Engine, with a bunch of roles that lets you read all the information you need.

Did you know KNewStuff supports multiple providers?

Another long standing issue in KNewStuffCore::Engine, as non-critical as it was, is that it never properly understood what to do with a relative path for a knsrc file. In daily operation this isn't an issue at all, since you just pass it the filename of an installed one, or the full path if you manage your own, and that works just fine. For testing, though, being able to pass in a relative path to for example the multi-provider test knsrc shown in the upload page screenshot above is just kind of handy.

KNewStuff is supposed to be able to handle multiple languages. This turns out to never have worked right for the StaticXML provider, which would simply run through all the title entries, and assign all of them to the provider's title string, which would invariably end up with the last one. Now, though, it will pick the correct one, depending on the current system locale.

Thoughts?

The intention (of course) for NewStuff.UploadPage and the functionality its name suggests is to be expanded in the future. We are looking into ways for how to add the upload functionality back in, in a way that does not also turn into a spam vector. One method we have considered here is to, basically, retain the functionality in OCS as it exists right now, but have a vetting process for users (which then will need some way to essentially "knock" to be allowed API upload privileges). Another idea we have floated is to not allow new content to be added, but for it to be possible to change existing content. I am not really sure precisely what to do, and i also see the two previous ideas could potentially work simultaneously. But, for the time being, while we work this out, we now have a way to at least guide people through to how to actually add their own content to the store (and, indeed, any other source that KNewStuff handles).


The word of the day is: Incremental. Because this obviously isn't the end product here, there will be website-less uploads again, sometime, somehow!

Labels: , , ,

Thursday, June 10, 2021

Graceful Downtime

Occasionally, services need to go down for some reason or another. That's just a thing that happens. Servers need software updates too, but what happens to the clients that need those services? Well, luckily we've got these HTTP Status responses, and one of those is the 503 response, which is described as meaning "Service Unavailable". The actual English interpretation of that is more akin to temporarily unavailable, and even better, if it is also paired with a "Retry-After" header, with a time sometime in the near-ish future, then we can reasonably assume that that what's happening is an expected downtime, or maintenance.

As of 5.84, KNewStuff will handle that on the various services it supports, and in particular the KDE Store (since that is accessed through the Attica library, which also got a bit of attention to allow for this introspection to be done).

What if error, but helpful?!

It's a small thing, but it means a lot to our users that they don't just sit there staring at something and then get a "lol it's broken" type message, when in fact we do know better what is going on. A side effect of putting in this bit of infrastructure in the library also means we now have somewhere to deal with other unfortunate networking situations in a more graceful manner - not done yet, of course, but we've got a starting point for it.

Just a little one this time, but i thought it was worth mentioning none the less. Not everything has to be huge or groundbreaking, sometimes "this little thing is nice for our users" is also good ;)


The word of the day is: Failure. Because that's something we have to deal with sometimes :)

Labels: , ,

Friday, May 21, 2021

KDE's Author Avatars and Not Phoning Home

For a long time now, KDE's about dialogues (the ones you find in the help menus in many of our apps) have supported the ability to fetch a bunch of information about the authors of our applications from the KDE Store through the Open Collaboration Services API. It does this by sending a request to the store for each of the authors who have an ocs username defined, to get the information on user avatars, profile links, and a few other potentially interesting details.

Phoning Home

If you are paying attention, you are now squinting at the screen and going "wait, I saw that title up there, and it clearly says not phoning home, and this is phoning home". You are, of course, entirely correct, and while it certainly was never done with ill intent, it is hard to dispute the fact that it is, in fact, phoning home. As a result, we have been poking about with ways of fixing this, without dropping overly much of the functionality.

Some of those crazy author people what make Discover happen

You might now be thinking what functionality, and sure, it's seems like perhaps a small thing, but remember: KDE is a world-wide community of people who work on this massive pile of software, and the about dialogue is basically the first place where many people are likely to learn of that concept, if they decide to go and look. As such, we want to put our best face forward, and in this case what we want is to firstly not be causing any undue internet traffic (because nobody wants that), but also we want to literally put faces forward.

Not Phoning Home

As of a couple of weeks ago, the KDE Store has had a simple url which will give you a redirect to the avatar that you have set on there, at the scale you need of it, and that's what we're using now. You can use it yourself as well - there's a short introduction to it over here. You can also link directly to your profile in a similar manner, by just linking to store.kde.org/u/someusername - for example, mine is store.kde.org/u/leinir.

Oh look, authors what do money managementy things!

The result is two patches, which landed recently: One for Kirigami, and one for KXMLGui. All of this was originally spawned from a desire to reduce the complexity of KXMLGui itself, and specifically removing the requirement on Attica, which while certainly not heavy, was still doing an inordinate amount of work for an arguably small gain in this particular instance.

There is more to be done on this, mind you - if you read comments on the Kirigami patch, you will notice that one intention is to expand this avatarness to support things other than the store as well, and while i do have some ideas on the topic, if you've got some, don't hesitate to give me a poke! (not "why don't you just use gravatar", that's not the point here, any expansion of this needs to be generic, otherwise it doesn't make a huge deal of sense - the reason we're doing it this way is in part that the ocsUsername field is a part of KAboutData already, and it will Just Work(TM) for anybody who already uses that data structure).

Over To You?

Part of this work could arguably have been done before (specifically that not phoning home part, which from a user perspective is a checkbox which defaults to being off), but since this was originally based on removing the Attica requirement, frankly, this particular angle is something which i must confess, sadly, to have quite entirely missed.

And that, i guess, is the point here: It is staggeringly obvious in hindsight that this was totally a case of phoning home, and while it was never intended to be that, and to my knowledge was never used like that, it took someone pointing at it and going "yeah, this is doing a phoney homey thing" for me to go "yup, it clearly is, let's make that not happen". So that's what you can do here: Be that person that points out a blindingly obvious case of phoning home to someone who's just not noticed in a decade that that's what's happening, furthering KDE's goal of ensuring our software operates in a privacy conscious manner.

Finally, a direct question: Having to tick those boxes in each about dialogue is, arguably, a little far the other direction again, and having that tick apply to all about dialogues in our software would make that bit of life just a tiny bit simpler. Not a lot, arguably, but a little is also good, of course. The question, then, is this: Is it an acceptable tradeoff in privacy terms to let this tick box affect the about boxes in all our software, or should it be per-application? Personally i'm leaning toward it being acceptable, but i wanted to put it to the wider community before diving into that bit of the code.


The word of the day is: Care. Because we should, and we do :)

Labels: , , ,

Tuesday, April 20, 2021

Peruse 2.0 Beta 1 "The Long Awaited Beta"

A fair while ago, in the before times of late 2016, a release was made of a piece of software known as Peruse. Since then, it spent some time getting work done on it on and off, until sometime last year when we decided that it really was time to stop the thing just floundering in some free software equivalence of development hell, and actually get it ready for its next release.

Peruse?

First things first. For those of you who are new, Peruse is KDE's comic book reader project, which consists of the reader application, Peruse Reader, and the comic book creation tool called Peruse Creator.

The project's releases further include a library by the name of libacbf, which allows applications to use Advanced Comic Book Format (ACBF) metadata without doing manual parsing or generation of the xml data. If this doesn't mean anything to you, don't worry, as a reader or maker of comic books, what that really means is that you get rich comic books that are not simply a collection of images in a specific order.

What's New?

Since that most recent release, a fair lot of stuff has happened, including a great deal of polish and fixing in various places throughout the project. In the following, i am going to try and highlight the more impactful ones, in a rough order of coderiness.

Frame Based Navigation

One frame of a much larger page, so you can see all the gorgeous details

From the very start of Peruse, one of the goals was to eventually be able to read comics not only on a page-by-page basis, but more akin to what you might do if you get really deeply into something on paper and focus hard on each panel, except in a guided manner. This is one of the things that ACBF allows the authors of comic books (using an application like Peruse Creator) to do, by letting them mark out areas on a page, and assign them an order, which then lets applications like Peruse Reader know precisely what to show and in what order. Not only is this useful in a way that makes comic books more engrossing to read, but it also makes it much easier to do so on a smaller, hand held device like a phone.

Translated Comics

Translations - because language shouldn't be a barrier to enjoying a good comic book

One of the powerful features of ACBF is the concept of TextLayers. What those are, in essence, is translations for comic books - a way of putting formatted text on top of an image, for speech bubbles and the like. Peruse now has support for this, and if you would like, there's a blog entry right over here talking about that more deeply.

Better Navigation in Books

The sidebar pulled out, with page thumbnails

 Another feature in ACBF is the ability to link between various parts of a book to another. It seems simple enough on the surface, but this allows for some really nifty stuff. On a basic level, you can create a table of contents and jump from there to other places, but you can also create things akin to a choose your own adventure book using this method. There is plenty more to say about this, which is why there is a whole blog entry over here talking about that specifically.

Greatly Expanded Creator

Editing a text-area with a link in
 
The version of Peruse Creator shipped with Peruse 1.2 was an extremely simple tool, designed primarily to just create a simple comic book archive and fill it with pictures, and annotate it with some basic metadata. In Peruse 2.0, while it is not yet able to do everything that ACBF will do, a great deal of it is (such as, but not limited to, references, embedded files, as well as the three types of page areas: frames, jumps, and text areas). In short, Peruse Creator is starting to become a tool that is actually, genuinely good for creating comic book archives and annotating them with ACBF metadata.

Collection Cache

Previously, Peruse would scan the system on startup every time, and build a full database of all the books. This, as you might expect, was an extraordinarily heavy operation, and with any more than a few tens of books, it effectively made it impossible to use Peruse in the casual and immersive fashion the rest of the application intends.

Graduating from Playground

A more organisational thing that happened was that Peruse has graduated from being a Playground project (KDE's experimental section for projects that are not considered quite full featured yet), and is now a proper, full member of KDE. For most people this is a small detail, but one of the larger effects of this is that it means that KDE considers it a "real" project, and it gets attention for things like translations.

ACBF Library

The details of a book
 
Another kind of user we envision for Peruse is other people also working on software which handles comic books, and particularly ACBF enhanced ones. Peruse's ACBF support was always intended to be usable by others (it was built specifically to only require QtCore, but annotated with enough bits to also use it from QML), and as of Peruse 2.0 we are releasing the library versioned according to the Peruse release. It was also expanded greatly, and now supports almost the entirety of the ACBF specification. Round-tripping documents is still a work in progress, but it's already pretty solid.
More on this in a later blog post, but for now, the cmake module is called AdvancedComicBookFormat, and your starting point is AdvancedComicBookFormat::Document in the AcbfDocument.h header.

Kirigami 2

The original release of Peruse was built on top of Kirigami 1, during the early days of the development towards what would eventually become Plasma Mobile. One of the first things to happen after the release of version 1.2 was to port Peruse to Kirigami 2, and the result for the user is partly just more modern and stable code, but also much more easily navigable using a keyboard. Since then, the Peruse team has been working to bring more of the features of Kirigami' which didn't exist in the first version into Peruse, such as the way the search field works, the way scrolling pages are handled, page row layers, action handling, and a whole bunch more.

Gentler, Safer Threading

The way images are served into QML is something called an Image Provider. The old method used by Peruse was a set of simple image providers, which attempted to throttle their own behaviour somewhat, but in reality tended to block operations fairly badly, and also caused severe threading overload on slower systems (such as, for example, on a PinePhone). The end result of that was that you would regularly end up not being given an image when you loaded a book, or your thumbnails would take forever to load.
The new code has been refactored heavily, and now uses what is called an asynchronous image provider, and also makes sure to not ever launch more threads than are actually available on the system it's running on. To you as a user, what this means is not only a more reliable image generation, but often also faster, and safer to boot (which is not really a result of this change to a new kind of image provider, so much as the old code just not being very stable).

No More Submodules

The thing in this list which will be least relevant to someone who just wishes to learn about what Peruse does for reading comic books, this one is for the packagers and self-builders: Peruse previously used an external bit of code to read rar based comic book archives (the ones with the file suffix cbr, and seemingly the most common out in the wild). This turned out to cause endless headaches for packagers, and the decision was made to import that code fully into Peruse.

Gimme!

Before we get to the downloads: This is a beta version, and you should expect it to behave like one of those: Things may well be a bit broken or unpolished, and we will be very happy to see reports any bugs you run into over on the Peruse product category on bugs.kde.org. With that out of the way, head over to peruse.kde.org to grab yourself a shiny new copy of Peruse :)


The word of the day is: Polish. Because that's something to be done when you've got a beta out of the door ;)

Labels: , , ,

Friday, March 19, 2021

New. Stuff. Action!

In my last entry, one of the thing i spoke a bit about was how sometimes you run across places where a ui elements don't quite fit into a window and end up being cut off. One of the examples of this was how a row of buttons in a lot of our control centre modules would be too wide, and just end up outside the window. The way we solved that was to use Kirigami's ActionToolbar, which then semi-magically folds buttons into a little kebab-iconed overflow menu, and everything is lovely and works as expected.
A little kebab-menu which shows things for which we haven't otherwise got the room

Problem?

One detail i omitted from this was that how the QtQuick NewStuff components used to allow users to show things was either through manually creating a NewStuff.Dialog, or a NewStuff.Page, or the convenient shortcut that is NewStuff.Button. Now, if you are observant here, or otherwise familiar with the way KDE's software stack works, you'll notice that all of these things are items with a defined visualisation: Dialogues are explicitly a window with some buttons at the bottom (like the one in the screenshot above, and in the case of NewStuff.Dialog, there's a close button), Pages are things you can put into a QtQuick style Page Stack (such as the one found in Kirigami applications), and a Button is, well, a button.
The problem you run into when everything has a defined visualisation like that is, what do you do when you need to present the user with something else, such as in the case of that magic, folding set of controls up there? Well, in the original merge request for this problem, the solution was to manually create a NewStuff.Dialog, stored in a Loader to emulate the way NewStuff.Button doesn't try and load things until the dialogue is shown, and then create a separate Action entry in our new Kirigami.ActionToolbar which worked with that Loader. 
You'll notice by that description, and if you go and look at the code in the merge request itself, that this is considerably more work than it was to use the NewStuff.Button. What's needed to get around that is a new component in the QtQuick NewStuff components which has no representation of its own, and just gives you the functionality.

No, Solution!

Oh look, a Page, with New Stuff in it, i wonder what that component could be called ;)
Enter NewStuff.Action, a handy dandy little component which has no visual representation of its own, but will happily sit in a list of actions such as that used by Kirigami.ActionToolbar and look however that decides that it should look.
The API is very similar to NewStuff.Button, in that you set a text, a config file. For dealing with things having been installed or removed, use one of the signals which deal with entries changing (changedEntries remains for ease of porting, but the new entryEvent signal should be used whenever you can, as it's much more informative about what's actually happening and when).
Not only that, but while NewStuff.Button works deliberately very similarly to the old KNS3::Button control in that it opens up a Dialog, NewStuff.Action will do that by default, but if you tell it which pageStack to use, it will instead push a NewStuff.Page onto that page stack (and if it's able it will even switch back to that page if activated again).

Over To You

You may be looking at this and going "well, why are you telling me all this?". Here's the deal: The idea behind this is to allow others to more easily do the minor surgery that was allowing those things to fold out of the way when there isn't enough space. If you've been looking for some low hanging fruit to pick, here's a nice, ripe bunch for you :)

The word of the day is: Actionable. Because this kind of is ;)

Labels: , ,

Friday, February 26, 2021

Sometimes It's The Little Things

Big, new things are always a blast to work on, but sometimes polishing is also an enormously important part of software development which we often find ourselves just kind of pushing ahead of us on the todo list, because there's more fun things to be working on. However, those rough edges and lacklustre surfaces also need attention.

Just One Word

Occasionally you come across something where there's just that one word that looks out of place. You end up assuming that there must be some huge, complex underlying reason for why it's like that. And then, when you finally decide to go and look at it, you discover that it really is just a small wording error, either a copy/paste error, or just outright mis-wording something and then not catching it before rolling it out.
For example, when performing a system update in Discover, the Tasks view showed the string "View Updates - Installing". It turned out that, rather than being some scary thing due to a high level of abstraction and reuse of strings in various places, requiring decoupling and things like that, this was one of those situations where it was just worded incorrectly, and that's been fixed now.

Down In Front

A super specific one here. Sometimes in Kirigami applications, the handles for the drawers (global and context) will be covering bits of the UI. This happens when something is put at the bottom of a page, specifically on the very left or right most side of the page. The fix is extremely simple, so if you come across something like that, sorting it out just takes a single line.

Don't Get Cut Off

You're going through your day to day, maybe playing around with the layout of your desktop, or actually working on some important work type thing, or an even more important hobby task, and you come across a bit of the user interface that looks like it's been chopped off.
Sometimes these turn into something a bit more involved, but even then you can start out with something that maybe isn't exactly perfect, or even particularly good at all. Other members of our little community will be able to guide you in a direction that actually works more properly, and perhaps even helps fix an issue found in other, sometimes surprising places.
Sometimes they are outright simple, however. Indeed, this second one (unmerged as i'm writing these words) was what made me write this entry, because...

Now Over To You

My hope in writing this short update of semi-randomly selected things is that i might convince you that when you spot things like that, you are more than welcome hop over to KDE's Invent and take a look at the code yourself. Maybe it is one of the big, scary things, and that's where bugs.kde.org comes in - tell us it's wrong, because while it might be super obvious to you, maybe the rest of us just haven't noticed, and that makes your observation great in itself.
But if it's not, well... why not grab yourself a clone and put up a merge request or two? Remember, those merge requests exist to specifically make sure that if you've missed something, others will catch it during the review, so you don't have to be scared. Give it a shot, the worst that can happen is you'll learn something about a codebase you've not looked at before :)



The word of the day is: Shiny, because that's what things become when you polish them

Labels: , ,

Monday, February 22, 2021

The Application Of New Things

KDE has, for a very long time, had this thing called Get Hot New Stuff, which is the name for a whole pile of tech which all exists just so you can just click a button in your wallpapers dialog that will pop up a dialog where you can, well, get hot new wallpapers for your system. Or mouse cursors. Or Plasma themes. Or books in Peruse. Or templates in a bunch of apps, or any variety of other things.

For a while now, it's been possible to add something called an adoption command, which is what will make a button show up in that dialog, and in Discover, labelled "Use". It's been used in a few places, but i recently sat down and got a bunch of little tools done that lets you set various things from the command line, and that in turn allowed me to also add those tools as adoption commands for the Get Hot New Stuff dialogues which download the stuff that those tools can apply.

How To Use A Wallpaper

What that means is that, fresh off the back of the 5.21 release, we've got that merged in, and it should become available to anybody running master pretty much immediately, and anybody who doesn't, well, hopefully in not too long.

The specific things that have had an adoption command added are:
  • Window Decorations - that is, themes for KWin's Aurora theming engine
  • Wallpapers - technically there was already an adoption command set, but it didn't work very reliably
  • Cursor Themes - cursor as in mouse cursor
  • Color Schemes - the things which define what colours your entire desktop uses
  • Plasma Themes - what defines how Plasma draws all it's UI components (panels, applets, all that lovely stuff)
  • Global Themes - complete packages of full-desktop settings, which adapt the look and feel of your entire desktop to something new
What all this means is that when scrolling through the content of one of the dialogues which let you grab these things, if there's a way to just outright guess what the thing should be applied to, in a global sort of fashion, there should be an adoption command for it.

It also means that, apart from the KWin tool, which is not installed as a systemwide tool (look for kwin-applywindowdecoration in your libexec if you want a play), you can now interact with these things from the command line. This is more or less done the same way you've been able to do with Global Themes for a while now using lookandfeeltool, which with this patch also got a quick bit of attention to make sure it would work as an adoption command, as well as a quick rename to match the naming scheme for the new tools. The new tools are all named plasma-apply-(thingtheyapply), so if you just type that out and tap the tab button, you should see all of them show up for you to play with.

What Desktop Themes Does leinir Have?

Finally, if you spot a dialog that seems like it should have this, but doesn't, do give me a poke, either here or on bugs.kde.org, and we can try and sort it out. Also, if you look at the merge request itself, you'll notice how these tools really aren't particularly scary for the most part. If you would like somewhere nice and self contained to jump in and do some work? Well, there's a good spot for you :)

The word of the day is: User. The thing you become upon clicking the Use button in a Get Hot New Stuff dialog ;)

Labels: , ,