Skip to main content

Sysadmin, interested in new technologies, communications, multimedia, accessibility, better Linux than Windows, better Android than IOS and similar.

pvagner

pvdeejay

mastodon.sk/@pvagner

Peter Vágner

Emacs A11y Tip #3: Emacs with speechd-el running on Termux for Android

5 min read

After a long while I am here with another post in my collection of .
This time I am not going to talk about emacs environment with speech as provided by speechd-el, I will try to describe how I have managed to get a lot from emacs on the go while running it on Termux for Android.
My reasoning behind this setup is that Emacs can be run on pretty much any computing device. I have used to carry a RPI 2 with me to have access to basic linux CLI tools and emacs. Now I believe using my phone with external keyboard connected will serve this purpose even better. Additionally after a bit of learning now I can use emacs even with braille touch keyboard as provided by the Corvus access solution for android as it can emulate ctrl and alt keys. Emacs letter based keyboard shortcuts and braille keyboard are perfect fit together.
There appear to be multiple ways on how to run emacs on Android. Up to now I was not aware of a single setup where I can also have speechd-el and its dependencies working on Android in a way so I can make some good use out of it.

I know the title of this article has a lot of things mixed together so before I'll describe the setup I'll at least link to more details about all these things I have mentioned so far.

Android is an operating system that powers your mobile phone or tablet.
Termux is an awesome app for Android that includes powerfull partially accessible terminal emulator and features repository of traditional command line apps similar to most linux distributions. As of this writing termux is returning to google play it can be installed easily again and for running emacs it's more than capable enough.

So here are the steps:

  • Install Termux either from F-Droid or from Google play.
  • Launch termux and use it directly on your device with Talkback running at least to pass this initial setup.
    On first launch termux will show its terminal view and enable the keyboard. While typing on the keyboard keys are directly passed to the app running in the terminal. You can dismiss the keyboard by pressing the device back button and review the terminal view content with your screen reader. You can double tap the terminal view to get the keyboard back if the app running is not consuming the double tap as a click (emacs does this for example). Termux also has an app drawer you can reach by pressing the back button of your device when the keyboard is closed or you can swipe two fingers from the left hand side if screen reader is running (single finger when it's not). On the drawer there is a list of terminal sessions and two unlabelled buttons. First one shows the keyboard, when long pressing it displays extra row of buttons that complement the keyboard such as ctrl key, alt key, arrow keys and similar. These extra buttons are displayed on the bottom part of the screen inside a view pager. Swiping the buttons to the left switches to the second page with the text input view that can be used with all the android keyboard and accessibility specific review capabilities while typing. While emacs is not running on the device I like to type in commands into this input entry field. When this text entry field is empty pressing the enter key also sends the enter key into the terminal view.
    Also don't forget to read termux documentation where it's talking about the touch keyboard and even the hardware keyboard if you have one.
  • Allow termux to read and write to storage by running
    termux-setup-storage
  • Then install ssh daemon on Termux by running these commands into the terminal one after the other paying attention to the output
    pkg update
    pkg upgrade
    pkg install openssh
  • In order to be able to login to Termux via SSH, you need to prepare a private / public key pair on your PC by running ssh-keygen, then transfer public key to termux saving it into ~/.ssh/authorized_keys. See more about running sshd on termux at the Termux wiki.
  • Start ssh daemon on Termux just by running
    sshd
  • If you like you can execute the following steps inside an SSH session from your PC. You can connect to termux via SSH like this
    ssh user@<deviceIP> -p 8022
  • Install speech-dispatcher and emacs along with its dependencies such as needed termux specific packages and espeak
    pkg install speechd emacs
  • Clone speechd-el git repository where emacs can load it
    git clone https://github.com/brailcom/speechd-el.git $HOME/../usr/share/emacs/site-lisp/
  • Test if speech-dispatcher is working by launching
    spd-say "Hello world"
  • If you can hear espeak saying hello world it's all working fine.
  • Now make a symlink so speechd-el can find speech-dispatcher unix socked with no other configuration changes.
    cd && ln -s .cache/speech-dispatcher .speech-dispatcher
  • Configure emacs to start speechd-el by writing this content into the .emacs file for example by using nano a text editor bundled with termux.
    nano $HOME/.emacs
  • Put this content into the file
    (setq speechd-out-active-drivers '(ssip ))
    (autoload 'speechd-speak
    "speechd-speak" nil t)
    (speechd-speak)
  • Finally launch emacs by simply typing in
    emacs

Refer to other to find out more.

 

Peter Vágner

Chromium is getting #Accessibility support on linux

2 min read

Update: More up to date snapshot than chromium-snapshot-bin 80 is now available. Make sure you are running the latest snapshot for testing and reporting bugs.

 

Accessibility support with Chromium on linux is a thing that developers are working very hard on this year and it turns out it’s getting better and better all the time. I’d say now it’s very usable already. Joan Marie has written a wiki article explaining its current state. I’ve expressed that it looks to be awesome, feels snappy.

Now I’ll add a few simple steps explaining how to install the latest chromium snapshot and enable its built-in accessibility support on Arch linux and other linux distros based off of it.

  • All the commands you are executing should be executed as a normal user i.e. not root. Those that require super user privileges are starting with sudo.

  • Download and install chromium-snapshot-bin package from the AUR

    wget https://aur.archlinux.org/cgit/aur.git/snapshot/chromium-snapshot-bin.tar.gz
    tar xvzf chromium-snapshot-bin.tar.gz
    cd chromium-snapshot-bin
    makepkg -s
  • Now pay attention what package version this will end up building for example as of today it’s chromium-snapshot-bin-80.0.3970.0.r716024-1-x86_64.pkg.tar.xz.

  • Install the package like this

    sudo pacman -U chromium-snapshot-bin-80.0.3970.0.r716024-1-x86_64.pkg.tar.xz 
  • Now set a required variable named ACCESSIBILITY_ENABLED to 1 and write it to your desktop session profile

    sudo bash -c 'echo "export ACCESSIBILITY_ENABLED=1" > /etc/profile.d/chromium-accessibility.sh'
  • Now Write suggested chromium command line flags to the config file wrapper script responsible for launching chromium is looking for

    echo "--force-renderer-accessibility --enable-caret-browsing " > ~/.config/chromium-flags.conf
  • Now relogin to your desktop session, launch chromium whatewer way you prefer and you should enjoy its accessibility support with orca.

Peter Vágner

Braille typing on an #Android device

4 min read

A lot of blind people like to accelerate their typing skills on their smart phones by using eyes free methods. Typing in braille is the most popular of these I think.
Many of us like it and some more would like to get used to this too. It's why questions like what is the best braille keyboard for android, and how to type in braille on androidareasked very frequently.

I have just answered such a question so I'm publishing my current answers.

This is about Soft braille keyboard which is free and open-source published on github although I don't know if it's still available to download from the Google play.

I think details related to device positioning, finger placement and similar will also apply to any other braille keyboard on the planet, e.g. MBraille is working fine too.

Okay so first about Soft braille keyboard setup.  I like these settings in theKeyboard Settings Rotate keyboard with device   check box unchecked Invert keyboard   check box checked All other keyboard settings are on their defaults. When its configured like this then you should be holding your device in landscape with home button to the left screen facing away of you.  Again slowly explaining each suggestion: * device should be in landscape * home button should be on your left hand side * you should hold it in a way so device screen is turned away from you. Imagine if you wanted to use device's front camera to take pictures.  Now position of your hands. Index, middle and ring fingers ofboth your hands are reserved for typing on the braille keyboard displayed on the screen. Thumb fingers are touching the device back cover gently meaning there is nothing to hold the device is just sitting put on your thumb fingers. Pinky fingers are touching the device side on the bottom. You should be able to touch your-self using your pinkies when holding the device like this if you really wanted to do so.  And now final puzzle the braille dots: I imagine you know an ordinary braille type writer such as Perkins or even Picht type writer. If you look at the type writer keyboard you can realize it is not all horizontal meaning keys are not positioned exactly one next to another. Dot three and dot six keys are a bit smaller and slightly pointed to the sides. So by knowing this and considering how little space you have on your device screen you are trying to fit your fingers to the screen as much as possible in order to resemble the braille type writer keyboard layout. Your index fingers are close to each other near the device side at the top, Your ring fingers are far from each other on the device side on the bottom, And your middle fingers are well in the middle. Your left index types dot 1, Your left middle types dot 2, Your left ring types dot 3, Your right index types dot 4, Your right middle types dot 5, And your right ring types dot 6. When you start typing you can callibrate the keyboard. That's easiest done when you put your left hand fingers to the screen and hold down all three for more than a second. If you lift them you will receive a prompt saying put next three fingers on the screen or such. So do the same thing with your right hand and you should be all setup.  This is everything you need to know in order to become productive with soft braille keyboard. Choosing your braille table is just a personal preference.

Peter Vágner

Editing text with Commentary #ScreenReader on #Android

5 min read

Commentary screen reader is a modern and trendy app for android that adds some inovative and usefull features on the top of the necessary screen reading features.
It's worth noting that as compared to Talkback it is very very responsive and feels snappy.

Lets look at how Commentary screen reader (CSR for short) handles text editing.

Imagine we are writing a message using the Gmail app. We can open the app, locate the Compose button somewhere at the top of the screen, bring up the compose screen, tap message text field in the center of the compose screen. All this is a standard screen reader interaction.
Keyboard such as Google keyboard (GBoard for short) opens and we can begin typing.
Let's write at least two sentences so you have a bit of text to practice editing with.
If you are done typing, touch the text box you have just been typing into. You will receive feetback from CSR stating you can use left and right arrows to navigate over the text.
If you want to make simple changes to your text near the start of your text navigating letter by letter and using backspace key on the keyboard is enough however if you need to edit parts of your text in the middle or near the end of the text it would not be very practical to navigate character by character there.

CSR has an editing entry in the actions menu. So either flick right then up and execute editing from the action menu or flick right then down to open the same editing menu, the choice is yours. It's best to inwoke this after touching or navigating to text box where the editing makes sense. When using the Action menu you can open the editing menu for just any content on the screen even buttons, checkboxes and similar. That way you can review the content, copy parts of it or use it to your heart's imagination, of course editing won't work in that case.
When the editing menu is displayed on the screen it has row of buttons on the bottom and most of the screen space is taken by the list. By using the buttons on the bottom you can configure the list to split the text into characters, words or paragraphs. If you tap the Char button, the list will have as many items as there are characters in your text. If you choose words then the number of items in the list relates to how many words there are in your text. If you choose paragraphs it will split your text by end of line character so wrapped lines don't count. The buttons currently say Char, Sentence and Paragraph. Perhaps that's minor translation discrepancy while translating from chinese to english as the text is clearly divided to the individual words rather than sentences when the Sentence button is pressed.
If you have a large text you can start by splitting that to paragraphs. Find the paragraph you are interested in and reconfigure the list to split text into words if the paragraph is very long and continue navigating word by word just by browsing the list.
When you double tap an entry in the list, only the chosen part of text is shown in a simple text box dialog. This dialog is the most simple dialog you can get. It has a title a text box and OK and Cancel buttons. It only displays your chosen part of the text in the box so you can double tap it and edit it as a simple short text by navigating character by character and deleting using keyboard backspace / delete button.
It is even possible to call editing from this dialog again if you have clever use case for that. So you may use this split editing feature recursivelly and focus on the text you wish to work with. This way it is helping you to prevent accidental keypresses that may introduce typos and other unwanted edits.
This editing menu can split text up to 100 characters in the free CSR version, so if you would like to use it for serious editing you will have to activate the premium version.

It is also possible to work with the text the traditional way when using CSR. There is so called Word by word mode. Actually there are two modes Word by word mode and Focus browsing mode. We can toggle these two modes by swiping left then down.
In focus browsing mode you are navigating from item to item on the screen by swiping either up or down. Left or right swipes can be used to skip a group of items such as scroll to next page, move past a list and similar. This is also working on the web.
In word by word mode up and down swipes move line by line and left or right swipes move a character. When you cross an item boundary for example moving from button to button or out of a text box, CSR beeps or vibrates according to the configured preferences.
There are additional word by word mode specific gestures:
Swipe left then right - Skip to previous paragraph.
Swipe right then left - Skip to next paragraph.
Swipe up then down -
Swipe down then up -
Swipe left then up -
Swipe right then down -

I am not sure what exactly are these four gestures supposed to do. They are moving to the start or to the end of a text. But they are duplicated for a reason I would say.

Feel free to experiment with these features and be sure to discuss how it affects your productivity with your Android device.
The official SCR Telegram group is at https://t.me/jieshuochat

Peter Vágner

Building eSpeak-ng for Android with libsonic built-in

2 min read

By a popular demand I have written a few steps how I am building espeak-ng for android.
ESpeak-ng has a optional dependency on a library called libsonic.
It's not critical for its functionality but it allows speeding up synthesised voice so we can get eSpeak-ng speaking at very very fast speech rates.
On linux the build system is configured to take advantage of system wide installation of all the required libraries. This does not nicely apply to the cross compilation for Android as all the libraries have to be prebuilt for the target platform.
And since there is no other distribution channel for the libsonic library other than its git repository with its source code, there are no prebuilt libraries for android.
To workaround this I am cloning libsonic repository, linking its files to the eSpeak-ng source tree and then patching eSpeak-ng source code to include the libsonic files as if these were part of eSpeak-ng it-self.

I am running all this on arch linux, but debian, ubuntu and any other linux distro with gradle, Android-SDK 26, android-sdk-build-tools 28.0.3, recent enough version of android-ndk will work fine.
I like to install all these components via the linux distro package manager.
Espeak-ng Readme has even more details I can write here. There are also some android specific dependencies

If everything is installed here are the commands I can run from the terminal:
mkdir ~/espeak # create a working folder
cd ~/espeak # enter that folder
git clone https://github.com/espeak-ng/espeak-ng.git # clone espeak-ng git repo
git clone https://github.com/espeak-ng/sonic.git # clone libsonic repository
ln -s ../../../sonic/sonic.{c,h} espeak-ng/src/libespeak-ng/ # link sonic files to eSpeak-ng source tree
wget https://files.pvagner.tk/f/e9c6874015fd4241b6c2/?dl=1 -O espeak-ng-libsonic-android.patch # download a patch
cd espeak-ng # change directory to the espeak-ng repo
patch -p1 < ../espeak-ng-libsonic-android.patch # apply the changes from the patch
./autogen.sh # prepare the configure script
./configure --prefix=/usr --with-gradle=gradle --with-extdict-ru --with-extdict-zh --with-extdict-zhy # run the configure script
make apk-debug # build the actual apk

The resulting app is placed in the path android/build/outputs/apk/debug/espeak-debug.apk
You can install this on your device and enjoy fast rates up to 800 WPM.

Peter Vágner

Likes and Reposts handled by the @WithKnown Bookmarks plugin (part 2)

2 min read

Two days ago I have posted an article describing how I started using @WithKnown built-in Bookmarks plugin to handle Likes and Reposts uninstalling Reactions plugin I was using before.
Some people (including andrea and Chris Aldrichreacted on it that prompted me to look at it again and try to clear a few more points.
I did a mistake in my original article and I had to edit it. The bookmarks plugin handles all three classes within a single entity_subtype and I have recommended to create two entity subtypes IdnoPlugins\Like\Like and IdnoPlugins\Like\Repost where i should have only recommended the former.
The Reactions plugin handles the body property of the contents database column differently for Likes and for Reposts so I have added some notes explaining the situation.
And I have completelly missed the look and feel of resulting pages.
As andrea points out, all the Likes and Reposts and Bookmarks now look identical on my site. Unfortunatelly there are only two small differences. The correct classes are used and each type has its own icon. I don't care for the visual appearance that much my-self, however the fact correct indieweb classes are there make me happy I have chosen this route. If someone skilled enough can step up to provide additions to the Bookmark plugin template handling these post types differently, I am happy to see it  on the web and on my site.

There are some more serious issues with this and I hope either I or someone else will be able to suggest and / or add improvements. When posting via micropub e.g. from woodwind all is working well. When posting via bookmarklet or from the Known UI, all the entries are stored as bookmarks. This is the most serious issue.
I have chosen some of my posts so you can see these are valid: Like, Repost, Bookmark.
So I think we are slowly approaching what Chris Aldrich suggests i.e. unifying it all working in the core of Known.

Peter Vágner

Untangling @WithKnown plugin conflicts on the #IndieWeb (Reactions vs Bookmarks)

18 min read

Regarding various Known post types there is a story I would say I think so because at least for me it took so long to sort it out on my instance.
After I've installed Known on my domain some time in july 2016 I have realized the Repost and Like post types don't appear to be available right on the main page so I've installed Reactions plugin.
Everything worked smoothly for me at that time I was posting a lot of likes to my site, I have even reposted a few things. So given the fact it was all perfectly pieced together and worked fine I was not following the Known development and I missed all its updates. In particular one significant change was that since version 0.9.2built in Bookmarks plugin deployed inside the IdnoPlugins/Like folder received an ability to handle likes, reposts and bookmarks. I have only acknowledged this issue about a year later in june 2017.
Looking through both issues there was no easy solution to this seemingly misterious incompatibility and that got me thinking in somewhat different direction.

  • Built-in Bookmarks plugin can now handle likes and reposts.
  • Do I need seperate Bookmark, Like and Repost buttons on the main page if I am either using corresponding bookmarklet or posting from the phone using an android app?
  • Is there something else I might miss in the future Reactions plugins provides?


I was unable to answer the last question however first two points indicate I no longer need Reactions plugin because Bookmarks plugin which lives in the core can do what I need it to do.
Okay so I then went to examine how the data are stored in the database trying to work out if I can turn Likes and Reposts created with Reactions plugin into Likes and Reposts built-in Bookmark plugin can now handle. I'm using MariaDB and first I wanted to see how many entries there are in my database I have created using Reactions plugin.

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%";

Now how many of them are Likes

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Like";

And finally how many of them are Reposts

SELECT COUNT(*) FROM entities WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Repost";

While examining these data I have noticed that the entity_subtype is a dedicated database table column, however the same thing is also stored in the contents column holding all the entity content as a json string. So I have just double checked if these two places agree with each other.

SELECT COUNT(*) FROM entities WHERE contents LIKE "%\"entity_subtype\":\"IdnoPlugins%Reactions%\"%";

And now a different check of the same thing:

SELECT COUNT(*) FROM entities WHERE INSTR(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions") > 0;

Now I think I can use these building blocks to conditionally select entities I will be changing. However I don't yet know what changes to do.

This is how the Like created with the Reactions plugin is stored in the database:

MariaDB [mydatabase]> SELECT * FROM entities WHERE (entity_subtype LIKE "%like" ) ORDER BY created LIMIT 1;
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+
| uuid                                                                             | _id                              | owner                              | entity_subtype        | created             | contents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | search                                    | publish_status |
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+
| https://pvagner.tk/2016/liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63 | 58debaa17faedc195f6ca78ca23249f5 | https://pvagner.tk/profile/pvagner | IdnoPlugins\Reactions\Like | 2016-07-10 12:36:42 | {"access":"PUBLIC","owner":"https:\/\/pvagner.tk\/profile\/pvagner","likeof":"http:\/\/notes.whatthefuck.computer\/1467388500.0-note.html","syndicatedto":["https:\/\/twitter.com\/rrrrrrrix\/status\/748993485538111488","https:\/\/www.facebook.com\/10153834879468856\/posts\/10154372324658856"],"description":"Ryan Rix's Catastrophic Data Loss and Me","_id":"58debaa17faedc195f6ca78ca23249f5","slug":"liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63","created":1468154202,"updated":1468154202,"uuid":"https:\/\/pvagner.tk\/2016\/liked-ryan-rixs-catastrophic-data-loss-and-me-0647a70c63","entity_subtype":"IdnoPlugins\\Reactions\\Like"} | ryan rix's catastrophic data loss and me  | published      |
+----------------------------------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------+

And this is how a different like created with Bookmarks plugin is stored:

MariaDB [mydatabase]> SELECT * FROM entities WHERE (entity_subtype LIKE "%like" ) ORDER BY created DESC LIMIT 1;
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+
| uuid                                                     | _id                              | owner                              | entity_subtype        | created             | contents                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | search                                                                                    | publish_status |
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+
| https://pvagner.tk/view/9251ea447da9ae82fdc29af9cac2ee56 | 9251ea447da9ae82fdc29af9cac2ee56 | https://pvagner.tk/profile/pvagner | IdnoPlugins\Like\Like | 2018-01-23 12:48:38 | {"access":"PUBLIC","owner":"https:\/\/pvagner.tk\/profile\/pvagner","body":"https:\/\/torrentfreak.com\/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123\/","likeof":"https:\/\/torrentfreak.com\/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123\/","description":null,"tags":null,"pageTitle":"Denuvo Has Been Sold to Global Anti-Piracy Outfit Irdeto - TorrentFreak","slug":"denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto","created":1516711718,"updated":1516711719,"publish_status":"published","_id":"9251ea447da9ae82fdc29af9cac2ee56","uuid":"https:\/\/pvagner.tk\/view\/9251ea447da9ae82fdc29af9cac2ee56","shorturl":"1hJTnB","posse":{"twitter":[{"url":"https:\/\/twitter.com\/pvagner\/status\/955784340310581248","identifier":"@pvagner","item_id":"955784340310581248","account_id":"pvagner"}],"mastodon":[{"url":"https:\/\/mastodon.sk\/@pvagner\/99399219252030242","identifier":"pvagner@mastodon.sk","item_id":"pvagner@mastodon.sk","account_id":""}]},"entity_subtype":"IdnoPlugins\\Like\\Like"} | https://torrentfreak.com/denuvo-has-been-sold-to-global-anti-piracy-outfit-irdeto-180123/ | published      |
+----------------------------------------------------------+----------------------------------+------------------------------------+-----------------------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------+----------------+

Based off all the stuff I have gathered so far I compiled this short list of steps:

  • Create a backup of your running database so you can go back and retry if something is not working the way you are expecting.
  • Disable reactions plugin. This will stop displaying the broken Likes and Reposts for a while.
  • Tweak the search database table column to contain the same URL  the same thing as body, likeof or repost inside the contents json.
  • Tweak the contents column for all these Likes and reposts which were created by the Reactions plugin
    1. to have "entity_subtype":"IdnoPlugins\\Like\\Like" or "entity_subtype":"IdnoPlugins\\Like\\Repost" respectively. Basically replacing IdnoPlugins\\Reactions with IdnoPlugins\\Like.
    2. to have the same body than the respective "likeof" or "repost". Note that entries created with Reactions plugin are lacking the body property.
    3. To repurpose description into a pageTitle as Reactions plugin does not allow entering a description and makes no use of pageTitle.
  • Change the database table column entity_subtype the same way we have changed entity_subtype within the contents column. This will make all the entries visible again.


Now I need to be able to retrieve the likeof url from the contents discarding all the rest. I know there is a json specific extension for current development version of MariaDB, however I am still running version 10.1, so I'll have to resort to string manipulation and regular expressions. If you are running other database flavour or an older version you will have to tweak this I guess.
I will be only showing queries tweaking Likes, if you are interested you can easily run them again for Reposts as well.

SELECT REPLACE(SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), '\\/', '/') FROM entities WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"body\":") <= 0) ORDER BY created DESC LIMIT 10;

At this point we are finally ready to run some UPDATE statements doing what I have just suggested.

Changing the search database table column for all the Likes created by the Reactions plugin (needs adjusting in order to work with Reposts):

UPDATE entities SET search = REPLACE(SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), '\\/', '/') WHERE (entity_subtype LIKE "IdnoPlugins%Reactions%Like");

Tweaking the entity_subtype within the contents column (handles both Likes and Reposts at the same time):

UPDATE entities SET contents = REPLACE(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions", "\"entity_subtype\":\"IdnoPlugins\\\\Like") WHERE INSTR(contents, "\"entity_subtype\":\"IdnoPlugins\\\\Reactions") > 0;

Creating a missing body property inside the contents column (you need to adjust it to work with Reposts):

UPDATE entities SET contents = REPLACE(contents, REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), CONCAT("\"body\":\"", SUBSTR(REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'), 11), "\",", REGEXP_SUBSTR(contents, '"likeof":"https?:[^"]*'))) WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"body\":") <= 0);

Repurposing descriptions to pageTitles within the contents column for all Likes where there is no pageTitle (you need to also adjust this to work on Reposts):

UPDATE entities SET contents = REPLACE(contents, "\"description\"", "\"pageTitle\"") WHERE (entity_subtype LIKE "%Like" AND INSTR(contents, "\"pageTitle\":") <= 0);

And a final step changing entity_subtype column to be handled by the built-in Bookmarks plugin:

UPDATE entities SET entity_subtype="IdnoPlugins\\Like\\Like" WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Like";
UPDATE entities SET entity_subtype="IdnoPlugins\\Like\\Repost" WHERE entity_subtype LIKE "IdnoPlugins%Reactions%Repost";

Definatelly there might be a more straightforward way on how to accomplish this. Tweaking the data may even not be the right solution, however I think it worked fine for me.

Edit: It turned out I was wrong on some points. So I have edited this article correcting incorrect stuf and I have also posted a follow up article explaining what I have done wrong here.

Peter Vágner

Obrovské rozmery projektov okolo Biblie

4 min read

Ako som si tak jeden nedeľný podvečer pozeral novinky v katalógu open-source aplikácií pre Android F-Droid, cez aplikáciu RadioDroid som si v databáze rádio staníc z celého sveta radio-browser.info všimol stanicu bible.is, ktorá vysiela čítané aj dramatizované texty z biblie v množstve jazykov.
Viem, silnejšie veriaci a ostatní, ktorí máte bibliu podrobnejšie naštudovanú určite toto poznáte, no mňa ohromilo takéto hnutie. Otvoril som si teda stránku bible.is a nestačil som sa čudovať. Majú texty a nahrávky biblie v nespočetnom množstve jazykov, perličkou je napr. biblia vo východoslovenskom - karpatskom dialekte rómštiny, kde dramatizovaná biblia bola nahrávaná v čechách a zverejnená v roku 2014. Slovenský preklad biblie z roku 1997, dramatizovaný ešte o niekoľko rokov neskôr je žiaľ len audio, teda nie je tak pri počúvaní tejto slovenskej dramatizovanej biblie možné zároveň to isté aj čítať očami, príp si kontrolovať verše podobne ako by sme listovali skutočnou tlačenou knihou ako je možné robiť s anglickým, českým alebo už spomínaným rómskym prekladom.
Nie je to teda len rádio v tradičnom zmysle slova s mobilnými aplikáciami, satelitným vysielaním, ale je to aj online knižnica textov a nahrávok.
Trošičku ma absencia slovenského prekladu v textovej podobe zamrzela, tak som si povedal, že si aspoň pozriem, čo všetko dokážem o tomto zistiť a odhadnem si len tak pre seba ako veľmi je pravdepodobné, že sa to časom zmení. Pochopil som to tak, že stránku bible.is prevádzkuje spoločenstvo viera počúvaní, ktoré zastrešuje nahrávky už preložených textov biblie v rôznych jazykoch.
Čo vedia robia sami, no bez spolupráce s lokálnymi organizáciami by to nešlo. U nás je takouto organizáciou slovenská biblická spoločnosť. Na stránke biblia.sk ponúkajú 6 rôznych prekladou biblie v textovej podobe a podľa tohoto článku zapadajú tiež do celkového kontextu projektu s nepredstaviteľnými rozmermi. Okrem nahrávok nového zákona z roku 1997 resp. 2001, ktorý môžeme počúvať aj na bible.is niekedy približne v roku 2014 dokončili nahrávanie starého zákona, vydávajú rôzne publikácie napr. bibliu vo zväčšenom písme pre ľudí s poruchami zraku, nedávno zverejnili video nahrávky pre sluchovo postihnutých v slovenskej posunkovej reči na adrese nepocujuci.biblia.sk.
 a tak som sa dopátral až k obsahovému mozgu nad týmto biblickým projektom, ktorý poháňa tzv. digital bible platform. Myslím si, že skôr či neskôr sa tam dostanú aj materiály, ktoré publikuje slovenská biblická spoločnosť.

No povedzte, nemá spolupráca na takto rozsiahlych projektoch súvisiacich s bibliou okrem duchovného rozmeru ešte aj spoločenský, filozofický a technický rozmer? Myslím si, že toto je dobrá myšlienka pre všetkých, ktorí podporujú dobrovoľnícke open-source, charitatívne alebo iné projekty, kde výsledkom je niečo, čo môžu všetci získať bezplatne a nezištne.

Peter Vágner

How to apply different paragraph styles in Libreoffice Writer

2 min read

Today I have spent some 20 minutes looking for a way how can I apply different paragraph styles in Libreoffice Writer by using keyboard exclusively.

 

Initially I was afraid It can’t be done however finally I have learned how to do it and here are the steps working for me:

 

  • Select text you want to style differently

  • Press ctrl+F11 to focus formatting toolbar

  • Use up and down arrows to choose your style. If you have found your choice press the enter key. If you haven’t found the suitable style choose the last option more styles...

  • Now the fun begins since this option ends with three dots I was expecting I can activate the selection somehow which should bring up a dialog of some sort. Pressing enter on this even in combination with other keys did nothing usefull. So to browse for more styles I have ditched looking at formatting toolbar, pressed F6 several times to jump to the sidebar. It is possible to use up and down arrow keys to move between parts of the UI here on the sidebar. Properties is the first item and Styles is the second one. So when you hear properties pannel, you should press down arrow key to change to styles. You can then press the tab key and become overwhelmed with loads of styles Libreoffice has to offer. I’m sure you can even write a book using these.

 

Peter Vágner

How to hack #Kodi screen reader addon into #LibreElec image

4 min read

In order to make this really work I had to do a few edits to this article. Last change has been made at 29th of december 2016.
Today I was asked by one of the online friends how to make LibreElec htpc software include Kodi screen reader addon.
First we had some disscussion in the IRC channel on freenode. We have found out adding Kodi screen reader into the official image is not likely to happen. We are still free to make our blindness specific spin though.
There are several things to overcome.
Rebuilding the whole LibreELEC image is an overkill we just would like to inject our addon.
The addon has a feature that will not start when it's preinstalled into system wide kodi addons directory so we have to patch the addon with a dirty change until a better solution is found.
And this is updated proof of concept tweak how we can hack Kodi screen reader into image of Raspberry pi 2 / Raspberry pi 3 build of Libre Elec.


# Create an empty directory where we will do our job
mkdir /tmp/libreelec
cd /tmp/libreelec/
# download libreelec image. You can get the Kripton or more up to date version but pay extra attention in that case
wget "http://ftp.belnet.be/libreelec.tv/LibreELEC-RPi2.arm-7.0.2.img.gz"
# unpack the downloaded archive
gunzip LibreELEC-RPi2.arm-7.0.2.img.gz
# inspect what partitions the unpacked image has
fdisk -lu LibreELEC-RPi2.arm-7.0.2.img
# Note the sector size of the image is 512 bytes, first partition starts at sector 2048 thus we need to setup a loop device starting at offset 2048*512
sudo losetup -o 1048576 /dev/loop0 LibreELEC-RPi2.arm-7.0.2.img
# create a temporary folder where we'll mount the unpacked image
mkdir image
sudo mount /dev/loop0 image
# unpack squashfs image to a current directory (has to be executed as root to preserve file permissions and ownership)
sudo unsquashfs image/SYSTEM
# Download current Kodi screen reader addon from one of the kodi.tv addon repository mirrors
wget "http://ftp.halifax.rwth-aachen.de/xbmc/addons/krypton/service.xbmc.tts/service.xbmc.tts-1.0.6.zip"
# Change to the directory where you can unpack Kodi screen reader addon
cd squashfs-root/usr/share/kodi/addons/
# unzip the Kodi screen reader addon (do it as root to fit within the rest of the target system image)
sudo unzip ../../../../../service.xbmc.tts-1.0.6.zip
# Patch the addon not to disable it-self on first run when it detects it's preinstalled
sudo sed 's/return os\.path\.exists(preInstalledPath)/return False \.path\.exists(preInstalledPath)/g' service.xbmc.tts/lib/util.py 1<> service.xbmc.tts/lib/util.py
# change back to the original working directory
cd ../../../../..
# If you have image including Kodi Kripton or possibly newer version, uncomment the next line to add our addon into the addon-manifest.xml
sudo xmlstarlet ed -L --subnode "/addons" -t elem -n "addon" -v "service.xbmc.tts" squashfs-root/usr/share/kodi/system/addon-manifest.xml || : # ignore error
# Recreate the squashfs SYSTEM image (again it's important to do that as root)
sudo mksquashfs squashfs-root SYSTEM -b 131072 -comp lzo -no-xattrs
# Create a md5 sum for your new squashfs image
md5sum SYSTEM > SYSTEM.md5
# now if you like you can compare size and features of both the images.
ls -l SYSTEM
ls -l image/SYSTEM
unsquashfs -s SYSTEM
unsquashfs -s image/SYSTEM
# Finally move your newly created SYSTEM and SYSTEM.md5 files into the proper place
sudo mv SYSTEM* image/
# unmount the image as we are done tampering with it
sudo umount image
# If you like just check the image if it has been really modified recently
ls -l LibreELEC-RPi2.arm-7.0.2.img
# Compress the image inplace as much as gzip allows
gzip -9 LibreELEC-RPi2.arm-7.0.2.img
# Flash / upload file for a friend and clean up your self please