#!/usr/bin/env python
"""
Copyright (C) 2009 Programble
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import os
import mimetypes
import thread
import gobject
DEBUG = False
folder_icon = gtk.Button("").render_icon(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_DIALOG)
def listdir(path, liststore, show_hidden=False):
"""Add files and directories in path to liststore"""
if (DEBUG): print "listdir", path, liststore
dirs = []
files = []
# List files/dirs
for fd in os.listdir(path):
# Show/Hide hidden files
if (show_hidden == False and fd[0] == "."):
continue
# Get absolute path
abspath = os.path.join(path, fd)
# Sort files/dirs
if (os.path.isfile(abspath)):
files.append((fd, abspath))
elif (os.path.isdir(abspath)):
dirs.append((fd, abspath))
# Sort alphabetically and case-insensitive
dirs.sort(key=lambda x: (x[0].lower(),) + x[1:])
files.sort(key=lambda x: (x[0].lower(),) + x[1:])
# Add dirs to liststore
for d in dirs:
liststore.append([d[0], folder_icon, d[1]])
# Add files to liststore with icons
for f in files:
ico = get_icon(f[1])
liststore.append([f[0], ico, f[1]])
if (DEBUG): print "(listdir)files", len(files), "dirs", len(dirs)
return False
icon_cache = {}
mime_cache = {}
def get_icon(path):
"""Return a pixbuf containing an icon for the file path"""
global icon_cache, mime_cache
if (DEBUG): print "get_icon", path
# Limit size of icon cache
if (len(icon_cache) > 1000):
icon_cache.popitem()
ret = None
# Load icon from icon cache if possible
if (icon_cache.has_key(path)):
if (DEBUG): print "-icon_cache"
return icon_cache[path]
# First try to guess mime type from extension
mimetypes.init()
mime = mimetypes.guess_type(path, False)[0]
# If python cannot find mime, use command line utility 'file'
if (mime == None):
import commands
mime = commands.getoutput('file --mime-type -L "' + path + '"')
mime = mime[mime.find(":")+2:]
generic = ""
genericx = ""
genericf = ""
# Load current icon theme
icosd = gtk.icon_theme_get_default()
# Load default gnome icon theme
icosg = gtk.IconTheme()
icosg.set_custom_theme("gnome")
# If no mime found, return default file icon
if (mime == None):
ret = icosd.load_icon("gtk-file", 48, 0)
else:
# Find all variations of mime type (generic, x, and short)
mime = mime.replace("/", "-").replace("-httpd", "").replace("program", "executable").replace("msdos", "ms-dos")
generic = mime.split("-")
generic = generic[:-1]
genericx = generic[0:len(generic)]
genericx.append("x")
generic.append("generic")
genericx.append("generic")
genericf = generic[0]
generic = "-".join(tuple(generic))
genericx = "-".join(tuple(genericx))
if (DEBUG): print "-mime", mime
# Load icon from mime cache if possible
if (mime_cache.has_key(mime)):
if (DEBUG): print "-mime_cache"
if (DEBUG): print "-icon_cache", len(icon_cache), "mime_cache", len(mime_cache)
# Also add file to icon cache
icon_cache[path] = mime_cache[mime]
return mime_cache[mime]
# For each mime variation, try in current theme, then in default theme
if (icosd.has_icon(mime)):
ret = icosd.load_icon(mime, 48, 0)
elif (icosg.has_icon(mime)):
ret = icosg.load_icon(mime, 48, 0)
elif (icosd.has_icon("gnome-mime-" + mime)):
ret = icosd.load_icon("gnome-mime-" + mime, 48, 0)
elif (icosg.has_icon("gnome-mime-" + mime)):
ret = icosg.load_icon("gnome-mime-" + mime, 48, 0)
elif (icosd.has_icon(genericx)):
ret = icosd.load_icon(genericx, 48, 0)
elif (icosg.has_icon(genericx)):
ret = icosg.load_icon(genericx, 48, 0)
elif (icosd.has_icon(generic)):
ret = icosd.load_icon(generic, 48, 0)
elif (icosg.has_icon(generic)):
ret = icosg.load_icon(generic, 48, 0)
elif (icosd.has_icon(genericf)):
ret = icosd.load_icon(genericf, 48, 0)
elif (icosg.has_icon(genericf)):
ret = icosg.load_icon(genericf, 48, 0)
else:
# If no icon found, return default file icon
if (DEBUG): print "-no_icon"
ret = icosd.load_icon("gtk-file", 48, 0)
# Add file to icon cache
icon_cache[path] = ret
# Add mime to mime cache
mime_cache[mime] = ret
if (DEBUG): print "-icon", ret
if (DEBUG): print "-icon_cache", len(icon_cache), "mime_cache", len(mime_cache)
return ret
def get_home():
"""Return the home directory of the current user"""
return os.path.expanduser("~")
def isdir(path):
"""Returns true if path is a directory"""
return os.path.isdir(path)
def isfile(path):
"""Returns true if path is a file"""
return os.path.isfile(path)
def get_parentdir(path):
"""Get the parent directory of path"""
return os.path.split(path)[0]
def execute(path):
"""Use the command line 'exo-open' to open/execute a file"""
if (DEBUG): print "execute", path
os.system('exo-open "' + path + '"')
def get_home_dirs():
"""List all directories in the current users home"""
home = get_home()
dirs = []
for fd in os.listdir(home):
if (isdir(os.path.join(home, fd)) and fd[0] != "."):
dirs.append((fd, os.path.join(home, fd)))
dirs.sort(key=lambda x: (x[0].lower(),) + x[1:])
return dirs