2/24/2020

From Owncloud to Nextcloud

I had been using Owncloud for nearly ten years, and was quite satisfied.

So naturally, when a friend needed a similar solution, my first step was to set up Owncloud for him. You use the tools that you know best.

After the installation and before he even started using it, I got a feeling creeping up that I had better check the differences between Owncloud and Nextcloud. And so I did. And then I decided that Nextcloud was the better solution. I spare you the comparison, you can do a web search yourself; suffice it to say that many of the differences were quite appealing to me, last but not least the fact that it is completely open source and has a very active community.

I had already invested time into setting up users, groups and permissions, so I thought, the best was was to run the upgrade script that Nextcloud provide to migrate from Owncloud. I reckoned, it would be quite fast, as there was no content yet. Well, tough s**t: it upgraded from Owncloud 10 to Nextcloud 12, the last compatible version. OK, then you would have to upgrade Nextcloud step by step until you reach version 18 - seems like a very long way. Maybe I would have gone down that path, but I could not even run Nextcloud 12, because it requires PHP 7.1 or lower, a packe not supported any longer and thus (and this is a good thing) not available on the server.

So, back to square one, a clean installation of Nextcloud 18, and creating all the stuff again. It was a bit tiresome, but well worth it. Even during the installation process I was impressed with the quality of the checks, security considerations and advice they offered.

Now this was done, I was able to get my own take on the differences. It was like buying a new bike after 15 years: you were quite satisfied with the old one, but one you had a taste of the new one, there was no going back :-)

So now I needed to migrate my own Owncloud instance, which contained a lot of data. After my experience describe above, I went for a clean install again.

Users, groups, permissions etc. were set up rather quickly.

Migrating the data took a long time, but it was mostly waiting for the computer: I decided to copy the data directory, so I had a backup just in case; moving it obviously had saved several hours.

After copying (or moving) the data directory, running occ files:scan took another couple of hours. This is required so Nextcloud knows about the files I had slipped there behind its back.

Finally, address books an calendars are easy to migrate via export and import. Boring manual work, but I had my reward already in sight :-)

I then put Owncloud into maintenance mode, updated all clients, and switched it off completely. Of course, if you just re-use
Now I am happy and smiling with my new bike Nextcloud instance!

I still have not explored all the new options and apps, there is a lot to explore. This will keep me busy for a while ...


2/21/2020

Falaffelstand mit Wahlwerbung der AfD

Letztens habe ich an "meinem" Falaffel-Stand gesehen, daß dort unter anderen Wahlwerbung der AfD ausliegt. Sympathisanten können die arabischen Inhaber doch wohl kaum sein.

Also, wie kommt der Müll da hin? Hat die AfD bei Verweigerung mit dem Abfackeln des Standes gedroht? Wollen die Inhaber sich für den Fall der Machtergreifung anbiedern? Letzteres hat ja schon früher nicht wirklich funktioniert ...

Ich konnte leider nicht nachfragen, da schon einige Leute ungeduldig anstanden, und hatte gute Lust, gleich alle Flyer mitzunehmen und zusammen mit dem Einwickelpapier meines Falaffel-Wraps dahin zu bringen, wo sie hingehören.

Schade, dass man das nicht darf. Hat trotzdem geschmeckt, und die Freundlichkeit der Inhaber hat mich ebenfalls sehr erfreut.

2/11/2020

CSU: Tempolimit? NEIN Danke!

Die CSU sammelt (im Auftrag des bescheuerten Bundesverkehrsministers?) Unterschriften gegen ein Tempolimit.


Und sie führen auch "gute Gründe" dafür an:
  1. Die Zahl der Verkehrstoten ist in Ländern mit Tempolimit zum Teil drastisch höher als in Deutschland.
  2. Unser Problem sind die Straßen, auf denen bereits Tempolimits gelten. Auf Bundes-, Landes- und Kommunalstraßen liegen die eigentlichen Herausforderungen der Verkehrssicherheit.
  3. Der Umwelteffekt eines Tempolimits ist sehr gering. Mit einem generellen Tempolimit von 130 km/h könnten lediglich 0,6 % der CO2-Emissionen des Verkehrssektors eingespart werden. Es gibt heute also wesentlich effizientere Maßnahmen für mehr Klimaschutz im Verkehr.
OK, schauen wir uns das mal genauer an:

Zu 1: Solche Länder mag es geben, auch wenn keines genannt wird (warum eigentlich nicht?). Dennoch ist hier nicht widerlegt, dass die Zahl der Verkehrsopfer (Tote und Verletzte) durch ein Tempolimit signifikant sinkt.

Im Gegensatz zur CSU führe ich gerne Beispiele an: Dänemark, UK, Niederlande, Schweden, ... Im Vergleich zu Dänemark hat Deutschland mehr als doppelt so viele Todesfälle auf Autobahnen bezogen auf die gefahrenen Gesamtkilometer.

Zudem sollte man einen Erfolg oder Misserfolg hier in Relation zu den Verkehrsopfern vor Einführung eines Tempolimits sehen. Glücklicherweise gibt es auch hier Zahlen, sogar aus Deutschland: nach Einführung eines Tempolimits zwischen Wittstock/Dosse und Havell sank die Zahl der Verkehrsopfer dort um satte 57%!

Zu 2: Wo ist hier ein Argument gegen ein Tempolimit auf Autobahnen? Es spricht ja nichts dagegen, im gleichen Zug auch andere Straßen sicherer zu machen.

Zu 3: Wow, das klingt nach eine präzise durchgeführten wissenschaftlichen Studie. Allerdings antwortet die CSU auf Nachfrage, welche Studie es belegt, nicht, bzw. löscht weitere Nachfragen ungelesen. Professionell geht anders. Selbst wenn der Umwelt-Effekt gering wäre, was ich ohne weiter Information zu der zugrundeliegenden Studie stark bezweifeln würde, wäre es immer noch hilfreich. In der derzeitigen Situation zählt jede Maßnahme, nach dem Motto "Kleinvieh macht auch Mist".

Hier hat sich CSU freiwillig bloßgestellt, nur um einen (weiteren) unfähigen Bundesminister aus ihren Reihen zu unterstützen, statt ihn nach dem Maut-Debakel verdient abzusägen.

Dass Scheuer und die CSU den vom Minister so gepriesenen "gesunden Menschenverstand" nicht besitzen, ist wohl offenkundig.

Als Einwohner Bayerns bin auch ich peinlich berührt.


Wer das "Original" immer noch sehen oder gar unterschreiben (wehe!) mag, findet den Aufruf der CSU hier: https://www.csu.de/tempolimit-nein-danke/

Also wirklich, Ihr wollt immer noch unterschreiben? Dann vielleicht vorher auch dies noch lesen: https://www.br.de/nachrichten/wissen/tempolimit-was-ist-dran-an-der-csu-kampagne

Nachtrag: man hört ja gerne von CDU/CSU und FDP, dass mündige, verantwortungsvolle Bürger keine Verbote brauchen. Nun ist es leider so, dass die immer größer werdende Schar von Egoisten dies sehr wohl brauchen. Und dass Verbote gute Auswirkungen haben und negative Befürchtungen sogar ausbleiben, zeigt sehr schön das Rauchverbot. Es zeigt leider auch, dass Bayerns Regierung, also die CSU mal wieder, zu so etwas nicht fähig ist, und es ein Volksbegehren dazu braucht. Schade, dass es dieses Instrument auf Bundesebene (immer noch) nicht gibt.

Vorgänge in Thürigen haben das Vertrauen in die Politik nicht gemindert

Wo nichts ist, kann auch auch nichts weniger werden, bzw. weniger als Null geht halt nicht.

Die CDU stellt sich mal wieder als würdiger Nachfolger der Zentrumspartei in Sachen Steigbügelhalter für Nazis dar.

2/01/2020

Javascript Promise - My Personal Best Practice

I just love promises. I do not think I could handle asynchronous operations without them. For me they present a simple way to abstract from parallel execution, so the code looks sequential to the programmer, which is a concept that is much easier to comprehend for the human mind - or at least mine.

This article assumes that you have a basic understanding of promises already. There are plenty of good tutorials out there, so I will focus on my personal take on best practices.

Let us look at a dead simple Promise and how its result can be handled:

new Promise((fulfill, reject) =>
{
  fulfill("hello world");
})
.then(
  (value) => { console.log("fulfilled", value); },
(message) => { console.log("rejected", message); }
)
.catch((error) => { console.log("error", error)})
.finally(() => { console.log ("finally")})
;
// console output:
// fulfilled hello world
// finally

This Promise, for the sake of a simple example, just fulfills immediately.
 
You can handle both, fulfillment and rejection in a single then-clause. I often see examples that use "then" to handle fulfillment and "catch" to handle rejection. This is semantically not correct, so do avoid this pattern. I will explain the difference later.

The catch-clause handles and unforeseen errors, such as trying to work with a null object. If not handled in a preceding then-clause, the catch-clause will also handle rejection. In this case, however, you will not know, whether there was a real error, which you better handle in your code, or if it was a "clean" rejection.

Finally, the finally-clause will be executed regardless of whether the Promise has been fulfilled or rejected. It will, mind you, only execute, after the Promise has been settled, i.e. was fulfilled or rejected. As long as the Promise is pending, the finally-clause will not execute.

N.B.: when I talk about "clauses" here, it just helps me to conceptualize the behaviour, I am aware that these are methods that take callbacks as their arguments. You may find another concept more helpful to streamline your own thoughts :-)

Now let us introduce a run-time error into the fulfillment handler:

new Promise((fulfill, reject) =>
{
  fulfill("hello world");
})
.then(
  (value) => { console.log("fulfilled", value); x = null.x; },
(message) => { console.log("rejected", message); }
)
.catch((error) => { console.log("error", error)})
.finally(() => { console.log ("finally")})
;
// console output:
// fulfilled hello world
// error TypeError: "null has no properties"
// [with a reference to your code]
// finally

As you can see in the output, the catch handler is invoked, and the error message can be logged. If you fail to do so, troubleshooting your code may soon become a nightmare.

I will not mention the finally handler, as it will always be called. Boring :-)


Now, moving the catch handler before the then handler makes a big difference:

new Promise((fulfill, reject) =>
{
  fulfill("hello world");
})
.catch((error) => { console.log("error", error)})
.then(
  (value) => { console.log("fulfilled", value); x = null.x; },
(message) => { console.log("rejected", message); }
)
.finally(() => { console.log ("finally")})
;
// console output:
// fulfilled hello world
// TypeError: null has no properties
// [with a clickable reference to your code]
// finally

Now the catch handler will handle any run-time errors preceding the then handler. Errors in the then handler itself, however, will not be handled, and thus will be automatically logged to the console as errors. That is helpful for two reasons: it does not matter, should you forget to display the error in the catch handler, and it gives you a clickable code reference to the origin of the error, so you can see the code and call stack. Nice :-)

Not to miss out on rejection, we will cover this as well:

new Promise((fulfill, reject) =>
{
  reject("hello world");
})
.then(
  (value) => { console.log("fulfilled", value); },
(message) => { console.log("rejected", message); }
)
.catch((error) => { console.log("error", error)})
.finally(() => { console.log ("finally")})
;
// console output:
// rejected hello world
// finally

And last but not least, this is an example that I often see in tutorials, which makes me mad:

new Promise((fulfill, reject) =>
{
    reject("hello world");
})
.then(
    (value) => { console.log("fulfilled", value); }
)
.catch((error) => { console.log("error", error)})
.finally(() => { console.log ("finally")})
;
// console output:
// error hello world
// finally

Because this relies on the catch handler to handle rejects, your code will be at a loss whether there was and error or a "clean" rejection. DO NOT DO THIS!

To summarize my personal best practice:
  1. use then() to handle bot, fulfillment and rejection
  2. put  catch() before then()

These two tiny details make life so much easier :-)
adaxas Web Directory