Wednesday, July 25, 2018

Mimic PC NumLock on Mac with 101/102 Key PC Keyboard

I use a MacBook Pro with a leftover Dell 102-key PC keyboard. For almost everything it works great. Even the volume keys work. However, the NumLock doesn't behave the way it does on a PC.

I mostly use the number pad on the right to move the cursor around for editing. It makes editing really fast because the cursor keys are easily reached; just like using the A,S,D,W keys for navigating in a video game. I rarely use the number pad for entering numbers; just when I have a long series of number I want to rapidly input. If it's only one or two numbers, I use the number keys at the top of the keyboard. Using the NumLock key to switch back and forth between cursor control and number entry is extremely handy, but the Apple keyboard doesn't have this feature.

Karabiner to the rescue


I found a popular keyboard-mapping utility for Mac called Karabiner. It allows me to remap the keyboard for specific keyboards, so I can map the keypad 0-9 keys to cursor movement for just the Dell keyboard; however I can't quickly switch back to the default functions.

Map NumLock to toggle between keyboard profiles


The solution is to create 2 keyboard profiles. I modified the "Default profile" to map the keypad keys for cursor movement and created another profile, "NumLock On" that reverts to the original function of the keypad keys for number entry. Then I mapped the NumLock key to run a shell_command calling Karabiner from the command line and loading the other profile. You can see the way it's set up in ~/.config/karabiner/karabiner.json. Here is the relevant code:
    {   
        "from": {
            "key_code": "keypad_9"
        },
        "to": {
            "key_code": "page_up"
        }
    },
    {
        "from": {
            "key_code": "keypad_num_lock"
        },
        "to": {
            "shell_command": "'/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli' --select-profile 'NumLock On'"
        }
    },
    {
        "from": {
            "key_code": "keypad_period"
        },
        "to": {
            "key_code": "delete_forward"
        }
    }
The key_code, "keypad_num_lock", in the profile, "Default profile", is mapped to a "shell_command" which runs the Karabiner command-line interface (cli) and selects the "NumLock On" profile.

In the "NumLock On" profile, keypad_num_lock also runs the Karabiner cli but selects the "Default profile", like this:
     {
         "from": {
             "key_code": "f12"
         },
         "to": {
             "consumer_key_code": "volume_increment"
         }
     },
     {
         "from": {
             "key_code": "keypad_num_lock"
         },
         "to": {
             "shell_command": "'/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_cli' --select-profile 'Default profile'"
         }
     }
For more on Karabiner, see:

Karabiner Manual

Karabiner JSON Reference Manual

Wednesday, September 27, 2017

View or Suppress Logback Status

Logback always shows status statements if there are configuration errors


Logback will log its own status statements to the console if you have any configuration problems resulting in WARN or ERROR messages, which will also show INFO messages. The Logback levels are, from lowest level to highest level:

TRACE < DEBUG < INFO < WARN < ERROR

(See Logback Architecture: error levels for details.)

See Logback status statements


To see Logback's status statements in the console (standard out) regardless of whether or not there are any configuration errors, set the debug attribute to true in the configuration element.
  <configuration debug="true">
    ...
  <configuration>

Suppress Logback status statements


To suppress display of Logback's status statements to the console, omit the debug attribute in the configuration element or set it to false. This will not suppress status statements if there are configuration problems with Logback.
  <configuration>
    ...
  </configuration>
If there is no debug attribute or it's set to false and you see Logback status statements, fix the problems causing the WARN or ERROR statements and the statements will no longer display.

If you can't fix the configuration problem but want to suppress the status statements, you can configure an alternate StatusListener like NopStatusListener to completely remove status statements.
  <configuration>
    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
    ...
  </configuration>
See also:

Logback Configuration: Automatic printing of status messages in case of warning or errors
Logback Configuration: Show status data
Logback Configuration

Wednesday, March 1, 2017

Use swagger-codegen to generate Java code from Swagger Spec

Swagger is the most popular standard for describing RESTful APIs. The Swagger Specification (formerly known as the OpenAPI Specification) is a JSON or YAML document that describes an API's endpoints, HTTP methods (GET, PUT, POST, etc.), possible responses and fields, possible errors, etc.

Swagger has code generators that will read a Swagger Specification and generate code in a variety of programming languages to consume the API. This saves a lot of time. The command line code generator is a Java Jar file. You need Java 7 or higher installed to run it. There is also a Maven plugin for Java projects that can generate the code for you as part of your project build process.


You can get help from the command line utility by running:
java -jar swagger-codegen-cli.jar help

which shows:
The most commonly used swagger-codegen-cli commands are:
    config-help   Config help for chosen lang
    generate      Generate code with chosen lang
    help          Display help information
    langs         Shows available langs
    meta          MetaGenerator. Generator for creating a new template set...
    version       Show version information

See 'swagger-codegen-cli help <command>' for more information on a specific command.

If you want detailed help about the generate command:
java -jar swagger-codegen-cli.jar help generate

The code generator can use a local Swagger doc or one hosted on a website. There is a quirk about how it handles URLs.

If the Swagger doc path is a URL and the URL has query parameters in it separated by an ampersand (&), you have to modify the URL slightly depending on whether you are using the command-line utility or the Maven plugin.

Command Line Utility (CLI)


When using swagger-codegen-cli.jar, enclose the -i (or --input-spec) parameter in double quotes if the URL has query parameters, like this:
-i "https://my.api.com/store/api-docs?provider=USER/me&name=MyNewService&version=v1"

For example:
java -jar swagger-codegen-cli.jar generate -l java --library jersey1 -o my/dir --model-package my.model.svc -i "https://my.api.com/store/api-docs?provider=USER/me&name=MyNewService&version=v1"

Maven swagger-codegen-maven-plugin


When using the Maven plugin, substitute &amp; for the & character if the URL has query parameters, like this:
https://mysite.com?color=red&flavor=sweet

Right: ?color=red&amp;flavor=sweet
<configuration>
  <inputSpec>https://mysite.com/api?provider=USER/me&amp;name=MyGreatService&amp;version=v1</inputSpec>
</configuration>

Wrong: ?color=red&flavor=sweet
<configuration>
  <inputSpec>https://mysite.com/api?provider=USER/me&name=MyGreatService&version=v1</inputSpec>
</configuration>

pom.xml

<build>
  <plugins>
    <plugin>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-codegen-maven-plugin</artifactId>
      <version>2.2.1</version>
      <executions>
        <execution>
          <goals>
            <goal>generate</goal>
          </goals>
          <configuration>
            <inputSpec>https://my.api.com/store/api-docs?provider=USER/me&name=MyGreatService&version=v1</inputSpec>
            <language>java</language>
            <configOptions>
              <dateLibrary>joda</dateLibrary>
            </configOptions>
            <library>jersey1</library>
            <modelPackage>my.model.svc</modelPackage>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Monday, February 6, 2017

Pretty Print JSON and XML from Mac OS Command Line

JSON


Must have Python 2.6 or higher version installed.

From Clipboard


After copying unformatted JSON to clipboard (ctrl+c), run this:

pbpaste | python -m json.tool

From File


After saving unformatted JSON to a file called, for example, ugly.json, run this to write it to a file called pretty.json:

cat ugly.json | python -m json.tool > pretty.json

XML


From Clipboard


After copying unformatted XML to clipboard (ctrl+c), run this:

pbpaste | xmllint --format -

pbpaste | xmllint --format -

From File


After saving unformatted XML to a file called, for example, ugly.xml, run this to write it to a file called pretty.xml:

cat ugly.xml | xmllint --format -o pretty.xml -


Monday, July 11, 2016

Signing a PDF Document With Adobe Reader

You can sign a PDF document using a signature created by Adobe Reader or you can scan in your actual signature and re-use it for any documents that need signing.  You can even create multiple versions of your signature.  Here's how.

1. Download and install Adobe Reader if you haven't already.

2. Open the document in Adobe Reader and select "Fill & Sign" in the right sidebar.


3. Select "Sign" in the toolbar at the top.  If you haven't created a signature yet, it will prompt you for one.  Let's assume you haven't created one yet.


4. Write a signature.  Using the selections at the top, you can type it, draw it with your mouse, provide a scanned image of your signature, or even use your laptop camera to scan one in that you wrote on a piece of paper.  When you're done, select "Apply".


5. Your signature will appear on the document.  Move it where you want with your mouse and click when done.


6. A box will show around the signature with a handle in the lower-right corner that you can drag to make the signature bigger or smaller.  When it's sized they way you want, click somewhere outside the box.  Don't worry if you don't get it right.  You can adjust the size and location by clicking on the signature again.  Changing the location is as simple as placing the mouse cursor inside the box until a cross-haired cursor appears, then clicking and dragging the signature where you want.


7. Once you have clicked outside the box another cursor appears allowing you to place printed text anywhere on the page, for example a printed name or date.  Move the cursor where you want to type and click.  A box will appear for you to enter text into.  You can change the size of the text by clicking on the smaller or larger "A" above your text.


8. When everything looks right, save the document or select Save As to save it as another name.


9. Now you can send an email back to the requestor and attach the saved document with your signature.

Creating PDF Documents With Signatures

Creating a PDF document with a place for a signature is easy.  This example shows how to do it with Microsoft Word.  It's just as easy in Google Docs.  Just 3 steps.

1. Create the document in Microsoft Word or some other word processor that can save as PDF.  You can use Google Docs too.



2. Save it as a PDF.

In Word, navigate to Save As... > PDF.





In Google Docs, navigate to File > Download as > PDF Document (.pdf)

3. Email it with instructions on how to sign it.

Wednesday, March 30, 2016

Not Great: Yahoo Developer Network (YDN)

Here are some reasons why:


1. The Yahoo Developer documentation website takes forever (minutes) to display, if it even does. Mostly it doesn't and this is what you'll see instead:



Maybe they could spin up a second server to host their website so more than a dozen people can access it at a time. Or is that more than the number of developers interested in building Yahoo apps?

2. You can't set or change API permissions on your application after you've created it. This is what the page looks like if you haven't selected API permissions when you set it up.



When you select the "Update" button, it says "updating..." then comes back with the happy message "Your application has been successfully updated." Updated with what? It never gave me any options to select. It's not a big deal to delete the app and start over again, but it's not obvious either.

3. No support. There doesn't seem to be any place to let them know that their YDN server (servers?) is (are?) not displaying content, nor do they ask for feedback. There's a FaceBook page and a Twitter account where you could presumably post a message or a tweet, but really?

Build stuff, ignore feedback...where have I seen that before? Oh yeah, the big Detroit automakers until the Japanese showed them how to build better cars. Buy some copies of The Machine That Changed The World and learn about lean manufacturing, Yahoo. Better yet, read up on Agile Development; you know, that thing that all the successful software businesses are doing?

Hmmm... I wonder why Yahoo is divesting itself of its web businesses.

YouTube 5.1 Channel Audio Fail in Browsers

Ignore any blog posts or YouTube videos that claim to show you how to play 5.1 surround from YouTube videos in a browser. They don’t work. A...