Last active
November 19, 2022 06:19
-
-
Save ytturi/0c23ad5ab89154d24c340c2b1cc3432b to your computer and use it in GitHub Desktop.
Python: Use a subprocess to open a file with it's default program on multi-platform OS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# ------------------------------------------------------ | |
# Author: Ytturi | |
# Author's e-mail: ytturi@protonmail.com | |
# Original Gist: https://gist.github.com/ytturi/0c23ad5ab89154d24c340c2b1cc3432b | |
# Version: 0.1 | |
# License: MIT | |
# ------------------------------------------------------ | |
# This script allows the user to run the default program | |
# to open a file for it's given type or extension. | |
# | |
# It contains the `subprocess_open` method that calls | |
# for the program in a subprocess using subprocess' Popen. | |
# | |
# But also the `get_open_command` that returns the | |
# script to run in a shell so you can call it as you want. | |
# | |
# If you want to test it, you can use this same script to | |
# open the file. | |
# Note that "click" is required in order to test it. | |
# ------------------------------------------------------ | |
from subprocess import Popen, PIPE | |
from subprocess import check_output | |
from platform import system | |
OSNAME = system().lower() | |
def get_open_command(filepath): | |
""" | |
Get the console-like command to open the file | |
for the current platform: | |
- Windows: "start {{ filepath }}" | |
- OS X: "open {{ filepath }}" | |
- Linux based (wdg): "wdg-open {{ filepath }}" | |
:param filepath: Path to the file to be opened | |
:type filepath: string | |
:return: Command to run from a shell | |
:rtype: string | |
""" | |
if 'windows' in OSNAME: | |
opener = 'start' | |
elif 'osx' in OSNAME or 'darwin' in OSNAME: | |
opener = 'open' | |
else: | |
opener = 'xdg-open' | |
return '{opener} {filepath}'.format(opener=opener, filepath=filepath) | |
def subprocess_opener(filepath): | |
""" | |
Method to open the file with the default program in a subprocess. | |
As being called in a subprocess, it will not block the current one. | |
This method runs the command on a subprocess using the default system shell. | |
Check the docs of subprocess module for more info: | |
https://docs.python.org/2/library/subprocess.html#subprocess.Popen | |
The subprocess will run in background so you won't be able to bring back | |
the result code, but the current log can be obtained via the Popen's PIPE: | |
Usage: | |
``` | |
# Run as subprocess | |
subproc = subprocess_opener(filepath) | |
# Get the stdout for the subprocess | |
print(subproc.stdout) | |
# Get the stderr for the subprocess | |
print(subproc.stderr) | |
``` | |
:type filepath: string | |
:param filepath: Path to the file to open | |
:rtype: subprocess | |
:return: The pointer the subprocess returned by the Popen call | |
""" | |
subproc = Popen( | |
get_open_command(filepath), | |
stdout=PIPE, stderr=PIPE, shell=True | |
) | |
subproc.wait() | |
return subproc | |
# Code to run it as a script | |
if __name__ == '__main__' : | |
import click | |
@click.command() | |
@click.argument('filepath') | |
@click.option( | |
'-v', '--verbose', type=bool, is_flag=True, default=False, | |
help='Show verbose messages') | |
def command_opener(filepath, verbose): | |
from os.path import isfile | |
if not isfile(filepath): | |
print('Filepath does not get to a file!') | |
exit(-1) | |
if verbose: | |
print('Opening: "{}" with: "{}"'.format( | |
filepath, get_open_command(filepath=filepath))) | |
subproc = subprocess_opener(filepath) | |
if verbose: | |
print('File opened in a child process') | |
command_opener() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment