Source code for libdesktop.applications

# coding: utf-8

# This file is part of libdesktop

# The MIT License (MIT)
#
# Copyright (c) 2016 Bharadwaj Raju
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


import subprocess as sp
import tempfile
import os
import shlex

from libdesktop import desktopfile
from libdesktop import system


[docs]def mac_app_exists(app): '''Check if 'app' is installed (OS X). Check if the given applications is installed on this OS X system. Args: app (str): The application name. Returns: bool: Is the app installed or not? ''' APP_CHECK_APPLESCRIPT = '''try tell application "Finder" set appname to name of application file id "%s" return 0 end tell on error err_msg number err_num return 1 end try''' with open('/tmp/app_check.AppleScript', 'w') as f: f.write(APP_CHECK_APPLESCRIPT % app) app_check_proc = sp.Popen( ['osascript', '-e', '/tmp/app_check.AppleScript']) if app_check_proc.wait() != 0: return False else: return True
[docs]def open_file_with_default_program(file_path, background=False, return_cmd=False): '''Opens a file with the default program for that type. Open the file with the user's preferred application. Args: file_path (str) : Path to the file to be opened. background (bool): Run the program in the background, instead of waiting for completion. Defaults to ``False``. return_cmd (bool): Returns the command to run the program (str) instead of running it. Defaults to ``False``. Returns: str: Only if ``return_cmd``, the command to run the program is returned instead of running it. Else returns nothing. ''' desktop_env = system.get_name() if desktop_env == 'windows': open_file_cmd = 'explorer.exe ' + "'%s'" % file_path elif desktop_env == 'mac': open_file_cmd = 'open ' + "'%s'" % file_path else: file_mime_type = system.get_cmd_out( ['xdg-mime', 'query', 'filetype', file_path]) desktop_file = system.get_cmd_out( ['xdg-mime', 'query', 'default', file_mime_type]) open_file_cmd = desktopfile.execute(desktopfile.locate( desktop_file)[0], files=[file_path], return_cmd=True) if return_cmd: return open_file_cmd else: def_program_proc = sp.Popen(open_file_cmd, shell=True) if not background: def_program_proc.wait()
[docs]def terminal(exec_='', background=False, shell_after_cmd_exec=False, keep_open_after_cmd_exec=False, return_cmd=False): '''Start the default terminal emulator. Start the user's preferred terminal emulator, optionally running a command in it. **Order of starting** Windows: Powershell Mac: - iTerm2 - Terminal.app Linux/Unix: - ``$TERMINAL`` - ``x-terminal-emulator`` - Terminator - Desktop environment's terminal - gnome-terminal - urxvt - rxvt - xterm Args: exec\_ (str) : An optional command to run in the opened terminal emulator. Defaults to empty (no command). background (bool): Run the terminal in the background, instead of waiting for completion. Defaults to ``False``. shell_after_cmd_exec (bool): Start the user's shell after running the command (see exec_). Defaults to `False`. return_cmd (bool): Returns the command used to start the terminal (str) instead of running it. Defaults to ``False``. Returns: str: Only if ``return_cmd``, returns the command to run the terminal instead of running it. Else returns nothing. ''' desktop_env = system.get_name() if not exec_: shell_after_cmd_exec = True if desktop_env == 'windows': terminal_cmd_str = 'start powershell.exe' if desktop_env == 'mac': # Try iTerm2 first, apparently most popular Mac Terminal if mac_app_exists('iTerm2'): terminal_cmd_str = 'open -a iTerm2' else: terminal_cmd_str = 'open -a Terminal' else: # sensible-terminal if os.getenv('TERMINAL'): # Not everywhere, but if user *really* has a preference, they will # set this terminal_cmd_str = os.getenv('TERMINAL') elif system.is_in_path('x-terminal-emulator'): # This is a convenience script that launches terminal based on # user preferences. # This is not available on some distros (but most have it) # so try this first terminal_cmd_str = 'x-terminal-emulator' elif system.is_in_path('terminator'): terminal_cmd_str = 'terminator' elif desktop_env in ['gnome', 'unity', 'cinnamon', 'gnome2']: terminal_cmd_str = 'gnome-terminal' elif desktop_env == 'xfce4': terminal_cmd_str = 'xfce4-terminal' elif desktop_env == 'kde' or desktop_env == 'trinity': terminal_cmd_str = 'konsole' elif desktop_env == 'mate': terminal_cmd_str = 'mate-terminal' elif desktop_env == 'i3': terminal_cmd_str = 'i3-sensible-terminal' elif desktop_env == 'pantheon': terminal_cmd_str = 'pantheon-terminal' elif desktop_env == 'enlightenment': terminal_cmd_str = 'terminology' elif desktop_env == 'lxde' or desktop_env == 'lxqt': terminal_cmd_str = 'lxterminal' else: if system.is_in_path('gnome-terminal'): terminal_cmd_str = 'gnome-terminal' elif system.is_in_path('urxvt'): terminal_cmd_str = 'urxvt' elif system.is_in_path('rxvt'): terminal_cmd_str = 'rxvt' elif system.is_in_path('xterm'): terminal_cmd_str = 'xterm' if exec_: if desktop_env == 'windows': if keep_open_after_cmd_exec and not shell_after_cmd_exec: exec_ += '; pause' if os.path.isfile(exec_): terminal_cmd_str += exec_ else: terminal_cmd_str += ' -Command ' + '"' + exec_ + '"' if shell_after_cmd_exec: terminal_cmd_str += ' -NoExit' else: if keep_open_after_cmd_exec and not shell_after_cmd_exec: exec_ += '; read' if shell_after_cmd_exec: exec_ += '; ' + os.getenv('SHELL') if desktop_env == 'mac': terminal_cmd_str += ' sh -c {}'.format(shlex.quote(exec_)) else: terminal_cmd_str += ' -e {}'.format( shlex.quote('sh -c {}'.format(shlex.quote(exec_)))) if return_cmd: return terminal_cmd_str terminal_proc = sp.Popen([terminal_cmd_str], shell=True, stdout=sp.PIPE) if not background: # Wait for process to complete terminal_proc.wait()
[docs]def text_editor(file='', background=False, return_cmd=False): '''Starts the default graphical text editor. Start the user's preferred graphical text editor, optionally with a file. Args: file (str) : The file to be opened with the editor. Defaults to an empty string (i.e. no file). background (bool): Runs the editor in the background, instead of waiting for completion. Defaults to ``False``. return_cmd (bool): Returns the command (str) to run the editor instead of running it. Defaults to ``False``. Returns: str: Only if ``return_cmd``, the command to run the editor is returned. Else returns nothing. ''' desktop_env = system.get_name() if desktop_env == 'windows': editor_cmd_str = system.get_cmd_out( ['ftype', 'textfile']).split('=', 1)[1] elif desktop_env == 'mac': editor_cmd_str = 'open -a' + system.get_cmd_out( ['def', 'read', 'com.apple.LaunchServices', 'LSHandlers' '-array' '{LSHandlerContentType=public.plain-text;}'] ) else: # Use def handler for MIME-type text/plain editor_cmd_str = system.get_cmd_out( ['xdg-mime', 'query', 'default', 'text/plain']) if '\n' in editor_cmd_str: # Sometimes locate returns multiple results # use first one editor_cmd_str = editor_cmd_str.split('\n')[0] if editor_cmd_str.endswith('.desktop'): # We don't use desktopfile.execute() in order to have working # return_cmd and background editor_cmd_str = desktopfile.parse( desktopfile.locate(editor_cmd_str)[0])['Exec'] for i in editor_cmd_str.split(): if i.startswith('%'): # %-style formatters editor_cmd_str = editor_cmd_str.replace(i, '') if i == '--new-document': # Gedit editor_cmd_str = editor_cmd_str.replace(i, '') if file: editor_cmd_str += ' {}'.format(shlex.quote(file)) if return_cmd: return editor_cmd_str text_editor_proc = sp.Popen([editor_cmd_str], shell=True) if not background: text_editor_proc.wait()