Search This Blog

Thursday 29 December 2011

Blogger, double line spacing

This has been bugging the crap out of me for ages so I finally sat down this evening and worked it out.  Or at least I worked a work-around out !

When creating posts blogger would kindly add </br> tags into the html. </br> is a HTML line break.  So when writing a post with CR to create a single line space for a paragraph blogger would kindly add a br tags all over the place, and so you end up with double line spacing.

Note:Changing the line break options made bugger all difference.

I had my default blogger font as Trebuchet but in the WYSIWIG blogger editor the font would show as Times Roman.  Each blog post I created I'd select all and use the font drop down to show me the correct font.

Bingo ! .. its at that point blogger gets all crazy with the br tags.

What I hadn't realised is if you leave the editor font alone and look at the preview then you get the default font you've set in the blog template design.  And if you don't change the font in the editor then blogger never inserts the </br> tag.

I am happy now.  No more switching to HTML view and deleting tags ..

VLC, Windows 7 to Basic Mode & Black screen

Debugging an audio issue I have on XBMC and dropped to trusty VLC. Windows (7 x32) flicked into basic mode and VLC only played the audio.


A quick google showed a few hits with the same issue, but no resolution. Check video drivers, update VLC etc.  All rather generic.


It also wasn't version specific (I horde older versions) and they all behaved in the same way.


No amount of preference changes resolved it.


Fix : Shut some apps, in my case Chrome was hogging all the RAM and I was >70% used. Releasing some system resources fixed VLC. So not directly a VLC issue. 


Hope that helps some people. The problem seems to have been around a while ..

Wednesday 14 December 2011

Installing flash on Backtrack 5

Backtrack comes with flash installed, but it doesn't work.  Believe it or not Nessus requires flash ! A security scanner that requires flash, oh the irony ..

Following the instructions provided by BT didn't work for me so I'm reproducing the 32bit steps which did :


Grab the correct/latest flash install from adobe.com : 

install_flash_player_11_linux.i386.tar.gz
Run the following commands : 
Remove BT installed files 
apt-get purge flashplugin-nonfree flashplugin-installer gnash gnash-common mozilla-plugin-gnash swfdec-mozillarm -f /usr/lib/firefox/plugins/*flash*
rm -f /usr/lib/firefox-addons/plugins/*flash*rm -f /usr/lib/mozilla/plugins/*flash*
rm -f ~/.mozilla/plugins/*flash*sorm -rfd /usr/lib/nspluginwrapper
Install downloaded version
tar xvfz install_flash_player_11_linux.i386.tar.gz
mkdir ~/.mozilla/plugins
mv -f libflashplayer.so ~/.mozilla/plugins/
Test within the browser, firefox about:plugins

UPDATE : This process also works for Chromium

Wednesday 30 November 2011

Crowbar & OpenStack Install Part 1

A few weeks ago I decided to investigate OpenStack.  The core components are a collaboration and resulting love child of NASA and RackSpace and is an Open Source solution to build a blaah blaah cloud.  It seems to be gaining good traction and is often mentioned in the same breath as VMware.  In fact it appears everyone not in VMwares back pocket is jumping on the bandwagon and so seemed worthy of a look.

This is still a moving target for me, its not 'up' and has certainly not been painless and smooth, but I'm writing up Pt.1 as much for me as for the blogosphere.


OpenStack is, well, just that, a stack of different products which together produce an end solution.  In my eyes and how I'd describe it to 'management' is its comparable to LAMP.  Linux, Apache, MySQL and PHP.


I won't go into the details you can read yourself - http://en.wikipedia.org/wiki/OpenStack


I started by reading the install docs and attempting to install each piece individually and then I guess hook them all together.


This didn't go well and a twitter reply from Matthew McClean suggested I take look at Dells Crowbar.


The rest of this post will be the process, troubleshooting and useful links I've come across as I attempt to install Crowbar on my journey to OpenStack nirvana ..


Crowbar background


https://github.com/dellcloudedge/crowbar/wiki

http://robhirschfeld.com/2011/03/14/how-openstack-installer-works/

Resources


4 VMware guests - Each has two NICS each on a vlan, eth0 vlan 66 and eth1 99.  eth0 will be re-configured from the default so its available on my corp LAN.

  • Admin Node - 2GB RAM, 20GB disk
  • Node 1 - 1GB RAM, 15GB  disk
  • Node 2 - 1GB RAM, 8GB disk
  • Node 3 - 1GB RAM, 8GB disk


Installation

The documented install procedure - https://github.com/dellcloudedge/crowbar/wiki/Install-crowbar


If only it were that simple.

NB//Crowbar.iso is a base install, it has none of the OpenStack components. 
This will build, pretty seamlessly, your 'admin' node which is then used to build the other components.
Here things went a little squiffy.

Theres a  nice YouTube video of building the environment which I started to follow :




But with little success.  The first barclamp (name assigned to the Crowbar packages, which actually in turn directly represent Chef cookbooks) which the video has you assign is Glance, which for me failed.  Attempting to resolve this I joined the Crowbar lists and co-coincidently someone else asked about the order to install applications and had another link :

MySQL
Keystone
Nova Dashboard
Glance
Nova
Very different to the order on the video ! - But its still worthwhile watching.

Another little find went into some further details - http://kb.dtosolutions.com/wiki/Deploying_a_small_OpenStack_test_environment_using_Crowbar


From these I eventually cooked up the following install method which seems to be more successful than anything else so far.

Due to a bug in the dashboard when removing or adding nodes I found you had to create all your nodes upfront before you start to apply barclamps.  Create 3 nodes, power them all on so they run the discovery image and become available in the Crowbar console (unassigned, yellow).

Click bulk edit and assign all three.  They will install the OS, reboot a few times and then go 'assigned' in the console with a green icon.


Assuming you have the admin node built and three green nodes.

  • Build MySQL proposal and assign server to node 1 and client to node 2 and 3
  • Build Keystone and assign to node 1
  • Nova Dashboard to node 1
  • Glance to node 1
  • Nova.  
Nova requires a 'controller' and then compute nodes.  Trying to do all three failed for me so I did them individually.  In my case I'm using VMware for this POC so the nova proposal needs to be changed.  Edit the line :
"libvirt_type": "kvm", -> "libvirt_type": "qemu",
And assign Controller to node 1 and then compute to 2 and 3.

Throughout all of this I had a tail -f running to the admin log :



/opt/dell/crowbar_framework/log/production.log


By all accounts I should now have a working environment. I don't, everything appears to be installed but the learning curve continues.

Nova dashboard is not working which I've traced to a routing issue on node 2. It has the admin interface up but the default gateway is using one of the networks I didn't change at the install time.


Nagios is not working. Watching the production.log during the barclamp installs showed Nagios errors but I'm ignoring them/that for now.


Troubleshooting / Hints 'n' tips : 


Barclamps sometimes report failure to deploy but repeating the same task will be successful.


If your running your POC on hypervisors or something else that has the technology make good use of snapshots. 

Wednesday 23 November 2011

Empathy new IM notifications / window

Part of my continued insistence on using Linux rather than Windows has meant using Pidgin as my IM client for corporate Sametime and Google chat.


Not being 100% happy with it I switched to Empathy.  Much cleaner interface and generally more happy.


But, new IM conversations appeared on the notifications bar (Gnome3) rather than launching a new window.  Annoying and very easily missed.


Nothing obvious in the preferences.   Clutched at straws by disabling (Preferences | General) 'Display incoming events in the notification area' and bingo. 
 
New tabs/windows open on a new IM - happy (for now)


Monday 24 October 2011

OCD, me !?

A conversation in the office on how to lace shoes, something I have very strong feelings about,  resulted in me making a list :
  1. Shoe laces must be over not under and be symmetrical.
  2. If a shirt has button down collars - use them !
  3. Shirt/T-shirts are not allowed to have the top button done up.  Unless a tie is involved.
  4. Under no circumstance will anyone touch my screens with fingers.
  5. Toilet rolls, over not under.
  6. Cables will not be crossed in my data centre.
  7. Wooden cutlery, simply not allowed.
  8. Rattles in car.  Must be found.
  9. Plastic film on remote controls/electronic devices - not allowed and will be removed ASAP.

Tuesday 4 October 2011

Powershell file & directory purge script

I've been wanting to learn something new for a while and since @darrenparkinson comments on my DNS update batch file I thought I'd have a look at Powershell, aka POSH (I like that).

Started by diligently reading each chapter of 'Mastering Powershell', Dr. Tobias Weltner. I say each chapter, my attention levels waned after about chapter, erm 1.


Plan B.

I already have a few scripts (batch) running in the office so picked on one of those and started trying to write a replacement. In this case a purge files after # days which we run on a fileshare.

Dive in, used the book for reference and of course the worlds saviour our good friend google.


Lots of reading, lots of searching, lots of head scratching, lots of trying others examples and lots of grumpiness resulted in below.


# // ----------------------------------------------------------------------------------//

# // This script will delete files and directories based on path and days set below //
# // Errors are written to the Application event log and an email summary sent. //
# // //
#
# // Revision history :
# // Created : 03/10/2011 - Paul Regan //
# // ----------------------------------------------------------------------------------//

// READ THESE TWO SECTIONS !!!
//
// 1. Before you can start writting to system logs you have to register the source - only once. Not particulary well documented so left here
// for reference :
// New-EventLog -Logname "<name>" -Source "<a name you can reference>"
// eg
// new-EventLog -Logname "Application" -Source "POSH:Script"

// 2. Depending on your local security you may need to set script execution policy.
// http://technet.microsoft.com/en-us/library/ee176961.aspx
//
// set-executionpolicy <level>
// eg
// set-executionpolicy unrestricted

# // *********** Set your variables here !
# //
# // -Days ## is the period you want to retain
$span = new-timespan -Days 30
# // Working directory
$SourcePath = "s:\temporary"
# // Set logging variables
$logname = "s-temp-delete-$todaynumerical.log"
$logpath = "c:\scripts\logs"
# // Set eMail variables
$subject = "POSH Script : Files and directories deleted from $sourcepath on $todaynumerical"
$fromAddress = "posh@domain.co.uk"
$smtpServerName = "smtpserver.domain.co.uk"
$toAddress = "people@domain.co.uk"
# // Send attachment or results in the body of the email [true/false]
$emailattach = "false"
# // System variable - DONT CHANGE unless you know what you are doing (not that I do)
$today = get-date
$todaynumerical = get-date -format "yyyy-d-M"
$CutoffTime = $today-$span

# // Creates a function with all the param needed for the commane Write-EventLog
function WriteEventLog ($message, $entrytype)
{
Write-EventLog -Logname "Application" -Source "FilesScript" -Message $message -EntryType $entrytype -EventID 4001
}

# // Set the two variables
$message = "PS Log file message"
$entrytype = "Information"

# // I think this writes the first message to the Windows event log defined above, gives you a 'start of process' point to find in a busy log.
WriteEventLog $message $entrytype

# // Builds a file list (PS can accept/apply multiple output messages to the same variable.
# // Where-Object {$_.PSIsContainer -eq $False = Only files, directories would return TRUE
$files = get-childitem -recurse $SourcePath | Where-Object {$_.PSIsContainer -eq $False}

# // empty arrays to hold file lists
$removedFiles = @()
$skippedFiles = @()
$failedactionfiles =@()

# // Start the for loop to read $files and determin the action based on the modified date
foreach ($file in $files)
{
remove-item -ev a -path $file.fullname -recurse -force -whatif | Where-Object {$_.lastwritetime -le $CutoffTime}

<#
#####################################################################################################################
if ($file.lastwritetime -gt $CutoffTime)
{
$skippedFiles += $file.fullname
# $message = "Not moving newer: " -join $file.fullname
# $entrytype = "Information"
# // I don't really want to write files not deleted/moved into the EventLog
# WriteEventLog $message $entrytype
}
else
{
# // Build the newname variable using destination path, old file name and todays date
# $newname = $DestPath + "\" + $file.name + "-" + $file.lastwritetime.tostring("yyyy-MMM-dd")

# // -ev = ErrorVariable which the output from is being set to 'a'
# // $file.fullname pulls the full path from the object (file)
#move-item -ev a -path $file.fullname -destination $newname
remove-item -ev a -path $file.fullname -recurse -force -whatif
# // From the variable $a .count the number of entries, entries against $a would mean an error
#####################################################################################################################
#>
# // Are there any errors ?
if ($a.count -gt 0)
{
# // Creates a $message variable based on $a (output from Remove-Item) and $file (The file we're working on)
# // remote-item generates a nice clean message. move-item does-not, both message options below.
#$message = $file.fullname + " - " + $a[0].tostring()
$message = $a[0].tostring()
# // Writes the error to the event log defined above
$type = "Error"
WriteEventLog $message $type
# // Also add the message to the $failedactionfiles array, which we'll use later ..
$failedactionfiles += $message
}
else
{
$removedFiles += $file.fullname
}
}

# // I have now removed all files older than $span and will start removing all EMPTY directories that match the same cut off time

# // Build a list of home directories from $sourcepath and apply to $rootdirs
$rootdirs = get-childitem $sourcepath | Where-Object {$_.PSIsContainer -eq $True}

<# // This function is not actually being used but I am proud of it, my first, so its staying here for now.
function getemptydirs ($source)
{
# // Command from http://technet.microsoft.com/en-us/library/ff730953.aspx
# // (Get-ChildItem c:\scripts\working\live -recurse | Where-Object {$_.PSIsContainer -eq $True}) | Where-Object {$_.GetFiles().Count -eq 0} | Select-Object FullName,root,parent
(Get-ChildItem $source -recurse | Where-Object {$_.PSIsContainer -eq $True}) | Where-Object {$_.GetFiles().Count -eq 0} | Select-Object FullName
}

# // Get-ChildItem c:\scripts\working\live\paul | get-member << to display available properties
# // (Get-itemproperty -path c:\scripts\working\live\paul).lastwritetime << to display lastwrite time property
# // Get-ChildItem c:\scripts\working\live -recurse | Where {$_.psIsContainer -eq $true} | get-member -membertype property
# // Get-ChildItem c:\scripts\working\live -recurse | Where {$_.psIsContainer -eq $true} | get-itemproperty -name "Parent"

#>

# // Create some empty arrays and default options to be used
$emptydirs = @()
$removeddirs = @()
$message = "PS Log file message"
$entrytype = "Information"

# // Loop through $rootdirs and create an array containing all directories with zero file count and older than # days (set above)
foreach ($directory in $rootdirs)
{
$emptydirs += (Get-ChildItem $directory.fullname -recurse | Where-Object {$_.PSIsContainer -eq $True}) | Where-Object {$_.lastwritetime -le $CutoffTime} | Where-Object {$_.GetFiles().Count -eq 0}
}

# // Now delete the list we just made
# // First compare the count of $rootdirs & $emptydirs. If they are the same it indicates there are no directories to delete.
if ($emptydirs.count -eq $rootdirs.count) {
echo "Zero to delete"}
else {
# // Loop through $emptydirs removing each directory
# // NB// If the root dir is actually empty, ie has no dirs that match the remove filter then it will generate a null error if you watch the script live.
foreach ($emptydir in $emptydirs) {
remove-item -errorvariable err -path $emptydir.fullname -recurse -force -whatif

if ($err.count -gt 0) {
# // Creates a $message variable based on $error (output from remove-item)
$message = $err[0].tostring()
# // Writes the error to the event log defined above
#$type = "Error"
#WriteEventLog $message $type
# // Also add the message to the $failedactiondir array, which we'll use later ..
$failedactiondir += $message }
else {
$removeddirs += $emptydir.fullname}
}
}

# // Create the log files
# // Moosh both the results arrays into a single with output to a txt file
$attachments = $removedfiles+$removeddirs | out-file $logpath\$logname

# // Just to keep the email clean I'll check for empty file actions and set a cute little message
if ($failedactionfiles.count -eq 0) {$failedactionfiles = "No file remove failures"}
if ($removedfiles.count -eq 0) {$removedfiles = "No files removed"}
if ($skippedfiles.count -eq 0) {$skippedfiles = "No files skipped"}
if ($removeddirs.count -eq 0) {$removeddirs = "No directories removed"}

# // Construct the email message
$bodyText = @()
$bodyText += "Failed to remove: "
$bodyText += $failedactionfiles
$bodyText += "----------------------------------------------------"
$bodyText += "Removed files: "
$bodyText += $removedFiles
$bodyText += "----------------------------------------------------"
$bodyText += "Skipped files: "
$bodyText += $skippedFiles
$bodyText += "----------------------------------------------------"
$bodyText += "Removed directories: "
$bodyText += $removeddirs

# // The text from the array $bodyText when sent via email comes out as a single line. | Out-String deals with that.
# // http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/e0213b00-331f-4588-be90-afd0ce5ed50b/
$bodyText = $bodyText | Out-String
$bodyString = @"
$bodyText
"@

if ($emailattach -eq "false") {
# // Send email with results in the body
send-mailmessage -To $toAddress -Subject $subject -From $fromAddress -Body $bodyString -SmtpServer $smtpServerName
}
else {
# // Send email with attachment log file
send-mailmessage -To $toAddress -Subject $subject -From $fromAddress -attachments "$logpath\$logname" -SmtpServer $smtpServerName
}

So my journey is far from over, in fact its just started and I'll re-visit this at some point as its pretty scrappy and no doubt horribly inefficient, but it works and I even managed to improve on the previous script as before empty directories got left behind and thats now addressed with this so I'm happy(ish). I at least now have a much better understanding of the potential. 

I'm also resigned that I'll never be a developer and I can certainly relate to this girl .. 

Replace Pi with many POSH cmdlets and statements I've attempted to understand over the past month or so .....

What is an Object?


What is an Object?
An “Object” is something we can gather information from and/or perform an action upon. An object, in PowerShell, consists of properties (information we can gather) and methods (actions we can perform).
As an example, let’s look at a “light bulb.” The object should be obvious, it’s a light bulb. The properties of a light bulb could be color, wattage, and type (florescent, incandescent, or halogen). Methods are the actions we can perform on the object such as; turn on the light bulb and turn off the light bulb.

Wednesday 7 September 2011

XBMC Addons (finding the bloody things)

After wasting too much time trying to find an addon I'd just installed.  


Go to the type of media, eg video, and navigate up !

Wednesday 31 August 2011

Visio Vertices

Because literately everytime I go to do this I forget, its my Visio black hole ..

Vertices appear when you select the Line or Pencil tool !

Tuesday 30 August 2011

Humax IR problem, BlueEye to the rescue !

Replacing my Sky service with a Humax receiver has only been a good thing but the IR 'issue' was bugging me. It just wasn't up to the job in the way my room is laid out.

I settled on an IR extended from BlueEye, ordered, arrived, excelled service.

I tested it for a few days and it solved the problem. I made the final install by routing the cable through the case and tucking the IR sender into the back of the IR component on the front facing board. Its a few screws and the front pops off, all pretty simple.

Friday 19 August 2011

Getting the cute profile picture in Google search results

Looking for something this morning and I noticed peoples picture appearing next to some searches :
Some random person
Apparently easy. Well the first part was, getting a full sign off on the webmaster snippets testing tool took a fair amount of reading.
You need :
  1. Website, Blog, or I think pretty much anything online would work as long as you can edit the code
  2. Google profile
Your going to create a link between those two things which Google magic uses to look you up in searches that hit your content.

On your site/blog create a link to your Google profile :
Your profile url will be something like : https://plus.google.com/102726977217362443519

NB// the rel="author" is the super important bit.

I already had a Google+ link (top left) on my blog so just added the rel="author"




Next step is to edit your Google profile so that it includes a link to the site you just added the link on.


Running the snippet test tool against this blog gave me a single error :
Warning: Missing required field "updated".
4 hours later and much reading I came across this which talks about enabling your blog for hatom, part of the microformats initiative - and way out of the scope for this post.



The pertinent part for me was the class='timestamp-link' section with the class 'updated'. And the part missing from my blogger template.


Edit the design of your template and go into raw edit HTML, enable the widget check box and then search for the text 'timestamp-link'.


In my template there were two entries. Add 'updated' to the class. Save and re-run the snippet test, you should be good.
<a class='timestamp-link updated' expr:href='data:post.url' rel='bookmark' title='permanent link'><abbr class='published' expr:title='data:post.timestampISO8601'><data:post.timestamp/></abbr></a>
So now you wait <insert Google time> until they get around to crawling the site and updated the index.

Thursday 18 August 2011

Enabling Cisco Call Manager (6.1) Music on Hold (MOH) Multistreaming

Enable Multicast :

global switch/router commands (VRF)

ip multicast-routing
ip pim send-rp-announce Loopback0 scope 10

ip pim send-rp-discovery scope 10

ip multicast-routing vrf

ip pim vrf INTERNAL send-rp-announce scope 100 -- Best practice is Loopback rather than interface

ip pim vrf send-rp-discovery scope 100

Add ip pim sparse-dense-mode to all Interfaces that need to participate in the multicast stream or pass traffic

Show commands :

sh ip mroute
sh ip mroute vrf INTERNAL

Output :
*Snip*
(*, 239.1.1.1), 01:35:57/stopped, RP 10.2.70.253, flags: SP
Incoming interface: , RPF nbr 10.2.70.253, RPF-MFD
Outgoing interface list: Null
*Snip*


Call Manager Config :

Enable Multicast on MOH Audio Source
Enable Multicast on MOH Server - default IP is 239.1.1.1:16384
- enable increment port
Enable Multicast on Media Resource Group

NB//Enabling Multicast on the MRG requires endpoints to be reset to pick up the new settings, including gateways.

Something aaS

Nice article : http://www.katescomment.com/iaas-paas-saas-definition/


Wednesday 3 August 2011

A way/hack to use your own domain with Google Picasa

Assumes you already have :

a - domain
b - it being hosted somewhere with some space
c - access to create/edit .htaccess file.

Open up one of your galleries and we're looking for the part of the URL after google.com.

eg: http://picasaweb.google.com/paulregan73/GalleryName

In that URL paulregan73 is my Picasa user name and will remain on the new URL we'll create.

Now add the following to the .htaccess file, replace picasauser with your specific account name.

RewriteRule ^picasauser(.*) http://picasaweb.google.com/picasauser$1 [NC,P,L] #Rev proxy picasa
RewriteRule ^m(.*) http://picasaweb.google.com/m$1 [NC,P,L] #Rev proxy mobile picasa

The first rule means you can now hit the Picasa files using :

http://your_domain/picasauser/gallery
NB// Of course this only works for public galleries and not private/https - the google.com cert will fail for private.


The second rule takes care of mobile users. Google will redirect them to /m. Having this rule seems to take care of that.

EDIT : 24/8/2011 - Google seem to be switching the user id part of the URL from the name to a numerical representation of you google id.

https://picasaweb.google.com/102726977217362443519

So a new line in My .htaccess :

RewriteRule ^102726977217362443519(.*) http://picasaweb.google.com/102726977217362443519$1 [NC,P,L] #Rev proxy picasa url to paulregan.co.uk


It also looks like Google are redirecting all mobile access to https. So the ^m(.*) above still works if you specify the full mobile url, eg something like :
http://www.paulregan.co.uk/m/viewAlbum?uname=paulregan73&aid=5635917397624685905&start=0&fgl=true&pli=1


but when you use a regular link and hit it with a mobile client the https gets in the way and your dumped on the picasa login screen ... booooo. I'll keep playing with this but I don't see a way around it, which kind makes the whole thing worthless now. Maybe Google will let us use our own domains in the future, a-la blogger ..

Friday 22 July 2011

Adding CoolIris embed to PhpBB

 Under the 'posting' section in the ACP.

Create a new BBCode :

BBCode :
[cooliris]http{SIMPLETEXT}://picasaweb.google.com/{INTTEXT}/{IDENTIFIER2}[/cooliris]

HTML replacement :

<script type="text/javascript"         src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
    </script>
  <div id="wall{INTTEXT}{IDENTIFIER2}">    <script>
        var flashvars = {
            feed: encodeURIComponent("api://picasaweb.google.com/?user={INTTEXT}&album={IDENTIFIER2}")
        };
        var params = {
             allowFullScreen: "true",
             allowscriptaccess: "always"
        };
        swfobject.embedSWF("http://apps.cooliris.com/embed/cooliris.swf",
            "wall{INTTEXT}{IDENTIFIER2}", "600", "450", "9.0.0", "",
            flashvars, params);
    </script>
</div>



NB// This JS code is from http://lysergo.blogspot.com/2010/05/bbcode-picasa.html.  I made two changes from the original blog post.  '#' dropped and {SIMPLETEXT} added to the BBCode.


Assuming it saves OK you can now test this by manually adding a URL between the [cooliris][/cooliris] tags.  If it all works OK you can go back to the code edit and enable the 'Display on posting page' and add a little help text.

Adding Web Picasa Slide show to PhpBB

Under the 'posting' section in the ACP.


Create a new BBCode :


BBCode :
[picasa]http{SIMPLETEXT}://picasaweb.google.com/{INTTEXT}/{IDENTIFIER2}[/picasa]


HTML replacement :


<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>
<div id="piks{INTTEXT}{IDENTIFIER2}"> <script>
var flashvars = {
feed: "http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F{INTTEXT}%2Falbum%2F{IDENTIFIER2}%3Falt%3Drss%26kind%3Dphoto%26hl%3Den_US",
RGB: "0x000000"
};
var params = {
pluginspage: "http://www.macromedia.com/go/getflashplayer",
allowscriptaccess: "always"
};
swfobject.embedSWF("http://picasaweb.google.com/s/c/bin/slideshow.swf",
"piks{INTTEXT}{IDENTIFIER2}", "600", "450", "9.0.0", "",
flashvars, params);
</script>
</div>



NB// This JS code is from http://lysergo.blogspot.com/2010/05/bbcode-picasa.html.  I made two changes from the original blog post.  '#' dropped and {SIMPLETEXT} added to the BBCode.


Assuming it saves OK you can now test this by manually adding a URL between the [picasa][/picasa] tags.  If it all works OK you can go back to the code edit and enable the 'Display on posting page' and add a little help text.