disable debug output
[quasselfs.git] / quasselfs.py
blob499ab57b460864d8ffd5dfd2e2b5446234e359b7
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # "THE BEER-WARE LICENSE" (Revision 42):
5 # Enko <enko@thewired.hacked.jp> wrote this file. As long as you
6 # retain this notice you can do whatever you want with this stuff. If
7 # we meet some day, and you think this stuff is worth it, you can buy
8 # me a beer in return.
11 import os,stat,errno
12 import fuse
13 fuse.fuse_python_api = (0, 2)
14 from fuse import Fuse
15 import sqlite3
16 from datetime import date
17 import datetime
18 import time
19 import codecs
21 import quasseltool
23 class QuasselFileStat(fuse.Stat):
24 def __init__(self):
25 self.st_mode=0
26 self.st_ino=0
27 self.st_dev=0
28 self.st_nlink=0
29 self.st_uid=0
30 self.st_gid=0
31 self.st_size=0
32 self.st_atime=0
33 self.st_mtime=0
34 self.st_ctime=0
36 class QuasselFS(Fuse):
37 flags = 1
38 _bufs = {}
40 def __init__(self, *args, **kw):
41 Fuse.__init__(self, *args, **kw)
43 self.groupings = ("daily", "weekly", "monthly")
44 self.log = quasseltool.Logutil()
46 def _getbuf(self, path):
47 if QuasselFS._bufs.has_key(path):
48 QuasselFS._bufs[path].update()
49 else:
50 QuasselFS._bufs[path] = QuasselFS.Buf(path)
51 return QuasselFS._bufs[path]
53 def getattr(self, path):
54 print ("getattr",path)
55 st = QuasselFileStat()
56 st.st_uid = 1000
57 st.st_gid = 100
58 st.st_ctime = time.time()
59 st.st_atime = time.time()
60 st.st_mtime = time.time()
61 print path.split("/")
62 params = path.split("/")
63 paramcount = len(params)
64 if path == '/':
65 st.st_mode = stat.S_IFDIR | 0755
66 st.st_nlink = 2
67 elif (paramcount == 2) and (len(params[1]) > 0) and self.log.is_user(params[1]):
68 #/user/
69 st.st_mode = stat.S_IFDIR | 0755
70 st.st_nlink = 2
71 elif (paramcount == 3) and self.log.is_network(params[1], params[2]):
72 #/user/network/
73 st.st_mode = stat.S_IFDIR | 0755
74 st.st_nlink = 2
75 elif (paramcount >= 4) and self.log.is_buffer(params[1], params[2], params[3]):
76 #/user/network/channel/
77 if paramcount == 4:
78 st.st_mode = stat.S_IFDIR | 0755
79 st.st_nlink = 2
80 elif paramcount == 5:
81 if params[4] == params[3]+".log":
82 #/user/network/channel/channel.log
83 st.st_mode = stat.S_IFREG | 0444
84 st.st_nlink = 1
85 #TODO
86 #log = getlog(params[1],params[2],time.strptime(params[3].split(".")[0],"%Y-%m-%d"))
87 st.st_size = len(self._getbuf(path))
88 #st.st_size = 0
89 else:
90 #/user/network/channel/weekly/
91 st.st_mode = stat.S_IFDIR | 0755
92 st.st_nlink = 2
93 elif paramcount == 6:
94 #/user/network/channel/daily/2008-11-23.log
95 st.st_mode = stat.S_IFREG | 0444
96 st.st_nlink = 1
97 #TODO: proper size calculations, maybe with time-based Invalidation of Buf objects
98 #log = getlog(params[1],params[2],time.strptime(params[3].split(".")[0],"%Y-%m-%d"))
99 st.st_size = len(self._getbuf(path))
100 #st.st_size = 0
101 else:
102 return -errno.ENOENT
103 return st
105 def readdir(self, path, offset):
106 #print("readdir",path, offset)
107 ret = ['.',
108 '..']
109 params = path.split("/")
110 paramcount = len(params)
112 #print ("param",params,paramcount)
113 if path == "/":
114 ret.extend(self.log.get_users())
115 elif (paramcount == 2) and (len(params[1]) > 0):
116 #/user
117 ret.extend(self.log.get_networks(params[1]))
118 elif (paramcount == 3):
119 #/user/network
120 ret.extend(self.log.get_buffers(params[1], params[2]))
121 ret.remove("")
122 elif (paramcount == 4):
123 #/user/network/channel
124 ret.append(params[3]+".log")
125 ret.extend(self.groupings)
126 #print ("ret",ret)
127 for r in ret:
128 yield fuse.Direntry(r)
130 class Buf(object):
131 def __init__(self, path):
132 self.string = u""
133 self.params = path.split("/")
134 self.expires=0.0
135 self.update()
137 def __len__(self):
138 return len(self.string)
140 def update(self):
141 if time.time() > self.expires:
142 log = quasseltool.Logutil()
143 if len(self.params) > 4:
144 if log.is_buffer(self.params[1], self.params[2], self.params[3]) and self.params[4] == self.params[3]+".log":
145 self.string = ""
146 self._fill(log)
147 #expires every 10 minutes
148 self.expires = time.time()+600
150 def write(self, string):
151 #print ("string", string)
152 self.string += string
153 #self.pos += len(string)
155 def read(self, size, offset):
156 print ("read", self.params)
157 slen = len(self.string)
158 if offset < slen:
159 if offset + size > slen:
160 size = slen - offset
161 buf = self.string[offset:offset+size]
162 else:
163 buf = ""
164 #buf = str(buf)
165 print ("buf", buf)
166 #TODO: if buf is unicode then this will fail
167 #buf = u"Hallo"
168 #print dir(buf)
169 #help(buf.decode)
170 return buf.decode("iso8859_15", "replace")
172 def _fill(self, log):
173 oldtime = time.time()
174 print "start: "+str(oldtime)
175 log.getlog(self.params[1], self.params[2], self.params[3], self)
176 newtime = time.time()
177 print "end: "+str(newtime)+" Duration: "+str(newtime - oldtime)
179 def read(self, path, size, offset):
180 print ("def read", path, size, offset)
181 buf = self._getbuf(path)
182 return buf.read(size, offset)
186 def main():
187 usage="""
188 Userspace hello example
190 """ + Fuse.fusage
191 server = QuasselFS(version="%prog " + fuse.__version__,
192 usage=usage,
193 dash_s_do='setsingle')
195 server.parse(values=server, errex=1)
196 server.main()
198 if __name__=='__main__':
199 main()