Skip to content

Instantly share code, notes, and snippets.

@Axel-Erfurt
Last active August 19, 2025 19:22
Show Gist options
  • Save Axel-Erfurt/a45513a3d27ddfc1df165a46f51a8fdd to your computer and use it in GitHub Desktop.
Save Axel-Erfurt/a45513a3d27ddfc1df165a46f51a8fdd to your computer and use it in GitHub Desktop.
Filmliste
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gi
gi.require_versions({'Gtk': '3.0'})
from gi.repository import Gtk
import sqlite3 as db
import pandas as pd
from subprocess import run
from os import path, chdir, remove
from sys import argv, exit
chdir(path.abspath(path.dirname(argv[0])))
class GenericException(Exception):
pass
class MyWindow(Gtk.Window):
def __init__(self):
# Window
Gtk.Window.__init__(self)
### check csv
csv_file = 'filmliste.csv'
if not path.isfile(csv_file):
self.open_message_window("filmliste.csv existiert nicht!\nKopiere filmliste.csv nach ~/.local/share/Filmliste\n\nStarte dann Filmliste erneut.")
exit()
self.set_resizable(True)
self.set_border_width(10)
self.set_size_request(950, 700)
self.set_position(Gtk.WindowPosition.CENTER)
# Header
self.header = Gtk.HeaderBar()
self.header.set_title('Filmliste')
self.header.set_show_close_button(True)
self.set_titlebar(self.header)
# Models
self.model = Gtk.ListStore(str, str, str)
self.filter = self.model.filter_new()
# Boxes
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
vbox.set_homogeneous(False)
hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
hbox.set_homogeneous(False)
vbox.pack_start(hbox, False, True, 0)
self.add(vbox)
# Search Entry Titel
self.entry_band = Gtk.SearchEntry(width_chars=25)
self.entry_band.set_placeholder_text("Filmtitel suchen ...")
self.entry_band.connect("changed", self.refresh_filter)
self.header.add(self.entry_band)
# Play Button
self.play_button = Gtk.Button(tooltip_text = "Wiedergabe")
self.play_button.add(
Gtk.Image.new_from_icon_name('media-playback-start-symbolic', 2))
self.play_button.set_relief(2)
self.play_button.set_sensitive(False)
self.play_button.connect('clicked', self.play_movie)
# Folder Button
self.folder_button = Gtk.Button(tooltip_text = "Ordner öffnen")
self.folder_button.add(
Gtk.Image.new_from_icon_name('document-open', 2))
self.folder_button.set_relief(2)
self.folder_button.set_sensitive(False)
self.folder_button.connect('clicked', self.open_folder)
# Database Button
self.db_button = Gtk.Button(tooltip_text = "Datenbank neu laden")
self.db_button.add(
Gtk.Image.new_from_icon_name('view-refresh', 2))
self.db_button.set_relief(2)
self.db_button.set_sensitive(True)
self.db_button.connect('clicked', self.update_db)
self.header.pack_end(self.db_button)
self.header.pack_end(self.folder_button)
self.header.pack_end(self.play_button)
self.filter.set_visible_func(self.visible_cb)
# TreeView
self.treeview = Gtk.TreeView(model=self.filter)
self.treeview.set_enable_search(True)
self.treeview.set_search_column(0)
for i, column_title in enumerate(["Filmtitel", "Größe", "Speicherort"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
self.treeview.append_column(column)
db_file = 'filmliste.db'
if path.isfile(db_file):
print("Datenbank existiert, starte App")
con = db.connect(db_file)
c = con.cursor()
csv_file = 'filmliste.csv'
df = pd.read_csv(csv_file, delimiter = ";")
df.to_sql('filmliste', con, if_exists='replace', index = False)
### Ende Filmliste neu erstellen ###
full_line = c.execute('SELECT * FROM filmliste ORDER BY Filmtitel').fetchall()
for row in full_line:
self.model.append(row)
else:
print("Datenbank existiert nicht\nerstelle Datenbank ...")
self.update_db()
self.treeview.get_column(2).set_visible(False)
self.treeview.set_activate_on_single_click(True)
self.treeview.connect("row-activated", self.on_selection_changed)
self.treeview.connect("move-cursor", self.on_selection_changed_by_key)
# Scrolled Window
self.sw = Gtk.ScrolledWindow()
self.sw.add(self.treeview)
vbox.pack_start(self.sw, True, True, 1)
self.treeview.grab_focus()
self.set_geometry(0, 0, 900, 600)
#self.menu()
def update_db(self, *args):
if path.exists("filmliste.db"):
remove("filmliste.db")
print("lösche filmliste.db")
else:
print("Datenbank existiert nicht")
self.model.clear()
db_file = 'filmliste.db'
print("Datenbank wird neu erstellt ...")
self.open_message_window("Datenbank wird neu erstellt ...")
### Filmliste neu erstellen ###
con = None
con = db.connect(db_file)
csv_file = 'filmliste.csv'
df = pd.read_csv(csv_file, delimiter = ";")
df.to_sql('filmliste', con, if_exists='replace', index = False)
### Ende Filmliste neu erstellen ###
c = con.cursor()
full_line = c.execute('SELECT * FROM filmliste ORDER BY Filmtitel').fetchall()
for row in full_line:
self.model.append(row)
def open_message_window(self, message, *args):
dialog = Gtk.MessageDialog(
flags=0,
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
title="Filmliste",
text=message)
dialog.run()
dialog.destroy()
def set_geometry(self, x, y, w, h):
self.resize(w, h)
self.move(x, y)
def on_selection_changed(self, trview, event, *args):
model, pathlist = trview.get_selection().get_selected()
if pathlist:
self.song_file_path = model[pathlist][2]
self.header.set_title(model[pathlist][0])
self.header.set_subtitle(model[pathlist][1])
self.play_button.set_sensitive(True)
self.folder_button.set_sensitive(True)
def on_selection_changed_by_key(self, trview, event, *args):
index = trview.get_selection().get_selected_rows()[1][0][0]
model, pathlist = trview.get_selection().get_selected()
if pathlist:
self.song_file_path = model[index + 1][2]
self.header.set_title(model[pathlist][0])
self.header.set_subtitle(model[index + 1][1])
self.play_button.set_sensitive(True)
self.folder_button.set_sensitive(True)
def open_folder(self, *args):
wd = self.song_file_path.rpartition("/")[0]
run(["xdg-open", wd])
def play_movie(self, *args):
# start celluloid
run(["xdg-open", self.song_file_path])
def refresh_filter(self,widget):
self.filter.refilter()
self.treeview.scroll_to_cell(0)
def visible_cb(self, model, iter, data=None):
if self.entry_band.has_focus():
search_query = self.entry_band.get_text().lower()
if search_query == "":
return True
value = model.get_value(iter, 0).lower()
if search_query in value:
return True
return False
else:
return True
win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment