Add more logging and configurable levels
This commit is contained in:
parent
f460a2f145
commit
30fe994c68
15
sn_fuse.py
15
sn_fuse.py
|
@ -71,9 +71,14 @@ class StandardNotesFUSE(LoggingMixIn, Operations):
|
||||||
path_parts = path.split('/')
|
path_parts = path.split('/')
|
||||||
note_name = path_parts[1]
|
note_name = path_parts[1]
|
||||||
note = self.notes[note_name]
|
note = self.notes[note_name]
|
||||||
text = note['text'][:offset] + data.decode()
|
|
||||||
uuid = note['uuid']
|
uuid = note['uuid']
|
||||||
|
|
||||||
|
try:
|
||||||
|
text = note['text'][:offset] + data.decode()
|
||||||
|
except UnicodeError:
|
||||||
|
logging.error('Unable to parse non-unicode data.')
|
||||||
|
raise FuseOSError(errno.EIO)
|
||||||
|
|
||||||
self.item_manager.writeNote(uuid, text)
|
self.item_manager.writeNote(uuid, text)
|
||||||
|
|
||||||
return len(data)
|
return len(data)
|
||||||
|
@ -84,6 +89,7 @@ class StandardNotesFUSE(LoggingMixIn, Operations):
|
||||||
|
|
||||||
# disallow hidden files (usually editor / OS files)
|
# disallow hidden files (usually editor / OS files)
|
||||||
if note_name[0] == '.':
|
if note_name[0] == '.':
|
||||||
|
logging.error('Creation of hidden files is disabled.')
|
||||||
raise FuseOSError(errno.EPERM)
|
raise FuseOSError(errno.EPERM)
|
||||||
|
|
||||||
now = datetime.utcnow().isoformat()[:-3] + 'Z' # hack
|
now = datetime.utcnow().isoformat()[:-3] + 'Z' # hack
|
||||||
|
@ -103,6 +109,10 @@ class StandardNotesFUSE(LoggingMixIn, Operations):
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def mkdir(self, path, mode):
|
||||||
|
logging.error('Creation of directories is disabled.')
|
||||||
|
raise FuseOSError(errno.EPERM)
|
||||||
|
|
||||||
def chmod(self, path, mode):
|
def chmod(self, path, mode):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@ -112,9 +122,6 @@ class StandardNotesFUSE(LoggingMixIn, Operations):
|
||||||
def destroy(self, path):
|
def destroy(self, path):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def mkdir(self, path, mode):
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def readlink(self, path):
|
def readlink(self, path):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ from fuse import FUSE
|
||||||
|
|
||||||
OFFICIAL_SERVER_URL = 'https://sync.standardnotes.org'
|
OFFICIAL_SERVER_URL = 'https://sync.standardnotes.org'
|
||||||
APP_NAME = 'standardnotes-fs'
|
APP_NAME = 'standardnotes-fs'
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
|
|
||||||
# path settings
|
# path settings
|
||||||
cfg_env = os.environ.get('SN_FS_CONFIG_PATH')
|
cfg_env = os.environ.get('SN_FS_CONFIG_PATH')
|
||||||
|
@ -28,9 +27,13 @@ def parse_options():
|
||||||
help='Standard Notes username to log in with')
|
help='Standard Notes username to log in with')
|
||||||
parser.add_argument('--password',
|
parser.add_argument('--password',
|
||||||
help='Standard Notes password to log in with\n'
|
help='Standard Notes password to log in with\n'
|
||||||
'NOTE: It is NOT recommended to use this! The\n'
|
'NOTE: It is NOT recommended to use this option!\n'
|
||||||
' password may be stored in history, so\n'
|
' The password may be stored in history, so\n'
|
||||||
' use the password prompt instead.')
|
' use the password prompt instead.')
|
||||||
|
parser.add_argument('-v', '--verbosity', action='count',
|
||||||
|
help='output verbosity -v or -vv (implies --foreground)')
|
||||||
|
parser.add_argument('--foreground', action='store_true',
|
||||||
|
help='run standardnotes-fs in the foreground')
|
||||||
parser.add_argument('--sync-url',
|
parser.add_argument('--sync-url',
|
||||||
help='URL of Standard File sync server. Defaults to:\n'
|
help='URL of Standard File sync server. Defaults to:\n'
|
||||||
''+OFFICIAL_SERVER_URL)
|
''+OFFICIAL_SERVER_URL)
|
||||||
|
@ -48,6 +51,15 @@ def main():
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
keys = {}
|
keys = {}
|
||||||
|
|
||||||
|
# configure logging
|
||||||
|
if args.verbosity == 1:
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
elif args.verbosity == 2:
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logging.basicConfig(level=logging.CRITICAL)
|
||||||
|
if args.verbosity: args.foreground = True
|
||||||
|
|
||||||
config_file = args.config if args.config else CONFIG_FILE
|
config_file = args.config if args.config else CONFIG_FILE
|
||||||
config_file = pathlib.Path(config_file)
|
config_file = pathlib.Path(config_file)
|
||||||
|
|
||||||
|
@ -55,9 +67,9 @@ def main():
|
||||||
if args.logout:
|
if args.logout:
|
||||||
try:
|
try:
|
||||||
config_file.unlink()
|
config_file.unlink()
|
||||||
print('Config file deleted.')
|
print('Config file deleted and logged out.')
|
||||||
except OSError:
|
except OSError:
|
||||||
print('Already logged out.')
|
logging.info('Already logged out.')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# make sure mountpoint is specified
|
# make sure mountpoint is specified
|
||||||
|
@ -69,17 +81,21 @@ def main():
|
||||||
if not args.no_config_file:
|
if not args.no_config_file:
|
||||||
try:
|
try:
|
||||||
config_file.parent.mkdir(mode=0o0700, parents=True, exist_ok=True)
|
config_file.parent.mkdir(mode=0o0700, parents=True, exist_ok=True)
|
||||||
|
log_msg = 'Using config directory "%s".'
|
||||||
|
logging.info(log_msg % str(config_file.parent))
|
||||||
except OSError:
|
except OSError:
|
||||||
err_msg = 'Error creating directory "%s".'
|
log_msg = 'Error creating config file directory "%s".'
|
||||||
logging.critical(err_msg % str(config_file.parent))
|
logging.critical(log_msg % str(config_file.parent))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with config_file.open() as f:
|
with config_file.open() as f:
|
||||||
config.read_file(f)
|
config.read_file(f)
|
||||||
|
log_msg = 'Loaded config file "%s".'
|
||||||
|
logging.info(log_msg % str(config_file))
|
||||||
except OSError:
|
except OSError:
|
||||||
err_msg = 'Unable to read config file "%s".'
|
log_msg = 'Unable to read config file "%s".'
|
||||||
logging.info(err_msg % str(config_file))
|
logging.info(log_msg % str(config_file))
|
||||||
|
|
||||||
# figure out all login params
|
# figure out all login params
|
||||||
if args.sync_url:
|
if args.sync_url:
|
||||||
|
@ -88,6 +104,8 @@ def main():
|
||||||
sync_url = config.get('user', 'sync_url')
|
sync_url = config.get('user', 'sync_url')
|
||||||
else:
|
else:
|
||||||
sync_url = OFFICIAL_SERVER_URL
|
sync_url = OFFICIAL_SERVER_URL
|
||||||
|
log_msg = 'Using sync URL "%s".'
|
||||||
|
logging.info(log_msg % sync_url)
|
||||||
|
|
||||||
if config.has_option('user', 'username') \
|
if config.has_option('user', 'username') \
|
||||||
and config.has_section('keys') \
|
and config.has_section('keys') \
|
||||||
|
@ -107,15 +125,14 @@ def main():
|
||||||
if not keys:
|
if not keys:
|
||||||
keys = sn_api.genKeys(password)
|
keys = sn_api.genKeys(password)
|
||||||
sn_api.signIn(keys)
|
sn_api.signIn(keys)
|
||||||
|
log_msg = 'Successfully logged into account "%s".'
|
||||||
|
logging.info(log_msg % username)
|
||||||
login_success = True
|
login_success = True
|
||||||
except:
|
except:
|
||||||
err_msg = 'Failed to log into account "%s".'
|
log_msg = 'Failed to log into account "%s".'
|
||||||
logging.critical(err_msg % username)
|
logging.critical(log_msg % username)
|
||||||
login_success = False
|
login_success = False
|
||||||
|
|
||||||
if login_success:
|
|
||||||
fuse = FUSE(StandardNotesFUSE(sn_api), args.mountpoint, foreground=True, nothreads=True)
|
|
||||||
|
|
||||||
# write settings back if good, clear if not
|
# write settings back if good, clear if not
|
||||||
if not args.no_config_file:
|
if not args.no_config_file:
|
||||||
config.read_dict(dict(user=dict(sync_url=sync_url, username=username),
|
config.read_dict(dict(user=dict(sync_url=sync_url, username=username),
|
||||||
|
@ -124,9 +141,21 @@ def main():
|
||||||
with config_file.open(mode='w+') as f:
|
with config_file.open(mode='w+') as f:
|
||||||
if login_success:
|
if login_success:
|
||||||
config.write(f)
|
config.write(f)
|
||||||
|
log_msg = 'Config written to file "%s".'
|
||||||
|
logging.info(log_msg % str(config_file))
|
||||||
|
else:
|
||||||
|
log_msg = 'Clearing config file "%s".'
|
||||||
|
logging.info(log_msg % username)
|
||||||
|
config_file.chmod(0o600)
|
||||||
except OSError:
|
except OSError:
|
||||||
err_msg = 'Unable to write config file "%s".'
|
log_msg = 'Unable to write config file "%s".'
|
||||||
logging.error(err_msg % str(config_file))
|
logging.error(log_msg % str(config_file))
|
||||||
|
|
||||||
|
if login_success:
|
||||||
|
logging.info('Starting FUSE filesystem.')
|
||||||
|
fuse = FUSE(StandardNotesFUSE(sn_api), args.mountpoint, foreground=args.foreground, nothreads=True)
|
||||||
|
|
||||||
|
logging.info('Exiting.')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user