Showing posts with label tools. Show all posts
Showing posts with label tools. Show all posts

Wednesday, September 26, 2018

Emacs on Mac

Until recently, I have been an Aquamacs user on the Mac. However, recently I have been switching back to a more standard Emacs distribution for Mac. After some time of research I ended up with the Emacs Mac Port. This distribution is easily installed and updated through Homebrew, and since I am already using Homebrew for other important software on my Mac (including bsdmake), this was an obvious choice. I use Homebrew to install the Emacs Mac Port from railwaycat with these commands:

  brew tap railwaycat/emacsmacport
  brew install emacs-mac

Later, when I want to update to the latest release, I just do this:

  brew update emacs-mac

Optionally, you can also create a soft-link in the Application directory to be able to access Emacs from there:

  ln -s /usr/local/opt/emacs-mac/Emacs.app /Applications

Tips to run Emacs from command line prompt can be found here.

Since I want to have a more Mac feel to my Emacs on the Mac (used Aquamacs to long, I guess), the final configuration I suggest is to add support for typical Mac key bindings. I use a modified version of this mac-port-keys.el. My remapping of modifiers is changed to the following (use the function modifier key for meta since I need option modifier key for different key modifiers, including typing the Norwegian letters æ, ø and å):

  (when (symbolp 'mac-control-modifier)
  ;; Re-map modifiers
  (setq mac-control-modifier 'control
        ;mac-option-modifier 'meta      ; (AA)
        mac-function-modifier 'meta     ; (AA)
        mac-command-modifier 'super)
  )

On my iMac keyboard, I do not have the function modifier key on a proper location, so I use Karabiner-Elements to map the unused Caps Lock key to the function modifier (the fn-key). I actually do this on all my Macs, since I never use Caps Locks and the meta key is used a lot in Emacs.

And I use Cua-Mode (but I disable the overriding of standard Emacs bindings):

  ;; Cua-mode (AA)
  (cua-mode t)
  (setq cua-enable-cua-keys nil)          ; C-v and M-v to scroll!

Thursday, October 26, 2017

Run all Airmail rules

I currently use Airmail as my Mac (and iOS) mail client. With many email accounts I found that Airmail fits my needs OK. And I have created a large number of rules that is automatically performed on new emails in my inbox. However, for different reasons I would sometimes like to perform all my rules manually. As far as I know this is not possible in the Mac version of Airmail. So I had to implement it myself using AppleScript. You can find the program below. A few things you should be aware of: (i) This program do not open the Airmail application (I expect Airmail to be in use on your Mac). (ii) The program needs to be able to control your computer (see System Preferences → Security & Privacy → Privacy → Accessibility). (iii) I have tried to make it robust, but no guarantees. It could mess up.

I suggest to save this code as the application RunAllAirmailRules.app in the Applications folder of your home directory (choose File Format → Application in the save dialog in Script Editor). Enjoy.

-- An Airmail 3 application
tell application "System Events" to tell process "Airmail 3"
  set frontmost to true
  
  -- Activate (and open) "Rules" window of Airmail 3
  set rules to windows where title contains "Rules"
  if rules is {} then
    click menu item "Rules" of menu "Window" of menu bar 1
    delay 1
    set rules to windows where title contains "Rules"
  end if
  if rules is not {} then
    perform action "AXRaise" of item 1 of rules
    
    -- Traverese all rules
    set all_rules to rows of table 1 of scroll area 1 of item 1 of rules
    repeat with rule in all_rules
      
      -- Select rule and go to preview of the rule
      set the value of attribute "AXSelected" of rule to true
      set enabled_rule to the value of checkbox "Enable" of item 1 of rules as boolean
      if enabled_rule then
        click button "Preview" of item 1 of rules
        
        -- Click "Apply to ..." button
        set btn_ok to false
        repeat while not btn_ok
          try
            set btn to button "Apply to previous messages" of sheet 1 of window "Rules"
            if enabled of btn then
              set btn_ok to true
            end if
          on error msg
            delay 0.1
            set btn_ok to false
          end try
        end repeat
        click btn
        
        -- Click "Close" button
        set btn_ok to false
        repeat while not btn_ok
          try
            set btn to button "Close" of sheet 1 of window "Rules"
            if enabled of btn then
              set btn_ok to true
            end if
          on error msg
            delay 0.1
            set btn_ok to false
          end try
        end repeat
        click btn
        
      end if
    end repeat
  end if
end tell

Friday, May 15, 2015

Cryptography with Python 3

In 2012 I posted a post on using PyCrypto with Python 3 and some AES and RSA examples. Now, I usually use the cryptography Python library (implemented for both Python 2 and 3). I have ported all my PyCrypto examples from 2012 (see the README file) to the cryptography library.

pycryptex.py / pycryptex-cbc.py

pycryptex.py [src] is a small example using AES to encrypt and decrypt a text:

> python3 pycryptex.py

The example includes two versions, one using the high level Fernet class and the other using the more low level hazmat functions. In pycryptex-cbc.py [src] the second version is implemented using CBC mode (where padding is necessary):

> python3 pycryptex-cbc.py

pycrypto-mkkey.py / pycrypto-encrypt.py / pycrypto-decrypt.py

An example with three programs. pycrypto-mkkey.py [src] is used to generatea RSA key-pair. To generate an RSA key pair stored in the file k1 and protected with the password "passwd" is done with the following command (the public key is stored in the k1.pub file):

> python3 pycrypto-mkkey.py k1 "passwd"

pycrypto-encrypt.py [src] generates an AES key and use this key to encrypt plaintext data read from stdin (README in the example below). The ciphertext is written to stdout (CIPHER in the example below). The AES key is encrypted using the public RSA key k1.pub generated above and then saved to file k2 (no password needed since the public key is not password protected):

> python3 pycrypto-encrypt.py k1.pub k2 < README > CIPHER

pycrypto-decrypt.py [src] reads the encrypted AES key k2 end decrypts it using the RSA key k1 (k1 is protected with the password "passwd"). It then use the AES key to decrypt the ciphertext data read from stdin (CIPHER in the example below). The plaintext is written to stdout:

> python3 pycrypto-decrypt.py k1 k2 "passwd" < CIPHER

pwsec-server.py / pwsec-client.py

An example with two programs, a server pwsec-server.py [src] and a client pwsec-client.py [src]. The example demonstrates secure communication using AES. The shared key is generated from a password (the shared secret). We are using CTR mode, and the initial value (for the counter) is sent first in the first message. First start the server then the client:

> python3 pwsec-server.py localhost 3456 "mypass" &
> python3 pwsec-client.py localhost 3456 "mypass"

These two programs are using the tcp module from NOOP project (currently, only a few of the modules from the NOOP project are released, May 2015).

pubsec-send.py / pubsec-receive.py

An example with two programs, a sender pubsec-send.py [src] and a receiver pubsec-receive.py [src]. The example demonstrates secure communication using a combination of RSA and AES. The sender use the public RSA key of the receiver to encrypt the first message sent to the receiver. This message contains the shared secret AES key of the session. Then the sender sends a message encrypted with this key. First start the receiver then the sender:

> python3 pubsec-receive.py k1 localhost 3456 "passwd" &
> python3 pubsec-send.py k1.pub localhost 3456

These two programs are also using the tcp module from NOOP project.

Note

This code is not meant to be robust. All error checking is ignored.

Monday, April 27, 2015

Run automator workflow with keyboard shortcuts

In the last post we demonstrated how to automate a task using AppleScript and the Fake scriptable web browser. Often, I use automator included on every Mac to perform such task. To activate them, we bind them to a keyboard shortcut in the given application. The example we will use today is to press the a keyboard shortcut to load the remote content of an email in Mail.app (you have of course turned off loading all remote content in emails by unselecting Load remote content in messages in the Viewing part of Mail.app Preferences).

Create the automator workflow

We start by creating the automator workflow:

  1. Start Automator and select New Document.
  2. Choose the type of workflow to be Services.
  3. Choose that service receives no input in Mail.app.
  4. Open Mail.app and open an email with (unloaded) remote content.
  5. In Automator, press the Record button.
  6. In Mail.app, press the Load Remote Content button.
  7. In Automator, terminate recording.
  8. Save the service workflow with the name Load Remote Content.

You should now be able to run this from the Automator to test it (try it by selecting a message with remote content, where the remote content is not loaded). Before you test it be sure that you have given Automator (and Mail.app) access to control your computer. You do that in System Preferences (Security & Privacy → Privacy → Accessibility).

The keyboard shortcut

You should check that the Service you have created is visible in the Mail → Services menu (the Load Remote Content menu is there). If it is there, let us create the keyboard shortcut for it. Open System Preferences and select Keyboard → Shortcut. In App Shortcut add a new with the plus (+) button. Choose Mail.app for the Application, and in the menu title type exactly as it was written above: Load Remote Content. Choose your Keyboard Shortcut (I used Shift-Control-Cmd-I) and press Add.

Now, whenever you read as message with (unloaded) remote content, pressing the keyboard shortcut will load the content in the message.

Automate tasks with AppleScript, Fake, and the keychain

You can make life a lot easier on your Mac if you learn how to automate things. The standard approach to do this on Macs are to use Automator (see How to use Automator: What Automator is and how it works from Macworld UK). If you include AppleScript, Fake, and the keychain in your toolchain, you can achieve even more. As an example I will develop an automated task to create a new email alias using a web portal. This example is used since it includes user input (email alias), access of password in keychain, filling in and submitting forms on web pages, and return data to the user though the clipboard. An example using Automator is also available.

AppleScript

The main parts of this example are an AppleScript script and a Fake workflow. We also expect that the password of the user is stored in the keychain [1]. The first thing we do is to fetch the password for the web portal from the keychain:

  set domain_name to "mydomain.com"
  set user_name to "myusername"
  set pwd_cmd to "security find-generic-password"
  set pwd_script to pwd_cmd & " -a " & user_name & " -w"
  set pass_wd to do shell script pwd_script

The next step is to prompt the user for the email alias (including converting the input to lower case [2]):

  set dialog_txt to "New email alias (<alias>@" & domain_name & "):"
  display dialog dialog_txt default answer ""
  set email_alias_case to text returned of result
  set email_alias to _string's lowerString(email_alias_case)

The typical use for the user of a new email alias is to type the new email address in to a web form. To make this easier for the user we'll copy the new email address to the clipboard:

  set the clipboard to email_alias & "@" & domain_name

The final part of the AppleScript is to execute the Fake workflow. We have to transfer three parameters (variables) to the workflow:

  tell application "Fake"
    set variable with name "emailAlias" to email_alias
    set variable with name "userName" to user_name
    set variable with name "passWd" to pass_wd
    activate
    open "Users:aa:Applications:MakeEmailAlias.fakeworkflow"
    delay 1
    run workflow with variables { \
      emailAlias:email_alias, \
      userName:user_name, \
      passWd:pass_wd \
    }
    wait until done
    close front document
    quit
  end tell

The only thing missing in the AppleScript code above is loading of the text string manipulation library _string.scpt [2]:

  set _string to load script alias ( \
    (path to library folder from user domain as text) & \
    "Scripts:Libraries:" & "_string.scpt")

Fake workflow

The Fake workflow receives 3 parameters (variables) from the AppleScript; the new email alias (emailAlias), the username (userName), and the password (passWd) to log in to the portal. In the Fake workflow we use these variables to fill in the correct values at web form. The following Fake workflow is an example, and it as to be updated based on the actual web portal you are using. The example workflow consists of 4 steps (and 10 Fake workflow actions):

  1. Go to login web page:
    • Load URL: example.com
  2. Log in with username and password (and wait a second):
    • Set Value of HTML Element:
      • with id: user
      • to: {userName}
    • Set Value of HTML Element:
      • with id: password
      • to: {passWd}
    • Click HTML Element:
      • for XPath: /html/body/div/...
    • Delay:
      • for: 1.0 seconds
  3. Select web page where email aliases can be added:
    • Click HTML Link:
      • with text: email@mydomain.com
  4. Add email alias (and wait tw seconds):
    • Focus HTML Element:
      • with id: newalias
    • Set Value of HTML Element:
      • with id: newalias
      • to: {emailAlias}
    • Click HTML Element:
      • with id: submit
    • Delay:
      • for: 2.0 seconds

In the example above we use different approaches to identify the elements on web pages (with id, for XPath, with text). In your case you should use the approach that is easiest for the web pages you are scripting. Fake provide a feature where you can drag the id of an element to the workflow action id value.

Notes

  1. To store and access data in the keychain we use the security command line interface. To add a new account name with password pwd to the keychain you can do the following command:
      security add-generic-password -a name -s service -w pwd
    Then we can print this password with the following command:
      security find-generic-password -a name -w
    (In the first command service is a human readable name describing your service.)
  2. In the examples above I expect the AppleScript library _string.scpt from Brati's Lover AppleScript library.

Friday, March 20, 2015

Including source code in papers and on the web

I've written many papers and a lot of web pages that includes source code. Since Python code was an important part of my Dr. thesis, I even wrote a tool to generate a pretty-printed Python code for LaTeX (this was written in 1997, but since I've been using it ever since it has had a few minor bug fixes since then; however, it needs Python 1.6 and it was the first Python program I ever wrote!). Just by accident (being sidetracked when I was checking out Middleman extensions) I rediscovered Pygments yesterday. I know I've seen it before, but I had forgotten all about it. This time I checked it out, and I think it will finally replace my home-written tool. Since I write most of my papers in LaTeX and I use BSDmake to do the magic, I have included a few new rules in my Makefile (using my old ltk.mk file):

PY2TEX =	pygmentize -f latex -P "verboptions=frame=single" -O linenos
SRCSTYLE =	srcstyle.sty
STYLETYPE =	default
MKSTYLE =	$(PY2TEX) -S $(STYLETYPE)

.include	"$(HOME)/lib/mk/ltx.mk"

$(LTXSRC):	$(SRCSTYLE)

$(SRCSTYLE):
		$(MKSTYLE) > $(.TARGET)

In the LaTeX document I have to include the generated style file and the fancyvrb package (and for most styles the color package). If the source code included in the document is in the file src/mypycode.py, then you will find this in the LaTeX document (ltx.mk expects to find source code files in the src directory):

\usepackage{fancyvrb}
\usepackage{color}
\usepackage{srcstyle}
...
\begin{figure}
  \begin{minipage}{0.9\linewidth}
    \input{src/mypycode.tex}
  \end{minipage}
  \caption{The caption text describing mypycode.}
\end{figure}

Pygments can be used to generate TeX, LaTeX, HTML and many other formats. It supports a wide range of programming languages, and can easily be extended to other formats and other programming languages. It is highly configurable and flexible, and the command line way of using it is the simple approach. For full control and flexibility you write your own tool using Pygments as a Python library (and it supports both Python 2 and 3).

The styles, programming languages, formats, and filters available can easily be listed with these commands:

pygmentize -L styles		# styles
pygmentize -L lexers		# programming languages
pygmentize -L formatters	# formats
pygmentize -L filters		# filters
pygmentize -L			# all

Wednesday, January 8, 2014

A suggestion for backup on Mac

A lot of options for backup on your Mac exists. I use Time MachineBackblaze, Crash PlanTransporterCarbon Copy Cloner, and other tools for different types of backup on different Macs. The challenging backup for me are my pictures. I want at least one backup not in my house. The size of this backup is large, and since I am using Aperture, the meta-data of the file-system has to be preserved. Large amount of data and continuous minor updates of the data also suggest that the backup solution should support incremental backups. My first thought was to use two Transporters, one at home and one at my office. This will give me the option to have two (or more) working copies of the Aperture data and everything will just work. However, this doesn't work because the Transporter doesn't support HFS+ (with meta-data), and Aperture uses the features of the file system extensively.

Newer versions of rsync does support HFS+ meta-data. I am currently using version 3.0.9 (3.1.0 has an annoying bug on OS X). OS X 10.9.1 comes with rsync version 2.6.9, and this is to old for our purpose. I installed version 3.0.9 using Homebrew.

The magic option of rsync that we need is -X, preserve extended attributes. We will also use the -a option to transfer the files in archive mode (ensures that symbolic links, devices, attributes, permissions, ownerships, etc. are preserved in the transfer). You might also add the -H option to preserve hard links and -v for verbose mode. If you are brave you might even add the --delete option. This will remove files at the backup folder that is no longer at the source folder. If you don't use this option you might end up with more files in the backup folder. See the manual pages of rsync for more details.

To back up a folder (the source folder with my Aperture library) I will use the following rsync command:

rsync -avXH --delete source-folder backup-folder

In my case the source and backup folders are located on different computers at home and work. I prefer that the file transfer over the network is using ssh. To do this I add the option --rsh=ssh. So from my home computer I will use the following command to backup my Aperture library to the backup folder of my work computer:

rsync -avXH --delete --rsh=ssh Pictures my.work.com:backup

I had to install rsync version 3.0.9 on both computers and I had to configure the remote computer to use that version of rsync and not the pre-installed version. You can do this command to check what version of rsync that will be executed on the remote computer my.work.com:

ssh my.work.com "rsync --version"

Saturday, April 6, 2013

Snowman shell prompt

My new bash shell prompt:

Snowman shell prompt

Matching the large amount of snow outside. A more detailed picture of the snowman:

snowman

Inspired by put a burger in your shell.

Thursday, October 11, 2012

Coding fonts

I consider myself a programmer, and to perform this task I rely on a set of tools. I need a text editor, compilers and/or run-times, build-systems, code repositories, documentation, and sometimes even an IDE. Since the late 80s my text editor of choice has been Emacs (and Aquamacs on OS X), but I am also comfortable with vi (including Vim) and ed. Currently, I am investigating time in newer text editors, like Sublime Text (writing editor plugins in Python should be fun) and Chocolat, but we are not close friends yet (but I will spend more time with subl to see how our relationship evolves). More on these tools later.

When programming, the code is viewed in a text editor (or IDE) in a font (the size and style of a particular typeface). The default fonts for most code editors are OK, but we can do better than OK. On OS X I have tried and used a lot of different fonts for coding. Since yesterday my preferred font for coding Python was Menlo Regular 13 (also used by Xcode):

Menlo Regular 13

I believe Apple's Menlo has evolved from DejaVu Sans Serif Mono (common on Linux) and Bitstream Vera Sans Mono. Previously, I used Monaco Regular 12, but I switched to Menlo since I find it less noisy. Yesterday I came over this announcement of the open source font Source Code Pro from Adobe (via Daring Fireball):

Source Code Pro Regular 13

Now I have used Source Code Pro Regular 13 for one day programming in Python, and it is too early to conclude that the font is a good coding font option for me. My first impression is good. The font has a lightness to it that I like, and it is readable and clean. I will use it for a few more hours and then conclude if it should replace Menlo Regular 13 as my preferred coding font. I might even end up using different fonts depending on programming language and text editor. However, I recommend that you download and try this new open source font from Adobe.

Adobe also have other open source fonts available, including Source Sans Pro (revise and hosted on GitHub) and Kenten Generic.

Update 20140721: Other interesting coding fonts are Inconsolata and Fira Mono (from Mozilla's typeface Fira). This is Inconsolata:

Screen Shot 2014 07 21 at 09 36 39

And this is Fira Mono (Regular):

Screen Shot 2014 07 21 at 09 38 33

Update 20140805: You could also consider Input:

Input is a flexible system of fonts designed specifically for code by David Jonathan Ross. It offers both monospaced and proportional fonts, all with a large range of widths, weights, and styles for richer code formatting.