Package: dwim
Thedwimprogram is a location aware application launcher. To use it you
are required to create a profile at~/.dwimrc. This profile is a simplePythonscript that defines which applications you want to start automatically,
in which order the applications should start and whether some applications
should only be started when your computer is on a specific physical location.
The location awareness works by matching a unique property of the network that
your computer is connected to (theMAC addressof your currentnetwork
gateway).Every time you run thedwimprogram your~/.dwimrcprofile is evaluated
and your applications are started automatically. If you rundwimagain it
will not start duplicate instances of your applications, but when you quit an
application and then rerundwimthe application will be started again.InstallationUsageCommand line interfaceCreating a profileLocation awarenessAbout the nameContactLicenseInstallationThedwimpackage is available onPyPIwhich means installation should be as
simple as:$pipinstalldwimThere’s actually a multitude of ways to install Python packages (e.g. theper
user site-packages directory,virtual environmentsor just installing
system wide) and I have no intention of getting into that discussion here, so
if this intimidates you then read up on your options before returning to these
instructions ;-).UsageThere are two ways to use thedwimpackage: As the command line programdwimand as a Python API. For details about the Python API please refer to
the API documentation available onRead the Docs. The command line interface
is described below.Please note that you need tocreate a profile(see below) before you can use
the program.Command line interfaceUsage:dwim [OPTIONS]The dwim program is a location aware application launcher. To use it you are
required to create a profile at ~/.dwimrc. This profile is a simple Python
script that defines which applications you want to start automatically, in
which order the applications should start and whether some applications
should only be started given a specific physical location.The location awareness works by checking the MAC address of your gateway
(the device on your network that connects you to the outside world, usually
a router) to a set of known MAC addresses that you define in ~/.dwimrc.Every time you run the dwim program your ~/.dwimrc profile is evaluated and
your applications are started automatically. If you run dwim again it will
not start duplicate instances of your applications, but when you quit an
application and then rerun dwim the application will be started again.Supported options:OptionDescription-c,--config=FILEOverride the default location of the profile script.-v,--verboseIncrease logging verbosity (can be repeated).-q,--quietDecrease logging verbosity (can be repeated).-h,--helpShow this message and exit.Creating a profileTo usedwimyou need to create a profile at~/.dwimrc. The profile is a
simplePythonscript that defines which applications you want to start
automatically, in which order the applications should start and whether some
applications should only be started on a specific physical location. The
profile script has access to functions provided by thedwimPython package.
Please refer tothe documentationfor the available functions. The examples
below show the most useful functions.Starting your first programModifying the “is running” checkEnabling location awarenessExample profileStarting your first programIf you’d like to get your feet wet with a simple example, try this:launch_program('pidgin')When you’ve created the above profile script and you run thedwimprogram
it will start thePidginchat client on the first run. On the next run nothing
will happen because Pidgin is already running.Modifying the “is running” checkThe default “is running” check comes down to the following shell command line:# Replace `pidgin' with any program name.pidof$(whichpidgin)This logic will not work for all programs. For example in my profile I start
theDropboxclient using a wrapper script. Once the Dropbox client has been
started the wrapper script terminates so thepidofcheck fails. The
solution is to customize the “is running” check:launch_program('dropbox start',is_running='pgrep -f "$HOME/.dropbox-dist/*/dropbox"')The example above is for the Dropbox client, but the same principle can be
applied to all other programs. The only trick is to find a shell command that
can correctly tell whether the program is running. Unfortunately this part
cannot be automated in a completely generic manner. The advanced profile
example below contains more examples of defining custompidofchecks andpgrep-fchecks.Enabling location awarenessThe first step to enabling location awareness is to add the following line
to your profile:determine_network_location()Even if you don’t pass any information to this function it will still report
your current gateway’s MAC address. This saves me from having to document the
shell commands needed to do the same thing :-). Run thedwimcommand and
take note of a line that looks like this:We're not connected to a known network (unknown gateway MAC address 84:9c:a6:76:23:8e).Now edit your profile and change the line you just added:location=determine_network_location(home=['84:9c:a6:76:23:8e'])When you now rerundwimit will say:We're connected to the home network.So what did we just do? We took note of the current gateway’s MAC address and
associated that MAC address with a location named “home”. In our profile we can
now start programs on the condition that we’re connected to the home network:iflocation=='home':# Client for Music Player Daemon.launch_program('ario --minimized')else:# Standalone music player.launch_program('rhythmbox')The example profile below (my profile) contains a more advanced example
combining multiple networks and networks with multiple gateways.Example profileI’ve been using variants ofdwim(previously in the form of aBashscript
:-) for years now so my profile has grown quite a bit. Because of this it may
provide some interesting examples of things you can do:# vim: fileencoding=utf-8# ~/.dwimrc: Profile for dwim, my location aware application launcher.# For more information please see https://github.com/xolox/python-dwim/.# Standard library modules.importosimporttime# Packages provided by dwim and its dependencies.fromexecutorimportexecutefromdwimimport(determine_network_location,launch_program,LaunchStatusset_random_background,wait_for_internet_connection)# This is required for graphical Vim and gnome-terminal to have nicely# anti-aliased fonts. See http://awesome.naquadah.org/wiki/Autostart.iflaunch_program('gnome-settings-daemon')==LaunchStatus.started:# When my window manager is initially started I need to wait for a moment# before launching user programs because otherwise strange things can# happen, for example programs that place an icon in the notification area# might be started in the background without adding the icon, so there's# no way to access the program but `dwim' will never restart the program# because it's already running! ಠ_ಠlogger.debug("Sleeping for 10 seconds to give Awesome a moment to initialize ..")time.sleep(10)# Determine the physical location of this computer by matching the MAC address# of the gateway against a set of known MAC addresses. In my own copy I've# documented which MAC addresses belong to which devices, but that doesn't seem# very relevant for the outside world :-)location=determine_network_location(home=['84:9C:A6:76:23:8E'],office=['00:15:C5:5F:92:79','B6:25:B2:19:28:61','00:18:8B:F8:AF:33'])# Correctly configure my multi-monitor setup based on physical location.iflocation=='home':# At home I use a 24" ASUS monitor as my primary screen.# My MacBook Air sits to the left as the secondary screen.execute('xrandr --output eDP1 --auto --noprimary')execute('xrandr --output HDMI1 --auto --primary')execute('xrandr --output HDMI1 --right-of eDP1')iflocation=='work':# At work I use a 24" LG monitor as my primary screen.# My Asus Zenbook sits to the right as the secondary screen.execute('xrandr --output eDP1 --auto')execute('xrandr --output HDMI1 --auto')execute('xrandr --output HDMI1 --left-of eDP1')# Set a random desktop background from my collection of wallpapers. I use the# program `feh' for this because it supports my desktop environment / window# manager (Awesome). You can install `feh' using `sudo apt-get install feh'.set_random_background(command='feh --bg-scale{image}',directory=os.path.expanduser('~/Pictures/Backgrounds'))# Start my favorite programs.launch_program('gvim')launch_program('nm-applet')launch_program('keepassx $HOME/Documents/Passwords/Personal.kdb -min -lock',is_running='pgrep -f "keepassx $HOME/Documents/Passwords/Personal.kdb"')# I actually use three encrypted key passes, two of them for work. I omitted# those here, but their existence explains the complex is_running command.launch_program('fluxgui',is_running='pgrep -f $(which fluxgui)')# The remaining programs require an active internet connection.wait_for_internet_connection()launch_program('chromium-browser',is_running='pidof /usr/lib/chromium-browser/chromium-browser')launch_program('pidgin')iflocation=='home':# Mozilla Thunderbird is only useful at home (at work IMAPS port 993 is blocked).launch_program('thunderbird',is_running='pidof /usr/lib/thunderbird/thunderbird')launch_program('dropbox start',is_running='pgrep -f "$HOME/.dropbox-dist/*/dropbox"')launch_program('spotify')Location awarenessThe location awareness works by matching theMAC addressof your currentnetwork gateway(your router). I’ve previously also used public IPv4
addresses but given the fact that most consumers will have a dynamic IP address
I believe the gateway MAC access is the most stable unique property to match.About the nameIn programming culture the abbreviation DWIM stands forDo What I Mean. The
linked Wikipedia article refers toInterlispbut I actually know the term from
the world ofPerl. The reason I chose this name for my application launcher is
because I like to make computer systems anticipate what I want. Plugging in a
network cable, booting my laptop and having all my commonly used programs
(depending on my physical location) instantly available at startup is a great
example of Do What I Mean if you ask me :-)ContactThe latest version ofdwimis available onPyPIandGitHub. The
documentation is hosted onRead the Docs. For bug reports please create an
issue onGitHub. If you have questions, suggestions, etc. feel free to send me
an e-mail atpeter@peterodding.com.LicenseThis software is licensed under theMIT license.© 2017 Peter Odding.