def apply(self, formatname, function, posts, evaluation, options): '''RegisterImport[formatname_String, function_, posts_, OptionsPattern[RegisterImport]]''' if function.has_form('List', None): leaves = function.get_leaves() else: leaves = [function] if not (len(leaves) >= 1 and isinstance(leaves[-1], Symbol) and all(x.has_form('RuleDelayed', None) for x in leaves[:-1])): # TODO: Message return Symbol('$Failed') conditionals = { elem.get_string_value(): expr for (elem, expr) in (x.get_leaves() for x in leaves[:-1]) } default = leaves[-1] posts = {} IMPORTERS[formatname.get_string_value()] = (conditionals, default, posts, options) return Symbol('Null')
def apply_elements(self, filename, elements, evaluation, options={}): 'Import[filename_, elements_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]' # Check filename path = filename.to_python() if not (isinstance(path, str) and path[0] == path[-1] == '"'): evaluation.message('Import', 'chtype', filename) return Symbol('$Failed') # Download via URL if isinstance(filename, String): if any(filename.get_string_value().startswith(prefix) for prefix in ('http://', 'https://', 'ftp://')): return Expression('FetchURL', filename, elements, *options_to_rules(options)) # Load local file findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('Import', 'nffil') return findfile def determine_filetype(): return Expression( 'FileFormat', findfile).evaluate(evaluation=evaluation).get_string_value() return self._import(findfile, determine_filetype, elements, evaluation, options)
def apply_elements(self, filename, expr, elems, evaluation, options={}): "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message('Export', 'noelem', elems, String(format_spec[0])) return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, evaluation) exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) if exporter_function.evaluate(evaluation) == Symbol('Null'): return filename return Symbol('$Failed')
def apply(self, url, elements, evaluation, options={}): 'FetchURL[url_String, elements_, OptionsPattern[]]' import tempfile import os py_url = url.get_string_value() temp_handle, temp_path = tempfile.mkstemp(suffix='') try: # some pages need cookies or they will end up in an infinite redirect (i.e. HTTP 303) # loop, which prevents the page from getting loaded. f = urllib2.build_opener(urllib2.HTTPCookieProcessor).open(py_url) try: if sys.version_info >= (3, 0): content_type = f.info().get_content_type() else: content_type = f.headers['content-type'] os.write(temp_handle, f.read()) finally: f.close() # on some OS (e.g. Windows) all writers need to be closed before another # reader (e.g. Import._import) can access it. so close the file here. os.close(temp_handle) def determine_filetype(): return mimetype_dict.get(content_type) result = Import._import(temp_path, determine_filetype, elements, evaluation, options) except HTTPError as e: evaluation.message( 'FetchURL', 'httperr', url, 'the server returned an HTTP status code of %s (%s)' % (e.code, str(e.reason))) return Symbol('$Failed') except URLError as e: # see https://docs.python.org/3/howto/urllib2.html if hasattr(e, 'reason'): evaluation.message('FetchURL', 'httperr', url, str(e.reason)) elif hasattr(e, 'code'): evaluation.message('FetchURL', 'httperr', url, 'server returned %s' % e.code) return Symbol('$Failed') except ValueError as e: evaluation.message('FetchURL', 'httperr', url, str(e)) return Symbol('$Failed') finally: os.unlink(temp_path) return result
def apply(self, filename, expr, elems, evaluation): "Export[filename_, expr_, elems_List]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') ## Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message('Export', 'noelem', elems, String(format_spec[0])) return Symbol('$Failed') # Load the exporter exporter_symbol = EXPORTERS[format_spec[0]] exporter_function = Expression(exporter_symbol, filename, expr) if exporter_function.evaluate(evaluation) == Symbol('Null'): return filename return Symbol('$Failed')
def apply_noelems(self, filename, expr, evaluation): "Export[filename_, expr_]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') # Determine Format form = self._infer_form(filename, evaluation) if form is None: evaluation.message('Export', 'infer', filename) return Symbol('$Failed') else: return self.apply(filename, expr, String(form), evaluation)
def get_results(tmp_function): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp])
def apply_elements(self, data, elements, evaluation, options={}): 'ImportString[data_, elements_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]' if not (isinstance(data, String)): evaluation.message('ImportString', 'string', data) return Symbol('$Failed') def determine_filetype(): if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match("", data=data.to_python())) result = [] for key in mimetype_dict.keys(): if key in mime: result.append(mimetype_dict[key]) # the following fixes an extremely annoying behaviour on some (not all) # installations of Windows, where we end up classifying .csv files als XLS. if len(result) == 1 and result[0] == 'XLS' and path.lower().endswith('.csv'): return String('CSV') if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return result return self._import(None, determine_filetype, elements, evaluation, options, data = data)
def _importer_exporter_options(available_options, options, builtin_name: str, evaluation): stream_options = [] custom_options = [] remaining_options = options.copy() if available_options and available_options.has_form('List', None): for name in available_options.leaves: if isinstance(name, String): py_name = name.get_string_value() elif isinstance(name, Symbol): py_name = strip_context(name.get_name()) else: py_name = None if py_name: value = get_option(remaining_options, py_name, evaluation, pop=True) if value is not None: expr = Expression('Rule', String(py_name), value) if py_name == 'CharacterEncoding': stream_options.append(expr) else: custom_options.append(expr) syntax_option = remaining_options.get("System`$OptionSyntax", None) if syntax_option and syntax_option != Symbol("System`Ignore"): # warn about unsupported options. for name, value in remaining_options.items(): evaluation.message( builtin_name, "optx", Expression('Rule', strip_context(name), value), strip_context(builtin_name)) return stream_options, custom_options
def apply(self, url, elements, evaluation): 'FetchURL[url_String, elements_]' import tempfile import os py_url = url.get_string_value() temp_handle, temp_path = tempfile.mkstemp(suffix='') try: f = urllib2.urlopen(py_url) try: if sys.version_info >= (3, 0): content_type = f.info().get_content_type() else: content_type = f.headers['content-type'] os.write(temp_handle, f.read()) finally: f.close() def determine_filetype(): return mimetype_dict.get(content_type) result = Import._import(temp_path, determine_filetype, elements, evaluation) except HTTPError as e: evaluation.message( 'FetchURL', 'httperr', url, 'the server returned an HTTP status code of %s (%s)' % (e.code, str(e.reason))) return Symbol('$Failed') except URLError as e: # see https://docs.python.org/3/howto/urllib2.html if hasattr(e, 'reason'): evaluation.message('FetchURL', 'httperr', url, str(e.reason)) elif hasattr(e, 'code'): evaluation.message('FetchURL', 'httperr', url, 'server returned %s' % e.code) return Symbol('$Failed') except ValueError as e: evaluation.message('FetchURL', 'httperr', url, str(e)) return Symbol('$Failed') finally: os.unlink(temp_path) return result
def apply(self, expr, evaluation): 'System`Convert`B64Dump`B64Decode[expr_String]' try: clearstring = base64.b64decode(bytearray(expr.get_string_value(), 'utf8')).decode('utf8') clearstring = String(str(clearstring)) except Exception as e: evaluation.message("System`Convert`B64Dump`B64Decode", "b64invalidstr", expr) return Symbol("$Failed") return clearstring
def apply_elements(self, filename, elements, evaluation, options={}): 'Import[filename_, elements_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]' # Check filename path = filename.to_python() if not (isinstance(path, str) and path[0] == path[-1] == '"'): evaluation.message('Import', 'chtype', filename) return Symbol('$Failed') # Load local file findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('Import', 'nffil') return findfile def determine_filetype(): return Expression( 'FileFormat', findfile).evaluate(evaluation=evaluation).get_string_value() return self._import(findfile, determine_filetype, elements, evaluation, options)
def get_results(tmp_function, findfile): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmpfile = False if findfile is None: tmpfile = True stream = Expression('OpenWrite').evaluate(evaluation) findfile = stream.leaves[0] if not data is None: Expression('WriteString', data).evaluate(evaluation) else: Expression('WriteString', String("")).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) stream = None tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) if tmpfile: Expression("DeleteFile", findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): if findfile is None: stream = Expression('StringToStream', data).evaluate(evaluation) else: stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') evaluation.predetermined_out = current_predetermined_out return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): evaluation.predetermined_out = current_predetermined_out return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} evaluation.predetermined_out = current_predetermined_out return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp])
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) result = [] for key in mimetype_dict.keys(): if key in mime: result.append(mimetype_dict[key]) # the following fixes an extremely annoying behaviour on some (not all) # installations of Windows, where we end up classifying .csv files als XLS. if len(result) == 1 and result[0] == 'XLS' and path.lower().endswith( '.csv'): return String('CSV') if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) result = [] for key in mimetype_dict.keys(): if key in mime: result.append(mimetype_dict[key]) if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def apply(self, filename, evaluation): 'FileFormat[filename_String]' findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('FileFormat', 'nffil', Expression('FileFormat', filename)) return findfile path = findfile.get_string_value() if not FileFormat.detector: loader = magic.MagicLoader() loader.load() FileFormat.detector = magic.MagicDetector(loader.mimetypes) mime = set(FileFormat.detector.match(path)) # If match fails match on extension only if mime == set([]): mime, encoding = mimetypes.guess_type(path) if mime is None: mime = set([]) else: mime = set([mime]) # TODO: Add more file formats typedict = { 'application/dicom': 'DICOM', 'application/dbase': 'DBF', 'application/dbf': 'DBF', 'application/eps': 'EPS', 'application/fits': 'FITS', 'application/json': 'JSON', 'application/mathematica': 'NB', 'application/mdb': 'MDB', 'application/mbox': 'MBOX', 'application/msaccess': 'MDB', 'application/octet-stream': 'OBJ', 'application/pdf': 'PDF', 'application/pcx': 'PCX', 'application/postscript': 'EPS', 'application/rss+xml': 'RSS', 'application/rtf': 'RTF', 'application/sla': 'STL', 'application/tga': 'TGA', 'application/vnd.google-earth.kml+xml': 'KML', 'application/vnd.ms-excel': 'XLS', 'application/vnd.ms-pki.stl': 'STL', 'application/vnd.oasis.opendocument.spreadsheet': 'ODS', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'XLSX', # nopep8 'application/vnd.sun.xml.calc': 'SXC', 'application/vnd.msaccess': 'MDB', 'application/vnd.wolfram.cdf': 'CDF', 'application/vnd.wolfram.cdf.text': 'CDF', 'application/vnd.wolfram.mathematica.package': 'Package', 'application/xhtml+xml': 'XHTML', 'application/xml': 'XML', 'application/x-3ds': '3DS', 'application/x-cdf': 'NASACDF', 'application/x-eps': 'EPS', 'application/x-flac': 'FLAC', 'application/x-font-bdf': 'BDF', 'application/x-hdf': 'HDF', 'application/x-msaccess': 'MDB', 'application/x-netcdf': 'NetCDF', 'application/x-shockwave-flash': 'SWF', 'application/x-tex': 'TeX', # Also TeX 'audio/aiff': 'AIFF', 'audio/basic': 'AU', # Also SND 'audio/midi': 'MIDI', 'audio/x-aifc': 'AIFF', 'audio/x-aiff': 'AIFF', 'audio/x-flac': 'FLAC', 'audio/x-wav': 'WAV', 'chemical/seq-na-genbank': 'GenBank', 'chemical/seq-aa-fasta': 'FASTA', 'chemical/seq-na-fasta': 'FASTA', 'chemical/seq-na-fastq': 'FASTQ', 'chemical/seq-na-sff': 'SFF', 'chemical/x-cif': 'CIF', 'chemical/x-daylight-smiles': 'SMILES', 'chemical/x-hin': 'HIN', 'chemical/x-jcamp-dx': 'JCAMP-DX', 'chemical/x-mdl-molfile': 'MOL', 'chemical/x-mdl-sdf': 'SDF', 'chemical/x-mdl-sdfile': 'SDF', 'chemical/x-mdl-tgf': 'TGF', 'chemical/x-mmcif': 'CIF', 'chemical/x-mol2': 'MOL2', 'chemical/x-mopac-input': 'Table', 'chemical/x-pdb': 'PDB', 'chemical/x-xyz': 'XYZ', 'image/bmp': 'BMP', 'image/eps': 'EPS', 'image/fits': 'FITS', 'image/gif': 'GIF', 'image/jp2': 'JPEG2000', 'image/jpeg': 'JPEG', 'image/pbm': 'PNM', 'image/pcx': 'PCX', 'image/pict': 'PICT', 'image/png': 'PNG', 'image/svg+xml': 'SVG', 'image/tga': 'TGA', 'image/tiff': 'TIFF', 'image/vnd.dxf': 'DXF', 'image/vnd.microsoft.icon': 'ICO', 'image/x-3ds': '3DS', 'image/x-dxf': 'DXF', 'image/x-exr': 'OpenEXR', 'image/x-icon': 'ICO', 'image/x-ms-bmp': 'BMP', 'image/x-pcx': 'PCX', 'image/x-portable-anymap': 'PNM', 'image/x-portable-bitmap': 'PBM', 'image/x-portable-graymap': 'PGM', 'image/x-portable-pixmap': 'PPM', 'image/x-xbitmap': 'XBM', 'model/x3d+xml': 'X3D', 'model/vrml': 'VRML', 'model/x-lwo': 'LWO', 'model/x-pov': 'POV', 'text/calendar': 'ICS', 'text/comma-separated-values': 'CSV', 'text/csv': 'CSV', 'text/html': 'HTML', 'text/mathml': 'MathML', 'text/plain': 'Text', 'text/rtf': 'RTF', 'text/scriptlet': 'SCT', 'text/tab-separated-values': 'TSV', 'text/texmacs': 'Text', 'text/vnd.graphviz': 'DOT', 'text/x-csrc': 'C', 'text/x-tex': 'TeX', 'text/x-vcalendar': 'VCS', 'text/x-vcard': 'VCF', 'video/avi': 'AVI', 'video/quicktime': 'QuickTime', 'video/x-flv': 'FLV', # None: 'Binary', } result = [] for key in typedict.keys(): if key in mime: result.append(typedict[key]) if len(result) == 0: result = 'Binary' elif len(result) == 1: result = result[0] else: return None return from_python(result)
def apply_elements(self, expr, elems, evaluation, options={}): "ExportString[expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Just to be sure that the following evaluations do not change the value of this property current_predetermined_out = evaluation.predetermined_out # Infer format if not present if format_spec is None: evaluation.message('ExportString', 'infer', filename) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems if format_spec != []: evaluation.message('ExportString', 'noelem', elems, String(format_spec[0])) else: evaluation.message('ExportString', 'noelem', elems, String("Unknown")) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] function_channels = exporter_options.get("System`FunctionChannels") stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, evaluation) if function_channels is None: evaluation.message('ExportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elif function_channels == Expression('List', String('FileNames')): # Generates a temporary file import tempfile tmpfile = tempfile.NamedTemporaryFile(dir=tempfile.gettempdir()) filename = String(tmpfile.name) tmpfile.close() exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) if exporter_function.evaluate(evaluation) != Symbol('Null'): evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') else: try: tmpstream = open(filename.value, 'rb') res = tmpstream.read().decode('utf-8') tmpstream.close() except Exception as e: print("something went wrong") print(e) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') res = String(str(res)) elif function_channels == Expression('List', String('Streams')): from io import StringIO from mathics.builtin.files import STREAMS, NSTREAMS pystream = StringIO() n = next(NSTREAMS) STREAMS.append(pystream) stream = Expression('OutputStream', String('String'), Integer(n)) exporter_function = Expression( exporter_symbol, stream, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) if res == Symbol('Null'): res = String(str(pystream.getvalue())) else: res = Symbol("$Failed") Expression('Close', stream).evaluate(evaluation) else: evaluation.message('ExportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') evaluation.predetermined_out = current_predetermined_out return res
def apply(self, filename, elements, evaluation): 'Import[filename_, elements_]' # Check filename path = filename.to_python() if not (isinstance(path, basestring) and path[0] == path[-1] == '"'): evaluation.message('Import', 'chtype', filename) return Symbol('$Failed') findfile = Expression('FindFile', filename).evaluate(evaluation) if findfile == Symbol('$Failed'): evaluation.message('Import', 'nffil') return findfile # Check elements if elements.has_form('List', None): elements = elements.get_leaves() else: elements = [elements] for el in elements: if not isinstance(el, String): evaluation.message('Import', 'noelem', el) return Symbol('$Failed') elements = [el.get_string_value() for el in elements] # Determine file type for el in elements: if el in IMPORTERS.keys(): filetype = el elements.remove(el) break else: filetype = Expression( 'FileFormat', findfile).evaluate(evaluation=evaluation).get_string_value() if filetype not in IMPORTERS.keys(): evaluation.message('Import', 'fmtnosup', filetype) return Symbol('$Failed') # Load the importer (conditionals, default_function, posts, importer_options) = IMPORTERS[filetype] # XXX OptionsIssue # function_channels = importer_options.get(String("FunctionChannels")) function_channels = importer_options.get(Symbol("FunctionChannels")) # XXX OptionsIssue # default_element = importer_options.get(String("DefaultElement")) default_element = importer_options.get(Symbol("DefaultElement")) def get_results(tmp_function): if function_channels == Expression('List', String('FileNames')): tmp = Expression(tmp_function, findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenRead', findfile).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') return None tmp = Expression(tmp_function, stream).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO print appropriate error message raise NotImplementedError tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} return dict((a.get_string_value(), b) for (a, b) in map(lambda x: x.get_leaves(), tmp)) # Perform the import defaults = None if elements == []: defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') if default_element == Symbol("Automatic"): return Expression( 'List', *(Expression('Rule', String(key), defaults[key]) for key in defaults.keys())) else: result = defaults.get(default_element.get_string_value()) if result is None: evaluation.message('Import', 'noelem', default_element, from_python(filetype)) return Symbol('$Failed') return result else: assert len(elements) == 1 el = elements[0] if el == "Elements": defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') # Use set() to remove duplicates return from_python( sorted( set(conditionals.keys() + defaults.keys() + posts.keys()))) else: if el in conditionals.keys(): result = get_results(conditionals[el]) if result is None: return Symbol('$Failed') if len(result.keys()) == 1 and result.keys()[0] == el: return result.values()[0] elif el in posts.keys(): # TODO: allow use of conditionals result = get_results(posts[el]) if result is None: return Symbol('$Failed') else: if defaults is None: defaults = get_results(default_function) if defaults is None: return Symbol('$Failed') if el in defaults.keys(): return defaults[el] else: evaluation.message('Import', 'noelem', from_python(el), from_python(filetype)) return Symbol('$Failed')
def apply(self, formatname, function, evaluation, options): 'RegisterExport[formatname_String, function_, OptionsPattern[RegisterExport]]' EXPORTERS[formatname.get_string_value()] = function return Symbol('Null')
def apply_elements(self, filename, expr, elems, evaluation, options={}): "Export[filename_, expr_, elems_List?(AllTrue[#, NotOptionQ]&), OptionsPattern[]]" # Check filename if not self._check_filename(filename, evaluation): return Symbol('$Failed') # Process elems {comp* format?, elem1*} leaves = elems.get_leaves() format_spec, elems_spec = [], [] found_form = False for leaf in leaves[::-1]: leaf_str = leaf.get_string_value() if not found_form and leaf_str in EXPORTERS: found_form = True if found_form: format_spec.append(leaf_str) else: elems_spec.append(leaf) # Just to be sure that the following calls do not change the state of this property current_predetermined_out = evaluation.predetermined_out # Infer format if not present if not found_form: assert format_spec == [] format_spec = self._infer_form(filename, evaluation) if format_spec is None: evaluation.message('Export', 'infer', filename) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') format_spec = [format_spec] else: assert format_spec != [] # First item in format_spec is the explicit format. # The other elements (if present) are compression formats if elems_spec != []: # FIXME: support elems evaluation.message('Export', 'noelem', elems, String(format_spec[0])) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the exporter exporter_symbol, exporter_options = EXPORTERS[format_spec[0]] function_channels = exporter_options.get("System`FunctionChannels") stream_options, custom_options = _importer_exporter_options( exporter_options.get("System`Options"), options, evaluation) if function_channels is None: evaluation.message('Export', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elif function_channels == Expression('List', String('FileNames')): exporter_function = Expression( exporter_symbol, filename, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): stream = Expression('OpenWrite', filename, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`OutputStream': evaluation.message('Export', 'nffil') evaluation.predetermined_out = current_predetermined_out return Symbol("$Failed") exporter_function = Expression( exporter_symbol, stream, expr, *list(chain(stream_options, custom_options))) res = exporter_function.evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) if res == Symbol('Null'): evaluation.predetermined_out = current_predetermined_out return filename evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed')
def _import(findfile, determine_filetype, elements, evaluation, options, data=None): current_predetermined_out = evaluation.predetermined_out # Check elements if elements.has_form('List', None): elements = elements.get_leaves() else: elements = [elements] for el in elements: if not isinstance(el, String): evaluation.message('Import', 'noelem', el) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') elements = [el.get_string_value() for el in elements] # Determine file type for el in elements: if el in IMPORTERS.keys(): filetype = el elements.remove(el) break else: filetype = determine_filetype() if filetype not in IMPORTERS.keys(): evaluation.message('Import', 'fmtnosup', filetype) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Load the importer (conditionals, default_function, posts, importer_options) = IMPORTERS[filetype] stream_options, custom_options = _importer_exporter_options( importer_options.get("System`Options"), options, evaluation) function_channels = importer_options.get("System`FunctionChannels") if function_channels is None: # TODO message if data is None: evaluation.message('Import', 'emptyfch') else: evaluation.message('ImportString', 'emptyfch') evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') default_element = importer_options.get("System`DefaultElement") if default_element is None: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') def get_results(tmp_function, findfile): if function_channels == Expression('List', String('FileNames')): joined_options = list(chain(stream_options, custom_options)) tmpfile = False if findfile is None: tmpfile = True stream = Expression('OpenWrite').evaluate(evaluation) findfile = stream.leaves[0] if not data is None: Expression('WriteString', data).evaluate(evaluation) else: Expression('WriteString', String("")).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) stream = None tmp = Expression(tmp_function, findfile, *joined_options).evaluate(evaluation) if tmpfile: Expression("DeleteFile", findfile).evaluate(evaluation) elif function_channels == Expression('List', String('Streams')): if findfile is None: stream = Expression('StringToStream', data).evaluate(evaluation) else: stream = Expression('OpenRead', findfile, *stream_options).evaluate(evaluation) if stream.get_head_name() != 'System`InputStream': evaluation.message('Import', 'nffil') evaluation.predetermined_out = current_predetermined_out return None tmp = Expression(tmp_function, stream, *custom_options).evaluate(evaluation) Expression('Close', stream).evaluate(evaluation) else: # TODO message evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') tmp = tmp.get_leaves() if not all(expr.has_form('Rule', None) for expr in tmp): evaluation.predetermined_out = current_predetermined_out return None # return {a.get_string_value() : b for (a,b) in map(lambda x: # x.get_leaves(), tmp)} evaluation.predetermined_out = current_predetermined_out return dict((a.get_string_value(), b) for (a, b) in [x.get_leaves() for x in tmp]) # Perform the import defaults = None if not elements: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if default_element == Symbol("Automatic"): evaluation.predetermined_out = current_predetermined_out return Expression( 'List', *(Expression('Rule', String(key), defaults[key]) for key in defaults.keys())) else: result = defaults.get(default_element.get_string_value()) if result is None: evaluation.message('Import', 'noelem', default_element, from_python(filetype)) evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') evaluation.predetermined_out = current_predetermined_out return result else: assert len(elements) == 1 el = elements[0] if el == "Elements": defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') # Use set() to remove duplicates evaluation.predetermined_out = current_predetermined_out return from_python( sorted( set( list(conditionals.keys()) + list(defaults.keys()) + list(posts.keys())))) else: if el in conditionals.keys(): result = get_results(conditionals[el], findfile) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if len(list(result.keys())) == 1 and list( result.keys())[0] == el: evaluation.predetermined_out = current_predetermined_out return list(result.values())[0] elif el in posts.keys(): # TODO: allow use of conditionals result = get_results(posts[el]) if result is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') else: if defaults is None: defaults = get_results(default_function, findfile) if defaults is None: evaluation.predetermined_out = current_predetermined_out return Symbol('$Failed') if el in defaults.keys(): evaluation.predetermined_out = current_predetermined_out return defaults[el] else: evaluation.message('Import', 'noelem', from_python(el), from_python(filetype)) evaluation.predetermined_out = current_predetermined_otu return Symbol('$Failed')