Linux dla leworęcznych

Nauczyłem się obsługiwać myszkę lewą ręką. Prawa czasem pobolewa mnie po pracy, więc pomyślałem, że czas na zmianę. Wszystko generalnie działa, ale skróty klawiszowe, których Gnome ma coś około osiemdziesięciu i są naprawdę przydatne, są zaprojektowane pod używanie ich lewą ręką. Z pomocą przyszły stare, dobre Xsy. Podawany przeze mnie sposób nie zadziała na Waylandzie.

Najpierw sprawdzam jak wygląda moja klawiatura w Xsach:

xmodmap -pke

Następnie zmapowałem klawisze:

  • NUM7 jako F4,
  • NUM8 jako lewy ALT,
  • NUM4 jako TAB,
  • NUM0 jako WINDOWS,
  • NUM2 jako c,
  • NUM3 jako v.

Zapisałem to sobie w krótkim skrypcie shella, który z czasem będzie pewnie rozbudowywany:

#!/usr/bin/sh
# mapowanie klawiatury dla lewej reki
xmodmap -e "keycode 79 = F4 F4 F4 F4 F4 F4 XF86Switch_VT_4"
xmodmap -e "keycode 90 = Super_L"
xmodmap -e "keycode 88 = c"
xmodmap -e "keycode 89 = v"
xmodmap -e "keycode 80 = Alt_L"
xmodmap -e "keycode 83 = Tab ISO_Left_Tab Tab ISO_Left_Tab"

Po dwóch dniach przyzwyczajania pracuje mi się z tym wspaniale. Lewa ręka jest na myszcze, a prawa na klawiaturze numerycznej. Jednego, czego brakuje to lewego CRTL, którego chcę mieć pod jedynką, ale nie mogę go prawidłowo zmapować. Dopiszę, kiedy mi się to uda.

LibreOffice z Rawhide

Jest sobie Fedora 29 i jest Libre Office 6.2. Pozornie patowa sytuacja, bo nowego Libre dostanie Fedora 30, a ja chcę teraz. Mam kilka możliwości. Mogę ściągnąć program jako Flatpaka, albo Snapa. Jeżeli jednak mam do wyboru program z repozytorium, to wolę rpmy.

Zajrzymy do Rawhide i „pożyczymy” sobie z niego LibreOffice. Potrzebujemy pliku /etc/yum.repos.d/fedora-rawhide.repo:

[rawhide]
name=Fedora - Rawhide - Developmental packages for the next Fedora release
failovermethod=priority
baseurl=http://download.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/$basearch/os/
metalink=https://mirrors.fedoraproject.org/metalink?repo=rawhide&arch=$basearch
enabled=0
metadata_expire=6h
repo_gpgcheck=0
type=rpm
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
skip_if_unavailable=False

Usunąłem LibreOffice, żeby zależności również mieć z Rawhide:

sudo dnf remove *libreoffice*

A potem zainstalowałem nowszego:

sudo dnf --enablerepo=rawhide install libreoffice-writer libreoffice-calc libreoffice-impress libreoffice-langpack-pl

I na tym koniec. Plik fedora-rawhide.repo można zostawić tak jak jest, ponieważ ma linijkę enabled=0. Przy aktualizacji Fedory z czasem wersja stable nadgoni Libre Office i zaktualizuje go jak każdy inny pakiet.

Aktualizacja do Nextcloud 14

Jeżeli hostujesz Nextclouda 13 i skrypt sam z siebie nie wykrywa dostępnej aktualizacji do wersji 14, wszystko jest w porządku. Wersja 14.0 miała mały błąd, pojawiający się na kontach użytkowników ze spacją w nazwie. Wszystko jest naprawione, ale aktualizacje wydawane są „falami” dla kont i hostingów przewidzianych w nie wiem jaki sposób.

Można to obejść przełączając się na kanał beta w aktualizacjach. W kanale beta na obecną chwilę jest wersja 14.0.3, do której aktualizujemy Nextclouda tak, jak zawsze. Jeżeli używasz mailera z PHP do zmiany haseł i innych powiadomień, dostaniesz informację o konieczności wybrania innego serwera pocztowego. Może to być cokolwiek, konfiguruje się to tak samo jak Thunderbirda, Outlooka, czy Evolution.

Po aktualizacji możemy zmienić nasz kanał aktualizacji do stable, które niebawem nadgonią obecnie zainstalowaną wersję. Jeżeli brakuje nam miejsca na dysku, warto też usunąć stare kopie zapasowe z katalogu nextcloud/data/updater-[losowe_znaki]/backups/. Ja zawsze zostawiam tylko jeden, czy dwa ostatnie, gdyż zajmują sporo miejsca.

Nextcloud i Nautilus

Gnomowy menedżer plików ma kilka zalet, na przykład umiejętność podpinania się pod wszelkiego rodzaju zasoby sieciowe, bez potrzeby dłubania w /etc/fstab.

Z Nextcloudem może być trudniej, bowiem, w przypadku samodzielnego wygenerowania sobie certyfikatu ssl do bezpiecznych połączeń (a tak u mnie jest) Gnomowy kreator Konta Online odmawia współpracy z certyfikatem nieznanego pochodzenia. Na szczęście można wklepać ścieżkę do Nautilusa i działa. Jaka to ścieżka?

davs://domena.pl/remote.php

Nautilus również zwróci uwagę, że certyfikat pochodzi z nieznanego źródła, ale pliki pokaże. Login i hasło są takie same, jak logowanie do Nextclouda.

Mała strona z Pythonem

Ostatnio dłubię sobie stronę do obsługi programu javowego MegaMek. Jest tutaj: https://github.com/seem8/astech. Oczywiście pierwszym problemem było: w jakim pythonowym frameworku to zrobić? Jest Django, jest Flask, jest Bottle, jest Cherrypy, jest Pyramid i jeszcze jakieś 20 działających.

Zauważyłem, że są generalnie dwie kategorie stron internetowych:

  • operujące na dużych ilościach danych,
  • robiące coś fajnego.

Najistotniejsze w pierwszej kategorii jest utrzymanie spójności danych i bardzo szybkie na nich operowanie. Mamy kolekcję rzeczy, albo sklep, albo terminarz, albo bardzo dużo plików, albo coś takiego. I wówczas lepiej sprawdzają się duże frameworki, które pozwalają na tym się właśnie skupić, upraszczające tworzenie formularzy, wyszukiwarek, itp…

W drugiej kategorii ważne jest pozostawienie programiście swobody i generalnie zostawienie go w spokoju. Zauważyłem, że bardzo to lubię. Dlaczego? Bo można po prostu programować w Pythonie i nie przejmować się w ogóle faktem, że będzie to obsługiwane przez przeglądarkę.

Przedstawiam małe demo, które obrazuje powyższe:

#!/usr/bin/env python3

def read_logs(log_file):

  try:
    open(log_file,'r').close()
  except FileNotFoundError:
    open(log_file,'w').close()
    
  with open(log_file,'r') as myfile:
    mylines = myfile.readlines()
    lastlog = mylines[len(mylines)-50 : len(mylines)]
    lastlog.reverse()

    return lastlog

Powiedzmy, że mamy coś takiego. Zwykły kod, który działa wszędzie. Skorzystajmy więc z tej funkcji w programie tekstowym:

#!/usr/bin/env python3

def read_logs(log_file):

  try:
    open(log_file,'r').close()
  except FileNotFoundError:
    open(log_file,'w').close()

  with open(log_file,'r') as myfile:
    mylines = myfile.readlines()
    lastlog = mylines[len(mylines)-50 : len(mylines)]
    lastlog.reverse()

    return lastlog


important_logs = read_logs('journal.txt')

for i in important_logs:
  print(i)

Znowu nic niezwykłego. Wczytałem fragment logów systemowych i wypisałem 50 ostatnich linijek, korzystając z funkcji read_logs. Teraz zróbmy tak samo, ale żeby logi pokazywały się na stronie interenetowej.

#!/usr/bin/env python3

from bottle import template, route, run
def read_logs(log_file):

  try:
    open(log_file,'r').close()
  except FileNotFoundError:
    open(log_file,'w').close()

  with open(log_file,'r') as myfile:
    mylines = myfile.readlines()
    lastlog = mylines[len(mylines)-50 : len(mylines)]
    lastlog.reverse()

    return lastlog

@route('/')
def index_page():
  important_logs = read_logs('journal.txt')
  return template('index_page', logs=important_logs)

run(host='localhost', port=8080)

Tyle Pythona. Bottle używa dekoratorów, żeby określić jaki rodzaj funkcji deklarujemy: get, post, route, czy jeszcze jakiś inny. Jako „parametr” dekoratora wpisujemy ścieżkę, którą wpiszemy do przeglądarki. W tym wypadku po wpisaniu w pasek adresu localhost:8080 pokażą się nasze logi. Template potrzebuje co najmniej jednej informacji: jak ma się nazywać plik z końcówką .tpl, w którym będzie kod html. Oprócz tego możemy przekazać dowolną ilość argumentów, które pozwolą szablonowi na dostęp do naszych zmiennych oraz funkcji. Zmienna jest dla szablonu, a wartość to coś z naszego kodu Pythona, którą może być wszystko: zmienna, funkcja z parametrami, egzemplarz klasy, czy cokolwiek sobie umyślimy.

Musi to być jeszcze zrozumiałe dla przeglądarki, więc mamy do tego, wspomniany w kodzie, osobny plik index_page.tpl:

<html>
<head>
<title>Important Logs</title>
<head>
<body>

% for i in logs:
<p>{{i}}</p>
% end

</body>
</html>

Jest tutaj odrobina magicznych rzeczy:

  • znakiem % rozpoczynamy linijkę zawierającą kod Pythona,
  • na zmiennych w kodzie html operujemy poprzez konstrukcję {{zmienna}},
  • jako, że html ignoruje białe znaki, a Python ich właśnie używa do „kończenia” instrukcji for/if/def/itd…, korzystamy ze słowa kluczowego end, żeby wyjść z pętli.

Ścieżką może to być ‚/’, ‚/login’, albo ‚/read_logs/<log_file>’, co pozwala na przekazywanie argumentów na poziomie hiperłączy. Mógłbym więc rozpisać funkcję index_page w ten sposób:

@route('/read_logs/<log_file>')
def index_page(log_file):
  important_logs = read_logs(log_file)
  return template('index_page', logs=important_logs)

Wówczas łącze do przeglądarki wyglądałoby tak: http://localhost:8080/read_logs/journal.txt. Oczywiście jeżeli pozostawiamy cokolwiek użytkownikowi, zwłaszcza w internecie, trzeba się odpowiednio zabezpieczyć, ale o ciasteczkach i logowaniu napiszę innym razem.

Jeżeli ktoś widział kiedyś kod Django, to zapewne czuje już różnicę. To jest bardzo, bardzo proste. Pozwala mi skupić się na logice programu, który czasem robi dziwne rzeczy i nie stawia mi na drodze plików konfiguracyjnych oraz mnóstwa modułów. W dużym programie prędzej czy później taka swoboda odbija się czkawką (i poczułem to na sobie), ale w małym programie, tak do 1000 wierszy, robi świetną robotę.

Baszarek 6 – Wsteczna Refaktoryzacja

Zapraszam do posłuchania o programiście, który chciał za dużo na raz i jak się uratować z tej sytuacji. Może to też sposób dla Ciebie, może nie, ale mi pomogło i jestem ponownie szczęśliwym człowiekiem z projektem, który po długiej przerwie (a właściwie zatoczywszy duże koło) ruszył do przodu.

ściągnij mp3

Audacity, Fedora 28, nvidia

Natrafiłem niedawno na ciekawy błąd związany z Audacity po instalacji sterowników Nvidii. Po prostu się nie uruchamiał. Na terminalu wypisywał do enigmatyczny dla mnie błąd związany z biblioteką libavutil. Ardour co prawda działa dobrze, ale zdecydowanie przerósł moje oczekiwania. Postanowiłem spróbować przebudować pakiet źródłowy pobrany z Rpmfusion i już działa:

Do działania potrzeba tylko tego pierwszego, ale dla porządku wysłałem wszystkie. Pamiętajcie jeszcze, żeby ustawić w audacity prawidłowe wyjście dźwięku, bowiem po instalacji sterowników mamy również do dyspozycji hdmi na karcie grafiki.

Gnome i ostatnie aplikacje

Pulpit Gnome zapamiętuje sobie ostatnio używane programy. Czasem włączam sobie aplikacje korzystając z tej listy, więc nie lubię, kiedy coś mi się przypadkowo kliknie i ją zaśmieca. Lista jest trzymana w pliku ~/.local/share/gnome-shell/applications_state. Przykładowa linijka wygląda tak:

application id="vlc.desktop" open-window-count="0" score="239" last-seen="1532620310"/

Wystarczy więc ją usunąć i po następnym logowaniu (lub restarcie alt+F2, r, enter, jeżeli korzystasz z serwera X, a nie Wayland) Vlc nie będzie już na liście.