"""Install
Routine to install a parser/writer/converter style.
"""
import os
import re
import sys
import site
import shutil
import urllib2
import zipfile
import textwrap
import distutils.dir_util
import distutils.errors
from glob import iglob
from imp import load_source
from lexor.command import error
from lexor.command import config
DESC = """
Install a parser/writer/converter style.
"""
[docs]def add_parser(subp, fclass):
"""Add a parser to the main subparser. """
tmpp = subp.add_parser('install', help='install a style',
formatter_class=fclass,
description=textwrap.dedent(DESC))
tmpp.add_argument('style', type=str,
help='name of style to install')
tmpp.add_argument('--user', action='store_true',
help='install in user-site')
tmpp.add_argument('--path', type=str,
help='specify the installation path')
[docs]def install_style(style, install_dir):
"""Install a given style to the install_dir path. """
mod = load_source('tmp_mod', style)
info = mod.INFO
if info['to_lang']:
key = '%s.%s.%s.%s' % (info['lang'], info['type'],
info['to_lang'], info['style'])
typedir = '%s/%s.%s.%s'
typedir = typedir % (install_dir, info['lang'], info['type'],
info['to_lang'])
else:
key = '%s.%s.%s' % (info['lang'], info['type'], info['style'])
typedir = '%s/%s.%s'
typedir = typedir % (install_dir, info['lang'], info['type'])
if not os.path.exists(typedir):
try:
os.makedirs(typedir)
except OSError:
msg = 'OSError: unable to create directory. Did you `sudo`?\n'
error(msg)
moddir = os.path.splitext(style)[0]
base, name = os.path.split(moddir)
if base == '':
base = '.'
# Copy main file
old = '%s/%s.py' % (base, name)
new = '%s/%s-%s.py' % (typedir, name, info['ver'])
sys.stdout.write('writing %s ... ' % new)
try:
shutil.copyfile(old, new)
except OSError:
msg = 'OSError: unable to copy file. Did you `sudo`?\n'
sys.stdout.write('done\n')
# Copy auxilary modules
old = '%s/%s' % (base, name)
new = '%s/%s-%s' % (typedir, name, info['ver'])
sys.stdout.write('writing %s/* ... ' % new)
try:
distutils.dir_util.copy_tree(old, new)
except distutils.errors.DistutilsFileError:
pass
sys.stdout.write('done\n')
# Compile the style
new = '%s/%s-%s.py' % (typedir, name, info['ver'])
load_source('tmp_mod', new)
# Compile the rest
new = '%s/%s-%s/*.py' % (typedir, name, info['ver'])
for path in iglob(new):
load_source('tmp_mod', path)
# Check if its on development
cfg_file = config.read_config()
if 'develop' in cfg_file:
if key in cfg_file['develop']:
del cfg_file['develop'][key]
if 'version' in cfg_file:
cfg_file['version'][key] = info['ver']
else:
cfg_file.add_section('version')
cfg_file['version'][key] = info['ver']
# Write configuration
config.write_config(cfg_file)
[docs]def download_file(url, base='.'):
"""Download a file. """
try:
print '-> Retrieving %s' % url
response = urllib2.urlopen(url)
local_name = '%s/tmp_%s' % (base, os.path.basename(url))
with open(local_name, "wb") as local_file:
local_file.write(response.read())
except urllib2.HTTPError, err:
print "HTTP Error:", err.code, url
except urllib2.URLError, err:
print "URL Error:", err.reason, url
return local_name
[docs]def unzip_file(local_name):
"""Extract the contents of a zip file. """
zfile = zipfile.ZipFile(local_name)
dirname = zfile.namelist()[0].split('/')[0]
zfile.extractall()
return dirname
[docs]def run():
"""Run the command. """
arg = config.CONFIG['arg']
if arg.path:
install_dir = arg.path
elif arg.user:
try:
install_dir = '%s/lib/lexor' % site.getuserbase()
except AttributeError:
install_dir = 'lib/lexor'
else:
install_dir = '%s/lib/lexor' % sys.prefix
style_file = arg.style
if '.py' not in style_file:
style_file = '%s.py' % style_file
if os.path.exists(style_file):
install_style(style_file, install_dir)
return
matches = []
url = 'http://jmlopez-rod.github.io/lexor-lang/lexor-lang.url'
print '-> Searching in %s' % url
response = urllib2.urlopen(url)
for line in response.readlines():
name, url = line.split(':', 1)
if arg.style in name:
matches.append([name.strip(), url.strip()])
for match in matches:
doc = urllib2.urlopen(match[1]).read()
links = re.finditer(r' href="?([^\s^"]+)', doc)
links = [link.group(1) for link in links if '.zip' in link.group(1)]
for link in links:
if 'master' in link:
path = urllib2.urlparse.urlsplit(match[1])
style_url = '%s://%s%s' % (path[0], path[1], link)
local_name = download_file(style_url, '.')
dirname = unzip_file(local_name)
# Assuming there is only one python file
os.chdir(dirname)
for path in iglob('*.py'):
install_style(path, install_dir)
os.chdir('..')
os.remove(local_name)
shutil.rmtree(dirname)