mirror of
https://github.com/asciinema/asciinema.git
synced 2025-12-16 03:38:03 +01:00
Classes refactoring
This commit is contained in:
committed by
Marcin Kulik
parent
59e31503da
commit
1dea30c0d7
150
src/__main__.py
150
src/__main__.py
@@ -1,155 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
import httplib, urllib
|
||||
import socket
|
||||
import glob
|
||||
import ConfigParser
|
||||
import uuid
|
||||
|
||||
from constants import BASE_DIR, SCRIPT_NAME
|
||||
from asciicast import AsciiCast
|
||||
from uploader import Uploader
|
||||
|
||||
def check_pending():
|
||||
num = len(pending_list())
|
||||
if num > 0:
|
||||
print 'Warning: %i recorded asciicasts weren\'t uploaded. ' \
|
||||
'Run "%s upload" to upload them or delete them with "rm -rf %s/*".' \
|
||||
% (num, SCRIPT_NAME, AsciiCast.QUEUE_DIR)
|
||||
|
||||
|
||||
def upload_pending(api_url):
|
||||
print 'Uploading pending asciicasts...'
|
||||
for path in pending_list():
|
||||
url = Uploader(api_url, path).upload()
|
||||
if url:
|
||||
print url
|
||||
|
||||
|
||||
def auth(api_url, user_token):
|
||||
url = '%s/connect/%s' % (api_url, user_token)
|
||||
print 'Open following URL in your browser to authenticate and/or claim ' \
|
||||
'recorded asciicasts:\n\n%s' % url
|
||||
|
||||
|
||||
def pending_list():
|
||||
return [os.path.dirname(p) for p in glob.glob(AsciiCast.QUEUE_DIR + '/*/*.time')]
|
||||
|
||||
|
||||
def usage():
|
||||
text = '''usage: %s [-h] [-i] [-y] [-c <command>] [-t <title>] [action]
|
||||
|
||||
Asciicast recorder+uploader.
|
||||
|
||||
Actions:
|
||||
rec record asciicast (this is the default when no action given)
|
||||
upload upload recorded (but not uploaded) asciicasts
|
||||
auth authenticate and/or claim recorded asciicasts
|
||||
|
||||
Optional arguments:
|
||||
-c command run specified command instead of shell ($SHELL)
|
||||
-t title specify title of recorded asciicast
|
||||
-y don't prompt for confirmation
|
||||
-h, --help show this help message and exit
|
||||
--version show version information''' % SCRIPT_NAME
|
||||
print text
|
||||
|
||||
|
||||
def print_version():
|
||||
print 'asciiio 1.0'
|
||||
|
||||
from cli import CLI
|
||||
|
||||
def main():
|
||||
'''Parses command-line options and creates asciicast.'''
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'c:t:ihy', ['help', 'version'])
|
||||
except getopt.error as msg:
|
||||
print('%s: %s' % (sys.argv[0], msg))
|
||||
print('Run "%s --help" for list of available options' % sys.argv[0])
|
||||
sys.exit(2)
|
||||
|
||||
action = 'rec'
|
||||
|
||||
if len(args) > 1:
|
||||
print('Too many arguments')
|
||||
print('Run "%s --help" for list of available options' % sys.argv[0])
|
||||
sys.exit(2)
|
||||
elif len(args) == 1:
|
||||
action = args[0]
|
||||
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.add_section('user')
|
||||
config.add_section('api')
|
||||
config.add_section('record')
|
||||
|
||||
cfg_file = os.path.expanduser('~/.ascii.io/config')
|
||||
try:
|
||||
config.read(cfg_file)
|
||||
except ConfigParser.ParsingError:
|
||||
print('Config file %s contains syntax errors' % cfg_file)
|
||||
sys.exit(2)
|
||||
|
||||
try:
|
||||
user_token = config.get('user', 'token')
|
||||
except ConfigParser.NoOptionError:
|
||||
user_token = str(uuid.uuid1())
|
||||
config.set('user', 'token', user_token)
|
||||
|
||||
try:
|
||||
record_input = config.getboolean('record', 'input')
|
||||
except ConfigParser.NoOptionError:
|
||||
record_input = False
|
||||
|
||||
try:
|
||||
api_url = config.get('api', 'url')
|
||||
except ConfigParser.NoOptionError:
|
||||
api_url = 'http://ascii.io'
|
||||
|
||||
if not os.path.isdir(BASE_DIR):
|
||||
os.mkdir(BASE_DIR)
|
||||
|
||||
if not os.path.exists(cfg_file):
|
||||
with open(cfg_file, 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
api_url = os.environ.get('ASCII_IO_API_URL', api_url)
|
||||
|
||||
command = None
|
||||
title = None
|
||||
always_yes = False
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
usage()
|
||||
sys.exit(0)
|
||||
elif opt == '--version':
|
||||
print_version()
|
||||
sys.exit(0)
|
||||
elif opt == '-c':
|
||||
command = arg.split()
|
||||
elif opt == '-t':
|
||||
title = arg
|
||||
elif opt == '-i':
|
||||
record_input = True
|
||||
elif opt == '-y':
|
||||
always_yes = True
|
||||
|
||||
if action == 'rec':
|
||||
check_pending()
|
||||
if not AsciiCast(api_url, user_token, command, title, record_input, always_yes).create():
|
||||
sys.exit(1)
|
||||
elif action == 'upload':
|
||||
upload_pending(api_url)
|
||||
elif action == 'auth':
|
||||
auth(api_url, user_token)
|
||||
else:
|
||||
print('Unknown action: %s' % action)
|
||||
print('Run "%s --help" for list of available options' % sys.argv[0])
|
||||
|
||||
CLI().run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -5,22 +5,23 @@ import subprocess
|
||||
import json
|
||||
import shutil
|
||||
|
||||
from constants import SCRIPT_NAME, BASE_DIR
|
||||
from constants import BASE_DIR
|
||||
from pty_recorder import PtyRecorder
|
||||
from uploader import Uploader
|
||||
|
||||
class AsciiCast(object):
|
||||
QUEUE_DIR = BASE_DIR + "/queue"
|
||||
|
||||
def __init__(self, api_url, user_token, command, title, record_input, always_yes):
|
||||
self.api_url = api_url
|
||||
self.user_token = user_token
|
||||
def __init__(self, config, options):
|
||||
self.config = config
|
||||
self.api_url = config.api_url()
|
||||
self.user_token = config.user_token()
|
||||
self.path = AsciiCast.QUEUE_DIR + "/%i" % int(time.time())
|
||||
self.command = command
|
||||
self.title = title
|
||||
self.record_input = record_input
|
||||
self.command = options.command
|
||||
self.title = options.title
|
||||
self.record_input = options.record_input
|
||||
self.always_yes = options.always_yes
|
||||
self.duration = None
|
||||
self.always_yes = always_yes
|
||||
|
||||
def create(self):
|
||||
self._record()
|
||||
@@ -85,7 +86,7 @@ class AsciiCast(object):
|
||||
return process.communicate()[0].strip()
|
||||
|
||||
def _upload(self):
|
||||
url = Uploader(self.api_url, self.path).upload()
|
||||
url = Uploader(self.config, self.path).upload()
|
||||
if url:
|
||||
print url
|
||||
return True
|
||||
|
||||
66
src/cli.py
Normal file
66
src/cli.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
|
||||
import help_text
|
||||
from config import Config
|
||||
from options import Options
|
||||
from constants import SCRIPT_NAME
|
||||
from asciicast import AsciiCast
|
||||
from uploader import Uploader
|
||||
|
||||
class CLI:
|
||||
'''Parses command-line options and xxxxxxxxxxxxxxxxx.'''
|
||||
|
||||
def run(self):
|
||||
self.config = Config()
|
||||
self.options = Options(sys.argv)
|
||||
|
||||
action = self.options.action
|
||||
|
||||
if action == 'rec':
|
||||
self.check_pending()
|
||||
self.record()
|
||||
elif action == 'upload':
|
||||
self.upload_pending()
|
||||
elif action == 'auth':
|
||||
self.auth()
|
||||
elif action == 'help':
|
||||
self.usage()
|
||||
elif action == 'version':
|
||||
self.print_version()
|
||||
else:
|
||||
print('Unknown action: %s' % action)
|
||||
print('Run "%s --help" for list of available options' % sys.argv[0])
|
||||
|
||||
def record(self):
|
||||
if not AsciiCast(self.config, self.options).create():
|
||||
sys.exit(1)
|
||||
|
||||
def auth(self):
|
||||
url = '%s/connect/%s' % (self.config.api_url(), self.config.user_token())
|
||||
print 'Open following URL in your browser to authenticate and/or claim ' \
|
||||
'recorded asciicasts:\n\n%s' % url
|
||||
|
||||
def check_pending(self):
|
||||
num = len(self.pending_list())
|
||||
if num > 0:
|
||||
print 'Warning: %i recorded asciicasts weren\'t uploaded. ' \
|
||||
'Run "%s upload" to upload them or delete them with "rm -rf %s/*".' \
|
||||
% (num, SCRIPT_NAME, AsciiCast.QUEUE_DIR)
|
||||
|
||||
def upload_pending(self):
|
||||
print 'Uploading pending asciicasts...'
|
||||
for path in self.pending_list():
|
||||
url = Uploader(self.config, path).upload()
|
||||
if url:
|
||||
print url
|
||||
|
||||
def pending_list(self):
|
||||
return [os.path.dirname(p) for p in glob.glob(AsciiCast.QUEUE_DIR + '/*/*.time')]
|
||||
|
||||
def print_version(self):
|
||||
print 'asciiio 1.0'
|
||||
|
||||
def usage(self):
|
||||
print help_text.TEXT
|
||||
46
src/config.py
Normal file
46
src/config.py
Normal file
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
import ConfigParser
|
||||
import uuid
|
||||
|
||||
class Config:
|
||||
|
||||
def __init__(self):
|
||||
self.config_filename = os.path.expanduser('~/.ascii.io/config')
|
||||
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.add_section('user')
|
||||
config.add_section('api')
|
||||
config.add_section('record')
|
||||
|
||||
try:
|
||||
config.read(self.config_filename)
|
||||
except ConfigParser.ParsingError:
|
||||
print('Config file %s contains syntax errors' % self.config_filename)
|
||||
sys.exit(2)
|
||||
|
||||
self.config = config
|
||||
|
||||
# if not os.path.isdir(BASE_DIR):
|
||||
# os.mkdir(BASE_DIR)
|
||||
|
||||
def api_url(self):
|
||||
try:
|
||||
api_url = self.config.get('api', 'url')
|
||||
except ConfigParser.NoOptionError:
|
||||
api_url = 'http://ascii.io'
|
||||
|
||||
api_url = os.environ.get('ASCII_IO_API_URL', api_url)
|
||||
|
||||
return api_url
|
||||
|
||||
def user_token(self):
|
||||
try:
|
||||
user_token = self.config.get('user', 'token')
|
||||
except ConfigParser.NoOptionError:
|
||||
user_token = str(uuid.uuid1())
|
||||
self.config.set('user', 'token', user_token)
|
||||
|
||||
with open(self.config_filename, 'wb') as configfile:
|
||||
self.config.write(configfile)
|
||||
|
||||
return user_token
|
||||
17
src/help_text.py
Normal file
17
src/help_text.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from constants import SCRIPT_NAME
|
||||
|
||||
TEXT = '''usage: %s [-h] [-i] [-y] [-c <command>] [-t <title>] [action]
|
||||
|
||||
Asciicast recorder+uploader.
|
||||
|
||||
Actions:
|
||||
rec record asciicast (this is the default when no action given)
|
||||
upload upload recorded (but not uploaded) asciicasts
|
||||
auth authenticate and/or claim recorded asciicasts
|
||||
|
||||
Optional arguments:
|
||||
-c command run specified command instead of shell ($SHELL)
|
||||
-t title specify title of recorded asciicast
|
||||
-y don't prompt for confirmation
|
||||
-h, --help show this help message and exit
|
||||
--version show version information''' % SCRIPT_NAME
|
||||
41
src/options.py
Normal file
41
src/options.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
class Options:
|
||||
|
||||
def __init__(self, argv):
|
||||
self.action = None
|
||||
self.command = None
|
||||
self.title = None
|
||||
self.record_input = False
|
||||
self.always_yes = False
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(argv[1:], 'c:t:ihy', ['help', 'version'])
|
||||
except getopt.error as msg:
|
||||
print('%s: %s' % (argv[0], msg))
|
||||
print('Run "%s --help" for list of available options' % argv[0])
|
||||
sys.exit(2)
|
||||
|
||||
if len(args) == 0:
|
||||
self.action = 'rec'
|
||||
elif len(args) == 1:
|
||||
self.action = args[0]
|
||||
elif len(args) > 1:
|
||||
print('Too many arguments')
|
||||
print('Run "%s --help" for list of available options' % argv[0])
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ('-h', '--help'):
|
||||
self.action = 'help'
|
||||
elif opt == '--version':
|
||||
self.action = 'version'
|
||||
elif opt == '-c':
|
||||
self.command = arg.split()
|
||||
elif opt == '-t':
|
||||
self.title = arg
|
||||
elif opt == '-i':
|
||||
self.record_input = True
|
||||
elif opt == '-y':
|
||||
self.always_yes = True
|
||||
@@ -8,8 +8,8 @@ class Uploader(object):
|
||||
Uploads recorded script to website using HTTP based API.
|
||||
'''
|
||||
|
||||
def __init__(self, api_url, path):
|
||||
self.api_url = api_url
|
||||
def __init__(self, config, path):
|
||||
self.api_url = config.api_url()
|
||||
self.path = path
|
||||
|
||||
def upload(self):
|
||||
|
||||
Reference in New Issue
Block a user