Virtual Python File System. (9)

1 Name: #!/usr/bin/anonymous : 2008-04-23 15:40 ID:fCAsND1C

I need help making virtual computers in Python. Each computer will have a command line with familiar commands like dir, cd, cat, and others. The biggest problem I'm having is making a file system for each computer. So far for defining it I came up with this:

files = [
['A:',
['usr',
['file.txt','This is a test!'],
['test.html','<html>\nTEST\n</html>'],
['desktop',
['file_a.txt','sup?'],
['file_b.txt','SUP?']
]
],
['sys',
['kernel.bin'],
['os.bin'],
['null.bin'],
]
]
['Z:',
['usb.txt','text stuffs']
]
]

A big mess. I know. Is there a better method to create a structure like this?
I'm also having trouble printing data from the list.

Any help would be appreciated.

2 Name: #!/usr/bin/anonymous : 2008-04-23 18:05 ID:msw/mgAs

if you hit a roadblock, i would just make a stub for your filesystem (for instance, a flat mapping of (full) filename -> contents). creating a filesystem that works isn't hard, making it fast is the tricky part.

if you already have a stub in place (or want something fast before having something that "works"), i suggest you look into how other filesystems store data on disk and use a seperate file to simulate the persistent storage - look up stuff such as "inode".

what you're doing now is creating your own filesystem. it's going to take a lot of work and you won't be creating something "new" if you just use a nested directory structure like other filesystems do. creating all this in python liberates you from a lot of real-world concerns.. why not try something we've never seen before? (eg something wacky like making your entire filesystem one big JSON tree (lists, numbers, strings), or having an sql(ite) backend)

3 Name: #!/usr/bin/anonymous : 2008-04-23 19:23 ID:fCAsND1C

Well this isn't going to be for real use. Just for a game/demo. I just need a way too make a list, dictionary, or what ever works best to make a representation of a file system which the player can browse. I'm just not sure how to get specific data from a certain list like everything under 'desktop' or the files in 'sys'.

4 Name: #!/usr/bin/anonymous : 2008-04-24 10:52 ID:msw/mgAs

suppose "everything is a file", here's how you could do it:

  • represent a directory by [(filename,file), ...]
  • represent a flat file by "a string of it's contents"

for example:

root = [( "emptydir", []),
( "dir1", [( "file1", "hello world")]),
( "emptyfile", "")]

now simply start with writing your primitives (try to define them in terms of eachother):

  • read path, returns an entry
  • save path entry, saves a file/dir under a certain path
  • delete path
  • move/copy path newpath

5 Name: #!/usr/bin/anonymous : 2008-04-25 04:35 ID:Heaven

Please, please, please, don't base it on Windows. Drive letters are a seriously braindead way to map partitions.

>>2
BeOS had a database backend, so technically that's been seen before. :)

Personally I'd like to see a copy-on-write filesystem that consolidates identical file data into symlinks. (unless you specify otherwise; for various mostly performance-related reasons, it's useful to have two identical files, but generally it's a mistake) Also would be neat is the ability to separate the ideas of directories and filenames from the file content -- have a tag-based system underneath this, so instead of say, putting a file in /usr/bin, it would be tagged as 'usr', 'bin', and '/usr/bin'. That would essentially remove the necessity to maintain a $PATH: you'd just grab all directories tagged with 'bin'. This also applies for linked library resolution, help searching, etc. and would generally make the entire system heaps more flexible.

Oh and all that stuff is way easier ... if you put the whole filesystem into a database! BeOS didn't quite go that far, but I imagine if it'd been designed after the whole Web 2.0 thing, it would have used a similar structure. When it was made the whole tagging concept hadn't crossed most people's minds yet and I don't think anyone realized the magnitude of what such a system could allow.

6 Name: #!/usr/bin/anonymous : 2008-04-25 08:13 ID:fCAsND1C

I'm still having trouble just isolating the data that I need to print. Like if I just wanted to show the directorys under / or just show a single files contents. I still have no clue how too. I can do it with 'print files[0][0][1]' and such, but I have no way to do it with user input. Here's what I have so far:

class pc:
'a PC'
cd = '/'
def __init__(n,i,h):
name = n
ip = i
hd = h
def cmd(com):
if com[0] == 'dir':
for i in hd: #need to find a way to isolate only the data we need to print
print(i)
if com[0] == 'cd':
if com[0][1] == '/':
cd = com[1] #Need error handeling
else:
cd = cd + com[1] #Again, need error handeling.
files = [
['usr',[
('file.txt','This is a test!'),
('test.html','<html>\nTEST\n</html>'),
['desktop',[
('file_a.txt','sup?'),
('file_b.txt','SUP?')]
]
],
['sys',[
('kernel.bin',''),
('os.bin','')]
]
]
local = pc('localhost','127.0.0.1',files)
other = pc('alpha','132.321.123.333',files)
local.cmd( local.cd+raw_input(' $') )

I'm still pretty new to python so I don't really know what I'm even doing at this point.

>>5
Although that's a good idea, it's not really what I'm looking for. It would be a bit tedious to tag every file with everywhere it is. I think I will be going with a linux-like system( / as root )

7 Post deleted.

8 Name: #!/usr/bin/anonymous : 2008-04-25 16:32 ID:Heaven

>>7
Go back to /prog/.

9 Name: #!/usr/bin/anonymous : 2008-04-25 19:19 ID:Heaven

> def cmd(com):

Don't forget your self.
I think using a dict would be better, as it'd greatly simplify subdirectory lookup, avoid accidental duplicate filenames, and so forth.

I thought this was interesting so I played around with it a bit and here's what I came up with. You could probably add in additional filesystem types -- for example, T_DEV to hold an arbitrary python object, T_PIPE containing a StringIO, etc. etc.

import time, posixpath
# vaguely similar to stat's st_mode types
(
T_TEXT, # normal file 'string'
T_DIR, # subdirectory dict of name: data
T_EXEC, # executable function()
) = range(3)
class FSFile(object):
def __init__(self, name, data):
self.name = name
self.type = T_TEXT
self.data = data
def __repr__(self):
return '<File %r>' % self.name
class FSDir(FSFile):
def __init__(self, name, *data):
self.name = name
self.type = T_DIR
self.data = {'.': self}
for node in data:
self.data[a.name] = node
if node.type == T_DIR:
node.data['..'] = self
self.__getitem__ = self.data.__getitem__
def __repr__(self):
return '<Directory %r>' % self.name
def __getitem__(self, item):
return self.data.__getitem__(item)
class FSExec(FSFile):
def __init__(self, name, data):
self.name = name
self.type = T_EXEC
self.data = data
def __repr__(self):
return '<Executable %r>' % self.name
def __call__(self, *args, **kw):
return self.data(*args, **kw)
def print_date():
print time.ctime()
filesystem = FSDir('/',
FSDir('bin',
FSExec('true', lambda: None),
FSExec('false', lambda: 1),
FSExec('date', print_date),
),
FSDir('home',
FSDir('joeuser',
FSFile('file.txt', 'This is a test!'),
FSFile('test.html', '<html>\nTEST\n</html>'),
),
),
)
filesystem.data['..'] = filesystem
def ls_R(node, base=''):
path = posixpath.join(base, node.name)
if node.type == T_TEXT:
print '[txt] %6d %s' % (len(node.data), path)
elif node.type == T_EXEC:
print '[exe] %6d %s' % (len(node.data.func_code.co_code), path)
elif node.type == T_DIR:
print '[dir] %6d %s' % (len(node.data), path)
for name, subnode in node.data.iteritems():
if not name.startswith('.'):
ls_R(subnode, path)
#print subnode
else:
print '?--- %8d %s' % (0, path)
ls_R(filesystem)
filesystem['bin']['date']()
This thread has been closed. You cannot post in this thread any longer.