Excorporate 0.6.0: Exchange integration for Emacs

Here is Excorporate version 0.6.0.

New in this release:

– Support for overriding settings autodiscovery by manually configuring an EWS URL

– A check to prevent soap-client conflicts with other packages

– Handle user@sub.domain.com/autodiscover.domain.com autodiscovery case

– Support for Exchange 2013 (via the new API addition, exco-server-version)

Thanks to everyone who tested autodiscovery on the 0.5.4 release and provided feedback. I’ve listed most of you in the Acknowledgements section.

Excorporate has been accepted for inclusion in GNU ELPA but I’m still waiting on copyright assignment for one dependency before releasing it there. This release still takes the form of a tarball. First download it, then install it with M-x package-install-file.

Excorporate: EWS support for Emacs

I use Exchange at work for calendaring. I also use terminal-mode emacsclient when I’m logged in from another machine. In that scenario I can’t easily open a web browser to use Outlook Web Access. It annoyed me that I couldn’t check my schedule from within a terminal Emacs session. Thus, I did the only sensible thing and implemented full Exchange Web Services API support for Emacs.

Excorporate terminal screenshot

The result is a library called Excorporate that has proof-of-concept Calendar integration to show today’s meetings. It’s all written in Elisp, making it cross-platform. It’s also cross-Emacs; I tested it on Emacs 24.1 through Emacs 24.4, on GNU/Linux and MS-Windows. It works on all Emacs versions that support packages.

The tricky parts were:

  • extending soap-client to support all the XML Schema (XSD) datatypes required by the EWS WSDL file,
  • asynchronous URL retrieval without blocking the Emacs main loop,
  • autodiscovery of Exchange server settings from an email address, and,
  • implementing NTLMv2 authentication in Elisp.

I’m trying to get it into GNU ELPA so that other modes can always count on its core APIs being available from a default Emacs installation. I haven’t put it on GitHub yet, to keep it hidden from the ruthless efficiency of MELPA. I was impressed and appreciative when MELPA bundled slime-volleyball shortly after I released it. But I’d prefer to keep Excorporate in GNU ELPA only for now.

Anyway, I’m publishing this mode in the hope that it’s useful to other Emacs-and-Exchange users.

Emacs and TWiki

At work I have cause to edit a TWiki that my team uses for internal documentation. I wanted to use Emacs for this task, so that I wouldn’t need to interact with a web browser text area widget. I couldn’t find anything that did that, so I took the closest thing I could find, erin.el, a TWiki markup mode, and added connectivity to it via Emacs’s url package.

The result is a fork of erin.el that supports these new operations:

Log in: M-x erin-log-in
Edit a topic: M-x erin-edit-topic
Commit edits: C-c C-c
Cancel edits: C-c C-k
Log out: M-x erin-log-out

without ever leaving Emacs. Now with EWW to see the resulting pages, there’s no need to leave Emacs at all.

This being a fork, it doesn’t qualify for MELPA, and I can’t get in touch with the original author, so it will stay in limbo as a raw repo, without ever being packaged.

A while after I did this development, emacs-twiki-mode sprang up. It looks like it has some nice advantages, like orgtbl editing. If it used Emacs’s built-in URL handling instead of an external bash script I would probably switch to it. For now my erin.el fork works well enough for me. I do wish there were one monster Emacs mode that would handle all Wiki server implementations, including connectivity; a sort of Gnus for Wikis. Oh well.

Advice, serial-term and U-Boot

At work I make heavy use of the GNU Emacs mode serial-term to interface with various target boards. The boards all run U-Boot with a 5 second autoboot timeout. I often want to power-cycle a group of boards, then stop them all at the U-Boot prompt before they autoboot. It’s a race to C-x b to all the different buffers in time. I used to frequently miss some buffers; the boards would start booting, and I would have to wait to issue a software reset. It became annoying enough that I decided to create an autostop extension.

Luckily, serial-term is written in Emacs Lisp, so I can extend it to do exactly what I want. In this case I want a global “U-Boot autoboot-stop” mode. Here’s what I came up with:

First, a variable to to keep track of whether the mode is enabled or not.

;; Detect U-Boot autoboot prompt and stop it.
(defvar u-boot-stop-autoboot-mode nil
  "Non-nil if term-mode should prevent U-Boot from autobooting.
Use the function u-boot-toggle-stop-autoboot-mode to toggle.")

Then the advice itself. It jacks into the term-emulate-terminal process filter to detect the U-Boot autoboot prompt, then sends a newline in response.

(defadvice term-emulate-terminal
  (before u-boot-maybe-stop-autoboot activate disable)
  (with-current-buffer (process-buffer proc)
    (when (string-match "Hit any key to stop autoboot:" str)
      (message "U-Boot autoboot stopped in buffer %s"
               (buffer-name (current-buffer)))
      (term-send-raw-string "\n"))))

And finally a function to toggle the advice on and off.

(defun u-boot-toggle-stop-autoboot-mode ()
  "Toggle whether or not term-mode should interrupt U-Boot autoboot."
  (interactive)
  (if u-boot-stop-autoboot-mode
      (progn
        (ad-disable-advice
         'term-emulate-terminal 'before 'u-boot-maybe-stop-autoboot)
        (ad-update 'term-emulate-terminal)
        (setq u-boot-stop-autoboot-mode nil)
        (message "U-Boot autoboot will not be interrupted"))
    (progn
      (ad-enable-advice
       'term-emulate-terminal 'before 'u-boot-maybe-stop-autoboot)
      (ad-activate 'term-emulate-terminal)
      (setq u-boot-stop-autoboot-mode t)
      (message "U-Boot autoboot will be interrupted"))))

Now I can enable the mode globally with

M-x u-boot-toggle-stop-autoboot-mode

and be sure that all the boards will be interrupted in time.

It’s worth noting that developing this feature was relatively straightforward. I never left my Emacs session; I developed the code right in ~/.emacs.d/init.el, tested it quickly in a terminal buffer, and confirmed its operation in my existing serial-term buffers. Most of the development time was spent reading the Info documentation for Advice, to figure out how to enable and disable a specific piece of advice.

Think Penguin

I bought a ThinkPenguin.com laptop for my Mom for her birthday. She’s a long time GNU/Linux user and she was ready for an upgrade from her ThinkPad T41. I decided to try ThinkPenguin.com. I’m really impressed with their service and their product.

The laptop shipped within a few days, and when it arrived it had Fedora 17 pre-installed like I had requested. The build quality is very good. It’s a slim light laptop with attractive styling, and a solid keyboard. One of ThinkPenguin’s main selling points is hardware support, and it really was great. Graphics, Wi-Fi, suspend, hibernate, resume all worked perfectly, out-of-the-box, no configuration necessary. It’s fantastic to get this smooth out-of-the-box experience with GNU/Linux instead of a proprietary operating system.

If you care about Free Software and are in the market for a laptop, check out ThinkPenguin.com.

Pulse-Eight USB CEC Adapter

I bought the Pulse-Eight USB CEC adapter a few months back and so far it’s been a great addition to my XBMC setup. For a long time I wanted to control my TV from my Android phone, for a few reasons. First, I usually have it with me and charged up, unlike my TV remote which might be misplaced or out of batteries. Second, I find it annoying that the infrared TV remote requires line-of-sight. And finally, a smart phone remote just seems like the right way to control a TV in this day and age.

For such a tiny package the Pulse-Eight adapter enables a lot of functionality. I can turn my TV on and off from my phone over Wi-Fi, using the Official XBMC Remote Android app and a slightly-hacked version of XBMC. But there’s more. Guests who prefer using a TV remote can use its extended buttons to control XBMC playback. The adapter enables communication in both the TV-to-XBMC and XBMC-to-TV directions by passing CEC commands over the HDMI bus. And its inventors maintain a Free Software library, libcec, to control it. This is a much cleaner and cheaper solution than the various Wi-Fi-to-IR converters I’ve looked at.

If you run XBMC make sure to check out this adapter.

True Fullscreen Fit-to-Width Document Viewer

I like to read documents in fullscreen mode using keyboard navigation. I want a viewing mode with the following properties:

  1. No scrollbars
  2. No navigation toolbars
  3. No drop-shadow page borders
  4. Fit-to-width display
  5. Emacs-style scrolling, maintaining 2 lines of context for continuity

To me 1, 2 and probably 3 should be properties of anything claiming to be “fullscreen mode”. Unfortunately fullscreen mode now seems to mean “mostly fullscreen mode with some widgets reminding you you’re in fullscreen mode”. Nowadays what I want would be called “true fullscreen mode”.

The DjVuLibre document viewer can be configured to support all these requirements. It provides a perfectly clean mode, allowing you to really focus on the document itself with no distractions. Unfortunately it only supports DjVu documents.

Evince has excellent multi-format support but its fullscreen fit-to-width mode fails 1 with an ever-present vertical scrollbar, 3 and 5. Its presentation mode is fully-uncluttered but it is necessarily not fit-to-width, so it’s not great for just reading documents.

Okular seems at first glance to have format support equivalent to Evince but its fullscreen fit-to-width mode fails 2 with a non-removable navigation footer, 3 and 5.

Maybe I’ll file some Evince feature requests. In the meantime, any suggestions for other viewers?

Android Development

A patch I wrote for mobileorg-android was accepted and shipped to the Market in mobileorg-android 0.4.8. It works around lighttpd’s missing support for the Expect HTTP header. The issue was that pulling from lighttpd to the phone would work, but pushing from the phone to lighttpd wouldn’t.

To debug the problem I set up an Android development environment. In doing so I found android-mode.el and android.el (shipped with the SDK in android-sdk-linux_86/tools/lib) very useful both during development and initially for learning the Android Emacs workflow. For the most part, developing for my Nexus One was very straightforward. The only issue I ran into was not being able to start /sbin/adbd on the phone.

Since none of the Android development tutorials I Googled mentioned this problem, I’ll outline the symptoms here. If this issue affects you, the Settings -> Applications -> Development -> USB debugging check box on your phone will have no effect. After you’ve checked “USB debugging”, when you plug your phone into your development machine via USB, the USB file storage dialog will come up. “adb devices” on your development machine will not list the USB-connected phone. If you open a terminal window on your phone,

$ getprop persist.service.adb.enable

will print 0, and

$ ps

will not list /sbin/adbd.

When things are working correctly, checking USB debugging causes /sbin/adbd to be run on the phone. /sbin/adbd exports different USB endpoints to “adb fork-server server” (started by adb on the development machine) so that the phone shows up as an Android development device, instead of a USB hard drive.

In my case the workaround was to check “USB debugging” then reboot my phone. After the reboot, persist.service.adb.enable was set to 1 and /sbin/adbd started when I checked USB debugging.

Unfortunately I couldn’t find a way out of this scenario without rebooting my phone which I avoid doing if possible (my best uptime so far is 60 days ended by the 2.2.1 system update). I haven’t rooted my Nexus One so /sbin/adbd caused “Permission denied”, and I couldn’t change persist.service.adb.enable to 1 with setprop; it would stay set to 0. Without /sbin/adbd (and before I discovered the reboot workaround), I was left having to manually install a mobileorg-android .apk file via the SD card which was a pain. I was disappointed that I didn’t have control over persist.service.adb.enable (which I assume I would if I had root). The main reason I bought the Nexus One was for its unlocked hackability, so things like this leave a bad taste. Hopefully the issue I linked to gets resolved.