#!/usr/bin/env python

#    Copyright (C) 2006  Andrew Straw  <strawman@astraw.com>
#
#    This program can be distributed under the terms of the GNU LGPL.
#    See the file COPYING.
#

import os, stat, errno
# pull in some spaghetti to make this stuff work without fuse-py being installed
try:
    import _find_fuse_parts
except ImportError:
    pass
import fuse
from fuse import Fuse
import dbus, tempfile


if not hasattr(fuse, '__version__'):
    raise RuntimeError, \
        "your fuse-py doesn't know of fuse.__version__, probably it's too old."

fuse.fuse_python_api = (0, 2)

hello_path = '/hello'
hello_str = 'Hello World!\n'

class MyStat(fuse.Stat):
    def __init__(self):
        self.st_mode = 0
        self.st_ino = 0
        self.st_dev = 0
        self.st_nlink = 0
        self.st_uid = 0
        self.st_gid = 0
        self.st_size = 0
        self.st_atime = 0
        self.st_mtime = 0
        self.st_ctime = 0

class HelloFS(Fuse):
  
    def __init__(self, *args, **kwargs):
        Fuse.__init__(self, *args, **kwargs)
        self.files = {}
        self.grabbed = False

    def grab(self):
        bus=dbus.SessionBus()
        try:
            self.gimp = bus.get_object('org.gimp.GIMP.DBus','/')
        except:
            return
        for f in [str(x) for x in self.gimp.image_list()]:
            if not "/"+f in self.files:
                self.files["/" + f] = { "filename": None, "gimp_id": f }

    def get_save_file(self, path):
        if not self.files[path]["filename"]:
            # haven't yet saved the file: save it
            fname = tempfile.mktemp(".png", "/tmp/")
            self.gimp.save_as(self.files[path]["gimp_id"], fname)
            self.files[path]["filename"] = fname
        return self.files[path]["filename"]

    def getattr(self, path):
        st = MyStat()
        if not self.grabbed: self.grab()
        if path == '/':
            st.st_mode = stat.S_IFDIR | 0755
            st.st_nlink = 2
        elif path in self.files:
            st.st_mode = stat.S_IFREG | 0444
            st.st_nlink = 1
            fil = self.get_save_file(path)
            st.st_size = os.stat(fil)[stat.ST_SIZE]
        else:
            return -errno.ENOENT
        return st

    def readdir(self, path, offset):
        ids = [".", ".."] + [x["gimp_id"] for x in self.files.values()]
        for r in ids:
            yield fuse.Direntry(r)

    def open(self, path, flags):
        if not self.grabbed: self.grab()
        if path not in self.files:
            return -errno.ENOENT
        accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
        if (flags & accmode) != os.O_RDONLY:
            return -errno.EACCES

    def read(self, path, size, offset):
        if not self.grabbed: self.grab()
        if path not in self.files:
            return -errno.ENOENT
        fil = self.get_save_file(path)
        slen = os.stat(fil)[stat.ST_SIZE]
        if offset < slen:
            if offset + size > slen:
                size = slen - offset
            fp = open(fil)
            fp.seek(offset)
            buf = fp.read(size)
            fp.close()
        else:
            buf = ''
        return buf

def main():
    usage="""
Userspace hello example

""" + Fuse.fusage
    server = HelloFS(version="%prog " + fuse.__version__,
                     usage=usage,
                     dash_s_do='setsingle')

    server.parse(errex=1)
    server.main()

if __name__ == '__main__':
    main()

