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.

Zaszufladkowano do kategorii stdout | Otagowano | Możliwość komentowania Aktualizacja do Nextcloud 14 została wyłączona

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.

Zaszufladkowano do kategorii stdout | Otagowano , , | Możliwość komentowania Nextcloud i Nautilus została wyłączona

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ę.

Zaszufladkowano do kategorii #!/kody, stdout | Otagowano , , | Możliwość komentowania Mała strona z Pythonem została wyłączona

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

Zaszufladkowano do kategorii podkasty | Otagowano , , , , , | Możliwość komentowania Baszarek 6 – Wsteczna Refaktoryzacja została wyłączona

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.

Zaszufladkowano do kategorii stdout | Otagowano | Możliwość komentowania Audacity, Fedora 28, nvidia została wyłączona

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.

Zaszufladkowano do kategorii stdout | Możliwość komentowania Gnome i ostatnie aplikacje została wyłączona

Baszarek 5: Zwykłe Narzędzia

Wracamy do słuchania. Dzisiaj zajmiemy się wpływem narzędzi, których używam do programowania, na cały swój „warsztat” oraz, co nie było dla mnie wcześniej całkiem oczywiste, pisania zupełnie różnego kodu.

ściągnij odcinek | posłuchaj przez youtube

Zaszufladkowano do kategorii podkasty | Otagowano , | Możliwość komentowania Baszarek 5: Zwykłe Narzędzia została wyłączona

Pad serwera na OVH

Dzisiaj wieczorem udało mi się „przyłapać” OVH na niedostępności serwera. Przeglądając panel klietna zauważyłem, że z moim VPSem wszystko jest w porządku, a ssh zgłaszał przy próbie połączenia

ssh: connect to host ip.ip.ip.ip port 22: Network is unreachable

Jest to o tyle pocieszające, że po prostu coś się stało ze switchem po drodze. W tego typu przypadkach pewną pomocą może być strona http://travaux.ovh.com/vms/index_gra1.html , gdzie widać na bieżąco co się dzieje w serwerowniach.

Zaszufladkowano do kategorii stdout | Możliwość komentowania Pad serwera na OVH została wyłączona

Bash i zawijanie linii

Bash ma historię wpisywanych w terminal rzeczy. To bardzo dobrze. Używając strzałek w górę oraz w dół można przeglądać ostatnio wpisywane rzeczy. To również bardzo dobrze. W czym więc problem? Skąd właściwie bash wie, gdzie kończy się nasz prompt, a zaczyna historia? Skąd wie, gdzie umieścić znaki polecenia, które przekracza jedną linię?

Ano może sobie policzyć na której kolumnie terminala kończy się prompt, a na której zaczyna moje pisanie. Problem jest taki, że Bash liczy sobie znaki niedrukowane, na przykład kody kolorów, czy inne tego typu rzeczy. Oczywiście rachunek wychodzi błędnie, ponieważ ilość znaków w PS1 nie równa się tym wypisywanym na terminalu. Wynikiem tego są takie kwiatki:

[ lukasz@GAZEvim .bashrc

Jak temu zaradzić? Obszerne wyjaśnienie problemu jest na stronie Stack Exchange. Ja podam tylko wybrane przeze mnie rozwiązanie, polegające na wyciągnięciu niedrukowanych znaków do zmiennych i opatrzeniu ich numerkami:

green="\001$(tput setaf 2)\002"
blue="\001$(tput setaf 4)\002"
dim="\001$(tput dim)\002"
reset="\001$(tput sgr0)\002"
PS1="$green\u@\h $blue $ \n  $green->$reset  "
export PS1
unset green blue dim reset

Ło matko, co to jest? W zmiennych z kolorami oraz zmiennej resetującej kolor tłumaczymy Bashowi jak krowie na polu, że $(tput setaf 2) ma liczyć jako jeden znak. Czy te zmienne są niezbędne? Nie, ale bez nich czytelność linijki PS1 byłaby niewielka. Nazwy tych zmiennych oraz kolory ustawiane setafem nie mają oczywiście znaczenia. Dzięki nim unikamy znaków niedrukowanych w prompcie i bash wie, gdzie zacząć moje pisanie.

Zaszufladkowano do kategorii #!/kody | Otagowano , | Możliwość komentowania Bash i zawijanie linii została wyłączona