Friday, 6 December 2013

Create an ISO disk image from a CD/DVD in OS X

Problem:

I would like to back up a disc to an ISO image using OS X. (This can be useful when backing up personal content such as photo albums, home movies, etc.)

Solution:

  • Insert disc into disc drive
  • Open the "Disk Utility" application (Application -> Disk Utility)
  • Select your disc drive
  • Click on "New Image" (one of the buttons on the top of the window)
  • For "Image Format", select "DVD/CD master" (on the bottom)
  • Pick a filename and click "save". This should create a file with a .cdr extension
  • When the image is done being written to disk, rename the extension to .iso

Troubleshooting:

  • If the original image does not have an extension .cdr, but instead has an extension .dmg, etc., "DVD/CD master" was not selected. Restart the process, but this time select "DVD/CD master" as the image format.

Notes:

This should work on most versions of OS X until 10.9, and possibly even beyond. This how-to was tested to work using OS X 10.7 through 10.9.

References:

This how-to was adapted and condensed from the link below. It was written as a reminder, in case the page below ever goes down.

Thursday, 5 December 2013

Workaround to place XQuartz/X11 apps on second monitor in OS X Mavericks (apps like Inkscape)

Problem:

I've upgraded to OS X Mavericks and I can't place apps such as Inkscape on my second monitor any longer. I don't want to turn off "Displays have separate Spaces."

Before trying this workaround ...

This workaround was written as a reminder for myself. Even if you get it to work, X11 programs will be riddled with bugs because of how Mavericks currently treats Spaces coordinates, gravity, etc., with XQuartz. Thus, I'd recommend not following it for the time being unless you're curious. A better workaround is to simply turn off "Displays have separate Spaces" in: System Preferences ... -> Mission Control

This workaround only works under very specific conditions right now, and there is no guarantee that it will work under other conditions. The following are the conditions under which this workaround worked:

  • The OS X Team nor the XQuartz team have not addressed the issue yet (test this out to make sure that you're not using a workaround when things actually work)
  • OS X version is 10.9
  • XQuartz is installed and works
  • XQuartz version is XQuartz 2.7.4 (xorg-server 1.13.0) or under (haven't tested it with newer versions, and newer versions may fix this problem rendering this workaround pointless)
  • Inkscape and other X11 apps run
  • "Displays have separate Spaces" is checked under: System Preferences -> Mission Control
  • You haven't already dragged the application window out of bounds in one of your spaces (in which case you'll need to figure out how to reset its position first -- can't help there at the moment since each app handles its position in different ways. Advanced: Try resetting or reinstalling the X11 app, or editing its config file?)
  • You know what the following terms mean: "dock", "desktop", "mission control", "spaces", "X11", "XQuartz", "secondary click"

If you're here to try to get Inkscape or other X11 apps to work in Mavericks in the first place, try this post first: http://grammarofdev.blogspot.ca/2013/10/how-to-run-inkscape-in-os-x-109.html

Disclaimer:

This is hardly a permanent solution, nor is it guaranteed to work under all versions of OS X, XQuartz, etc. This workaround is just posted here in case anyone else finds it useful to be able to use X11 apps on their second monitor once again after upgrading to Mavericks, and doesn't mind jumping through a few hoops. Hopefully by the time you read this, someone at Apple or XQuartz would have fixed this issue. (If you're one of said Apple or XQuartz people, please fix this =) lol.)

Also note that because the bug seems to be related to coordinates, weird things can happen with this workaround, such as windows, child-windows, etc., opening out of bounds and therefore off-screen. Hopefully someone out there will be able to debug this problem as this workaround can't work around bugs like that.

Workaround:

  • Launch the X11 app so that XQuartz and the app's icon show up in the OS X dock
  • In the dock, secondary click the XQuartz icon and select: Options -> Assign To: None
  • In the dock, secondary click the app icon and select: Options -> Assign To: None
  • Go to mission control (hit f3 on most Macs, or triple-swipe upwards if that gesture is enabled)
  • Do NOT attempt to drag the app to the space/desktop on the other monitor as you do with native apps, as all this will do is set the window out of bounds on the current space/desktop. (At least, as of XQuartz 2.7.4 (xorg-server 1.13.0) or earlier.)
  • Drag the X11 app window (such as Inkscape's window) to the desktop/space mini-window on top of the other monitor (the one on top with the labelled "Desktop __" with the desktop number in place of __ -- not to the big desktop area below)
  • If all worked out, the app should now actually display on your second monitor
  • (Optional step - if you work for Apple) Program a patch to allow drag-and-drop of X11 apps to spaces residing on second monitor
  • (Optional step - if you work on the XQuartz project) Detect bounds of monitors and imitate native drag-and-drop behaviour (I'd like to help out, but I'm not entirely sure how to right now =/)

More:

As this issue hasn't been solved yet as of the time this post was written, I've decided instead to link to the closest bug report that I could find: https://discussions.apple.com/message/23717540#23717540

If you happen to have a better fix, please feel free to update us all in the comments below! =)

Wednesday, 4 December 2013

Turn off "Say OK Google" voice search feature in KitKat

Problem:

I'd like to turn off the "Say OK Google" always-listening voice search feature in KitKat. How can I do so?

Solution:

One way to turn this feature off on the stock version of Android, is to navigate to Settings -> Language&Input -> Voice Search and then uncheck "Hotword detection".

References:

For more information on turning off this always-listening feature in both voice search as well as Google Now, you can check out the more detailed articles below:

Thursday, 21 November 2013

SQL update multiple rows with a single query, different value per row

Problem:

I'd like to update many rows with each row having a possibly different value, while using only a single SQL query. A query with a single WHERE clause would be inadequate as a result.

Warning:

This how-to can possibly ruin a database if done wrong, so make sure that you first test it using toy data (and make sure it works properly). Use at your own risk!

Please feel free to point out any typos and mistakes in the comments below.

Solution:

This is a summary (for myself) of the solution found at Karl Rixon's page here. For greater detail, please follow the aforementioned link.

Example table:

We'll use the following table for this example:

Table name: 'membership_list'
IDS_IDNameCountryOne_or_zero
1205G0BobUSA1
2205G0CatUK0
3319E8JaneAustralia1
4518A1JoeIceland1
...............

Example 1 - multiple rows, single column:

In order to make multiple updates, you can use a CASE block in SQL combined with an appropriate WHERE clause to select the appropriate rows and set the different values. For example, in order to update the column `Country` based on column `ID` alone:

UPDATE `membership_list`
  SET `Country` = CASE `ID`
    WHEN '1' THEN 'Antarctica'
    WHEN '3' THEN 'Canada'
  END
WHERE `ID` IN (1,3);

Do NOT forget the WHERE clause otherwise all other values will be set to NULL.

Example 2 - multiple rows, multiple columns:

In order to change more than one column, more than one CASE blocks can be used. For example, in order to both the columns `Country` and `One_or_zero` based on `ID` alone:

UPDATE `membership_list`
  SET `Country` = CASE `ID`
    WHEN '1' THEN 'Antarctica'
    WHEN '3' THEN 'Canada'
  END,
      `One_or_zero` = CASE `ID`
    WHEN '1' THEN '1'
    WHEN '3' THEN '1'
  END
WHERE `ID` IN (1,3);

Example 3 - multiple rows, multiple WHERE conditions:

Now assuming that you only want to alter all rows in `membership_list` that have '205G0' as the `S_ID` and 'Bob' as the `Name`, and we want to set all `Country` to unique values based on `One_or_zero`:

UPDATE `membership_list`
  SET `Country` = CASE `One_or_zero`
    WHEN '1' THEN 'Switzerland'
    WHEN '0' THEN 'Russia'
  END
WHERE `One_or_zero` in (0,1) 
  AND `S_ID`='205G0'
  AND `Name`='Bob';

Example 4 - constructing a PHP query for Example 1:

Among other benefits, a single query for multiple updates becomes particularly useful when using server-side scripting such as PHP, as there is a significant gain of speed when compared to looping through many single queries.

Here is an example script to construct the query for the first example above:

$arr_id_country = array(
    '1' => 'Antarctica',
    '3' => 'Canada'
  );

$str_ids = implode(',', array_keys($arr_id_country));

$str_when_then = "";
foreach($arr_id_country as $id => $country) {
  $str_when_then .= sprintf(" WHEN '%d' THEN '%s' ",
      $id,
      $country // note, you'd sanitize this if from user input
  );
}

// whitespace + appends included in example for readability
$template =   "UPDATE `membership_list` "
            . "   SET `Country` = CASE `ID` "
            . "     %s "
            . "   END "
            . " WHERE `ID` IN (%s);"

$query = sprintf($template, $str_when_then, $str_ids);

// do database queries, etc., here ...

Notes:

Once again, do NOT forget to include the WHERE clause that contains all the values found in the CASE block in order to prevent accidentally affecting other rows unintentionally.

References:

Thursday, 14 November 2013

Autorun startup script on Raspberry Pi Arch Linux

Problem:

I want to run a custom script when my Raspberry Pi running Arch Linux starts up. I only need the most basic instructions.

Pre-requisites:

  • You're comfortable running commands in the console
  • You know what to do if you accidentally brick your RPi
  • You know how to write shell scripts
  • You're already familiar with basic linux shell commands

Disclaimer:

These instructions were written as a reminder to myself for a fresh install of Arch Linux (2013-07-22 version) in order to run custom startup scripts. Please read through the instructions and make sure you understand all the steps first before attempting this. Results may vary, but because you're doing things as root, you might brick your RPi if you do something wrong (or if things change in different versions of Arch Linux). Follow at your own risk.

Feel free to let me know of any typos in the comments and I'll fix them right away. Best of luck!

Solution:

Note that this is only one solution out of many possible ones. It may not even be the accepted correct practice, but it happened to work after lots of Googling. You can modify the instructions if you feel comfortable doing so. Also note that these instructions were written as a reminder for myself in case I need to do this again, so they may be a bit brief. This solution was tested to work with the archlinux-hf-2013-07-22.img.zip image from the Raspberry Pi downloads page. Your results may vary with other versions (including this not working at all).

Assumptions:

  • startup script is located at: /scripts/my_startup_script.sh
  • script already has executable privileges for root
  • we want to run our script in multi-user runlevel (if this doesn't make sense, see here for details)

Step 1: create the startup service file for systemd

In this example we're making a file called "myauto.service". In practise you can name it whatever you want, so long as it doesn't replicate another service's name.

# nano /etc/systemd/system/myauto.service

Step 2: edit the .service file to contain the information needed to both run and install your service

In this example, we've included some bare-basics only which points to our startup script /scripts/my_startup_script.sh:

[Unit]
Description=Autostart custom script

[Install]
WantedBy=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/scripts/my_startup_script.sh

Once you've edited this above file as you'd like, save it.

This file says that we want to make a service referred to as myauto.service, which should be installed at the runlevel of multi-user, that runs a one-shot command which is our startup script.

Step 3: install the service

Here we get systemctl to install the service. Remember to replace "myauto" with the name of your .service file created earlier.

# systemctl enable myauto.service

You'll see a symbolic link created in /etc/systemd/system/multi-user.target.wants that corresponds to the .service file created earlier (in this case myauto.service).

Step 4: check if service is running (after restart)

You can check if the service is running by the following command (substituting your service's name for myauto.service below):

# systemctl is-enabled myauto.service

Step 5: where do I get more information?

Check out the very helpful systemd documentation at https://wiki.archlinux.org/index.php/Systemd

Monday, 28 October 2013

How to run Inkscape in OS X 10.9 Mavericks

Problem:

After upgrading to OS X 10.9, Inkscape, as well as other X11 apps do not seem to work any longer. How can I run Inkscape?

Solution:

  • Install Inkscape (if haven't done so already) from http://inkscape.org/
  • Install XQuartz from http://xquartz.macosforge.org/landing/
  • Run Inkscape.app
  • When asked for "Where is X11?", click "browse ..." and select /Applications/Utilities/XQuartz.app (or just /Applications/Utilities/XQuartz)

Explanation:

As of OS X Mountain Lion, Apple no longer installs the X11.app by default, which was previously needed to run any X11 applications. XQuartz or another compatible X Server is now needed to run any X11 apps as a result. A full explanation can be found in the Apple knowledge base article here: http://support.apple.com/kb/HT5293

Additional comments:

This solution was tested to work with the default installation of OS X 10.9 and Inkscape 0.48.2.

Note that if XQuartz starts up when launching Inkscape, but Inkscape doesn't launch the first time along with XQuartz, (or the Inkscape window doesn't show up), you can try to quit both Inkscape and XQuartz, then launch Inkscape once more (which should also launch XQuartz). This bug occurred on the system that the above fix was tested on, and the workaround seems to have worked. Your mileage might vary.

Addendum:

(Added in 2014)

A useful post from commenter @Birtanish below seems to have helped a few people when the above instructions weren't sufficient, so it's reproduced below in case it helps. Best of luck!:

"Hi! I tried the above solution which in the end did not work at all unfortunately. Another solution is to launch Inkscape from within XQuartz, this is done by opening a terminal and type: open /Applications/Inkscape.app Additionally it is possible to create a shortcut for this in the XQuartz menu, by clicking on Applications -> Customize and the above command as the command and set name to Inkscape for instance. This worked for me, hope it can help somebody else as well. Good luck."

Saturday, 7 September 2013

VirtualBox OS X Host Ubuntu Guest - USB device captured but not mounting/showing - One workaround

Problem:

I am using VirtualBox 4.2.x on OS X 10.7.x running an Ubuntu Guest. When I try to plug in a USB device, such as a USB drive, USB MIDI keyboard such as the Keystation 88-es, etc., VirtualBox shows the device as captured (with a checkmark in the USB devices list), yet Ubuntu can't find it. I've already tried things such as installing VirtualBox Guest Additions, setting proper user permissions, etc.

One Workaround:

If you've managed to mount and capture the USB device but it's still not showing, you've probably already made it past most How-To's Googling will offer. One bug fix that seems harder to come across is this: Set the number of virtual CPUs to 1.

Apparently after VirtualBox version 3.2.0, a bug has caused USB devices to not show up in some Linux-based guests when the number of virtual CPUs is set to more than 1.

If this obscure bug fix doesn't help, check out the references below to lots of other potential solutions to the USB-won't-mount problem.

Good luck!

Notes:

I realize that this post isn't complete, however it was this one somewhat obscure bug that caused many hours of attempted debugging and Googling until it was found. So to save others the trouble of finding it buried in a page full of instructions and fixes, I opted to highlight only this one bug, and link to other pages full of good solutions.

Hopefully by the time you've reached this blog page Oracle, VirtualBox, Apple, or some others have managed to fix the problem!

This workaround is version specific so your mileage may vary depending on the version of OS X, VirtualBox, VirtualBox Guest Additions, Linux, etc., that you are running.

References:

Friday, 6 September 2013

Facebook Android SDK v3.5 tutorial workaround for error regarding android.support.v4.content.LocalBroadcastManager.getInstance

Problem:

In the very first Facebook SDK tutorial, when I finish the final steps to get a MainActivity.java that looks like the tutorial, instead of getting the message "Hello !" the app crashes and gives an error like "Could not find method android.support.v4.content.LocalBroadcastManager.getInstance, referenced from method com.facebook.Session.postActiveSessionAction", then followed by a bunch of exceptions, starting with "java.lang.NoClassDefFoundError: android.support.v4.content.LocalBroadcastManager".

My code looks exactly like the tutorial found at https://developers.facebook.com/docs/android/getting-started/facebook-sdk-for-android/. (For reference, the tutorial code as of September 6, 2013 is below, as it could be revised by now:)

package com.firstandroidapp;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;
import com.facebook.*;
import com.facebook.model.*;

public class MainActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // start Facebook Login
    Session.openActiveSession(this, true, new Session.StatusCallback() {

      // callback when session changes state
      @Override
      public void call(Session session, SessionState state, Exception exception) {
        if (session.isOpened()) {

          // make request to the /me API
          Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

            // callback after Graph API response with user object
            @Override
            public void onCompleted(GraphUser user, Response response) {
              if (user != null) {
                TextView welcome = (TextView) findViewById(R.id.welcome);
                welcome.setText("Hello " + user.getName() + "!");
              }
            }
          });
        }
      }
    });
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
  }

}

Please Note First:

This problem and its workaround appears to be version specific. Your mileage may vary if the error isn't exactly the same as the one encountered. The versions of things used when this error was encountered were Android ADT v22, facebook-android-SDK-3.5, with a build target set to Android 4.2.2. All source code, tool, etc., were unmodified from the versions downloaded from Google and Facebook. This problem was worked around September 6, 2013, so hopefully someone from Facebook or Google's Android team has already made the appropriate fixes (making this post no longer needed =p).

Workaround:

This problem is caused by a missing method that the Facebook SDK is expecting to find in android.support.v4, but cannot find in the current version of the Android libraries. A hint to this is a strange error (which you may or may not have seen when importing the Facebook SDK demos into Eclipse) mentions that the versions of android.support.v4 do not match. The demos seem to run properly when compiled, however the very first Facebook SDK program you write yourself does not.

To work around this problem, the Facebook SDK version 3.5 includes a jar file you need to link to your project, located in "/path/to/facebook-android-sdk-3.5/libs/android-support-v4.jar".

One way to do this is as follows:

  • Go to your project's properties in Eclipse, then go to "Java Build Path"
  • Click on the "Libraries" tab
  • Click on either "Add JARs..." or "Add External JARs...", depending on which of the two you'd like to do
  • Add the android-support-v4.jar that comes with the Facebook Android SDK v3.5
  • Click on the "Order and Export" tab
  • Check the newly-imported android-support-v4.jar
  • Clean the project (Project->Clean...) (this step is important as attempting to re-run the project without cleaning it first or altering its code will simply run the existing binary again, which will give the error once more)

Additional Notes:

There's also another change in the tutorial which you may want to make. The function "Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {....});" is deprecated in the v3.5 SDK. You can get rid of the "deprecated method" warning in Eclipse by changing the above code to "Request.newMeRequest(session, new Request.GraphUserCallback() {...}).executeAsync();".

Hopefully this post helped someone out there. I realize it's a pretty basic problem to debug for experienced coders, but I decided to post this anyway in case it came in handy.

Wednesday, 21 August 2013

Inkscape 0.48.x OS X extensions problem workaround

Problem:

When using extensions with Inkscape 0.48.2 in OS X I get an error similar to: "the fantastic lxml wrapper for libxml2 is required ..." and extensions won't work.

Prerequisites:

This workaround worked on the system it was used on, however the solution is potentially version specific. The versions of stuff installed on this system were:

  • OS X 10.7.5 with the installation of Python that came with it
  • Python 2.7.5 (you can find your version in the terminal by typing "python --version")
  • Fresh install of Inkscape 0.48.2
  • XCode (required to compile the modules that we're going to install)

Notes:

The following steps are not necessarily a permanent fix for this problem, however they worked on the system that they was tested on. Your mileage may vary as the problem seems to be version-specific. Make sure you know what you're doing and follow the instructions at your own risk. If you're unsure, refer to the links in the references for a more complete explanation before starting. Good luck!

Workaround:

This problem is caused by the OS X version of Inkscape not being able to find the version-specific Python module for libxml2 that it was compiled/packaged to use. OS X comes with its own version of python which happens to be missing a few things usually installed in other operating systems. To install the required modules for Inkscape extensions to work, the following steps were taken (though not all may be required for this workaround to succeed.)

This workaround is a combination of two solutions found on internet forums. One of them modifies Inkscape to use version 2.6 of python if it's on the system. (If it is, that modification can be done without installing the libxml modules). The other installs the libxml2 module Inkscape is looking for in version 2.7 of python.

If you're not comfortable with using the terminal, there's an unofficial patch you can install instead of using the below workaround. It can be found at this forum thread: http://boardgamegeek.com/thread/769281/installing-on-osx-lion-the-fantastic-lxml-wrapper (just search for "EggBot2.2.2.r2.mpkg.zip")

Caution: do not proceed if you are not comfortable with the Terminal, command line, or code editing

  • Make sure your install of Inkscape is a fresh, unmodified copy
  • Make sure your python 2 version is at least 2.7.5 (as this workaround was only tested with that version) If it's older, you can get 2.7.5 here: http://www.python.org/download/
  • Open Terminal
  • The following steps may produce errors. If they do, look at the errors and try to fix them to complete the steps before moving on! (The usual: Google if unsure, or do not proceed further)
  • Type the command "sudo easy_install pip" to install the python package manager pip
  • Type the command "sudo pip install virtualenv" (probably not required, but useful)
  • Type the command "sudo pip install lxml"
  • If there are no errors in the above few steps, you're good so far. If there are any errors, try to get the steps to complete without errors (the usual: look at the errors, Google a solution, etc.)
  • In a text editor, open the file "/Applications/Inkscape.app/Contents/Resources/bin/inkscape"
  • Above the line 32 (which reads: "export VERSIONER_PYTHON_PREFER_32_BIT=yes"), add the following line without quotes and save the modified file: "export VERSIONER_PYTHON_VERSION=2.6"
  • (Note that the python version 2.6 specification in the inkscape file may not do anything if version 2.6 isn't on the system, and inkscape may just default to the system's version of python. The above steps to install lxml should make libxml work on the current version of python nonetheless.)
  • Restart Inkscape. The extensions menu should work now.

References:

Friday, 7 June 2013

Test if an app is running on an android emulator

Problem:

How do I test that my app is running on the Android emulator and not a real device?

Solution:

import android.os.Build;

...

if( "sdk".equals( Build.PRODUCT ) ){
 // do emulator specific stuff here,
 // like set configs that are missing
}

Notes:

Tested to work using ADT Build: v22.0.1-685705. Your mileage may vary with other versions.

Note that in some versions you might need to test that Build.PRODUCT is "google_sdk" or "sdk_x86" instead of "sdk". An easy way to find the string is to print the value of Build.PRODUCT to the log or console while running your app in the emulator, then use that string.

This test can be useful if one needs to set configurations that would normally work on a device by default (but be missing in the emulator, such as needing to call setEGLConfigChooser(...) prior to doing anything else with a GLSurfaceView, as of ADT Build: v22.0.1-685705).

Tuesday, 23 April 2013

Getting "Must be a StateFieldPathExpression" Symfony2/Doctrine exception

Problem:

I'm getting a weird error when making a DQL query in my Symfony2 project. The error contains the phrase "Must be a StateFieldPathExpression". This seems to happen with queries that try to select an identity field (or something with a foreign key.)

Solution:

This may be a bit of a work around, but you can try using the IDENTITY() function in the DQL query to get the id. For instance, imagine that you wanted to select an external ID (un-creatively named 'extern_id'), among other (more un-creatively named) fields:

$dql = "
SELECT IDENTITY(s.extern_id) AS eid, 
  s.some_col AS sc,
  s.another  AS ac
FROM something s WHERE 1";

$em->createQuery($dql);

// ... etc ...

Notes:

This was tested to work using up to Symfony 2.1.4-DEV.

This workaround seems to work for now. If there's anyone out there with more knowledge of Doctrine and DQL, here's a question for you: is using IDENTITY() the right way to go on a permanent basis?

Find the length of an array in Twig

Problem:

How do I find the length of an array using Twig?

Solution:

Use the length filter, for instance:

{% if my_array|length < 1 %}
  {# ... do default thing ... #}
{% else %}
  {# ... do something ... #}
{% endif %}

Or if you'd like to use a variable instead ...

{% set arr_size = my_array|length %}

Friday, 15 March 2013

Disable spelling autocorrect in Safari

Problem:

I'd like to disable spelling auto-correct in Safari!

Solution:

Using OS X 10.7 or higher, there are at least two ways to disable automatic spelling correction: globally, and on an individual app basis. Disabling autocorrect can be useful for those who often need to spell out things that would come up as incorrect in the dictionary, such as HTML CSS style editors who need to use "center" instead of the autocorrected "centre".

To disable automatic spelling correction globally (at least across apps that use OS X's dictionary):

  • click on the apple icon on the top-left of the screen
  • click on System Preferences ...
  • click on Language & Text
  • click on the Text tab
  • uncheck Correct spelling automatically

To disable automatic spelling correction in Safari:

  • first click on any text field where you can type (otherwise the relevant menu option will be greyed out)
  • in the menu on the top of the screen, click Edit -> Spelling and Grammar
  • if checked, uncheck Correct Spelling Automatically

Notes:

Both of these worked using Safari 6.0.2 under OS X 10.7 and 10.8. Your mileage may vary across other versions of OS X and Safari.

Tuesday, 5 February 2013

Selectively and recursively copy all files of a single file type in OS X and Linux

Problem:

In OS X or Linux, how do I selectively copy only one type of file to a folder? For instance, how can I recursively copy all .mp3 files from a folder with many sub-folders into a single folder?

Solution:

Note: this solution assumes you have basic knowledge of using the Terminal and know how to avoid destructive commands.

To recursively check the paths of all files for instance all .mp3 in a folder and all its sub-folders, type the following into the Terminal (replacing the path and file extension to fit your need):

find /path/to/files/to/search -iname '*.mp3'

If everything looks alright, to copy the files use the following command (replacing the paths and the extension to fit your need - also note that this is a single line/command, but it's long so it may wrap to more than one line in your browser):

find /path/to/files/to/search -iname '*.mp3' -exec cp {} /path/to/destination/ ./mp3 \;

Important: make sure that the / is at the end of the destination path! (It will all be copied as a single file otherwise as it'll think that your destination is a file name and not a folder.)

Sunday, 3 February 2013

Passing a named associative array via URL

Problem:

How do I manually pass an associative array via URL?

Solution:

Let's say we have an associative array named 'arr_args' with the key-value pairs 'key1'=>'value1', 'key2'=>'value2', i.e. arr_args = [key1=>value1, key2=>value2]. Let's also assume we have a sample script called 'sample.php' that will be receiving this associative array.

One way that you can pass this into a URL as the following:

sample.php?arr_args[key1]=value1&arr_args[key2]=value2

Tuesday, 29 January 2013

How do I solve following HTML5 video error: HTTP "Content-Type" of "text/plain" is not supported

Problem:

When trying to play a video using the HTML5 tag in a web page being programmed, the video plays fine when running the file locally in Firefox. However, when running the web page using Apache, an error like the following comes up in the console:

HTTP "Content-Type" of "text/plain" is not supported. Load of media resource http://127.0.0.1/path/to/video.webm failed.

The videos are encoded properly, so they are not the issue.

Solution:

This error is happening as Apache isn't reporting the MIME type of the video files correctly. To solve this, add the following lines to the relevant .htaccess file that covers (at the very least) the folders of the videos that will be played:

AddType video/webm .webm
AddType video/ogg .ogv
AddType video/mp4 .mp4

Notes:

Alternatively, the proper MIME types can be placed into the appropriate configuration file for Apache. This solution is particularly relevant if your web server is set up to ignore .htaccess files.

Monday, 28 January 2013

Change Data Usage Cycle in Android 4.1.1

Problem:

How do I change the data usage cycle in Android 4.1.1? The option to change won't show.

Solution:

The first screenshot below illustrates the problem: it seems as though the option to change the billing cycle does not exist! Notice that mobile data is turned off at this point.

Turning on mobile data at first doesn't seem to fix the problem as seen in the screenshot below. The option to change billing cycles is still not there.

To work around this issue, try the following: exit the preferences to the home screen, and open the data usage preferences again. You should be able to see the option to change the billing cycle now.

Notes:

This seems to be a strange, intermittent problem with the interface. This solution was tested using Android 4.1.1 on a Galaxy Nexus. Your results may vary with other setups.

What's the font in the Google logo?

Question:

What's the name of the font used in the Google logo?

Answer:

The font is named "Catull". Find out more in the Wikipedia article for Catull here.

Use several wireless routers with only one DHCP server for a home network

Problem:

How do I connect more than one (D-Link) wireless router to make a single home network with only one router acting as a DHCP server?

(In other words, how do I make the other wireless routers in my home network act only as access points?)

Solution:

  • plug only one router into internet using the router's uplink/WAN port. This will be the primary wireless router and act as the network's gateway to the internet. This should preferably have a firewall and be the fastest router as all traffic from the network will be funnelled through it. This router should have several ethernet ports available to plug the other routers into it.
  • turn on the DHCP server in this router, and set the range to something that does not encompass the entire IP range (e.g. 192.168.0.100-192.168.0.255)
  • set the primary router's IP address to something outside of the DHCP server's range (like 192.168.0.1) -- this is to allow access to the web admin/setup application of the primary wireless router
  • plug the second (third, etc.) router into the primary router using one of the ethernet ports of both the primary and secondary (tertiary, etc.) wireless routers -- in other words, leave the WAN/uplink port of the secondary router empty
  • turn the DHCP server of all secondary wireless routers off
  • match the subnet of all secondary wireless routers to the subnet of the primary router (e.g. 255.255.255.0)
  • set the IP address of the secondary routers to something outside of the DHCP server's range (such as 192.168.0.2, etc.) -- this is to allow access to the admin/setup web applications of the secondary routers
  • (optional, but useful) set the SSIDs and authentication methods (like WPA2-only PSK) of all the wireless routers to the same as one another
  • (also optional) make sure the channels of the wireless routers are spread out as much as possible to minimize interference between them

Notes:

This has been tested with only D-Link routers, but should work for others, too. Again, while it's one of many solutions, it should be good enough for most home situations. The benefit of setting up the network this way (if necessary due to the nature of the location the wireless network is being set up, budget, etc.) is that all clients in the home's LAN should be able to communicate to one another if desired. (This can be useful for running local services, running a home file server, accessing networked printers, etc.)

As with any network, make sure that all machines connected to it are trusted and precautions have been taken to mitigate intrusions, viruses, anonymous logins, etc. This is beyond the scope of this reminder how-to, however a quick Google search should help with finding more information on this.

Reference:

The following reference probably explains this procedure better than this blog post. The blog post was written as a reminder to myself, in case the reference ever goes down. Hopefully this comes in handy for someone out there :)

Tuesday, 22 January 2013

Some useful postfix commands

Intro

This is a partial list of useful commands related to postfix/sendmail for my own reference. It's posted here in case anyone else finds this useful, too.

Commands

  • List stuff in the mail queue:
    mailq

  • Read a message in the mail queue with example id 012345678F:
    postcat -q 012345678F

  • Delete a message in the mail queue with example id 012345678F:
    postsuper -d 012345678F

  • Delete ALL messages in the mail queue (warning - no confirmation nor undo!):
    postsuper -d ALL

Wednesday, 2 January 2013

One workaround for Android not receiving MMS

Problem:

My Android (4.1) phone is often not receiving MMS messages in the Messaging app. It stays stuck on the "downloading" message. I have data turned on, so that's not the issue. I was also not roaming at the time. Sometimes Android would download the MMS messages, other times it would just remain on the MMS notification 'download'.

Workaround:

This workaround seemed to have success with my own device after several days of attempting other solutions (turning on/off background data, turning on/off wifi while 3G is turned on, etc.) Your mileage may vary, but hopefully it at least helps someone out there :)

  • in the Messaging app, go to the settings
  • scroll down to the "MULTIMEDIA (MMS) MESSAGES" section
  • uncheck "auto-retrieve"
  • when someone sends a MMS, click the "download" button that appears in place of the 'downloading ...' message
  • your message should now download, rather than forever remain on the "downloading..." message

Notes:

This was tested to work using Android 4.1.1 on a Samsung Galaxy Nexus while on the Fido network in Canada. Again, as many things can contribute to MMS messages not sending, your mileage may vary.

While this is not the ideal solution, most people will usually not be looking at a MMS message until they have the messaging app open in front of them, so hopefully this is an appropriate workaround for those who don't mind waiting a few seconds to manually download a MMS rather than have them automatically download.

By the way, if anyone at Google is reading this, hopefully this bug can be reproduced by your Android Messaging app team =) It's an intermittent bug and I have no idea how to reliably reproduce it, otherwise a bug report would have been filed by now! Have a great day!