[3.2] CLI update

Fragen rund um die Installation, Administration und Benutzung von phpBB 3.1.x und höher und die Konvertierung zu phpBB 3.2.x.
Forumsregeln
Bitte im Thementitel den Präfix deiner phpBB-Version [3.1.x] oder [3.2.x] angeben.
Benutzeravatar
tracer
Mitglied
Beiträge: 83
Registriert: 02.12.2004 21:37
Wohnort: Kollmar
Kontaktdaten:

[3.2] CLI update

Beitragvon tracer » 24.02.2018 17:58

Hallo,

ich hatte mal wieder ein paar phpBB die auf updates warteten.

Wie üblich hielt ich mich an die Anleitung im ACP, machte den Download wie gewohnt, und stellte dann fest, dass das bei phpBB 3.2 wohl alles nicht mehr gilt.

OK, geoggled.

Das gefunden: viewtopic.php?f=145&t=240853

Deckt sich mit meinen Erfahrungen, und dann hier geschaut: https://www.phpbb.de/kb/update32x

Äh ja. Ja, nee. Das können die nicht ernst meinen, habe ich mir gedacht. Mit dem Hin- und Herspringen ist das ja arg fehlerträchtig.
Und die Extensions alle mit der Maus aus und ein? Bei jedem update?

Hmm, danke, aber nein danke.

Aber meckern kann ja jeder, besser machen ist angesagt. OK.

Also, anbei ein Script, sollte selbsterklärend sein denke ich.

Ach ja, den ganz blöden Tipp B.1. (alles löschen ausser …) habe ich mal ganz schnell totgestellt, der schiesst ja so ziemlich jedes Bord ins aus, ausser man hat NULL Altlasten, laut Anleitung himmelt es ja schon direkt Tapatalk (/mobiquo) …

Also, wer testen will bitte, über feedback freue ich mich natürlich auch.

Frage noch: Seit wann wird "/cache/production" benutzt, und warum?


Script als Attachment, ansonsten einfach:

Code: Alles auswählen

git clone https://gitlab.24unix.net/tracer/phpbb_updates.git


dann ins Update-Verzeichnis (/phpbb_updates), und "php ./update.php" aufrufen.


Code: Alles auswählen

#!/usr/bin/env php
<?php

// make absolute or relative to phpBB /
define('PHPBB_ROOT_PATH', '../');
define('IN_PHPBB', true);


function confirm($message = 'Are you sure? ', $options = array('y', 'n'), $default ='n')
{
   // first $options means true, any other false

   echo $message, ' (';
   $first = true;
   foreach ($options as $option) {
      // mark default
      if ($option == $default) {
         $option = strtoupper($option);
      }
      if ($first) {
         echo $option;
         $first = false;
      } else {
         echo '/', $option;
      }
   }
   echo '): ';

   $handle = fopen("php://stdin", 'r');
   $line = trim(fgetc($handle));
   fclose($handle);


   if ($line == '') {
      // enter
      $line = $default;
   }

   if ($line == $options[0]) {
      $result = true;
   } else {
      $result = false;
   }

   return $result;
}



function deleteDirectory($dir, $excludes = array())
{
   if (!file_exists($dir)) {
      return false;
   }
   $dir = rtrim($dir, '/') . '/';
   static $skip = false;

   $entries = glob($dir . '{,.}[!.,!..]*', GLOB_MARK | GLOB_BRACE);

   foreach($entries as $entry) {
      if (!in_array(basename($entry), $excludes)) {
         if (is_dir($entry)) {
            deleteDirectory($entry);
         } else {
            unlink($entry);
         }
      } else {
         $skip = true;
      }
   }
   if ($skip == false) {
      rmdir($dir);
   }
}



function copyDirectory($source, $target)
{
   if (!file_exists($source)) {
      die("missing source: $source");
   }

   if (is_file($source)) {
      if (copy($source, $target)) {
         return true;
      } else {
         return false;
      }
   }

   if (is_dir($source)) {
      if (!file_exists($target)) {
         mkdir($target);
      }
      $source = rtrim($source, '/') . '/';
      $target = rtrim($target, '/') . '/';
      $dir = new DirectoryIterator($source);

      foreach ($dir as $entry) {
         if (!$entry->isDot()) {
            copyDirectory("$source$entry", "$target$entry");
         }
      }
   }

   // ignore links, not part of phpBB arch
}


$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    echo 'This script is intended for unixoid installations.';
    exit(1);
}


$fileowner = fileowner($phpbb_root_path);
$filegroup = filegroup($phpbb_root_path);
$fileownerName = posix_getpwuid($fileowner)['name'];
$filegroupName = posix_getgrgid($filegroup)['name'];


if (!empty($argv[1])) {
   switch ($argv[1]) {
      case '--prepare':
         // handle version stuff
         $sql = "SELECT config_value FROM ${table_prefix}config WHERE config_name = 'version'";
         $result = $db->sql_query($sql);
         $row = $db->sql_fetchrow($result);
         $installedVersion = $row['config_value'];
         print("Installed version: $installedVersion" . PHP_EOL);

         // phpBB has major, minor and maintenance version scheme
         list($major, $minor, $patch) = explode('.', $installedVersion);
         if ((intval($major) != 3) || (intval($minor) != 2)) {
            echo "This script only supports phpBB 3.2 branch.", PHP_EOL;
            exit(1);
         }


         // ok, start update
         $now = date('d.m.Y H:i');
         $disableMsg = "Softwareupdate am $now, das Bord ist kurzzeitig nicht erreichbar.";
         $sql = "UPDATE ${table_prefix}config SET config_value = '$disableMsg' WHERE config_name = 'board_disable_msg'";
         $result = $db->sql_query($sql);
         echo "Disable Message set …", PHP_EOL;

         $sql = "UPDATE ${table_prefix}config SET config_value = '1' WHERE config_name = 'board_disable'";
         $result = $db->sql_query($sql);
         echo "Board disabled …", PHP_EOL;

         // clear cache
         $data_global_cache = $phpbb_root_path . '/cache/data_global.' . $phpEx;

         if (file_exists($data_global_cache)) {
            unlink($data_global_cache);
            echo "Cache cleared …";
         }


         // http://version.phpbb.com/phpbb/versions.json
         $json = file_get_contents('http://version.phpbb.com/phpbb/versions.json');
         $versions = json_decode($json);
         $currentVersion = $versions->{'stable'}->{'3.2'}->{'current'};
         print("Current version: $currentVersion" . PHP_EOL);

         // check for existing update
         if (!file_exists('dist')) {
            echo "'dist' folder is missing, create a new one …'";
            mkdir ('dist');
         }
         $currentFile = "phpBB-$currentVersion-deutsch.tar.bz2";
         $filePath = "http://downloads.phpbb.de/pakete/deutsch/3.2/$currentVersion/$currentFile";
         $target = "dist/$currentFile";

         if (!file_exists($target)) {
            print("Downloading $currentFile");
            $phpBBtbz = file_get_contents($filePath);
            file_put_contents($target, $phpBBtbz);
         } else {
            print("File exists: $currentFile" . PHP_EOL);
            if (!confirm('Use this copy and continue?')) {
               echo "Aborted due to user request.", PHP_EOL;
               exit(1);
            }

         }
         $data  = new PharData($target);
         try {
            unset($data['phpBB3/config.php']);
            unset($data['phpBB3/.htaccess']);
         } catch (Exception $e) {
            echo 'error: ', $e;
         }

         // check for enabled extensions
         $sql = "SELECT ext_name FROM ${table_prefix}ext WHERE ext_active = '1'";
         $result = $db->sql_query($sql);
         $rows = $db->sql_fetchrowset($result);
         if (count($rows) > 0) {
            $rows = json_encode($rows);

            // safe enabled extensions
            $ofile = fopen('extensions.txt', 'w');
            fputs($ofile, $rows);
            fclose($ofile);

            // disable all extensions
            $sql = "UPDATE ${table_prefix}ext SET ext_active = '0' WHERE ext_active = '1'";
            $result = $db->sql_query($sql);
         }

         // disable all styles but prosilver
         $sql = "UPDATE ${table_prefix}styles SET style_active = '0' WHERE NOT style_name = 'prosilver'";
         $result = $db->sql_query($sql);

         // remove all old files
         $excludes = array(
            'config.php',
            '.htaccess',
            '.htpasswd',
            'images',
            'files',
            'ext',
            'styles',
            'store',
            'updates',
            'mobiquo');
         // this will fuck up nearly all modified boards, leave the files alone by default
         //         deleteDirectory($phpbb_root_path, $excludes);


         try {
            // $data->extractTo($phpbb_root_path, 'phpBB3');
            // does not work due to php bug:
            // https://bugs.php.net/bug.php?id=54289
            $data->extractTo($phpbb_root_path);

            $fromDir = $phpbb_root_path . 'phpBB3/';
            $toDir = $phpbb_root_path;

            copyDirectory($fromDir, $toDir);
            deleteDirectory($fromDir);

         } catch (Exception $e) {
            print("Error while extracting $data: $e");
            exit(1);
         }
         echo 'Moved the update in place.', PHP_EOL;

         echo 'Check fileowner', PHP_EOL;
         print("You might need to perform 'chown -R $fileownerName:$filegroupName $phpbb_root_path'" . PHP_EOL);

         echo 'prepare config.yml.', PHP_EOL;
         $oFile = fopen($phpbb_root_path . '/install/config.yml', 'w');
         fputs($oFile, 'updater:' . PHP_EOL . "        type: db_only" . PHP_EOL);
         fclose($oFile);
         echo "Now head over to ${phpbb_root_path}install and execute 'php phpbbcli.php update config.yml'", PHP_EOL;
         echo "After, return here and finish the update by excuting php $argv[0] --finish", PHP_EOL;
         exit(0);
      break;

      case "--finish":
         if (confirm('Remove the install directory?')) {
            deleteDirectory($phpbb_root_path . 'install');
         }

         $sql = "UPDATE ${table_prefix}config SET config_value = '0' WHERE config_name = 'board_disable'";
         $result = $db->sql_query($sql);

         echo "Board reenabled …", PHP_EOL;

         // clear cache
         $data_global_cache = $phpbb_root_path . '/cache/production/data_global.' . $phpEx;

         if (file_exists($data_global_cache)) {
            unlink($data_global_cache);
            echo "Cache cleared …", PHP_EOL;
         }
         echo "Your board should now be up and running, you might want to reeanble the extensions using php $argv[0] --reenable-extensions", PHP_EOL;
         exit(0);
      break;
      case "--reenable-extensions":
         $extensionsFile = 'extensions.txt';

         if (file_exists($extensionsFile)) {
            $iFile = fopen($extensionsFile, 'r');
            $extensions = json_decode(fgets($iFile), true);

            echo 'Enable extensions: ';

            foreach($extensions as $extension) {
               $ext = $extension['ext_name'];
               // disable all extensions
               $sql = "UPDATE ${table_prefix}ext SET ext_active = '1' WHERE ext_name = '$ext'";
               $result = $db->sql_query($sql);
               echo '.';
            }
            echo 'done.', PHP_EOL;

            // clear cache
            $data_ext_cache = $phpbb_root_path . '/cache/production/data_ext.' . $phpEx;

            if (file_exists($data_ext_cache)) {
               unlink($data_ext_cache);
               echo "Cache cleared …", PHP_EOL;
            }

         } else {
            echo 'There are no saved extension information available.', PHP_EOL;
         }
         exit(0);
      break;

      default:
         echo "unknow option $argv[1]", PHP_EOL;
      exit(1);
   }
} else {
   echo "$argv[0]: missing parameter", PHP_EOL;
   echo 'Usage:', PHP_EOL;
   echo 'To perfom an update, you need two steps. Fist prepare the board for the update:', PHP_EOL;
   echo "php $argv[0] --prepare", PHP_EOL;
   echo 'Then perform the DB update with the CLI tool from phpBB, after:', PHP_EOL;
   echo "php $argv[0] --finish", PHP_EOL;
   echo "Additional steps:", PHP_EOL;
   echo "php $argv[0] --reenable-extensions", PHP_EOL;
//   echo "php $argv[0] --reenable-styles", PHP_EOL;
//   really?
   exit(0);
}

Benutzeravatar
Melmac
Supporter
Supporter
Beiträge: 2916
Registriert: 15.10.2012 03:27

Re: [3.2] CLI update

Beitragvon Melmac » 24.02.2018 19:07

Hi,

vielleicht beschreibst Du kurz, was genau Dein Script macht - für diejenigen, die Dein Script zwar nicht "lesen" können, es aber dennoch für das nächste Update einsetzen wollen/werden.

btw:
tracer hat geschrieben:Ach ja, den ganz blöden Tipp B.1. (alles löschen ausser …) habe ich mal ganz schnell totgestellt, der schiesst ja so ziemlich jedes Bord ins aus, ausser man hat NULL Altlasten

Dass dies die Voraussetzung für diese Updatemethode ist, steht allerdings auch in der Anleitung drin ...
Was für die Masse der Anwender auch zutreffen dürfte.
Handle nur nach derjenigen Maxime, durch die du zugleich wollen kannst, dass sie ein allgemeines Gesetz werde.
(Immanuel Kant)

Benutzeravatar
tracer
Mitglied
Beiträge: 83
Registriert: 02.12.2004 21:37
Wohnort: Kollmar
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon tracer » 24.02.2018 19:19

Melmac hat geschrieben:Hi,

vielleicht beschreibst Du kurz, was genau Dein Script macht - für diejenigen, die Dein Script zwar nicht "lesen" können, es aber dennoch für das nächste Update einsetzen wollen/werden.


Ah, ja, OK.

Also, im Endeffekt automatisiert das Skript alle Schritte aus dem Dokument: https://www.phpbb.de/kb/update32x
Es fällt nur das Hin- und Hersprignen im Dokument weg.


btw:
tracer hat geschrieben:Ach ja, den ganz blöden Tipp B.1. (alles löschen ausser …) habe ich mal ganz schnell totgestellt, der schiesst ja so ziemlich jedes Bord ins aus, ausser man hat NULL Altlasten

Dass dies die Voraussetzung für diese Updatemethode ist, steht allerdings auch in der Anleitung drin ...
Was für die Masse der Anwender auch zutreffen dürfte.

Mir liegen da keine Erfahrungswerte vor, aber die Bords die ich kenne haben teilweise noch 3.0.x Altlasten …

Wer sich sicher ist, was er tut …

Code: Alles auswählen

         // this will fuck up nearly all modified boards, leave the files alone by default
         //         deleteDirectory($phpbb_root_path, $excludes);


Das sind die Zeilen 233 und 234, einfach die "//" in Zeile 234 entfernen …
In Ergänzung zum KB Eintrag "überleben" hier auch .htpasswd und Tapatalk.


Danke auf jeden Fall fürs feedback.

Benutzeravatar
Melmac
Supporter
Supporter
Beiträge: 2916
Registriert: 15.10.2012 03:27

Re: [3.2] CLI update

Beitragvon Melmac » 24.02.2018 19:34

tracer hat geschrieben:Also, im Endeffekt automatisiert das Skript alle Schritte aus dem Dokument: https://www.phpbb.de/kb/update32x

Alle?
Dort werden 3 verschiedene Update-Methoden genannt: welche wird hier jetzt automatisiert?

tracer hat geschrieben:Mir liegen da keine Erfahrungswerte vor, aber die Bords die ich kenne haben teilweise noch 3.0.x Altlasten …

Und wie stellt Dein Script sicher, dass keine dieser "Altlasten" mit der aktuellen phpBB- und/oder PHP-Version kollidieren?
Zwischen 3.0 und 3.2 hat sich eine ganze Menge an Code geändert ...
Du kannst also davon ausgehen, dass dieser hinzugefügte "Altcode", wenn überhaupt, nur noch in geringen Umfang mit 3.2 kompatibel ist.

Wie geht das Script mit den modifizierten Files um?
Handle nur nach derjenigen Maxime, durch die du zugleich wollen kannst, dass sie ein allgemeines Gesetz werde.
(Immanuel Kant)

Benutzeravatar
tracer
Mitglied
Beiträge: 83
Registriert: 02.12.2004 21:37
Wohnort: Kollmar
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon tracer » 24.02.2018 19:42

Melmac hat geschrieben:
tracer hat geschrieben:Also, im Endeffekt automatisiert das Skript alle Schritte aus dem Dokument: https://www.phpbb.de/kb/update32x

Alle?
Dort werden 3 verschiedene Update-Methoden genannt: welche wird hier jetzt automatisiert?

Na, das CLI-Update, so wie der Threadtitel andeutet:)

tracer hat geschrieben:Mir liegen da keine Erfahrungswerte vor, aber die Bords die ich kenne haben teilweise noch 3.0.x Altlasten …

Und wie stellt Dein Script sicher, dass keine dieser "Altlasten" mit der aktuellen phpBB- und/oder PHP-Version kollidieren?

Das Script bricht ab, wenn die installierte Version nicht 3.2.x ist.
Also, wer, wie ich bis dato immer den Anweisungen im ACP gefolgt ist, sollte damit zurechtkommen können.

Zwischen 3.0 und 3.2 hat sich eine ganze Menge an Code geändert ...
Du kannst also davon ausgehen, dass dieser hinzugefügte "Altcode", wenn überhaupt, nur noch in geringen Umfang mit 3.2 kompatibel ist.

Wie geht das Script mit den modifizierten Files um?

Gar nicht.
Aber das, was bis 3.2 "überlebt" hat, wird auch weiterhin funktionieren. Ich habe bis jetzt auf jeden Fall noch nicht gegenteiliges gefunden.

Das keine Mods aus 3.0-Zeiten mehr laufen sollte klar sein, aber viele Scripte, die so "drumherum" gecoded wurden, laufen mit dem 3.0-Code immer noch.

Und nicht jeder hat Zeit oder KnowHow, daraus Extensions zu machen.

Benutzeravatar
BNa
Valued Contributor
Beiträge: 2339
Registriert: 12.04.2010 23:51
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon BNa » 25.02.2018 02:03

Danke @ tracer :grin:

Benutzeravatar
tracer
Mitglied
Beiträge: 83
Registriert: 02.12.2004 21:37
Wohnort: Kollmar
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon tracer » 25.02.2018 12:27

BNa hat geschrieben:Danke @ tracer :grin:

Gerne.

Hast Du es schon ausprobiert?

Wenn ja, lief es ohne Probleme?

Benutzeravatar
schnagga
Mitglied
Beiträge: 732
Registriert: 10.03.2006 18:26
Wohnort: Verden
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon schnagga » 25.02.2018 16:37

Also für mich hört sich das total genial an. Beim nächsten Update werde ich das sicher testen.
Auch von mir: DANKE !
Ein Tischtennis-Forum aus Verden

Benutzeravatar
canonknipser
Supporter
Supporter
Beiträge: 1511
Registriert: 10.09.2011 11:14
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon canonknipser » 28.02.2018 10:10

Sieht grundsätzlich gut aus. Aber warum "verschonst" du das mobiquo-Verzeichnis? Mal abgesehen davon, dass ich von Tapatalk nichts halte und es mir unter 3.1/3.2 nicht weiter angeguckt habe - sollte die aktuelle Tapatalk-Extension nicht auch in das ext-Verzeichnis gehen? Oder machen die immer noch ein "Board neben dem Board"?
Noch ein paar weitere Anmerkungen zum Coding: Solltest du aus Gründen der Wartbarkeit nicht besser mit Konstanten / Variablen am Anfang des Scriptes arbeiten?
Du hast an mehreren Stellen relativ weit unten "Magic Numbers" definiert, z.B. für die Versionsnummer (Vergleich mit major und minor) oder auch Variablen wie den Dateinamen und die URL der Pakete.

Ein kleines Problem sehe ich noch: Anstelle die Extensions alle auf einen Schlag wieder zu aktivieren, sollte das besser über eine Liste der vor dem Update aktiven Extensions erfolgen (ich habe z.B. ein paar Extensions installiert und wieder deinstalliert, aber nicht via "delete data" und Löschen wieder rausgeworfen. Die würden dann durch dein Script unbeabsichtigt wieder aktiviert.)
. Ggf. sind einige auch nicht mehr komplett kompatibel zu der neuen phpBB-Version und sollten besser deaktiviert bleiben.


Ansonsten eine klasse Idee.
Grüße, canonknipser
"there are only 10 types of people: those, who understand binary and those, who don't"
just arrived ;) - Bilder
Kein Support via PN, nur im Board und (manchmal) im IRC

Benutzeravatar
tracer
Mitglied
Beiträge: 83
Registriert: 02.12.2004 21:37
Wohnort: Kollmar
Kontaktdaten:

Re: [3.2] CLI update

Beitragvon tracer » 28.02.2018 10:35

canonknipser hat geschrieben:Sieht grundsätzlich gut aus. Aber warum "verschonst" du das mobiquo-Verzeichnis? Mal abgesehen davon, dass ich von Tapatalk nichts halte und es mir unter 3.1/3.2 nicht weiter angeguckt habe - sollte die aktuelle Tapatalk-Extension nicht auch in das ext-Verzeichnis gehen? Oder machen die immer noch ein "Board neben dem Board"?

Ich bin davon ausgegangen, dass das verzeichnis immer noch benutzt wird, habe es für 3.2 aber tatsächlich noch nicht verifiziert, weil ich selber tapatalk auch nicht nutze.
Werde ich im Laufe des Tages nachholen.
Noch ein paar weitere Anmerkungen zum Coding: Solltest du aus Gründen der Wartbarkeit nicht besser mit Konstanten / Variablen am Anfang des Scriptes arbeiten?
Du hast an mehreren Stellen relativ weit unten "Magic Numbers" definiert, z.B. für die Versionsnummer (Vergleich mit major und minor) oder auch Variablen wie den Dateinamen und die URL der Pakete.

Ja, das macht durchaus Sinn, werde ich nachholen.
Dafür habe ich den Thread hier aufgemacht, und um feedback gebeten.
Für mich taugt das Teil wie es soll, ist dafür sogar schon "zu komfortabel".
Aber ich dachte mir, ich bin nicht der einzige, der sich über das aktuelle Update-verfahren geärgert hat.

Ein kleines Problem sehe ich noch: Anstelle die Extensions alle auf einen Schlag wieder zu aktivieren, sollte das besser über eine Liste der vor dem Update aktiven Extensions erfolgen (ich habe z.B. ein paar Extensions installiert und wieder deinstalliert, aber nicht via "delete data" und Löschen wieder rausgeworfen. Die würden dann durch dein Script unbeabsichtigt wieder aktiviert.)

Äh, nicht durch meins :)

Schau mal die Zeilen 290 bis 315 an. Da passiert genau das.

Code: Alles auswählen

         if (file_exists($extensionsFile)) {
            $iFile = fopen($extensionsFile, 'r');
            $extensions = json_decode(fgets($iFile), true);

            echo 'Enable extensions: ';

            foreach($extensions as $extension) {
               $ext = $extension['ext_name'];
               // disable all extensions
               $sql = "UPDATE ${table_prefix}ext SET ext_active = '1' WHERE ext_name = '$ext'";
               $result = $db->sql_query($sql);
               echo '.';
            }
            echo 'done.', PHP_EOL;

            // clear cache
            $data_ext_cache = $phpbb_root_path . '/cache/production/data_ext.' . $phpEx;

            if (file_exists($data_ext_cache)) {
               unlink($data_ext_cache);
               echo "Cache cleared …", PHP_EOL;
            }

         } else {
            echo 'There are no saved extension information available.', PHP_EOL;
         }

. Ggf. sind einige auch nicht mehr komplett kompatibel zu der neuen phpBB-Version und sollten besser deaktiviert bleiben.

Idealerweise stellt man das vorher im Entwicklungsboard fest.
"Totalausfälle" mit Extension hatte ich noch nie, maximal musste man die Extension gezielt deaktivieren, dafür kann ich das Script aber erweitern.

Ansonsten eine klasse Idee.

Danke schön. Mit solchem feedback macht es gleich doppelt Spaß, solche homebrew Sachen mit anderen zu teilen.
Davon habe ich noch einige in der Pipeline, wobei da noch ein paar andere Sachen zu klären sind.

Werden eigentlich Extensions validiert, die sich "vorsätzlich" nicht an die Coding-Styleguides vom phpBB halten?
Ich finde die teilweise unzumutbar, und werde meinen Stil, den ich seit über 20 Jahre habe nicht ändern.


Zurück zu „Support-Forum“