#!/usr/bin/env python ############################################################################## # # $RCSfile: hd24fuse.py,v $ # # Copyright (C) 2006 John Popplewell # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # # Author : John Popplewell # Email : john@johnnypops.demon.co.uk # Website: http://www.johnnypops.demon.co.uk/ # # $Id: hd24fuse.py,v 1.9 2006/08/30 04:45:02 jfp Exp $ # ############################################################################## _FILE_REVISION = "$Revision: 1.9 $" import os, stat, errno import fuse from fuse import Fuse from adatfst import AdatFst, getProjectName, getSongName, getTrackName if not hasattr(fuse, '__version__'): raise RuntimeError, \ "your fuse-py doesn't know of fuse.__version__, probably it's too old." DEFAULT_DRIVE = '/dev/hdb' class MyStat(fuse.Stat): def __init__(self): self.st_mode = 0 self.st_ino = 0 self.st_dev = 0 self.st_nlink = 1 self.st_uid = 0 self.st_gid = 0 self.st_size = 0 self.st_atime = 0 self.st_mtime = 0 self.st_ctime = 0 self.st_blocks = 0 self.st_blksize = 0 self.st_rdev = 0 class HD24FS(Fuse): def __init__(self, *args, **kw): Fuse.__init__(self, *args, **kw) self.drive = DEFAULT_DRIVE def main(self, *a, **kw): self.hd24 = AdatFst(self.drive) self.make_dirs() server = self class HD24File(object): def __init__(self, path, flags, *mode): info = server.dirs[path] song = info[1][1] track = info[2][0] self.fp = server.hd24.getWavFile(song, track) def read(self, length, offset): self.fp.seek(offset) return self.fp.read(length) def release(self, flags): self.fp.close() self.file_class = HD24File return Fuse.main(self, *a, **kw) def make_dirs(self): self.dirs = {} for pidx, proj in enumerate(self.hd24.info['projects']): proj_name = getProjectName(pidx, proj) self.dirs['/'+proj_name] = ((pidx, proj), ) if not proj['number-of-songs']: continue for sidx, song in enumerate(proj['songs']): song_name = getSongName(sidx, song) self.dirs['/'+proj_name+'/'+song_name] = ((pidx, proj), (sidx, song), ) if not song['num-samples']: continue for tidx in range(song['num-tracks']): track_name = getTrackName(tidx) self.dirs['/'+proj_name+'/'+song_name+'/'+track_name] = \ ((pidx, proj), (sidx, song), (tidx, song['file-size']), ) def access(self, path, mode): if path != '/': if not self.dirs.has_key(path): return -errno.EACCES if mode == os.F_OK: return 0 if mode & (os.W_OK): return -errno.EACCES return 0 def getattr(self, path): st = MyStat() if path == '/': st.st_mode = stat.S_IFDIR | 0755 return st n = path.count('/') if n == 1 or n == 2: if self.dirs.has_key(path): st.st_mode = stat.S_IFDIR | 0755 return st return -errno.ENOENT if n == 3: if self.dirs.has_key(path): info = self.dirs[path] st.st_mode = stat.S_IFREG | 0444 st.st_size = info[2][1] return st return -errno.ENOENT def readdir(self, path, offset): n = path.count('/') dirents = ['.', '..'] if path == '/': for idx, proj in enumerate(self.hd24.info['projects']): dirents.append(getProjectName(idx, proj)) elif n == 1: if self.dirs.has_key(path): info = self.dirs[path] proj = info[0][1] if proj['number-of-songs']: for idx, song in enumerate(proj['songs']): dirents.append(getSongName(idx, song)) elif n == 2: if self.dirs.has_key(path): info = self.dirs[path] song = info[1][1] if song['num-samples']: for track in range(song['num-tracks']): dirents.append(getTrackName(track)) for r in dirents: yield fuse.Direntry(r) def main(): usage=""" Read-only FUSE interface to the disk-drive of an Alesis ADAT HD24 digital recorder. """ + Fuse.fusage server = HD24FS(version="%prog " + fuse.__version__, usage=usage, dash_s_do='setsingle') server.parser.add_option(mountopt="drive", metavar="PATH", default=DEFAULT_DRIVE, help="HD24 drive device node [default: %default]") server.parse(values=server, errex=1) server.main() if __name__ == '__main__': main()