1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-09-20 03:11:04 +00:00
supysonic/cli.py

188 lines
7.2 KiB
Python
Raw Normal View History

2013-09-05 15:17:25 +00:00
# coding: utf-8
2013-09-07 10:58:28 +00:00
import sys, cmd, argparse, getpass
2013-09-05 15:17:25 +00:00
import config
2013-09-06 16:22:52 +00:00
class CLIParser(argparse.ArgumentParser):
def error(self, message):
self.print_usage(sys.stderr)
raise RuntimeError(message)
2013-09-05 15:17:25 +00:00
class CLI(cmd.Cmd):
prompt = "supysonic> "
def do_EOF(self, line):
return True
def default(self, line):
print 'Unknown command %s' % line.split()[0]
self.do_help(None)
def postloop(self):
print
def completedefault(self, text, line, begidx, endidx):
# First check if we have subparsers for the command
parsers = getattr(self, line.split()[0] + '_subparsers', None)
if not parsers:
return []
# Count how many 'words' (minus one) to begidx (there must be a better way to do that)
whitespace = False
num_words = 0
for i in xrange(len(line.split()[0]), begidx):
ws = line[i].isspace()
if ws != whitespace:
if not ws:
num_words = num_words + 1
whitespace = ws
if num_words == 0:
return [ a for a in parsers.choices.keys() if a.startswith(text) ]
return []
2013-09-06 16:22:52 +00:00
folder_parser = CLIParser(prog = 'folder', add_help = False)
folder_subparsers = folder_parser.add_subparsers(dest = 'action')
folder_subparsers.add_parser('list', help = 'Lists folders', add_help = False)
folder_add_parser = folder_subparsers.add_parser('add', help = 'Adds a folder', add_help = False)
folder_add_parser.add_argument('name', help = 'Name of the folder to add')
folder_add_parser.add_argument('path', help = 'Path to the directory pointed by the folder')
folder_del_parser = folder_subparsers.add_parser('delete', help = 'Deletes a folder', add_help = False)
folder_del_parser.add_argument('name', help = 'Name of the folder to delete')
folder_scan_parser = folder_subparsers.add_parser('scan', help = 'Run a scan on specified folders', add_help = False)
folder_scan_parser.add_argument('folders', metavar = 'folder', nargs = '*', help = 'Folder(s) to be scanned. If ommitted, all folders are scanned')
2013-09-05 15:17:25 +00:00
def do_folder(self, line):
2013-09-06 16:22:52 +00:00
try:
args = self.folder_parser.parse_args(line.split())
except RuntimeError, e:
2013-09-07 13:11:13 +00:00
print >>sys.stderr, e
2013-09-06 16:22:52 +00:00
return
2013-09-05 15:17:25 +00:00
2013-09-06 16:22:52 +00:00
if args.action == 'list':
2013-09-05 15:17:25 +00:00
print 'Name\t\tPath\n----\t\t----'
2013-09-07 10:58:28 +00:00
print '\n'.join('{0: <16}{1}'.format(f.name, f.path) for f in db.Folder.query.filter(db.Folder.root == True))
2013-09-06 16:22:52 +00:00
elif args.action == 'add':
ret = FolderManager.add(args.name, args.path)
if ret != FolderManager.SUCCESS:
print FolderManager.error_str(ret)
2013-09-05 15:17:25 +00:00
else:
2013-09-06 16:22:52 +00:00
print "Folder '%s' added" % args.name
elif args.action == 'delete':
ret = FolderManager.delete_by_name(args.name)
if ret != FolderManager.SUCCESS:
print FolderManager.error_str(ret)
2013-09-05 15:17:25 +00:00
else:
2013-09-06 16:22:52 +00:00
print "Deleted folder '%s'" % args.name
elif args.action == 'scan':
2013-09-05 16:25:33 +00:00
s = Scanner(db.session)
2013-09-06 16:22:52 +00:00
if args.folders:
folders = map(lambda n: db.Folder.query.filter(db.Folder.name == n and db.Folder.root == True).first() or n, args.folders)
2013-09-05 16:25:33 +00:00
if any(map(lambda f: isinstance(f, basestring), folders)):
print "No such folder(s): " + ' '.join(f for f in folders if isinstance(f, basestring))
for folder in filter(lambda f: isinstance(f, db.Folder), folders):
FolderManager.scan(folder.id, s)
else:
for folder in db.Folder.query.filter(db.Folder.root == True):
FolderManager.scan(folder.id, s)
added, deleted = s.stats()
db.session.commit()
print "Scanning done"
print 'Added: %i artists, %i albums, %i tracks' % (added[0], added[1], added[2])
print 'Deleted: %i artists, %i albums, %i tracks' % (deleted[0], deleted[1], deleted[2])
2013-09-05 15:17:25 +00:00
def help_folder(self):
2013-09-06 16:22:52 +00:00
self.folder_parser.print_help()
#for cmd, parser in self.folder_subparsers.choices.iteritems():
# parser.print_help()
2013-09-05 15:17:25 +00:00
2013-09-07 10:58:28 +00:00
user_parser = CLIParser(prog = 'user', add_help = False)
user_subparsers = user_parser.add_subparsers(dest = 'action')
user_subparsers.add_parser('list', help = 'List users', add_help = False)
user_add_parser = user_subparsers.add_parser('add', help = 'Adds a user', add_help = False)
user_add_parser.add_argument('name', help = 'Name/login of the user to add')
user_add_parser.add_argument('-a', '--admin', action = 'store_true', help = 'Give admin rights to the new user')
user_add_parser.add_argument('-p', '--password', help = "Specifies the user's password")
user_add_parser.add_argument('-e', '--email', default = '', help = "Sets the user's email address")
user_del_parser = user_subparsers.add_parser('delete', help = 'Deletes a user', add_help = False)
user_del_parser.add_argument('name', help = 'Name/login of the user to delete')
user_admin_parser = user_subparsers.add_parser('set-admin', help = 'Enable/disable admin rights for a user', add_help = False)
user_admin_parser.add_argument('name', help = 'Name/login of the user to grant/revoke admin rights')
user_admin_parser.add_argument('--off', action = 'store_true', help = 'Revoke admin rights if present, grant them otherwise')
user_pass_parser = user_subparsers.add_parser('changepass', help = "Changes a user's password", add_help = False)
user_pass_parser.add_argument('name', help = 'Name/login of the user to which change the password')
user_pass_parser.add_argument('password', nargs = '?', help = 'New password')
def do_user(self, line):
try:
args = self.user_parser.parse_args(line.split())
except RuntimeError, e:
2013-09-07 13:11:13 +00:00
print >>sys.stderr, e
2013-09-07 10:58:28 +00:00
return
if args.action == 'list':
print 'Name\t\tAdmin\tEmail\n----\t\t-----\t-----'
print '\n'.join('{0: <16}{1}\t{2}'.format(u.name, '*' if u.admin else '', u.mail) for u in db.User.query.all())
elif args.action == 'add':
if not args.password:
password = getpass.getpass()
confirm = getpass.getpass('Confirm password: ')
if password != confirm:
print >>sys.stderr, "Passwords don't match"
return
args.password = password
status = UserManager.add(args.name, args.password, args.email, args.admin)
if status != UserManager.SUCCESS:
print >>sys.stderr, UserManager.error_str(status)
elif args.action == 'delete':
user = db.User.query.filter(db.User.name == args.name).first()
if not user:
print >>sys.stderr, 'No such user'
else:
db.session.delete(user)
db.session.commit()
print "User '{0.name}' deleted".format(args)
elif args.action == 'set-admin':
user = db.User.query.filter(db.User.name == args.name).first()
if not user:
print >>sys.stderr, 'No such user'
else:
user.admin = not args.off
db.session.commit()
print "{0} '{1}' admin rights".format('Revoked' if args.off else 'Granted', args.name)
elif args.action == 'changepass':
if not args.password:
password = getpass.getpass()
confirm = getpass.getpass('Confirm password: ')
if password != confirm:
print >>sys.stderr, "Passwords don't match"
return
args.password = password
status = UserManager.change_password2(args.name, args.password)
if status != UserManager.SUCCESS:
print >>sys.stderr, UserManager.error_str(status)
else:
print "Successfully changed '{}' password".format(args.name)
def help_user(self):
self.user_parser.print_help()
2013-09-05 15:17:25 +00:00
if __name__ == "__main__":
if not config.check():
sys.exit(1)
import db
db.init_db()
2013-09-05 16:40:43 +00:00
from managers.folder import FolderManager
2013-09-07 10:58:28 +00:00
from managers.user import UserManager
2013-09-05 16:25:33 +00:00
from scanner import Scanner
2013-09-05 15:17:25 +00:00
if len(sys.argv) > 1:
CLI().onecmd(' '.join(sys.argv[1:]))
else:
CLI().cmdloop()