Commit 6e7b21a9 authored by Hugo Hörnquist's avatar Hugo Hörnquist

Initial commit.

parents
#!/usr/bin/env python3
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
import urllib.request
import xml.etree.ElementTree as ET
import time
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)
url = "https://datorhandbok.lysator.liu.se/index.php/Special:Exportera/{}"
ns = { 'mw': 'http://www.mediawiki.org/xml/export-0.10/' }
class Page:
"""
One "page" on the wiki. Currently only really supports "regular",
plain text, pages.
"""
def __init__(self, xml_response):
xml = ET.fromstring(xml_response)
page = xml.find("mw:page", ns)
self.name = page.find("mw:title", ns).text
revision = page.find("mw:revision", ns)
timestr = revision.find("mw:timestamp", ns).text
self.timestamp = time.strptime(timestr, "%Y-%m-%dT%H:%M:%Sz")
text = revision.find("mw:text", ns)
self.text = text.text
# TODO get propper length, something with character encoding, posibly
self.len = int(text.get("bytes") or len(self.text))
# TODO check hash
pages = {}
def get_page(name):
"""
Retuns the page with name "name". Downloads it if it's not already present
"""
p = pages.get(name)
if not p:
request = urllib.request.urlopen(url.format(name))
info = request.info()
s = info.get("content-type")
charset = info.get_charset() or s[len("charset=") + s.find("charset="):]
str = request.read().decode(charset)
pages[name] = p = Page(str)
return p
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 MediawikiFS(fuse.Fuse):
def getattr(self, path):
st = MyStat()
if path == '/':
st.st_mode = stat.S_IFDIR | 0o755
st.st_size = len(pages)
st.st_nlink = 2
else:
st.st_mode = stat.S_IFREG | 0o444
p = get_page(path[1:])
st.st_size = p.len
st.st_mtime = time.mktime(p.timestamp)
return st
def readdir(self, path, offset):
for r in '.', '..':
yield fuse.Direntry(r)
for r in pages.keys():
yield fuse.Direntry(r)
def open(self, path, flags):
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):
p = get_page(path[1:])
if offset < p.len:
if offset + size > p.len:
size = p.len - offset
buf = p.text[offset:offset+size]
else:
buf = ''
return buf
def main():
usage="""
Userspace hello example
""" + fuse.Fuse.fusage
server = MediawikiFS(version="%prog " + fuse.__version__,
usage=usage,
dash_s_do='setsingle')
server.parse(errex=1)
server.main()
if __name__ == '__main__':
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment