Pages

Saturday, December 28, 2024

Fedora 41 : Flutter first steps ...

Today, I tested flutter starting steps on Fedora 41.
You can find a good tutorial on the Fedora Magazine.
$ uname -a
Linux fedora 6.12.5-200.fc41.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Dec 15 16:48:23 UTC 2024 x86_64 GNU/Linux
mythcat@fedora:~$ sudo su 
[sudo] password for mythcat: 
root@fedora:/home/mythcat# dnf5 clean all
Removed 53 files, 35 directories. 0 errors occurred.
root@fedora:/home/mythcat# dnf5 update
...
root@fedora:/home/mythcat# dnf5 install bash curl file git unzip which xz zip mesa-libGLU clang cmake ninja-build pkg-config
...
root@fedora:/home/mythcat# exit
exit
mythcat@fedora:~$ mkdir ~/FlutterProjects
mythcat@fedora:~$ cd FlutterProjects/
mythcat@fedora:~/FlutterProjects$ wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.16.9-stable.tar.xz
Saving 'flutter_linux_3.16.9-stable.tar.xz'
HTTP response 200  [https://storage.googleapis.com/flutter_infra_release/releaseflutter_linux_3.16.9 100% [=============================>]  627.00M   10.42MB/s
                          [Files: 1  Bytes: 627.00M [9.41]
...
mythcat@fedora:~/FlutterProjects$ tar xf flutter_linux_3.16.9-stable.tar.xz
mythcat@fedora:~/FlutterProjects$ ll
total 642064
drwxr-xr-x. 11 mythcat mythcat      4096 Jan 25  2024 flutter
-rw-r--r--.  1 mythcat mythcat 657467644 Jan 25  2024 flutter_linux_3.16.9-stable.tar.xz
mythcat@fedora:~/FlutterProjects$ export PATH="$PATH:`pwd`/flutter/bin"
mythcat@fedora:~/FlutterProjects$ cd flutter/bin/
mythcat@fedora:~/FlutterProjects/flutter/bin$ pwd
/home/mythcat/FlutterProjects/flutter/bin
mythcat@fedora:~/FlutterProjects$ flutter doctor
mythcat@fedora:~/FlutterProjects$ flutter upgrade
...

Monday, December 16, 2024

Fedora 41 : The cirq python package only with Python 3.12.8.

Today I install the quil python package on Fedora 41, but with an older version of python :
Python 3.12.8 (main, Dec  6 2024, 00:00:00) [GCC 14.2.1 20240912 (Red Hat 14.2.1-3)] on linux
mythcat@localhost:~$ python3.12 -m pip install quil --user
First, install the python version then install the pip tool:
mythcat@localhost:~$ curl https://bootstrap.pypa.io/get-pip.py | python3.12 -
...
Installing collected packages: pip
Successfully installed pip-24.3.1
Next, install with the pip version:
mythcat@localhost:~$ python3.12 -m pip install quil --user
Collecting quil

Saturday, December 14, 2024

Fedora 41 : OpenCV example with PyQt6.

Today I tested another source code with opencv, numpy, PyQt6 python packages.
I install opencv python package with dnf5 tool:
root@localhost:/home/mythcat# dnf5 install  python3-opencv.x86_64
The source code let you to open, change a image and save using sliders and a reset option.
This is the source code:
import sys
import cv2
import numpy as np
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSlider, QFileDialog, QPushButton, QHBoxLayout
from PyQt6.QtGui import QImage, QPixmap
from PyQt6.QtCore import Qt, pyqtSlot

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Real-Time Color Selection")
        self.setGeometry(100, 100, 1200, 800)

        # Create central widget and main layout
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # Create image label
        self.image_label = QLabel()
        main_layout.addWidget(self.image_label)

        # Initialize sliders
        self.lower_h = QSlider(Qt.Orientation.Horizontal)
        self.lower_s = QSlider(Qt.Orientation.Horizontal)
        self.lower_v = QSlider(Qt.Orientation.Horizontal)
        self.upper_h = QSlider(Qt.Orientation.Horizontal)
        self.upper_s = QSlider(Qt.Orientation.Horizontal)
        self.upper_v = QSlider(Qt.Orientation.Horizontal)

        # Set slider ranges
        for slider in [self.lower_h, self.upper_h]:
            slider.setRange(0, 179)
        for slider in [self.lower_s, self.lower_v, self.upper_s, self.upper_v]:
            slider.setRange(0, 255)

        # Set initial slider values
        self.lower_h.setValue(50)
        self.lower_s.setValue(100)
        self.lower_v.setValue(50)
        self.upper_h.setValue(130)
        self.upper_s.setValue(255)
        self.upper_v.setValue(255)

        # Connect sliders to update function
        self.lower_h.valueChanged.connect(self.update_hsv_range)
        self.lower_s.valueChanged.connect(self.update_hsv_range)
        self.lower_v.valueChanged.connect(self.update_hsv_range)
        self.upper_h.valueChanged.connect(self.update_hsv_range)
        self.upper_s.valueChanged.connect(self.update_hsv_range)
        self.upper_v.valueChanged.connect(self.update_hsv_range)

        # Create slider layouts with labels
        sliders_layout = QVBoxLayout()
        
        # Add slider pairs with labels
        slider_pairs = [
            ("Lower Hue", self.lower_h),
            ("Lower Saturation", self.lower_s),
            ("Lower Value", self.lower_v),
            ("Upper Hue", self.upper_h),
            ("Upper Saturation", self.upper_s),
            ("Upper Value", self.upper_v)
        ]

        for label_text, slider in slider_pairs:
            row_layout = QHBoxLayout()
            label = QLabel(label_text)
            label.setMinimumWidth(120)
            row_layout.addWidget(label)
            row_layout.addWidget(slider)
            sliders_layout.addLayout(row_layout)

        main_layout.addLayout(sliders_layout)

        # Add buttons
        button_layout = QHBoxLayout()
        
        self.reset_button = QPushButton("Reset Values")
        self.reset_button.clicked.connect(self.reset_values)
        button_layout.addWidget(self.reset_button)

        self.open_image_button = QPushButton("Open Image")
        self.open_image_button.clicked.connect(self.open_image)
        button_layout.addWidget(self.open_image_button)

        self.save_button = QPushButton("Save Image")
        self.save_button.clicked.connect(self.save_image)
        button_layout.addWidget(self.save_button)
        main_layout.addLayout(button_layout)

        # Process initial image
        self.process_image()

    def process_image(self):
        image_bgr = cv2.imread("image.png")
        if image_bgr is None:
            image_bgr = cv2.imread("default_image.png")
        
        self.image_bgr = image_bgr
        self.image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

        # Create initial mask using current slider values
        lower_values = np.array([self.lower_h.value(), self.lower_s.value(), self.lower_v.value()])
        upper_values = np.array([self.upper_h.value(), self.upper_s.value(), self.upper_v.value()])
        
        mask_test = cv2.inRange(self.image_hsv, lower_values, upper_values)
        image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask_test)
        self.image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
        self.update_image()

    def update_image(self):
        height, width, channel = self.image_rgb.shape
        bytes_per_line = width * channel
        q_image = QImage(self.image_rgb.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
        pixmap = QPixmap.fromImage(q_image)
        self.image_label.setPixmap(pixmap.scaled(700, 500, Qt.AspectRatioMode.KeepAspectRatio))

    def update_hsv_range(self):
        lower_values = np.array([self.lower_h.value(), self.lower_s.value(), self.lower_v.value()])
        upper_values = np.array([self.upper_h.value(), self.upper_s.value(), self.upper_v.value()])
        mask_test = cv2.inRange(self.image_hsv, lower_values, upper_values)
        image_bgr_masked = cv2.bitwise_and(self.image_bgr, self.image_bgr, mask=mask_test)
        self.image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)
        self.update_image()

    def reset_values(self):
        self.lower_h.setValue(50)
        self.lower_s.setValue(100)
        self.lower_v.setValue(50)
        self.upper_h.setValue(130)
        self.upper_s.setValue(255)
        self.upper_v.setValue(255)

    def open_image(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Select Image File", "", "Image Files (*.png *.jpg *.jpeg)")
        if filename:
            self.image_bgr = cv2.imread(filename)
            if self.image_bgr is not None:
                self.image_hsv = cv2.cvtColor(self.image_bgr, cv2.COLOR_BGR2HSV)
                self.update_hsv_range()  # This will apply current filter and update display

    def save_image(self):
        filename, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG Files (*.png);;JPEG Files (*.jpg)")
        if filename:
            # Make sure filename has an extension
            if not filename.endswith(('.png', '.jpg', '.jpeg')):
                filename += '.png'
            # Convert and save
            output_image = cv2.cvtColor(self.image_rgb, cv2.COLOR_RGB2BGR)
            cv2.imwrite(filename, output_image)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

Thursday, December 12, 2024

Fedora 41 : The cirq python package cannot be install - build errors

Today, I tried to use cirq python package on Fedora 41. This need the python version 3.12.
root@localhost:/home/mythcat# dnf install python3.12.x86_6c
I got some errors because ask me to install the rust:
root@localhost:/home/mythcat# curl https://sh.rustup.rs -sSf | sh
info: downloading installer

Welcome to Rust!

This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.

Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:
...
Rust is installed now. Great!

To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).

To configure your current shell, you need to source
the corresponding env file under $HOME/.cargo.

This is usually done by running one of the following (note the leading DOT):
. "$HOME/.cargo/env"            # For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish"  # For fish
These are the next steps I used:
root@localhost:/home/mythcat# pip install --upgrade pip
...
root@localhost:/home/mythcat# pip install maturin
...
root@localhost:/home/mythcat# pip install cirq
...
Collecting cirq
  Using cached cirq-1.4.1-py3-none-any.whl.metadata (7.4 kB)
...
        cargo:rerun-if-env-changed=PYO3_USE_ABI3_FORWARD_COMPATIBILITY
      
        --- stderr
        error: the configured Python interpreter version (3.13) is newer than PyO3's maximum supported version (3.12)
        = help: please check if an updated version of PyO3 is available. Current version: 0.20.3
        = help: set PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 to suppress this check and build anyway using the stable ABI
      💥 maturin failed
        Caused by: Failed to build a native library through cargo
        Caused by: Cargo build finished with "exit status: 101": `env -u CARGO PYO3_ENVIRONMENT_SIGNATURE="cpython-3.13-64bit" PYO3_PYTHON="/usr/bin/python3" PYTHON_SYS_EXECUTABLE="/usr/bin/python3" "cargo" "rustc" "--features" "pyo3/extension-module" "--message-format" "json-render-diagnostics" "--manifest-path" "/tmp/pip-install-v0zuc831/quil_ebc006157dbd433dbc0890811ee80748/quil-py/Cargo.toml" "--release" "--lib" "--crate-type" "cdylib"`
      Error: command ['maturin', 'pep517', 'build-wheel', '-i', '/usr/bin/python3', '--compatibility', 'off'] returned non-zero exit status 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for quil
Failed to build quil
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (quil)
Not working ...

Monday, November 25, 2024

Fedora 41 : assembly fasm with cat command and qemu test.

I tested the basic direct binary concatenation where the second file is appended to the end of the first file, preserving all bytes exactly as they are without any linking metadata or relocations with the cat command.
Let's see how can do this.
You need to create two files: kernel.fasm and kernel2.fasm.
First will like this:
org 7C00h

; First stage bootloader
start:
    mov [bootdrive], dl
    mov ax, 0x2000  ; Load kernel at 0x2000:0
    mov es, ax
    xor bx, bx      ; ES:BX = buffer
    
    mov ah, 02h     ; Read sectors
    mov al, 6       ; Number of sectors to read
    mov ch, 0       ; Cylinder 0
    mov cl, 2       ; Start from sector 2
    mov dh, 0       ; Head 0
    mov dl, [bootdrive]
    int 13h
    
    jmp 0x2000:0    ; Jump to second stage

bootdrive db 0
times 510-($-$$) db 0
dw 0xAA55
The second one named kernel2.fasm will come with new features:
org 0

COLS equ 80
ROWS equ 25
VIDEO_MEM equ 0xB800

; Box drawing characters
BOX_DR    equ 201  ; ╔
BOX_HL    equ 205  ; ═
BOX_DL    equ 187  ; ╗
BOX_VL    equ 186  ; ║
BOX_UR    equ 200  ; ╚
BOX_UL    equ 188  ; ╝
BOX_BLOCK equ 219  ; █
...
Use fasm and cat commands to create the bin files and the result file for qemu:
mythcat@localhost:~/fasm$ ./fasm.x64 kernel.fasm kernel.bin
flat assembler  version 1.73.32  (16384 kilobytes memory, x64)
2 passes, 512 bytes.
mythcat@localhost:~/fasm$ ./fasm.x64 kernel2.fasm kernel2.bin
flat assembler  version 1.73.32  (16384 kilobytes memory, x64)
2 passes, 132 bytes.
mythcat@localhost:~/fasm$ cat kernel.bin kernel2.bin > os.img
The last step is to run qemu-system-i386 to test the result
mythcat@localhost:~/fasm$ qemu-system-i386 -fda os.img
The result is this:

Sunday, November 24, 2024

Fedora 41 : Error gio default application for image.

I run today an old python script in my Fedora 41 to create an image and the result after running was:
mythcat@localhost:~$ python test_001.py 
gio: file:///tmp/tmpwy1k4wyo.PNG: Failed to find default application for content type ‘image/png’
This can be fixed with an default application for images like feh:
$ sudo dnf5 install feh

Fedora 41 : remove package lead to unexpected results.

Today I saw the mutter package from Fedora distro come with a new update.
I don't use this package, ... is a mess in my oppinion.
But I found this output when I tried to remove
root@localhost:/home/mythcat# dnf5 remove mutter 
Package                          Arch   Version                 Reposit      Size
Removing:
 mutter                          x86_64 47.1-3.fc41             updates  12.5 MiB
Removing dependent packages:
 gdm                             x86_64 1:47.0-8.fc41           updates   5.3 MiB
 gnome-shell                     x86_64 47.1-1.fc41             updates  13.8 MiB
Removing unused dependencies:
 accountsservice                 x86_64 23.13.9-5.fc41          fedora  379.5 KiB
 accountsservice-libs            x86_64 23.13.9-5.fc41          fedora  212.3 KiB
 bluez-obexd                     x86_64 5.79-1.fc41             updates 345.1 KiB
 bolt                            x86_64 0.9.8-3.fc41            fedora  503.3 KiB
 boost-thread                    x86_64 1.83.0-8.fc41           fedora  136.8 KiB
 color-filesystem                noarch 1-34.fc41               fedora  151.0   B
 colord                          x86_64 1.4.7-5.fc41            fedora    1.7 MiB
 colord-gtk4                     x86_64 0.3.1-2.fc41            fedora   35.6 KiB
 composefs-libs                  x86_64 1.0.6-1.fc41            fedora  166.3 KiB
 cups-pk-helper                  x86_64 0.2.7-8.fc41            fedora  379.0 KiB
 dbus-daemon                     x86_64 1:1.14.10-4.fc41        fedora  553.2 KiB
 evolution-data-server           x86_64 3.54.1-1.fc41           updates   8.8 MiB
 evolution-data-server-langpacks noarch 3.54.1-1.fc41           updates   8.8 MiB
 flatpak-libs                    x86_64 1.15.10-1.fc41          fedora    1.0 MiB
 ...
 
Is this ok [y/N]: N
 ... 
If I used this command the gdm and gnome-shell is gone:
root@localhost:/home/mythcat# dnf5 remove --noautoremove mutter 
Package                        Arch   Version                   Repository        Size
Removing:
 mutter                        x86_64 47.1-3.fc41               updates       12.5 MiB
Removing dependent packages:
 gdm                           x86_64 1:47.0-8.fc41             updates        5.3 MiB
 gnome-session-wayland-session x86_64 47.0.1-1.fc41             fedora        15.9 KiB
 gnome-shell                   x86_64 47.1-1.fc41               updates       13.8 MiB

Transaction Summary:
 Removing:           4 packages
 
Is this ok [y/N]: N
...
I tried with the --noautoremove, and --exclude args and not result:
root@localhost:/home/mythcat# dnf5 remove --noautoremove --exclude=gnome-shell,gdm mutter
Failed to resolve the transaction:
Problem: installed package gnome-shell-47.1-1.fc41.x86_64 requires libmutter-15.so.0()(64bit), but none of the providers can be installed
  - installed package gnome-shell-47.1-1.fc41.x86_64 requires libmutter-clutter-15.so.0()(64bit), but none of the providers can be installed
  - installed package gnome-shell-47.1-1.fc41.x86_64 requires libmutter-cogl-15.so.0()(64bit), but none of the providers can be installed
  - installed package gnome-shell-47.1-1.fc41.x86_64 requires libmutter-mtk-15.so.0()(64bit), but none of the providers can be installed
  - installed package gnome-shell-47.1-1.fc41.x86_64 requires mutter(x86-64) >= 47.0, but none of the providers can be installed
  - conflicting requests
  - problem with installed package
The solution is old rpm tool:
root@localhost:/home/mythcat# rpm -e --nodeps mutter 
root@localhost:/home/mythcat# dnf5 remove mutter
No packages to remove for argument: mutter

Nothing to do.