mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-13 08:38:43 +03:00
Nix Setup and Docs (#5)
This commit is contained in:
parent
a759115a8d
commit
67359564eb
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/result
|
14
README.md
14
README.md
@ -1,9 +1,17 @@
|
||||
# urb
|
||||
|
||||
Unix control of Urbit
|
||||
|
||||
# dependencies
|
||||
# Running and Installing
|
||||
|
||||
To run without installing anything:
|
||||
|
||||
```bash
|
||||
sudo apt install libfuse-dev python-pip
|
||||
sudo pip install requests fuse-python
|
||||
nix-shell --pure --command 'python ./urb -d "(add 3 4)"'
|
||||
```
|
||||
|
||||
To install `urb`:
|
||||
|
||||
```bash
|
||||
nix-env -if .
|
||||
```
|
||||
|
39
default.nix
Normal file
39
default.nix
Normal file
@ -0,0 +1,39 @@
|
||||
let
|
||||
|
||||
rev = "61c3169a0e17d789c566d5b241bfe309ce4a6275";
|
||||
hash = "0qbycg7wkb71v20rchlkafrjfpbk2fnlvvbh3ai9pyfisci5wxvq";
|
||||
|
||||
nixpkgs = builtins.fetchTarball {
|
||||
name = "nixpkgs-2019-01-15";
|
||||
url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz";
|
||||
sha256 = hash;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{ pkgs ? import nixpkgs {} }:
|
||||
|
||||
let
|
||||
|
||||
pyenv = pkgs.python2.withPackages (py: [ py.requests ]);
|
||||
pyexe = "${pyenv}/bin/python";
|
||||
|
||||
in
|
||||
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
name = "urb";
|
||||
buildInputs = [ pyenv ];
|
||||
unpackPhase = "true";
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
cp ${./urb} $out/bin/urb.py
|
||||
|
||||
cat > $out/bin/urb <<EOF
|
||||
#!/usr/bin/env bash
|
||||
${pyexe} $out/bin/urb.py "\$@"
|
||||
EOF
|
||||
|
||||
chmod +x $out/bin/urb
|
||||
'';
|
||||
}
|
195
fuse
195
fuse
@ -1,195 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# write script for fuse/api/urb demo
|
||||
|
||||
# vere should start this as a child process
|
||||
# filenames (.)
|
||||
# speed
|
||||
# could say if no . then dir (else check)
|
||||
# drop size, thus no roundtrip on getattr
|
||||
|
||||
import os
|
||||
import sys
|
||||
import stat
|
||||
import errno
|
||||
import fuse
|
||||
import logging
|
||||
import json
|
||||
import requests
|
||||
import datetime
|
||||
import collections
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(levelname)s %(funcName)s %(lineno)s - %(message)s',
|
||||
filename='log')
|
||||
|
||||
|
||||
fuse.fuse_python_api = (0, 2)
|
||||
|
||||
url = "http://localhost:12321"
|
||||
|
||||
CacheEntry = collections.namedtuple('CacheEntry', ['when', 'what'])
|
||||
|
||||
Path = collections.namedtuple('Path',
|
||||
['vane', 'ship', 'desk', 'case', 'spur', 'mark'])
|
||||
|
||||
class Stat(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 FS(fuse.Fuse):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.xcache = {}
|
||||
super(FS, self).__init__(**kwargs)
|
||||
|
||||
def _path_to_path(self, path):
|
||||
logging.debug('_path_to_path %s' % path)
|
||||
parts = path.split('/')[1:]
|
||||
if len(parts) < 4:
|
||||
logging.warn('path too short! %s' % path)
|
||||
return Path('c', '=', '=', '=', '', '')
|
||||
else:
|
||||
return Path(parts[0],
|
||||
parts[1],
|
||||
parts[2],
|
||||
parts[3],
|
||||
'/' + '/'.join(parts[4:]) if parts[4:] else '',
|
||||
parts[-1] if len(parts) > 4 else '')
|
||||
|
||||
def _path_to_beam(self, care, path):
|
||||
return '%%%s%s /%s/%s/%s%s' \
|
||||
% (path.vane, care, path.ship, path.desk, path.case, path.spur)
|
||||
|
||||
def _get_x(self, path):
|
||||
payload = \
|
||||
{'source':
|
||||
{'as': {'mark': 'tang', 'next':
|
||||
{'hoon': {'code': '|=(mime [leaf+(trip q.q)]~)', 'next':
|
||||
{'as': {'mark': 'mime', 'next':
|
||||
{'as': {'mark': path.mark, 'next':
|
||||
{'dojo': '.^(noun %s)' % self._path_to_beam('x', path)}}}}}}}}},
|
||||
'sink': {'stdout': None}}
|
||||
r = requests.post(url, data=json.dumps(payload))
|
||||
if r.text[0] == '"':
|
||||
return r.text[1:-1].decode('string_escape').encode('ascii') + '\n'
|
||||
else:
|
||||
logging.warn('unrecognized response')
|
||||
return '\n'
|
||||
|
||||
# we're a file iff we have contents and no children. no
|
||||
# children and no contents is an implicitly-created
|
||||
# directory. no contents but children is clearly a
|
||||
# directory. contents and children is a directory, else
|
||||
# children would be inaccessible.
|
||||
def _is_dir(self, path):
|
||||
logging.debug('_is_dir %s' % self._path_to_beam('a', path))
|
||||
payload = \
|
||||
{'source':
|
||||
{'hoon': {'code': '|=(a/arch !?=({^ $~} a))', 'next':
|
||||
{'dojo': '.^(arch %s)' % self._path_to_beam('y', path)}}},
|
||||
'sink':
|
||||
{'stdout': None}}
|
||||
r = requests.post(url, data=json.dumps(payload))
|
||||
logging.debug('%s is%s a directory: %s' %
|
||||
(self._path_to_beam('a', path),
|
||||
'' if r.text == '"%.y"' else ' not', r.text))
|
||||
return r.text == '"%.y"'
|
||||
|
||||
def _direntries(self, path):
|
||||
payload = \
|
||||
{'source':
|
||||
{'hoon': {'code': '|=((list {knot $~}) (turn +< head))', 'next':
|
||||
{'hoon': {'code': '|=((map knot $~) (~(tap by +<)))', 'next':
|
||||
{'hoon': {'code': 'tail', 'next':
|
||||
{'dojo': '.^(arch %s)' % self._path_to_beam('y', path)}}}}}}},
|
||||
'sink':
|
||||
{'stdout': None}}
|
||||
r = requests.post(url, data=json.dumps(payload))
|
||||
logging.debug([x.encode('ascii') for x in r.text[1:-1].split('/')[1:]])
|
||||
return [x.encode('ascii') for x in r.text[1:-1].split('/')[1:]]
|
||||
|
||||
def _read_file(self, path):
|
||||
logging.debug('_read_file %s' % self._path_to_beam('a', path))
|
||||
logging.debug('xcache %s' % str(self.xcache))
|
||||
if self.xcache.get(path) is None or \
|
||||
datetime.datetime.now() - self.xcache.get(path).when > \
|
||||
datetime.timedelta(0, 2):
|
||||
logging.debug('None %s' % self._path_to_beam('a', path))
|
||||
result = self._get_x(path)
|
||||
logging.debug(self.xcache)
|
||||
self.xcache[path] = CacheEntry(datetime.datetime.now(), result)
|
||||
logging.debug(self.xcache)
|
||||
return result
|
||||
else:
|
||||
logging.debug('not None %s %s' %
|
||||
(datetime.datetime.now() - self.xcache.get(path).when,
|
||||
self.xcache.get(path)))
|
||||
return self.xcache.get(path).what
|
||||
|
||||
def getattr(self, path):
|
||||
logging.debug('getattr %s' % path)
|
||||
path = self._path_to_path(path)
|
||||
|
||||
st = Stat()
|
||||
if self._is_dir(path):
|
||||
st.st_mode = stat.S_IFDIR | 0755
|
||||
st.st_nlink = 2
|
||||
else:
|
||||
st.st_mode = stat.S_IFREG | 0444
|
||||
st.st_nlink = 1
|
||||
st.st_size = len(self._read_file(path))
|
||||
return st
|
||||
|
||||
def readdir(self, path, offset):
|
||||
logging.debug('readdir %s' % path)
|
||||
path = self._path_to_path(path)
|
||||
for child in ['.', '..'] + self._direntries(path):
|
||||
yield fuse.Direntry(child)
|
||||
|
||||
def open(self, path, flags):
|
||||
logging.debug('open %s' % path)
|
||||
path = self._path_to_path(path)
|
||||
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):
|
||||
logging.debug('read %s' % path)
|
||||
path = self._path_to_path(path)
|
||||
text = self._read_file(path)
|
||||
|
||||
# with open('/home/philip/urbit/urb/log', 'w') as f:
|
||||
# f.write(str([text, len(text), "\\'dull the pain\\'", len("\\'dull the pain\\'")]))
|
||||
length = len(text)
|
||||
if offset < length:
|
||||
if offset + size > length:
|
||||
size = length - offset
|
||||
buf = text[offset:offset+size]
|
||||
else:
|
||||
buf = ''
|
||||
return buf
|
||||
|
||||
def main():
|
||||
usage="""
|
||||
Just Do It
|
||||
|
||||
""" + fuse.Fuse.fusage
|
||||
|
||||
server= FS(version="%prog " + fuse.__version__,
|
||||
usage=usage,
|
||||
dash_s_do='setsingle')
|
||||
server.parse(errex=1)
|
||||
server.main()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user