You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pytdeextensions/app_templates/tdeioslave/src/tdeioslave.py

619 lines
21 KiB

#!/usr/bin/python
###########################################################################
# tdeioslave - description #
# ------------------------------ #
# begin : Mon May 2 2005 #
# copyright : (C) 2005 by AUTHOR #
# email : your@email.com #
# #
###########################################################################
# #
# 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 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################
# Import the required TQt and KDE modules.
from PyTQt.tqt import *
from tdeio import *
from tdecore import *
import os, time
# For debugging purposes, import the sys and traceback modules.
import sys, traceback
DEBUG = 1
# Define a class which will be used to create IOSlave instances.
############################################################################
class SlaveClass(TDEIO.SlaveBase):
"""SlaveClass(TDEIO.SlaveBase)
See tdelibs/tdeio/tdeio/slavebase.h for virtual functions to override.
"""
########################################################################
def __init__(self, pool, app):
# We must call the initialisation method of the base class.
TDEIO.SlaveBase.__init__(self, "tdeioslave", pool, app)
# Attach the DCOP client object associated with this IOSlave to the
# DCOP server.
self.dcopClient().attach()
self.debug("dcopClient: %i" % self.dcopClient().isRegistered())
self.contents = RAMDir(None,u"/")
self.host = ""
self.document = None
self.file = None
self.debug("Exiting __init__ now");
########################################################################
def __del__(self):
pass
########################################################################
# TDEIO.SlaveBase method
def setHost(self, host, port, user, passwd):
self.debug(
"setHost: %s %s %s %s" % (
repr(unicode(host)), repr(unicode(port)),
repr(unicode(user)), repr(unicode(passwd))
)
)
# This IOSlave does not allow a host to be specified as part of
# a URL.
if unicode(host) != u"":
self.closeConnection()
self.error(TDEIO.ERR_MALFORMED_URL, host)
return
########################################################################
# TDEIO.SlaveBase method
def openConnection(self):
# Don't call self.finished() in this method.
self.debug("openConnection")
########################################################################
# TDEIO.SlaveBase method
def closeConnection(self):
# Don't call self.finished() in this method.
self.debug("closeConnection")
########################################################################
# TDEIO.SlaveBase method
def get(self, url):
path = str(url.path())
self.debug("get(): %s" % path)
self.openConnection()
item = self.contents.resolve(path)
if item is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, path)
return
if item.isDir():
self.error(TDEIO.ERR_IS_DIRECTORY, path)
self.totalSize(len(item.getData()))
self.data(TQByteArray(item.getData()))
# The end of the data string.
self.data(TQByteArray())
self.finished()
########################################################################
# TDEIO.SlaveBase method
def put(self, url, permissions, overwrite, resume):
self.debug("put")
self.openConnection()
path = str(url.path())
parts = path.split('/')
filename = parts[-1]
parent_dir = self.contents.resolveParent(path)
if parent_dir is None:
parent_path = '/'.join(parts[:-1])
self.error(TDEIO.ERR_DOES_NOT_EXIST, parent_path)
return
if parent_dir.contains(filename):
if not overwrite:
self.error(TDEIO.ERR_COULD_NOT_WRITE, parent_path)
return
else:
parent_dir.unlink(filename)
# Read data from the application.
bytearray = TQByteArray()
bytes = 0
data = ""
while True:
self.dataReq()
result = self.readData(bytearray)
if result <= 0:
# An error or the end of data was encountered.
break
# The number of bytes read is given in the result.
bytes = bytes + result
data = data + str(bytearray)
parent_dir.insert(RAMFile(parent_dir,filename,data))
self.finished()
########################################################################
# TDEIO.SlaveBase method
def stat(self, url):
self.debug("stat: %s" % url.url(0,0))
self.openConnection()
self.debug("path:%s"% url.path())
# Return info the for the root.
item = self.contents.resolve(str(url.path()))
if item is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, str(url.path()))
return
self.statEntry(item.getStatEntry())
self.finished()
########################################################################
# TDEIO.SlaveBase method
def mimetype(self, url):
self.debug("mimetype: %s" % unicode(url))
self.openConnection()
path = str(url.path())
item = self.contents.resolve(path)
if item is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, path)
return
self.mimeType(item.getMimetype())
self.finished()
########################################################################
# TDEIO.SlaveBase method
def listDir(self, url):
# The "url" argument is a tdecore.KURL object.
self.debug("listDir: %s" % str(url.prettyURL(0)))
self.openConnection()
path = str(url.path())
dir = self.contents.resolve(path)
if dir is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, path)
return
if not dir.isDir():
self.error(TDEIO.ERR_IS_FILE, path)
return
for entry in dir.listDir():
self.listEntry(entry, 0)
self.listEntry([], 1) # Signal that the list is finished.
self.finished()
########################################################################
# TDEIO.SlaveBase method
def mkdir(self, url, permissions):
self.debug("mkdir")
self.openConnection()
parent_path = str(url.path())
parent_dir = self.contents.resolveParent(parent_path)
if parent_dir is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, parent_path)
return
new_dir_obj = parent_dir.mkdir(parent_path.split('/')[-1])
if new_dir_obj is None:
self.error(TDEIO.ERR_COULD_NOT_MKDIR, parent_path)
return
self.finished()
########################################################################
# TDEIO.SlaveBase method
def rename(self, src, dest, overwrite):
self.debug("rename: %s %s" % (src.path(), dest.path()))
self.openConnection()
src_path = str(src.path())
src_obj = self.contents.resolve(src_path)
if src_obj is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, src_path)
return
# See if the destination path already exists.
dest_path = str(dest.path())
dest_obj = self.contents.resolve(dest_path)
if dest_obj is not None:
if dest_obj is src_obj:
self.finished() # Done already.
return
if not overwrite:
# Can't overwrite. not bad.
self.error(TDEIO.ERR_CANNOT_RENAME, dest_path)
return
else:
# Over write, just remove the object.
dest_obj.getParent().unlink(dest_obj.getName())
dest_dir = self.contents.resolveParent(dest_path)
if dest_dir is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, dest_path)
return
src_obj.getParent().unlink(src_obj)
src_obj.setName(dest_path.split('/')[-1])
dest_dir.insert(src_obj)
self.finished()
# Other possible file operations are represented by the following
# methods which are not implemented.
#def symlink(self, target, dest, overwrite):
# debug("symlink")
# ...
# self.finished()
#def chmod(self, url, permissions):
# debug("chmod")
# ...
# self.finished()
########################################################################
# TDEIO.SlaveBase method
def copy(self, src, dest, permissions, overwrite):
self.debug("copy")
self.openConnection()
src_path = str(src.path())
src_obj = self.contents.resolve(src_path)
if src_obj is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, src_path)
return
# See if the destination path already exists.
dest_path = str(dest.path())
dest_obj = self.contents.resolve(dest_path)
if dest_obj is not None:
if dest_obj is src_obj:
self.finished() # Done already.
return
if not overwrite:
# Can't overwrite. not bad.
self.error(TDEIO.ERR_COULD_NOT_WRITE, dest_path)
return
else:
# Over write, just remove the object.
dest_obj.getParent().unlink(dest_obj.getName())
dest_dir = self.contents.resolveParent(dest_path)
if dest_dir is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, dest_path)
return
new_obj = src_obj.copy()
new_obj.setName(dest_path.split('/')[-1])
dest_dir.insert(new_obj)
self.finished()
########################################################################
# TDEIO.SlaveBase method
def del_(self, url, isfile):
self.debug("del_")
self.openConnection()
path = str(url.path())
item = self.contents.resolve(path)
if item is None:
self.error(TDEIO.ERR_DOES_NOT_EXIST, path)
return
item.getParent().unlink(item.getName())
self.finished()
########################################################################
# TDEIO.SlaveBase method
def disconnectSlave(self):
self.debug("disconnectSlave")
return
########################################################################
# TDEIO.SlaveBase method
def dispatchLoop(self):
self.debug("dispatchLoop")
TDEIO.SlaveBase.dispatchLoop(self)
########################################################################
# TDEIO.SlaveBase method
def error(self,errid,text):
self.debug("error: %i, %s" % (errid,text) )
TDEIO.SlaveBase.error(self,errid,text)
############################################################################
def debug(self,msg):
if DEBUG == 0: return
print("tdeioslave:"+str(msg)+"\n")
sys.stdout.flush()
############################################################################
class RAMDir(object):
############################################################################
def __init__(self,parent,name):
self.contents = {}
self.parent = parent
self.name = str(name)
############################################################################
def getParent(self):
return self.parent
############################################################################
def setParent(self,parent):
self.parent = parent
############################################################################
def getName(self):
return self.name
############################################################################
def setName(self,name):
self.name = str(name)
############################################################################
def resolve(self,path):
while path.endswith('/'):
path = path[:-1]
while path.startswith('/'):
path = path[1:]
if path=='':
return self
parts = path.split('/')
self.debug(path)
for item in self.contents.keys():
self.debug("keys:"+item)
if parts[0] in self.contents:
return self.contents[parts[0]].resolve('/'.join(parts[1:]))
self.debug("CHECKPOINT 1")
return None
############################################################################
def resolveParent(self,path):
while path.endswith('/'):
path = path[:-1]
while path.startswith('/'):
path = path[1:]
if path=="":
return None
parts = path.split('/')
return self.resolve('/'.join(parts[:-1]))
############################################################################
def mkdir(self,name):
if name in self.contents:
return None
new_dir = RAMDir(self,name)
self.contents[name] = new_dir
return new_dir
############################################################################
def getStatEntry(self):
# Return info the for the root.
length = 0
entry = []
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_NAME
atom.m_str = self.name
#debug("name: %s" % name)
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_SIZE
atom.m_long = length
#debug("length: %i" % length)
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_MODIFICATION_TIME
# Number of seconds since the epoch.
atom.m_long = int(time.time())
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_ACCESS
# The usual octal permission information (rw-r--r-- in this case).
atom.m_long = 0o644
entry.append(atom)
# If the stat method is implemented then entries _must_ include
# the UDE_FILE_TYPE atom or the whole system may not work at all.
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_FILE_TYPE
#atom.m_long = os.path.stat.S_IFREG
atom.m_long = os.path.stat.S_IFDIR
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_MIME_TYPE
atom.m_str = self.getMimetype()
entry.append(atom)
return entry
############################################################################
def listDir(self):
list = []
for item in self.contents.values():
list.append(item.getStatEntry())
return list
############################################################################
def isDir(self):
return True
############################################################################
def insert(self,item):
self.contents[item.getName()] = item
############################################################################
def contains(self,name):
return name in self.contents
############################################################################
def unlink(self,name):
if str(name) in self.contents:
del self.contents[str(name)]
############################################################################
def debug(self,msg):
if DEBUG == 0: return
print("tdeioslave:"+str(msg)+"\n")
sys.stdout.flush()
############################################################################
def getMimetype(self):
return "inode/directory"
############################################################################
def copy(self):
new_dir = RAMDir(None,self.name)
for item in self.contents.values():
new_item = item.copy()
new_item.setParent(new_dir)
new_dir.insert(new_item)
return new_dir
############################################################################
class RAMFile(object):
############################################################################
def __init__(self,parent,name,data=None):
self.parent = parent
self.name = str(name)
self.data = data
############################################################################
def getParent(self):
return self.parent
############################################################################
def setParent(self,parent):
self.parent = parent
############################################################################
def getName(self):
return self.name
############################################################################
def setName(self,name):
self.name = str(name)
############################################################################
def resolve(self,path):
if path!="":
return None
return self
############################################################################
def getData(self):
return self.data
############################################################################
def resolveParent(self,path):
return None
############################################################################
def getStatEntry(self):
# Return info the for the root.
length = 0
entry = []
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_NAME
atom.m_str = self.name
#debug("name: %s" % name)
entry.append(atom)
length = 0
if self.data is not None:
length = len(self.data)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_SIZE
atom.m_long = length
#debug("length: %i" % length)
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_MODIFICATION_TIME
# Number of seconds since the epoch.
atom.m_long = int(time.time())
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_ACCESS
# The usual octal permission information (rw-r--r-- in this case).
atom.m_long = 0o644
entry.append(atom)
# If the stat method is implemented then entries _must_ include
# the UDE_FILE_TYPE atom or the whole system may not work at all.
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_FILE_TYPE
atom.m_long = os.path.stat.S_IFREG
entry.append(atom)
atom = TDEIO.UDSAtom()
atom.m_uds = TDEIO.UDS_MIME_TYPE
atom.m_str = self.getMimetype()
entry.append(atom)
return entry
############################################################################
def isDir(self):
return False
############################################################################
def getMimetype(self):
return "text/html"
############################################################################
def copy(self):
return RAMFile(None,self.name,self.data)
############################################################################
def SlaveFactory(pool, app):
slave = SlaveClass(pool, app)
slave.dispatchLoop()