Example #1
0
    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')
Example #2
0
    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)
Example #3
0
    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')
Example #4
0
    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
Example #5
0
    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')
Example #6
0
    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)
Example #7
0
        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])
Example #8
0
    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)
Example #9
0
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
Example #10
0
    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
Example #11
0
 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
Example #12
0
    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)
Example #13
0
        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])
Example #14
0
    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)
Example #15
0
    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)
Example #16
0
    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)
Example #17
0
    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
Example #18
0
    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')
Example #19
0
    def apply(self, formatname, function, evaluation, options):
        'RegisterExport[formatname_String, function_, OptionsPattern[RegisterExport]]'
        EXPORTERS[formatname.get_string_value()] = function

        return Symbol('Null')
Example #20
0
    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')
Example #21
0
    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')