Friday, 22 April 2011

Wireless Sync Music between Ubuntu PC and Android Phone

PC: Linux - Ubuntu 10.10 Maverick
Phone: HTC Wildfire with HTC Sense for Android 2.2 Froyo

I have been looking for a good way to wirelessly sync music to my phone for ages. I tried various android apps that failed to meet my needs in one way or another:

-Winamp - need winamp client on PC - no version for linux
-DoubleTwist (AirSync) - only for iTunes
-Android Sync Manager WiFi - PC client requires winXP or above
-Dropbox - must upload all music to internet first (when dropbox syncs on PC), which takes AGES, AND cannot auto-download anything - have to select each song and long press>download (BUT could work with additional app "Sync Folder with Dropbox")
-SugarSync - no Linux client
-ZumoDrive - same as dropbox in that have to upload everything to the cloud first, and cannot auto sync a particular folder on android, so would have to manually download all songs

And then I found Syncness. It doesn't require a PC client as it connects straight to network shares over your WiFi. Requires minimal setup (see below), and then you can have a directory of music on your PC automatically syncing to your phone every night (or just manually whenever you want). It costs about £1, but is well worth it.


SETUP

Put some music in a dir on your PC, and share it: R click > Sharing Options (then it might ask you for permissions to install some sharing libs). Now open Syncness on your phone and create a new profile and give it a name e.g. Music. Click the "Share" folder icon, and let it scan your network for shares, and then select your share from the list. Next click the "Local" folder icon and select your Music dir (if you don't already have one, you may need to connect your phone to your PC and create it first). Set "Sync Type" to "Push To / Pull From Remote", check "Active" (so it appears in your "Active profiles" list), and also check "Allow file deletions", so it can wipe old music you don't want any more. Then enter your Ubuntu name/pass (I left Domain blank), and do Menu > Save. Then you can setup a sync schedule if you want, but I don't change my music that often, so I just do it manually by pressing the big blue SYNCHRONIZE button on the home-screen.

Android 2.2 Froyo - Moving contacts from Phone to Google

Phone: HTC Wildfire
OS: HTC Sense for Android v2.2 Froyo

Confusing contacts system: you can store your contacts in 3 different "accounts" on your phone: in your SIM card account, on your phone's native account, or in your Google account. Only contacts stored in the third list will be synced to your Google Contacts list (used in Gmail), and so really this is where you wanna store all of them.

So what if you already have some contacts in your "phone account"? Maybe you got sent a vCard in a text message and when you clicked it, it automatically got added there without asking (how annoying), or maybe when you first got your phone, you just imported all your old contacts to your phone account without thinking, and now want to move them to your Google account, so they sync.

The best way I have found of moving ALL contacts from your phone account to your Google account is as follows:

1) Save your "phone account" contacts to a file: go into your contacts list (called HTC People on the Wildfire), and do Menu > Import/Export > Export to SD, and select phone account.

Maybe you wanna connect your phone to your PC and backup this file and check it worked properly, as next we will be deleting the contacts from your phone! You can read more about this later in the article.

2) Delete all your phone account contacts: do Menu > View and only select "Phone", then do Menu > Delete, and then Menu > Select All...

3) Import your contacts to your Google account: Menu > Import/Export > Import from SD, then select Google account. If you did step 2, you will need to update your View preferences again to see contacts in your Google account.

Note: If you decided you wanted to backup your contacts file and check it was working, here is some advice:  The file will be stored in your SD card's root directory, with a name like "pcsc_pcsc_00001.vcf". One way to check the file works is to skip step 2, and just import them to your Google account. BUT then each contact is automatically "linked" to the corresponding one on the phone account, and so if you then delete all your phone account contacts, both of them will get deleted, and you will be left with nothing! Of course you then know you are safe to import them again.

Thursday, 31 March 2011

Drush - Backup and Migrate command documentation

Drush is an amazing command line tool for administrating Drupal. Backup and Migrate is a Drupal module which simplifies the process of backing up and restoring your Drupal database(s). When I found out that Backup and Migrate now includes Drush support, I was really excited, but then I could not find any documentation for it anywhere (at the time of writing, the documentation link on the module page was broken). Eventually I thought to try the command line, and found everything I needed in the drush help output, so thought I would post it here in case it helps others.

Commands
bam-backup - Backup the site's database with Backup and Migrate.
bam-backups - Get a list of previously created backup files.
bam-destinations - Get a list of available destinations.
bam-profiles - Get a list of available settings profiles.
bam-restore - Restore the site's database with Backup and Migrate.
bam-sources - Get a list of available sources.



bam-backup
Backup the site's database using default settings.

Examples:
drush bam-backup - Backup the default databse to the manual backup directory using the default settings.
drush bam-backup db scheduled mysettings - Backup the database to the scheduled directory using a settings profile called "mysettings"
drush bam-backup files - Backup the files directory to the manual directory using the default settings. The Backup and Migrate Files module is required for files backups.

Arguments:
source - Optional. The id of the source (usually a database) to backup. Use 'drush bam-sources' to get a list of sources. Defaults to 'db'
destination - Optional. The id of destination to send the backup file to. Use 'drush bam-destinations' to get a list of destinations. Defaults to 'manual'
profile - Optional. The id of a settings profile to use. Use 'drush bam-profiles' to get a list of available profiles. Defaults to 'default'



bam-backups
Get a list of previously created backup files.

Examples:
drush bam-backups manual - List of backup files currently in the destination called "manual"

Arguments:
destination - Required. The id of destination to list backups from. Use 'drush bam-destinations' to get a list of destinations.



bam-destinations
Get a list of available destinations.



bam-profiles
Get a list of available settings profiles.



bam-restore
Restore the site's database with Backup and Migrate.

Examples:
drush bam-restore db manual "LCC-31.03.2011-14.01.59.mysql.gz" - restore the default database using the given dump file, which can be found in the destination called "manual"

Arguments:
source - Required. The id of the source (usually a database) to restore the backup to. Use 'drush bam-sources' to get a list of sources. Defaults to 'db'
destination - Required. The id of destination to send the backup file to. Use 'drush bam-destinations' to get a list of destinations. Defaults to 'manual'
backup id - Required. The id of a backup file restore. Use 'drush bam-backups' to get a list of available backup files.



bam-sources
Get a list of available sources.



Closing Notes
I'm not sure if this is out of date or something, but in my experience you provide the name and not the id for all of the arguments.

Drupal 6 - Drush warning about orphaned actions

When I was executing drush commands, I got a warning similar to this:
WD actions: 2 orphaned actions (comment_unpublish_action, comment_publish_action) exist in the actions table. Remove orphaned actions
Solution is to use a badly-documented Drupal feature which automatically removes all orphaned actions. Simply visit the following hidden URL on your drupal site: yoursite.com/admin/settings/actions/orphan, and it will remove any orphaned actions and forward you to the Manage Actions page, where you will see they are no longer listed!


REFERENCES
https://drupal.org/node/445922#comment-2977526

Thursday, 24 February 2011

Drupal 6 - Webforms: Loading GIF on Submit

If you have a slow mail server, then submitting webforms can sometimes appear to do nothing for a while. For me, this is anywhere between 2 and 8 seconds, but I have read about a lot of other people in similar situations. While the problem is with the mail server, sometimes there's nothing that can be done about this, and a simple solution to keep the user calm is to add a little loading animation. No Ajax involved: the GIF is simply shown when the user clicks submit, and then after the wait, they will be taken to the success page.

1) Grab the right GIF animation from this amazing site: http://ajaxload.info/ and put it here: /sites/all/images/loading.gif

2) The CSS: make it so that the GIF is used when a certain class is applied to an input element
input.form-submit.loading-gif {
 background: url('/sites/all/images/loading.gif') 50% 1px no-repeat;
}

3) The jQuery script: in your theme dir, create js/submit-loading.js which will apply the CSS class to the submit button when it is clicked
$(document).ready(function()
{
    // preload image
    (new Image()).src = "/sites/all/images/loading.gif";
    
    $(".webform-client-form").submit(function() {
        // select the button
        var $button = $(this).find("#edit-submit");
        // remove the text, but persist the width of the button
        var $buttonWidth = $button.outerWidth();
        $button.attr('value', '').width($buttonWidth);
        // display the loading gif and disable the button
        $button.addClass("loading-gif").attr('disabled','disabled');
    });
});

4) Add the script only to the right page with a bit of PHP in your theme's template.php. See #2 in my article: Different ways of adding JavaScript to a page

Tuesday, 22 February 2011

PHP Logging on Ubuntu 10.04 Lucid

PHP CONFIGURATION
Enable PHP logging by setting up the appropriate variables in your php.ini. If you don't know where your php.ini file is, try the command: locate php.ini, mine was here: /etc/php5/apache2/php.ini:
error_reporting = E_ALL & ~E_DEPRECATED
log_errors = On
error_log = /var/log/apache2/php_errors.log
EXTRA: if you want to show PHP errors on screen, set:
display_errors = On
To finish, we restart apache: sudo /etc/init.d/apache2 restart


PERMISSIONS
Then find out what your apache user is called: ps aux | grep apache (mine was www-data), and ensure that user has full permissions on the log file directory (/var/log/apache2/). The best way to do this is ensure the user has group access i.e. either add the user the group currently assigned to the directory, or change the directory's group to one that the user is in! On my system, the directory had the group: adm, and so I added www-data to that group (see /etc/group). You then need to give the directory full permissions for group access: sudo chmod 770 /var/log/apache2/

To register these changes, we need to log out and back in again.


TESTING
An easy way to generate a PHP error is to call an undefined function i.e. put this PHP code into one of your pages:
a_function_that_doesnt_exist();
Now when you visit that page, you will either get a PHP error on screen (if you enabled that), or your browser will just display a 403 error, but importantly, your new log file php_errors.log should have been created and had it's first error logged.


INLINE PHP CONFIGURATION
One other method worth noting is inline configuration. During development, you may decide you want to temporarily enable showing errors on the screen for a particular page. The easiest way to do this, is simply to add this line of PHP to the top of your PHP file:
ini_set('display_errors', TRUE);

Wednesday, 2 February 2011

Drupal 6: Different ways of adding JavaScript to a page

REMEMBER
  • Always use drupal_add_js() as this lets Drupal handle it i.e. preprocess/cache it.
  • All of the examples assume your JS is in a script file, but you can also include an "inline" script by sending it as a string for the first argument, and setting the second to "inline" e.g. drupal_add_js('alert("Hello!")', 'inline');
  • If your script is in your theme directory, you can use path_to_theme() and then the relative path from there (with a preceding slash) e.g. path_to_theme().'/js/myscript.js'

1) Add a script to all pages
a) using template.php
drupal_add_js('sites/all/scripts/tweaks.js');
b) using your theme's .info file (the script needs to be somewhere within your theme directory)
scripts[] = script.js

2) Add a script to page(s) with a specific URL / URL pattern using template.php (the following will only add the script on site.com/my/page)
NOTE: if you are using URL aliases, you need to know the un-aliased version for this (see site.com/admin/build/path)
function mytheme_preprocess_page(&$vars) {
  if (arg(0) == 'my' && arg(1) == 'page' && arg(2) == null) {
    drupal_add_js(path_to_theme().'/js/myscript.js');
    $vars['scripts'] = drupal_get_js();
  }
}
OR use the following condition to add it to any pages that start with the URL site.com/my/page e.g. /my/page/1, /my/page/2, /my/page/2/edit etc.
if (arg(0) == 'my' && arg(1) == 'page') {...}
OR use the node ID
if (isset($vars['node']) && $vars['node']->nid == 23) {...}
OR apply to all nodes of a specific content type
if (isset($vars['node']) && $vars['node']->type == 'book') {...}

3) Add a script to a specific page by editing the page in Drupal, and setting the input format to "PHP code"
drupal_add_js('sites/all/scripts/tweaks.js');

4) Add a script to a block, which you can then setup to be included in a specific page or set of pages
drupal_add_js('sites/all/scripts/tweaks.js');


Also note that it is very similar to add stylesheets to pages. The function is drupal_get_css().


REFERENCES
http://drupal.org/node/304178
http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_add_js/6
http://stackoverflow.com/questions/61735/include-css-or-javascript-file-for-specific-node-in-drupal-6