Beispiel #1
0
def is_python_interpreter(filename):
    """Evaluate wether a file is a python interpreter or not."""
    real_filename = os.path.realpath(filename)  # To follow symlink if existent
    if (not osp.isfile(real_filename) or 
        not is_python_interpreter_valid_name(filename)):
        return False
    elif is_pythonw(filename):
        if os.name == 'nt':
            # pythonw is a binary on Windows
            if not encoding.is_text_file(real_filename):
                return True
            else:
                return False
        elif sys.platform == 'darwin':
            # pythonw is a text file in Anaconda but a binary in
            # the system
            if is_anaconda() and encoding.is_text_file(real_filename):
                return True
            elif not encoding.is_text_file(real_filename):
                return True
            else:
                return False
        else:
            # There's no pythonw in other systems
            return False
    elif encoding.is_text_file(real_filename):
        # At this point we can't have a text file
        return False
    else:
        return check_python_help(filename)
Beispiel #2
0
 def open(self, fnames=None):
     """Open files with the appropriate application"""
     if fnames is None:
         fnames = self.get_selected_filenames()
     for fname in fnames:
         if osp.isfile(fname) and encoding.is_text_file(fname):
             self.parent_widget.sig_open_file.emit(fname)
         else:
             self.open_outside_spyder([fname])
Beispiel #3
0
def is_python_interpreter(filename):
    """Evaluate wether a file is a python interpreter or not."""
    real_filename = os.path.realpath(filename)  # To follow symlink if existent
    if (not osp.isfile(real_filename) or encoding.is_text_file(real_filename)
        or not is_python_interpreter_valid_name(filename)):
        return False
    try:
        proc = run_program(filename, ["-h"])
        output = to_text_string(proc.communicate()[0])
        valid = ("Options and arguments (and corresponding environment "
                 "variables)")
        if 'usage:' in output and valid in output:
            return True
        else:
            return False
    except:
        return False
Beispiel #4
0
 def find_files_in_path(self, path):
     if self.pathlist is None:
         self.pathlist = []
     self.pathlist.append(path)
     for path, dirs, files in os.walk(path):
         with QMutexLocker(self.mutex):
             if self.stopped:
                 return False
         try:
             for d in dirs[:]:
                 dirname = os.path.join(path, d)
                 if re.search(self.exclude, dirname + os.sep):
                     dirs.remove(d)
             for f in files:
                 filename = os.path.join(path, f)
                 if re.search(self.exclude, filename):
                     continue
                 if is_text_file(filename):
                     self.find_string_in_file(filename)
         except re.error:
             self.error_flag = _("invalid regular expression")
             return False
     return True
Beispiel #5
0
def test_is_text_file(tmpdir):
    p = tmpdir.mkdir("sub").join("random_text.txt")
    p.write("Some random text")
    assert is_text_file(str(p)) == True
Beispiel #6
0
    def browse(self, fpath=None):
        """Prompt user to select an application not found on the list."""
        app = None
        item = None

        if sys.platform == 'darwin':
            if fpath is None:
                basedir = '/Applications/'
                filters = _('Applications (*.app)')
                title = _('Select application')
                fpath, __ = getopenfilename(self, title, basedir, filters)

            if fpath and fpath.endswith('.app') and os.path.isdir(fpath):
                app = os.path.basename(fpath).split('.app')[0]
                for row in range(self.list.count()):
                    item = self.list.item(row)
                    if app == item.text() and fpath == item.fpath:
                        break
                else:
                    item = None
        elif os.name == 'nt':
            if fpath is None:
                basedir = 'C:\\'
                filters = _('Applications (*.exe *.bat *.com)')
                title = _('Select application')
                fpath, __ = getopenfilename(self, title, basedir, filters)

            if fpath:
                check_1 = fpath.endswith('.bat') and is_text_file(fpath)
                check_2 = (fpath.endswith(('.exe', '.com'))
                           and not is_text_file(fpath))
                if check_1 or check_2:
                    app = os.path.basename(fpath).capitalize().rsplit('.')[0]
                    for row in range(self.list.count()):
                        item = self.list.item(row)
                        if app == item.text() and fpath == item.fpath:
                            break
                    else:
                        item = None
        else:
            if fpath is None:
                basedir = '/'
                filters = _('Applications (*.desktop)')
                title = _('Select application')
                fpath, __ = getopenfilename(self, title, basedir, filters)

            if fpath and fpath.endswith(('.desktop')) and is_text_file(fpath):
                entry_data = parse_linux_desktop_entry(fpath)
                app = entry_data['name']
                for row in range(self.list.count()):
                    item = self.list.item(row)
                    if app == item.text() and fpath == item.fpath:
                        break
                else:
                    item = None

        if fpath:
            if item:
                self.list.setCurrentItem(item)
            elif app:
                icon = get_application_icon(fpath)
                item = QListWidgetItem(icon, app)
                item.fpath = fpath
                self.list.addItem(item)
                self.list.setCurrentItem(item)

        self.list.setFocus()
        self._refresh()
Beispiel #7
0
def test_is_text_file(tmpdir):
    p = tmpdir.mkdir("sub").join("random_text.txt")
    p.write("Some random text")
    assert is_text_file(str(p)) == True
Beispiel #8
0
def get_icon_by_extension_or_type(fname, scale_factor):
    """Return the icon depending on the file extension"""
    application_icons = {}
    application_icons.update(BIN_FILES)
    application_icons.update(DOCUMENT_FILES)
    if osp.isdir(fname):
        return icon('DirOpenIcon', scale_factor)
    else:
        basename = osp.basename(fname)
        __, extension = osp.splitext(basename.lower())
        mime_type, __ = mime.guess_type(basename)
        if is_dark_interface():
            icon_by_extension = QIcon(get_image_path('binary.svg'))
        else:
            icon_by_extension = QIcon(get_image_path('binary_light.svg'))

        if extension in OFFICE_FILES:
            icon_by_extension = icon(OFFICE_FILES[extension], scale_factor)

        elif extension in LANGUAGE_ICONS:
            icon_by_extension = icon(LANGUAGE_ICONS[extension], scale_factor)
        else:
            if extension == '.ipynb':
                if is_dark_interface():
                    icon_by_extension = QIcon(
                        get_image_path('notebook_dark.svg'))
                else:
                    icon_by_extension = QIcon(
                        get_image_path('notebook_light.svg'))
            elif extension == '.tex':
                if is_dark_interface():
                    icon_by_extension = QIcon(
                        get_image_path('file_type_tex.svg'))
                else:
                    icon_by_extension = QIcon(
                        get_image_path('file_type_light_tex.svg'))
            elif is_text_file(fname):
                icon_by_extension = icon('TextFileIcon', scale_factor)
            elif mime_type is not None:
                try:
                    # Fix for spyder-ide/spyder#5080. Even though
                    # mimetypes.guess_type documentation states that
                    # the return value will be None or a tuple of
                    # the form type/subtype, in the Windows registry,
                    # .sql has a mimetype of text\plain
                    # instead of text/plain therefore mimetypes is
                    # returning it incorrectly.
                    file_type, bin_name = mime_type.split('/')
                except ValueError:
                    file_type = None
                if file_type is None:
                    if is_dark_interface():
                        icon_by_extension = QIcon(get_image_path('binary.svg'))
                    else:
                        icon_by_extension = QIcon(
                            get_image_path('binary_light.svg'))
                elif file_type == 'audio':
                    icon_by_extension = icon('AudioFileIcon', scale_factor)
                elif file_type == 'video':
                    icon_by_extension = icon('VideoFileIcon', scale_factor)
                elif file_type == 'image':
                    icon_by_extension = icon('ImageFileIcon', scale_factor)
                elif file_type == 'application':
                    if bin_name in application_icons:
                        icon_by_extension = icon(application_icons[bin_name],
                                                 scale_factor)
    return icon_by_extension
Beispiel #9
0
    def find_files_in_path(self, path):
        if self.pathlist is None:
            self.pathlist = []
        self.pathlist.append(path)
        for path, dirs, files in os.walk(path):
            with QMutexLocker(self.mutex):
                if self.stopped:
                    return False
            try:
                # For directories
                for d in dirs[:]:
                    with QMutexLocker(self.mutex):
                        if self.stopped:
                            return False

                    dirname = os.path.join(path, d)

                    # Only search in regular directories
                    st_dir_mode = os.stat(dirname).st_mode
                    if not stat.S_ISDIR(st_dir_mode):
                        dirs.remove(d)

                    if (self.exclude
                            and re.search(self.exclude, dirname + os.sep)):
                        # Exclude patterns defined by the user
                        dirs.remove(d)
                    elif d.startswith('.'):
                        # Exclude all dot dirs.
                        dirs.remove(d)

                # For files
                for f in files:
                    with QMutexLocker(self.mutex):
                        if self.stopped:
                            return False

                    filename = os.path.join(path, f)
                    ext = osp.splitext(filename)[1]

                    # Only search in regular files (i.e. not pipes)
                    st_file_mode = os.stat(filename).st_mode
                    if not stat.S_ISREG(st_file_mode):
                        continue

                    # Exclude patterns defined by the user
                    if self.exclude and re.search(self.exclude, filename):
                        continue

                    # Don't search in plain text files with skipped extensions
                    # (e.g .svg)
                    if ext in self.SKIPPED_EXTENSIONS:
                        continue

                    # It's much faster to check for extension first before
                    # validating if the file is plain text.
                    if (ext in self.PYTHON_EXTENSIONS
                            or ext in self.USEFUL_EXTENSIONS
                            or is_text_file(filename)):
                        self.find_string_in_file(filename)
            except re.error:
                self.error_flag = _("invalid regular expression")
                return False

        # Process any pending results
        if self.partial_results:
            self.process_results()

        return True
Beispiel #10
0
    def get_icon_by_extension_or_type(self, fname, scale_factor):
        """Return the icon depending on the file extension"""
        application_icons = {}
        application_icons.update(self.BIN_FILES)
        application_icons.update(self.DOCUMENT_FILES)

        basename = osp.basename(fname)
        __, extension = osp.splitext(basename.lower())
        mime_type, __ = mime.guess_type(basename)

        if osp.isdir(fname):
            extension = "Folder"

        if (extension, scale_factor) in self.ICONS_BY_EXTENSION:
            return self.ICONS_BY_EXTENSION[(extension, scale_factor)]

        if osp.isdir(fname):
            icon_by_extension = self.icon('DirOpenIcon', scale_factor)
        else:
            icon_by_extension = self.icon('binary')

            if extension in self.OFFICE_FILES:
                icon_by_extension = self.icon(self.OFFICE_FILES[extension],
                                              scale_factor)
            elif extension in self.LANGUAGE_ICONS:
                icon_by_extension = self.icon(self.LANGUAGE_ICONS[extension],
                                              scale_factor)
            else:
                if extension == '.ipynb':
                    icon_by_extension = self.icon('notebook')
                elif extension == '.tex':
                    icon_by_extension = self.icon('file_type_tex')
                elif is_text_file(fname):
                    icon_by_extension = self.icon('TextFileIcon', scale_factor)
                elif mime_type is not None:
                    try:
                        # Fix for spyder-ide/spyder#5080. Even though
                        # mimetypes.guess_type documentation states that
                        # the return value will be None or a tuple of
                        # the form type/subtype, in the Windows registry,
                        # .sql has a mimetype of text\plain
                        # instead of text/plain therefore mimetypes is
                        # returning it incorrectly.
                        file_type, bin_name = mime_type.split('/')
                    except ValueError:
                        file_type = None
                    if file_type is None:
                        icon_by_extension = self.icon('binary')
                    elif file_type == 'audio':
                        icon_by_extension = self.icon('AudioFileIcon',
                                                      scale_factor)
                    elif file_type == 'video':
                        icon_by_extension = self.icon('VideoFileIcon',
                                                      scale_factor)
                    elif file_type == 'image':
                        icon_by_extension = self.icon('ImageFileIcon',
                                                      scale_factor)
                    elif file_type == 'application':
                        if bin_name in application_icons:
                            icon_by_extension = self.icon(
                                application_icons[bin_name], scale_factor)

        self.ICONS_BY_EXTENSION[(extension, scale_factor)] = icon_by_extension
        return icon_by_extension
Beispiel #11
0
    def create_file_manage_actions(self, fnames):
        """Return file management actions"""
        only_files = all([osp.isfile(_fn) for _fn in fnames])
        only_modules = all([
            osp.splitext(_fn)[1] in ('.py', '.pyw', '.ipy') for _fn in fnames
        ])
        only_notebooks = all(
            [osp.splitext(_fn)[1] == '.ipynb' for _fn in fnames])
        only_valid = all([encoding.is_text_file(_fn) for _fn in fnames])
        run_action = create_action(self,
                                   _("Run"),
                                   icon=ima.icon('run'),
                                   triggered=self.run)
        edit_action = create_action(self,
                                    _("Edit"),
                                    icon=ima.icon('edit'),
                                    triggered=self.clicked)
        move_action = create_action(self,
                                    _("Move..."),
                                    icon="move.png",
                                    triggered=self.move)
        delete_action = create_action(self,
                                      _("Delete..."),
                                      icon=ima.icon('editdelete'),
                                      triggered=self.delete)
        rename_action = create_action(self,
                                      _("Rename..."),
                                      icon=ima.icon('rename'),
                                      triggered=self.rename)
        open_action = create_action(self, _("Open"), triggered=self.open)
        ipynb_convert_action = create_action(self,
                                             _("Convert to Python script"),
                                             icon=ima.icon('python'),
                                             triggered=self.convert_notebooks)

        actions = []
        if only_modules:
            actions.append(run_action)
        if only_valid and only_files:
            actions.append(edit_action)
        else:
            actions.append(open_action)
        actions += [delete_action, rename_action]
        basedir = fixpath(osp.dirname(fnames[0]))
        if all([fixpath(osp.dirname(_fn)) == basedir for _fn in fnames]):
            actions.append(move_action)
        actions += [None]
        if only_notebooks and nbexporter is not None:
            actions.append(ipynb_convert_action)

        # VCS support is quite limited for now, so we are enabling the VCS
        # related actions only when a single file/folder is selected:
        dirname = fnames[0] if osp.isdir(fnames[0]) else osp.dirname(fnames[0])
        if len(fnames) == 1 and vcs.is_vcs_repository(dirname):
            # QAction.triggered works differently for PySide and PyQt
            if not API == 'pyside':
                commit_slot = lambda _checked, fnames=[dirname]:\
                                    self.vcs_command(fnames, 'commit')
                browse_slot = lambda _checked, fnames=[dirname]:\
                                    self.vcs_command(fnames, 'browse')
            else:
                commit_slot = lambda fnames=[dirname]:\
                                    self.vcs_command(fnames, 'commit')
                browse_slot = lambda fnames=[dirname]:\
                                    self.vcs_command(fnames, 'browse')
            vcs_ci = create_action(self,
                                   _("Commit"),
                                   icon=ima.icon('vcs_commit'),
                                   triggered=commit_slot)
            vcs_log = create_action(self,
                                    _("Browse repository"),
                                    icon=ima.icon('vcs_browse'),
                                    triggered=browse_slot)
            actions += [None, vcs_ci, vcs_log]

        return actions
Beispiel #12
0
    def create_file_manage_actions(self, fnames):
        """Return file management actions"""
        only_files = all([osp.isfile(_fn) for _fn in fnames])
        only_modules = all([osp.splitext(_fn)[1] in ('.py', '.pyw', '.ipy')
                            for _fn in fnames])
        only_notebooks = all([osp.splitext(_fn)[1] == '.ipynb'
                              for _fn in fnames])
        only_valid = all([encoding.is_text_file(_fn) for _fn in fnames])
        run_action = create_action(self, _("Run"), icon=ima.icon('run'),
                                   triggered=self.run)
        edit_action = create_action(self, _("Edit"), icon=ima.icon('edit'),
                                    triggered=self.clicked)
        move_action = create_action(self, _("Move..."),
                                    icon="move.png",
                                    triggered=self.move)
        delete_action = create_action(self, _("Delete..."),
                                      icon=ima.icon('editdelete'),
                                      triggered=self.delete)
        rename_action = create_action(self, _("Rename..."),
                                      icon=ima.icon('rename'),
                                      triggered=self.rename)
        open_action = create_action(self, _("Open"), triggered=self.open)
        ipynb_convert_action = create_action(self, _("Convert to Python script"),
                                             icon=ima.icon('python'),
                                             triggered=self.convert_notebooks)
        
        actions = []
        if only_modules:
            actions.append(run_action)
        if only_valid and only_files:
            actions.append(edit_action)
        else:
            actions.append(open_action)
        actions += [delete_action, rename_action]
        basedir = fixpath(osp.dirname(fnames[0]))
        if all([fixpath(osp.dirname(_fn)) == basedir for _fn in fnames]):
            actions.append(move_action)
        actions += [None]
        if only_notebooks and nbexporter is not None:
            actions.append(ipynb_convert_action)

        # VCS support is quite limited for now, so we are enabling the VCS
        # related actions only when a single file/folder is selected:
        dirname = fnames[0] if osp.isdir(fnames[0]) else osp.dirname(fnames[0])
        if len(fnames) == 1 and vcs.is_vcs_repository(dirname):
            # QAction.triggered works differently for PySide and PyQt
            if not API == 'pyside':
                commit_slot = lambda _checked, fnames=[dirname]:\
                                    self.vcs_command(fnames, 'commit')
                browse_slot = lambda _checked, fnames=[dirname]:\
                                    self.vcs_command(fnames, 'browse')
            else:
                commit_slot = lambda fnames=[dirname]:\
                                    self.vcs_command(fnames, 'commit')
                browse_slot = lambda fnames=[dirname]:\
                                    self.vcs_command(fnames, 'browse')
            vcs_ci = create_action(self, _("Commit"),
                                   icon=ima.icon('vcs_commit'),
                                   triggered=commit_slot)
            vcs_log = create_action(self, _("Browse repository"),
                                    icon=ima.icon('vcs_browse'),
                                    triggered=browse_slot)
            actions += [None, vcs_ci, vcs_log]

        return actions