Skip to content

Commit

Permalink
Numerous updates and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dmzoneill committed May 18, 2024
1 parent b70b5e7 commit d58af9f
Show file tree
Hide file tree
Showing 16 changed files with 454 additions and 151 deletions.
59 changes: 40 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,31 +1,52 @@
FROM python:3.11
# Stage 1: Build Environment
FROM fedora:40

# Update
RUN apt-get update
# Install necessary packages
RUN dnf update -y && \
dnf install -y python3 python3-pip python3-gobject gtk4 xauth mesa-libGL mesa-dri-drivers

# Install dependencies
RUN apt-get install -y gtk-4-examples libgtk-4-dev python3-gi python3-gi-cairo python3-requests gir1.2-gtk-4.0
# Set user and group IDs
ARG USER_ID
ARG GROUP_ID
ARG USER_NAME=dfakeseeder
RUN groupadd -g ${GROUP_ID} ${USER_NAME} && \
useradd -m -u ${USER_ID} -g ${GROUP_ID} -s /bin/bash ${USER_NAME}

# cleanup
RUN rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app

# Copy the application files into the container
COPY . /app
# Change ownership of directories
RUN chown -R ${USER_NAME}:${USER_NAME} /app
COPY requirements.txt /app/

# Set the working directory
WORKDIR /app
# Create necessary directories and set permissions
RUN mkdir -vp /run/user/${USER_ID}/at-spi /home/${USER_NAME}/.cache /home/${USER_NAME}/.config
RUN chown -R ${USER_NAME}:${USER_NAME} /app /run/user/${USER_ID} /home/${USER_NAME}/.cache /home/${USER_NAME}/.config

# Switch to the created user
USER ${USER_NAME}

# Set environment variables
ENV XDG_RUNTIME_DIR=/run/user/${USER_ID}
ENV LIBGL_ALWAYS_SOFTWARE=1

# Install Python dependencies
RUN pip install -r requirements.txt
RUN pip3 install -r requirements.txt --no-warn-script-location

# Set environment variable to display GUI on the host
ENV DISPLAY=:0
# Copy application code
COPY . /app

# set working directory
WORKDIR /app/d_fake_seeder
# Set display environment variable
ENV DISPLAY=:0
ENV GTK_THEME=Adwaita:dark

# Set environment variable to include the path
# Set Python path
ENV PYTHONPATH="/usr/lib/python3/dist-packages:${PYTHONPATH}"

# Run the Python GTK application
CMD ["python3", "dfakeseeder.py"]
# Mount host's GTK theme configuration directory into the container
VOLUME /usr/share/themes
VOLUME /tmp/.X11-unix

# Set entrypoint command
WORKDIR /app/d_fake_seeder
CMD ["python3", "dfakeseeder.py"]
23 changes: 22 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ RPM_FILENAME := $(rpm_package_name)-$(package_version)
required:
pip3 install -r requirements.txt --break-system-packages


clearlog: required
truncate -s 0 d_fake_seeder/log.log

Expand Down Expand Up @@ -61,6 +60,28 @@ run-debug: ui-build
}
$(MAKE) clean_settings;

run-debug-docker: ui-build
-docker build \
--build-arg USER_ID=$$(id -u) \
--build-arg GROUP_ID=$$(id -g) \
-t dfakeseeder .

-docker ps -a -q --filter "name=dfakeseeder" | xargs -r docker rm -f

xhost +local:root
-docker run --privileged -it --rm \
--name dfakeseeder \
-e LOG_LEVEL=INFO \
-e DFS_PATH=/app \
-e DISPLAY=$$DISPLAY \
-v $$HOME/.config/dfakeseeder:/home/dfakeseeder/.config/dfakeseeder \
-v $$(pwd):/app \
-v /tmp/.X11-unix:/tmp/.X11-unix \
dfakeseeder
xhost -local:root

$(MAKE) clean_settings;

clean:
- sudo rm -rvf log.log
- sudo rm -rvf d_fake_seeder/log.log
Expand Down
48 changes: 47 additions & 1 deletion d_fake_seeder/lib/component/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ def __init__(self, builder, model):

# tab children
self.status_grid_child = None
self.files_grid_child = None
self.options_grid_children = []

tab_names = [
"status_tab",
"files_tab",
"details_tab",
"options_tab",
"peers_tab",
Expand Down Expand Up @@ -146,11 +148,13 @@ def update_notebook_peers(self, torrent):
row = TorrentPeer(str(peer), client, 0.0, 0.0, 0.0)
self.peers_store.append(row)

self.peers_columnview.set_model(self.peers_store)
self.peers_columnview.set_model(self.selection)

def setup(self, widget, item, property_name):
def setup_when_idle():
obj = item.get_item()
if obj is None:
return
property_type = obj.find_property(property_name).value_type
if property_type == GObject.TYPE_BOOLEAN:
widget_type = Gtk.CheckButton
Expand Down Expand Up @@ -290,6 +294,47 @@ def update_notebook_status(self, torrent):
self.status_tab = self.builder.get_object("status_tab")
self.status_tab.append(self.status_grid_child)

def update_notebook_files(self, torrent):
logger.info(
"Notebook update files",
extra={"class_name": self.__class__.__name__},
)

if self.files_grid_child is not None:
self.status_tab.remove(self.files_grid_child)
self.files_grid_child.unparent()

self.files_grid_child = Gtk.Grid()
self.files_grid_child.set_column_spacing(10)
self.files_grid_child.set_hexpand(True)
self.files_grid_child.set_vexpand(True)
self.files_grid_child.set_visible(True)

files = self.model.get_torrents()
filtered_torrent = next((t for t in files if t.id == torrent.id), None)

# Create columns and add them to the TreeView
for attribute_index, (fullpath, length) in enumerate(
filtered_torrent.get_torrent_file().get_files()
):
row = attribute_index

labeln = Gtk.Label(label=fullpath, xalign=0)
labeln.set_visible(True)
labeln.set_halign(Gtk.Align.START)
labeln.set_size_request(80, -1)
self.files_grid_child.attach(labeln, 0, row, 1, 1)

labelv = Gtk.Label(label=length, xalign=0)
labelv.set_visible(True)
labelv.set_halign(Gtk.Align.START)
labelv.set_size_request(280, -1)
labelv.set_selectable(True) # Enable text selection
self.files_grid_child.attach(labelv, 1, row, 1, 1)

self.files_tab = self.builder.get_object("files_tab")
self.files_tab.append(self.files_grid_child)

def update_view(self, model, torrent, attribute):
pass

Expand Down Expand Up @@ -322,3 +367,4 @@ def model_selection_changed(self, source, model, torrent):
self.update_notebook_status(torrent)
self.update_notebook_options(torrent)
self.update_notebook_peers(torrent)
self.update_notebook_files(torrent)
45 changes: 14 additions & 31 deletions d_fake_seeder/lib/component/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ def on_toolbar_remove_clicked(self, button):
"Toolbar remove " + str(selected.id),
extra={"class_name": self.__class__.__name__},
)
os.remove(selected.filepath)
self.model.torrent_list.remove(selected)
try:
os.remove(selected.filepath)
except Exception as e:
print(e)
pass
self.model.remove_torrent(selected.filepath)

def on_toolbar_pause_clicked(self, button):
logger.info(
Expand All @@ -107,7 +111,7 @@ def on_toolbar_pause_clicked(self, button):
return

selected.active = False
self.model.emit("data-changed", self.model, selected, {"active": selected.active})
self.model.emit("data-changed", self.model, selected)

def on_toolbar_resume_clicked(self, button):
logger.info(
Expand All @@ -119,7 +123,7 @@ def on_toolbar_resume_clicked(self, button):
return

selected.active = True
self.model.emit("data-changed", self.model, selected, {"active": selected.active})
self.model.emit("data-changed", self.model, selected)

def on_toolbar_up_clicked(self, button):
logger.info(
Expand All @@ -137,8 +141,8 @@ def on_toolbar_up_clicked(self, button):
if torrent.id == selected.id - 1:
torrent.id = selected.id
selected.id -= 1
self.model.emit("data-changed", self.model, selected, {"id": selected.id})
self.model.emit("data-changed", self.model, torrent, {"id": torrent.id})
self.model.emit("data-changed", self.model, selected)
self.model.emit("data-changed", self.model, torrent)
break

def on_toolbar_down_clicked(self, button):
Expand All @@ -157,8 +161,8 @@ def on_toolbar_down_clicked(self, button):
if torrent.id == selected.id + 1:
torrent.id = selected.id
selected.id += 1
self.model.emit("data-changed", self.model, selected, {"id": selected.id})
self.model.emit("data-changed", self.model, torrent, {"id": torrent.id})
self.model.emit("data-changed", self.model, selected)
self.model.emit("data-changed", self.model, torrent)
break

def on_toolbar_settings_clicked(self, button):
Expand Down Expand Up @@ -216,29 +220,7 @@ def show_file_selection_dialog(self):
dialog.show()

def get_selected_torrent(self):
logger.info(
"Toolbar get selected torrent",
extra={"class_name": self.__class__.__name__},
)
# Get the TreeView object using self.builder.get_object
columnview1 = self.builder.get_object("columnview1")

# Get the currently selected item
selection = columnview1.get_selection()
lmodel, tree_iter = selection.get_selected()

if tree_iter is None:
return

# Get the index of the selected item
index = int(lmodel.get_path(tree_iter).get_indices()[0]) + 1

# Remove the torrent from self.model.torrent_list
for torrent in self.model.torrent_list:
if torrent.id == index:
return torrent

return False
return self.selection

def update_view(self, model, torrent, attribute):
pass
Expand Down Expand Up @@ -268,3 +250,4 @@ def model_selection_changed(self, source, model, torrent):
"Model selection changed",
extra={"class_name": self.__class__.__name__},
)
self.selection = torrent
46 changes: 37 additions & 9 deletions d_fake_seeder/lib/component/torrents.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, builder, model):

# Create a gesture recognizer
gesture = Gtk.GestureClick.new()
gesture.connect("released", self.column_selection_menu)
gesture.connect("released", self.main_menu)
gesture.set_button(3)

# Create an action group
Expand All @@ -57,7 +57,7 @@ def __init__(self, builder, model):

self.update_columns()

def column_selection_menu(self, gesture, n_press, x, y):
def main_menu(self, gesture, n_press, x, y):
rect = self.torrents_columnview.get_allocation()
rect.width = 0
rect.height = 0
Expand All @@ -71,6 +71,21 @@ def column_selection_menu(self, gesture, n_press, x, y):

menu = Gio.Menu.new()

# Create submenus
queue_submenu = Gio.Menu()
queue_submenu.append("Top", "app.queue_top")
queue_submenu.append("Up", "app.queue_up")
queue_submenu.append("Down", "app.queue_down")
queue_submenu.append("Bottom", "app.queue_bottom")

# Add menu items and submenus to the main menu
menu.append("Pause", "app.pause")
menu.append("Resume", "app.resume")
menu.append("Update Tracker", "app.update_tracker")
menu.append_submenu("Queue", queue_submenu)

columns_menu = Gio.Menu.new()

# Check if the attribute is a visible column in the columnview
visible_columns = [
"id" if column.get_title() == "#" else column.get_title()
Expand All @@ -96,7 +111,9 @@ def column_selection_menu(self, gesture, n_press, x, y):
for attribute in attributes:
toggle_item = Gio.MenuItem.new(label=f"{attribute}")
toggle_item.set_detailed_action(f"app.toggle_{attribute}")
menu.append_item(toggle_item)
columns_menu.append_item(toggle_item)

menu.append_submenu("Columns", columns_menu)

self.popover = Gtk.PopoverMenu().new_from_model(menu)
self.popover.set_parent(self.torrents_columnview)
Expand Down Expand Up @@ -193,6 +210,7 @@ def update_columns(self):
elif (
attribute_type == GObject.TYPE_LONG
or attribute_type == GObject.TYPE_BOOLEAN
or attribute_type == GObject.TYPE_FLOAT
):
sorter = Gtk.NumericSorter.new(attribute_expression)

Expand Down Expand Up @@ -225,6 +243,7 @@ def setup_when_idle():
widget = Gtk.Label()
widget.set_hexpand(True) # Make the widget expand horizontally
widget.set_halign(Gtk.Align.START) # Align text to the left
widget.set_vexpand(True)

# Set the child widget for the item
item.set_child(widget)
Expand Down Expand Up @@ -266,9 +285,11 @@ def bind_when_idle():
self.to_str,
)
elif isinstance(widget, Gtk.ProgressBar):
# Bind the attribute to the widget's fraction property
item_data.bind_property(
attribute, widget, "fraction", GObject.BindingFlags.SYNC_CREATE
attribute,
widget,
"fraction",
GObject.BindingFlags.SYNC_CREATE,
)
# Add more cases for other widget types as needed

Expand All @@ -295,7 +316,7 @@ def update_model(self):
self.store = self.model.get_liststore()
self.sorter = Gtk.ColumnView.get_sorter(self.torrents_columnview)
self.sort_model = Gtk.SortListModel.new(self.store, self.sorter)
self.selection = Gtk.SingleSelection.new(self.sort_model)
self.selection = Gtk.MultiSelection.new(self.sort_model)
self.selection.connect("selection-changed", self.on_selection_changed)
self.torrents_columnview.set_model(self.selection)

Expand All @@ -314,9 +335,16 @@ def update_view(self, model, torrent, updated_attributes):
self.update_model()

def on_selection_changed(self, selection, position, item):
item = selection.get_selected_item()
if item is not None:
self.model.emit("selection-changed", self.model, item)
# item = selection.get_selected_item()
# if item is not None:
# self.model.emit("selection-changed", self.model, item)
for i in range(self.store.get_n_items()):
if self.torrents_columnview.get_model().is_selected(i):
self.model.emit(
"selection-changed",
self.model,
self.torrents_columnview.get_model().get_item(i),
)

def handle_settings_changed(self, source, key, value):
logger.debug(
Expand Down

0 comments on commit d58af9f

Please sign in to comment.