added initial gtk icon logiv

This commit is contained in:
itdominator 2021-04-24 06:39:09 -05:00
parent 3686034ac7
commit 511d05a8a7
19 changed files with 265 additions and 13 deletions

View File

@ -11,12 +11,24 @@ class Window:
def create_view(self):
view = View()
self.views.append(view)
return view
def pop_view(self):
self.views.pop()
def delete_view(self, index):
del self.views[index]
def delete_view(self, vid):
i = -1
for view in self.views:
i += 1
if view.id == vid:
del self.views[i]
break
def get_view(self, index):
def get_view_by_id(self, vid):
for view in self.views:
if view.id == vid:
return view
def get_view_by_index(self, index):
return self.views[index]

View File

@ -24,8 +24,7 @@ class WindowController:
def add_view_for_window(self, win_id):
for window in self.windows:
if window.id == win_id:
window.create_view()
break
return window.create_view()
def pop_window(self):
self.windows.pop()

View File

@ -0,0 +1,178 @@
# Python Imports
import os, subprocess, hashlib, threading
from os.path import isdir, isfile, join
# Gtk imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gio
from xdg.DesktopEntry import DesktopEntry
# Application imports
def threaded(fn):
def wrapper(*args, **kwargs):
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
return wrapper
class Icon:
def __init__(self):
self.SCRIPT_PTH = os.path.dirname(os.path.realpath(__file__)) + "/"
self.INTERNAL_ICON_PTH = self.SCRIPT_PTH + "./utils/icons/text.png"
def createIcon(self, dir, file):
fullPath = dir + "/" + file
return self.getIconImage(file, fullPath)
def createThumbnail(self, dir, file):
fullPath = dir + "/" + file
try:
fileHash = hashlib.sha256(str.encode(fullPath)).hexdigest()
hashImgPth = self.get_home() + "/.thumbnails/normal/" + fileHash + ".png"
thumbnl = self.createScaledImage(hashImgPth, self.viIconWH)
if thumbnl == None: # If no icon whatsoever, return internal default
thumbnl = Gtk.Image.new_from_file(self.SCRIPT_PTH + "./utils/icons/video.png")
return thumbnl
except Exception as e:
print("Thumbnail generation issue:")
print( repr(e) )
return Gtk.Image.new_from_file(self.SCRIPT_PTH + "./utils/icons/video.png")
def getIconImage(self, file, fullPath):
try:
thumbnl = None
# Video icon
if file.lower().endswith(self.fvideos):
thumbnl = Gtk.Image.new_from_file(self.SCRIPT_PTH + "./utils/icons/video.png")
# Image Icon
elif file.lower().endswith(self.fimages):
thumbnl = self.createScaledImage(fullPath, self.viIconWH)
# .desktop file parsing
elif fullPath.lower().endswith( ('.desktop',) ):
thumbnl = self.parseDesktopFiles(fullPath)
# System icons
else:
thumbnl = self.getSystemThumbnail(fullPath, self.systemIconImageWH[0])
if thumbnl == None: # If no icon whatsoever, return internal default
thumbnl = Gtk.Image.new_from_file(self.INTERNAL_ICON_PTH)
return thumbnl
except Exception as e:
print("Icon generation issue:")
print( repr(e) )
return Gtk.Image.new_from_file(self.INTERNAL_ICON_PTH)
def parseDesktopFiles(self, fullPath):
try:
xdgObj = DesktopEntry(fullPath)
icon = xdgObj.getIcon()
altIconPath = ""
if "steam" in icon:
steamIconsDir = self.get_home() + "/.thumbnails/steam_icons/"
name = xdgObj.getName()
fileHash = hashlib.sha256(str.encode(name)).hexdigest()
if isdir(steamIconsDir) == False:
os.mkdir(steamIconsDir)
hashImgPth = steamIconsDir + fileHash + ".jpg"
if isfile(hashImgPth) == True:
# Use video sizes since headers are bigger
return self.createScaledImage(hashImgPth, self.viIconWH)
execStr = xdgObj.getExec()
parts = execStr.split("steam://rungameid/")
id = parts[len(parts) - 1]
imageLink = "https://steamcdn-a.akamaihd.net/steam/apps/" + id + "/header.jpg"
proc = subprocess.Popen(["wget", "-O", hashImgPth, imageLink])
proc.wait()
# Use video thumbnail sizes since headers are bigger
return self.createScaledImage(hashImgPth, self.viIconWH)
elif os.path.exists(icon):
return self.createScaledImage(icon, self.systemIconImageWH)
else:
iconsDirs = ["/usr/share/pixmaps", "/usr/share/icons", self.get_home() + "/.icons" ,]
altIconPath = ""
for iconsDir in iconsDirs:
altIconPath = self.traverseIconsFolder(iconsDir, icon)
if altIconPath is not "":
break
return self.createScaledImage(altIconPath, self.systemIconImageWH)
except Exception as e:
print(".desktop icon generation issue:")
print( repr(e) )
return None
def traverseIconsFolder(self, path, icon):
altIconPath = ""
for (dirpath, dirnames, filenames) in os.walk(path):
for file in filenames:
appNM = "application-x-" + icon
if icon in file or appNM in file:
altIconPath = dirpath + "/" + file
break
return altIconPath
def getSystemThumbnail(self, filename, size):
try:
if os.path.exists(filename):
gioFile = Gio.File.new_for_path(filename)
info = gioFile.query_info('standard::icon' , 0, Gio.Cancellable())
icon = info.get_icon().get_names()[0]
iconTheme = Gtk.IconTheme.get_default()
iconData = iconTheme.lookup_icon(icon , size , 0)
if iconData:
iconPath = iconData.get_filename()
return Gtk.Image.new_from_file(iconPath) # This seems to cause a lot of core dump issues...
else:
return None
else:
return None
except Exception as e:
print("system icon generation issue:")
print( repr(e) )
return None
def createScaledImage(self, path, wxh):
try:
pixbuf = Gtk.Image.new_from_file(path).get_pixbuf()
scaledPixBuf = pixbuf.scale_simple(wxh[0], wxh[1], 2) # 2 = BILINEAR and is best by default
return Gtk.Image.new_from_pixbuf(scaledPixBuf)
except Exception as e:
print("Image Scaling Issue:")
print( repr(e) )
return None
def createFromFile(self, path):
try:
return Gtk.Image.new_from_file(path)
except Exception as e:
print("Image from file Issue:")
print( repr(e) )
return None
def returnGenericIcon(self):
return Gtk.Image.new_from_file(self.INTERNAL_ICON_PTH)

View File

@ -4,24 +4,38 @@ import os
from os import listdir
from os.path import isdir, isfile, join
from random import randint
# Lib imports
# Application imports
from .utils import Settings, Launcher
from . import Path
from . import Path, Icon
class View(Settings, Launcher, Path):
class View(Settings, Launcher, Icon, Path):
def __init__(self):
self.id = ""
self.files = []
self.dirs = []
self.vids = []
self.images = []
self.desktop = []
self.ungrouped = []
self.id_length = 10
self.set_to_home()
self.generate_id()
def random_with_N_digits(self, n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
def generate_id(self):
self.id = str(self.random_with_N_digits(self.id_length))
def load_directory(self):
path = self.get_path()
@ -128,6 +142,11 @@ class View(Settings, Launcher, Path):
home = self.get_home() + "/"
return path.replace(home, "")
def get_end_of_path(self):
parts = self.get_current_directory().split("/")
size = len(parts)
return parts[size - 1]
def get_dot_dots(self):
return self.hashSet(['.', '..'])
@ -145,7 +164,7 @@ class View(Settings, Launcher, Path):
if not os.path.exists(hashImgPth) :
fullPath = join(current_directory, video[0])
self.logger.debug(f"Hash Path: {hashImgPth}\nFile Path: {fullPath}")
self.generateVideoThumbnail(fullPath, hashImgPth)
self.generate_video_thumbnail(fullPath, hashImgPth)
return videos_set

View File

@ -1,4 +1,5 @@
from .utils import *
from .Icon import Icon
from .Path import Path
from .View import View

View File

@ -67,12 +67,50 @@ class Launcher:
return True
def generateVideoThumbnail(self, fullPath, hashImgPth):
def generate_video_thumbnail(self, fullPath, hashImgPth):
try:
proc = subprocess.Popen([self.FFMPG_THUMBNLR, "-t", "65%", "-s", "300", "-c", "jpg", "-i", fullPath, "-o", hashImgPth])
proc.wait()
except Exception as e:
self.logger.debug(repr(e))
self.ffprobe_generate_video_thumbnail(fullPath, hashImgPth)
def generate_video_thumbnail(self, fullPath, hashImgPth):
proc = None
try:
# Stream duration
command = ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=duration", "-of", "default=noprint_wrappers=1:nokey=1", fullPath]
data = subprocess.run(command, stdout=subprocess.PIPE)
duration = data.stdout.decode('utf-8')
# Format (container) duration
if "N/A" in duration:
command = ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", fullPath]
data = subprocess.run(command , stdout=subprocess.PIPE)
duration = data.stdout.decode('utf-8')
# Stream duration type: image2
if "N/A" in duration:
command = ["ffprobe", "-v", "error", "-select_streams", "v:0", "-f", "image2", "-show_entries", "stream=duration", "-of", "default=noprint_wrappers=1:nokey=1", fullPath]
data = subprocess.run(command, stdout=subprocess.PIPE)
duration = data.stdout.decode('utf-8')
# Format (container) duration type: image2
if "N/A" in duration:
command = ["ffprobe", "-v", "error", "-f", "image2", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", fullPath]
data = subprocess.run(command , stdout=subprocess.PIPE)
duration = data.stdout.decode('utf-8')
# Get frame roughly 35% through video
grabTime = str( int( float( duration.split(".")[0] ) * 0.35) )
command = ["ffmpeg", "-ss", grabTime, "-an", "-i", fullPath, "-s", "320x180", "-vframes", "1", hashImgPth]
proc = subprocess.Popen(command, stdout=subprocess.PIPE)
proc.wait()
except Exception as e:
print("Video thumbnail generation issue in thread:")
print( repr(e) )
self.logger.debug(repr(e))
def check_remux_space(self):

View File

@ -11,15 +11,20 @@ from os import path
class Settings:
logger = None
GTK_ORIENTATION = 1 # HORIZONTAL (0) VERTICAL (1)
ABS_THUMBS_PTH = None # Used for thumbnail generation and is set by passing in
REMUX_FOLDER = None # Used for Remuxed files and is set by passing in
FFMPG_THUMBNLR = None # Used for thumbnail generator binary and is set by passing in
HIDE_HIDDEN_FILES = True
lock_folder = True
go_past_home = False
lock_folder = False
go_past_home = True
subpath = "/LazyShare" # modify 'home' folder path
locked_folders = "Synced Backup::::venv::::flasks".split("::::")
iconContainerWH = [128, 128]
systemIconImageWH = [56, 56]
viIconWH = [256, 128]
subpath = "" # modify 'home' folder path
locked_folders = "venv::::flasks".split("::::")
mplayer_options = "-quiet -really-quiet -xy 1600 -geometry 50%:50%".split()
music_app = "/opt/deadbeef/bin/deadbeef"
media_app = "mpv"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB