Thursday, February 25, 2010

Test Code

This is a test of the intensedebate system.

Monday, June 15, 2009

64 Bit Ubuntu Flash - stopping the crash

While transitioning to Ubuntu as my primary desktop, one of the struggles was Flash. It crashed the browser, or quit working through a browsing session. Gmail would crash completely. Insanely annoying.

Adobe released an alpha version of their plugin for 64 bit linux. It doesn't require the plugin wrapper. Looking through ubuntuforums.org had several lengthy threads about how great the plugin was working.

I was not one of the happy ones. Flash sucked for me. I have however found a way to make it work.

First step is to completely remove any vestige of flash for the browser.
1) $ sudo apt-get remove flashplugin-nonfree
( do the same remove on any open source versions )
2) $ locate plugins | egrep -i "(firefox|xul|mozilla)" | egrep -v "(search|old|eclipse|Pandora)" | grep flash
This will show you everywhere that a flash player plugin is hiding. The -v "(search...ora)" part was due to some settings on my computer. The -v flag is a negating search. It will omit any results which contain any of those terms
3) rm -f any plugins returned.
4) start firefox, and go to about:plugins
You should see no listings for flash. If you do, then you will need to determine where the plugin is loading from.
5) Download the tar ball from Adobe: 10.0.22 Plugin from the Adobe download center
6) Using file roller or whatever archive application, untar the file. There is one file, libflashplayer.so.
7) Move that file into $HOME/.mozilla/plugins/ (or any other alternate location)
8) On my system, I had to link the file to a few other places. Your mileage may vary.
9) $ cd /usr/lib/firefox-addons/plugins && sudo ln -s $HOME/.mozilla/plugins/libflashplayer.so
10) $ cd /usr/lib/mozilla/plugins && sudo ln -s $HOME/.mozilla/plugins/libflashplayer.so
11) $cd /usr/lib/xulrunner-addons/plugins && sudo ln -s $HOME/.mozilla/plugins/libflashplayer.so
12) Start firefox. You should be able to have happy flash now.
I however still did not. Here is what I found. I installed tweetdeck using getlibs w/ 32bit lib files. For whatever reason this conflicts with the flash player.
How I resolved this:
13) Close tweetdeck & firefox
14) $rm -rf $HOME/.macromedia
15) Start firefox and visit youtube and play a video
16) Start tweetdeck
That's it. Firefox needs to start before tweetdeck. You can close firefox as many times as you want now. Once you close tweetdeck you need to follow step 15 & 16. Firefox first, then tweetdeck. I assume this is true for any other AIR application.

So why is this happening? I have no idea, and am not intelligent enough to know. My guess is that the libflashplayer.so which ships with AIR addresses some memory which the 64 bit version also tries to write too. By starting the 64 bit it 'grabs' this memory address, forcing the AIR startup to pick a new spot. I am completely pulling this out of my butt though.

I have been using this setup for over a week without any issues. I can play flash games, watch videos, whatever. No crashes with the exception of a few games on kongretate.

Be careful with these commands. They worked on my computer, but may completely destroy yours. Never blindly copy-paste any command you find on the Internet. Take a moment to look at them and understand what they are doing. sudo rm -f is a very dangerous command if you mistype it.

One last nitpick on Adobe. AIR needs to be ported to 64 bit. Don't tell me the link to the blog on Adobe. I submitted two email requests with no response.
Their bug system is horrid from a user experience. I can't even see my own bug because I don't have permissions. I would have loved to update the bug with what I found, but I can't. Dumb. Really dumb.

Conky twitter replies

Want twitter replies to show up in your conky display? Here is a quick way to accomplish that without installing any new modules.


$gedit $HOME/.conkyrc {or wherever your conky config file is located}
---------------------------
Under TEXT add
${rss http://your_twitter_user:your_twitter_pass@twitter.com/statuses/replies.rss 20 item_titles 4}


The format is your username, a colon, your password, an @ sign, and then the URL.
The "20 item_titles 4" portion indicates that the rss feed will update every 20 minutes, grabbing 4 item titles to display in conky.

I suggest keeping the update interval above 20 minutes. You only have 100 api requests per hour. This setup will take 5 of those. If you're using tweetdeck or other similar client and already up against your API limits it could affect the performance of these apps.

It goes without saying, but I will anyways, this puts your username and password out in clear text for anyone snooping your network (i.e. your laptop at starbucks). This is a huge security issue. There are other ways of accomplishing this (curl inside an sh script for one), but thought I would share this quick and dirty version.

Friday, May 29, 2009

Ubuntu, Virtual Box, Laptop, Drop Box; or how I tamed the multiple computers

It's been a few months now 'playing' with Ubuntu and making the transition to it as my primary desktop. The transition hasn't been without a few oddities and even a few failures.
I initially wanted dual monitors but found that the ATI card onboard wasn't able to do RGB displays very nicely. There seems to be a larger following for Intel/Nvidia based cards. I eventually went with a widescreen 19" monitor. I will upgrade the machine at some point to have a seperate Nvidia card so I can get dual screens back.

The main point of the post though is to outline how I have the multiple computers setup, and the
redundancy between them. I was issued a laptop for work, and originally used that exclusively. The ubuntu machine sat beside it, but with four monitors (two for the laptop, plus the laptop, and the ubuntu machine) and two keyboards/mouse the literal desktop was too cluttered. I also hated switching between them when I wanted to do personal work. I didn't feel morally right
poking around the internet, or helping Jeanette with freelance on my work machine. I like to play with new tech stuff (i.e. google apps) which just didn't seem 'right' to do on a work machine.

The final setup now is the Ubuntu desktop on the floor, connected to a single monitor. The laptop is beside the monitor sans separate keyboard and mouse. I sometimes travel for my job so the laptop must remain a 'primary' computer in the sense that the files and email needs to remain up to date. However, I wanted a setup which allowed me to shut down or take the laptop without
interrupting 'work' on the primary machine. Additionally the laptop was a bit slow when compared to the ubuntu machine.

I had a few options; remote desktop from the ubuntu to the laptop or setup a virtual box setup on Ubuntu. I decided to take a consolidated approach. I run a vbox of Windows XP Home on Ubuntu, as well as the remote to the laptop.

The laptop is used for my work based gmail account and to play pandora. I can pop on to rdesktop and do a video chat, or whatever then close it out. Because the laptop is used when I travel I had to setup a method to keep the work documents in sync. The ubuntu machine is setup with three physical drives. Two of them are RAID (mirrored) 250GB. The other is the primary disk (partitioned with virtual partitions). The raid has three top tier folders, mshare, steve, gshare. mshare is where all the computers in the house save the music. There are 4 computers in the house. steve is where I save all my work files along with other crticial back ups. gshare is a global share for all the computers where we transfer images, or whatever is
required between the network.

Using synctoy from Microsoft, the laptop echos the /steve/workfiles folder to the My Documents folder. The vbox windows has a shared drive connected to the /steve/workfiles folder. I could have used synctoy there as well, but it's proven to not be an issue to use the shared drive. The ubuntu machine obviously has access to it. The sync happens every night around 6PM. Because I rarely ever write a file from the laptop, it's mostly an one-way sync. However after traveling it can resync the changes easily enough.

This setup provided me a fair amount of fault tolerance but because the computers are within 2 feet of each other, I was at risk of data loss. If there were ever a fire/flood/whatever then all the available disks would be gone. Enter dropbox. I setup their client on the ubuntu machine to sync the raid files. The total folder size is less than 600MB. Dropbox offers a free 2GB so I have plenty of room to expand.

I looked at Dropbox as a way to do more than be a remote backup so I setup the folder for dropbox in my home directory. Using a symlink it captures changes in my raid file system to keep the remote files updated. Now if I get my netbook I want for Christmas I can be anywhere and access the files.

The raid is redundant so I can tolerate a disk failure. The laptop is synced so I can tolerate a system failure on the ubuntu. The files are stored in the cloud so I can have a catasrophe. My only risks now are dropbox being hacked and the files being made available for deletion.
If this happens it would require that a lot of really bad things happen at once. Catrosphe at the house just before hack. Anything is possible, but short of creating a USB backup and storing it in a bank, I think things are well protected.

Tech setup:
Ubuntu 64bit 9.04

/etc/samba/samba.conf
[steve]
comment = Internal Share
path = /path/to/shared/folder
read only = no
force user = somevaliduser
force group = somevalidgroup
guest ok = yes
force security mode = 0770
create mask = 0770

Dropbox
folder is set to: ~/Dropbox
$ln -s /path/to/shared/folder ~/Dropbox/folder

Ubuntu vbox
Windows XP Home
Guest Additions installed
Mapped drive to /steve on main Ubuntu

Laptop
Mapped drive to /steve on Ubuntu
synctoy set to echo between MyDocument/folder and mapped drive
Syncs at 6PM

Monday, December 15, 2008

Faking php resource types

There may be times when you need to mimic the resource type of PHP.
The resource type is most commonly used with mysql.
The code would be similar to

while($row=mysql_fetch_array($resource)){
echo $row[0];
}


It's possible to mimic his feature.


class fakewhile{
public $arrayCount;
public $arrayCounter;

function setArrValues(){
$this->arrValues = array(0 => array("apple","artichoke","apricot"),
1 => array("bears","dogs","cats"));
$this->arrayCounter = 0;
$this->arrayCount = count($this->arrValues);
}

function outputValues(){
/*
* Anything until the if statement is evaluted one more
* time then the array count
*/
$arrayInfo = $this->arrValues;
$arrCounter = $this->arrayCounter;
if($arrCounter > $this->arrayCount){
return false;
}
$endCounter = $arrCounter+1;
$this->arrayCounter = $endCounter;
return $arrayInfo[$arrCounter];
}

}

$fw = new fakewhile();
$fw->setArrValues();
while($row = $fw->outputValues()){
print_r($row);
}

?>



The other potential issue is that the function is called one more time the count of the array. In the example above, the $fw->outputvalues() function is called three times. Being careful about code placement inside the function would be required.

This code is just a prototype of how to do it. It's my no means an efficient use. A simple foreach would accomplish the same thing using the data structure above. However, there was a comment on the php site about someone looking to mimic this resource feature, so I thought I would post some proof of concept to encourage further modifications.

Sunday, December 14, 2008

Change twitter names and Twhirl issues

Just started messing around with twitter again.
Downloaded twhirl, and started tweeting again, adding users, etc..

In twitter, I decided to change my twitter url from wetmonkey to switkos.
Twhirl then shit itself, with no way to update the application. It wants me to login to my wetmonkey account. None of the application works.

Here is how to fix it.
The application stores the config in an xml file located at
C:\Documents and Settings\YOUR USER NAME\Application Data\de.makesoft.twhirl.SOME RANDOM NUMBER\Local Store

in that folder there is an accounts.xml file.
Make sure Thwirl is closed.
Open that file in a text editor, scroll down a bit until you see account service 'twitter' followed by your username


switkos

Change the username to your new username.
Restart Thwirl and enter your password.

Easy as pie

Saturday, December 13, 2008

Using lambda functions

I was working on a solution to import some information that was in delimited format. The code needed to be flexible so that it could accommodate different formats of the import. I try to make as much of my code 'separate' or abstract, using defines, or runtime variables to make the program react without going into the functions or classes and writing a bunch of code when something changes.

I came across the php function create_function. It was the perfect solution to the problem.

Here is the logic of the application

1) parse the file into lines
2) loop through the lines
3) modify the lines for data format
4) return the lines in an specific order

The end result is an array with the database column names, and the associated data for that column.
The database columns were rank, name, last_name, address,...

Consider a line formatted
|RANK|NAME|LAST NAME|ADDRESS
This is easy enough to make work, the columns line up with the database.

However, there were also files with the format
|RANK|NAME LAST NAME|ADDRESS
This requires that I find the first and last name inside one column.

This leaves two different filters for the "modify the lines for data format". One solution would be to do a switch statement inside that function. Another is nested if's. However I wanted that "modify the lines" to not have anything specific to to the lines in the code. I needed to abstract the filtering to another place.

Enter the create_function function, and arrays.
I created an array with the column names, and their data stypes
These variables are stored in a 'loader' script separate from the main data processing.

$this->dbcols = array(0 => 'rank','string'),
1 => 'name','string'),
2 => 'lname','string')
3 => 'address','string')
);
$this->funcref = array(0 => array(0 => "2",
1 => create_function('$d','$r = explode(" ",$d); return $r[1];'),
2 => "1"
)
);


Let's look at the different portion of the script
$this->dbcols is an array of the database column names.
$this->funcref is multideminsional array which outlines how to manipulate the data
$this->funcref[0][0] is the $this->dbcols array index which will be modified by the create_function defined in $this->funcref[0][1].
$this->funcref[0][2] is the array index of the source data which will be substituted for the variable '$d' defined in the create_function

Now to look at the processing script and how it all ties together.

$arrData = explode("|",$sourceline);
foreach($this->funcref as $arrfunc){
$arrRetData[$arrfunc[0]] = $arrfunc[1]($arrData[$arrfnc[2]]);
}


How it all breaks down.
The $arrData is another array of the source data broken apart by the delimeter (which should also be part of the loader )
In this example, we are working on the line with only three columns.
Once we have that array, we need to extract the first name from the data.
The foreach loop looks through the $this->funcref array and grabs each function group.
Within that function group is takes the first index ("2") and sets the return array, $arrRetData[2] index with the results of the function ($arrfunc[1] - explode..) passing the variable of the last index ("1") into the original array.
Rewritten to replace the variables;
$arrRetData[2] = index 1 of the function "explode(" ", $arrData[1])"

Now there are obvious defects in this code sample. The $arrRetData will only have one of the original datasets. This is only to demonstrate how it works. The loader script is much more enhanced in the version I am using.
Using this foreach(function array) style processes the functions in order, so it's important to make sure that values required/manipulated are in the correct order.

Here is an example of how this could be effective.

// data input now |name|rank|last_name
$arrData = explode("|",$sourceline);
foreach($this->funcref as $arrfunc){
$arrRetData[$arrfunc[0]] = $arrfunc[1]($arrData[$arrfnc[2]]);
}

$this->dbcols = array(0 => 'rank','string'),
1 => 'name','string'),
2 => 'lname','string')
3 => 'address','string')
);
// funcref[0][0] = dbcols array index
// funcref[0][1] = function definition
// funcref[0][2] = source array index to become $d
$this->funcref = array(0 => array(0 => "0",
1 => create_function('$d','return $d;'),
2 => "1"
),
1 => array(0 => "1",
1 => create_function('$d','return $d;'),
2 => "0"
),
2 => array(0 => "2",
1 => create_function('$d','return $d;'),
2 => "2"
);


This will reorder the fields to map correctly with the database. The original code isn't changed, only a new loader created.