Translate

Archive for the 'Code' Category

HTML 5 is out and about

Saturday, July 11th, 2009

I believe that the <canvas>, <audio>and <video> tags will make the web a pretty exciting place. A lot of Flash components will be rewritten or converted into Javascript+HTML5 Object components making available more reusable elements for a graphical and interactive web, all being open sourced (javascript) and with no extra plugins needed.

Some places where we can already see (or will) the use of HTML 5 tags and javascript on those elements are:

  • GMail Mobile for iPhone and Android
  • Yahoo! Pipes
  • Bespin, a code editor created by Mozilla lab, they basically rewrote the text editing component using the canvas tag so that its a high performance text editing component, with a nice look, selection highlighting, new scrollbars, command support, it can be extended with your own commands (reminds me of emacs)
  • Google Waves
  • Some blogs that are already using the <article>, <nav>, <footer> and other new HTML 5 tags
  • YouTube is getting ready for the video tag
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

How to make a Quick & Dirty HexViewer – Updated

Monday, April 20th, 2009

After I received comments from ispak on Flickr I made a few fixes.

ispak pointed out that it was a bad idea reading one byte at the time, also I had a gay ass try/catch that didn’t catch any exception :p

So now I read 16 byte chunks, and I also take care of the file ending. The previous version used to print the file ending with a bunch of null bytes. Now it stops reading at the end, and formats the output accordingly.

Here’s the new source:

//HexViewer.java
import java.io.*;

public final class HexViewer {
    public final static void printFile(String filePath) {
        try {
            File f = new File(filePath);
            BufferedInputStream bis =
                new BufferedInputStream(new FileInputStream(f));

            byte[] chunk = null;
            int readStatus = 0;
            while (true) {
                chunk = new byte[16];
                readStatus = bis.read(chunk, 0, 16);
                char[] line = new char[16];

                if (readStatus == -1)
                    break;

                for (byte i=0; i < readStatus; i++) {
                    int readByte = (chunk[i] < 0) ? (-1 * (int) chunk[i]) : chunk[i];
                    String paddingZero = (readByte < 16) ? "0" : "";
                    System.out.print(paddingZero + Integer.toHexString(readByte).toUpperCase() + " ");
                    line[i] = (readByte >= 33 && readByte <= 126) ? (char) readByte : '.';
                }

                //We add some padding to print the text line right below the one above.
                String padding = new String();
                if (readStatus < 16) {
                    for (byte i=0; i < 16-readStatus; i++) {
                        padding += "   ";
                    }
                }

                System.out.println(padding + new String(line));
            }
        } catch (Exception e1) { e1.printStackTrace(); }
    }

    public final static void main(String[] args) {
        if (args.length == 0)
            return;

        printFile(args[0]);
    }
}

HexViewer - r2

And see how it now handles file endings when the file size is not a multiple of 16 :p

Picture 2

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

How to make your own Quick & Dirty Hex File Viewer in Java

Saturday, April 18th, 2009

Update: You might want to read this new version of the code instead. Thanks ispak

I was playing with a hex editor recently and then I thought it would be pretty easy to make a program to output what you see on a text editor. Here’s a quick & dirty Hex Visor I wrote in like 5 minutes with Java. It shows 15 bytes per line, and on the right side it prints all the visible characters of the ascii table, the non-visible ones are replaced with “.”

Enjoy:

//HexViewer.java
import java.io.*;

public final class HexViewer {
    public final static void printFile(String filePath) {
        File f;
        try {
            f = new File(filePath);
        } catch (Exception e) {
            return;
        }

        try {

            FileInputStream fis = new FileInputStream(f);
            while (fis.available() > 0) {
                char[] line = new char[16];
                for (int i=0; i < 16; i++) {
                    int readByte = fis.read();
                    String paddingZero = (readByte < 16) ? "0" : "";
                    System.out.print(paddingZero + Integer.toHexString(readByte) + " ");
                    line[i] = (readByte >= 33 && readByte <= 126) ? (char) readByte : '.';
                }
                System.out.println(new String(line));
            }
        } catch (Exception e1) { e1.printStackTrace(); }
    }

    public final static void main(String[] args) {
        if (args.length == 0)
            return;

        printFile(args[0]);
    }
}

Usage:

java HexViewer &lt;path to file> | less
java HexViewer Desktop/Puppet.wmv | less

30 26 b2 75 8e 66 cf 11 a6 d9 00 aa 00 62 ce 6c 0&.u.f.......b.l
74 14 00 00 00 00 00 00 07 00 00 00 01 02 a1 dc t...............
ab 8c 47 a9 cf 11 8e e4 00 c0 0c 20 53 65 68 00 ..G.........Seh.
00 00 00 00 00 00 f4 10 68 f9 49 76 2e 43 b5 9f ........h.Iv.C..
09 0a 2d 19 45 7c 32 3a 24 00 00 00 00 00 70 ee ..-.E|2:$.....p.
14 06 fb da c7 01 28 01 00 00 00 00 00 00 00 8c ......(.........
bb 53 00 00 00 00 10 88 dd 52 00 00 00 00 b8 0b .S.......R......
00 00 00 00 00 00 02 00 00 00 40 1f 00 00 40 1f ..........@...@.
00 00 90 50 02 00 b5 03 bf 5f 2e a9 cf 11 8e e3 ...P....._......
00 c0 0c 20 53 65 61 10 00 00 00 00 00 00 11 d2 ....Sea.........
d3 ab ba a9 cf 11 8e e6 00 c0 0c 20 53 65 06 00 ............Se..
33 10 00 00 a9 46 43 7c e0 ef fc 4b b2 29 39 3e 3....FC|...K.)9>
de 41 5c 85 27 00 00 00 00 00 00 00 01 00 0c 65 .A\.'..........e
00 6e 00 2d 00 61 00 75 00 00 00 5d 8b f1 26 84 .n.-.a.u...]..&.
45 ec 47 9f 5f 0e 65 1f 04 52 c9 1a 00 00 00 00 E.G._.e..R......
00 00 00 02 01 ea cb f8 c5 af 5b 77 48 84 67 aa ..........[wH.g.
8c 44 fa 4c ca 62 01 00 00 00 00 00 00 06 00 00 .D.L.b..........
00 01 00 0c 00 02 00 02 00 00 00 49 00 73 00 56 ...........I.s.V
00 42 00 52 00 00 00 00 00 00 00 01 00 34 00 00 .B.R.........4..
00 06 00 00 00 44 00 65 00 76 00 69 00 63 00 65 .....D.e.v.i.c.e
00 43 00 6f 00 6e 00 66 00 6f 00 72 00 6d 00 61 .C.o.n.f.o.r.m.a
00 6e 00 63 00 65 00 54 00 65 00 6d 00 70 00 6c .n.c.e.T.e.m.p.l
00 61 00 74 00 65 00 00 00 4c 00 31 00 00 00 00 .a.t.e...L.1....
00 02 00 0c 00 02 00 02 00 00 00 49 00 73 00 56 ...........I.s.V
00 42 00 52 00 00 00 01 00 00 00 02 00 34 00 00 .B.R.........4..
00 0c 00 00 00 44 00 65 00 76 00 69 00 63 00 65 .....D.e.v.i.c.e
00 43 00 6f 00 6e 00 66 00 6f 00 72 00 6d 00 61 .C.o.n.f.o.r.m.a
00 6e 00 63 00 65 00 54 00 65 00 6d 00 70 00 6c .n.c.e.T.e.m.p.l
00 61 00 74 00 65 00 00 00 4d 00 50 00 40 00 4d .a.t.e...M.P.@.M
00 4c 00 00 00 00 00 01 00 2e 00 03 00 04 00 00 .L..............
00 57 00 4d 00 2f 00 57 00 4d 00 41 00 44 00 52 .W.M./.W.M.A.D.R
00 43 00 50 00 65 00 61 00 6b 00 52 00 65 00 66 .C.P.e.a.k.R.e.f
00 65 00 72 00 65 00 6e 00 63 00 65 00 00 00 a7 .e.r.e.n.c.e....
3f 00 00 00 00 01 00 34 00 03 00 04 00 00 00 57 ?......4.......W
00 4d 00 2f 00 57 00 4d 00 41 00 44 00 52 00 43 .M./.W.M.A.D.R.C
00 41 00 76 00 65 00 72 00 61 00 67 00 65 00 52 .A.v.e.r.a.g.e.R
00 65 00 66 00 65 00 72 00 65 00 6e 00 63 00 65 .e.f.e.r.e.n.c.e
00 00 00 b0 06 00 00 74 d4 06 18 df ca 09 45 a4 .......t......E.
ba 9a ab cb 96 aa e8 a4 0d 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

This how it looks on a full blown hex editor like HexEdit:
Same file on HexEdit

The Code of HexViewer.java on emacs:
HexViewer.java on emacs

Screenshot of the output:
HexViewer in action

Homework
Hack the code so that it ouputs the first column shown on the HexEdit screenshot. That column represents the byte position of each row. It’s basically a counter incremented 16 units at the time, and shown in Hex.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

OnLive could change the video game industry

Wednesday, March 25th, 2009

I feel it’s my geek given duty to make a post about this presentation. I was lucky to finally have the time to watch their hour long presentation and Q&A session at the Game Developer Conference 2009 (which ends a couple of days from today). They could have not picked a better place to finally demo their technology.

In short, they’ve introduced a huge new concept to the video game industry, I’d call it “Cloud Gaming” to not only host the games, but also host the processing juice. You won’t need a console anymore, they keep the hardware to execute and stream the game to your screen. They support TV (with a miniconsole), PC and Mac.

So bear with me, they say they have solved the issue that you’re thinking about now, Lag. The people behind this worked on apple to create Quicktime, and they identified differences between what it takes to compress linear (regular) video, vs Interactive Video. They say their compression algorithm doesn’t take seconds of lag (like when you stream over a webcam), but miliseconds. They have custom chips to process the graphics, and I bet they might even built their own network protocol right on top of IP.

So what are some of the implications of this:

  • We’ll all be able to finally play Crysis and even more demanding games on low end PCs
  • No more buying more hardware, no more upgrading your PC to be able to run games, no more buying consoles
  • All your games live on the platform, so you can play from any computer, and you’ll keep the state of your game until the last time you hit the Pause button
  • Your friends can see you play, live. I bet we’ll be able to see live tournaments, we’ll start seeing a new breed of famous people get more attention, the Elite gamers. Imagine seeing the best Call of Duty player in the world playing live
  • New Genres of video games will emerge on this platform, maybe even new genres of entertainment, think new Live Broadcast shows where participants use an avatar to either act or compete (game show)
  • Game Developers not need to think of the rendering limitations that they might have nowadays, and will be able to design games that could only be imagined in the past. Render quality only thought for movies will now exist for video games, think of virtual reality now
  • There’s about 100 million PCs/Macs/Laptops out there that are not ready today to play high end games, now they’ll have the possibility of playing virtually any game by installing a 1Mb plugin from OnLive.com
  • Takes Piracy out of the Business Equation
  • A bigger gaming audience makes an even better case for companies placing advertisement in video games, maybe there will be a lot more high end free games with bigger audiences, think the next Grand Theft Auto coming out for free with superb real life like graphics rendering, all ad sponsored and free to the consumer. The amount of people that you could have playing a great game for free would make other developers think twice about charging for their games and having their virtual worlds ad sponsored.
  • No more installs
  • Now multiplayer will have almost no latency since all players live inside their datacenter, you only get the latency of your ISP if there’s any
  • Nintendo, Sony and Microsoft must be shitting their pants
  • Services that sell used games are going to be selling vintage and their business will be reduced

However I think there will always be room for the old consoles. This is the biggest entertainment industry in the world, we have grown up with consoles for almost 30 years and there’s a lot of changes to push into people’s minds:

  • How do you convince me, that finally made up my mind after years and dropped $500 on a PS3 to play with my friends in latin america online to switch to this, if my friends will probably have no way to even have access to the system in years to come?
  • How do you convince PC gamers that rather pay for the hardware and pirate the games? (There’s plenty of those, probably the majority of the PC gaming population outside the US never plays for a PC game, and doesn’t get into consoles because they pirate the games) into renting or buying games on the cloud?
  • How do you convince all the people that they should switch when their gaming experience depends entirely on being connected to the internet. So If the ISP is having issues I can’t play? isn’t my console awesome?

It seems that many of these complains are similar to all the complains brought upon business models that didn’t exist online and that are now thriving. This presentation left me with my mouth wide open, and I highly recommend you watch it. You’ll be blown away by the power of the UI, and how as you Browse for games, you can even see how other people are playing live, it’s like streaming video is nothing for OnLive. Really sick technology.

In the case that they succeed, I just can’t wait for them to have competition by the existing big brands, it’s going to get so interesting once cloud gaming becomes the defacto platform, maybe we as consumers will end up playing games for free, all sponsored with in game ads.

Just by listening to the guy if you’re a techie, your mind will start to fly to barely start to imagine the awesomeness of the technology that should be behind this. I can imagine anything from custom virtualization technology, to custom GPUs, custom network cards, custom network protocols on top of IP, deals with major internet backbone networks, ISPs, deals with game publishers, sick level API development, incomprehensible comprehension technology for my retard brain… when I see shit like this, I always think… how the hell is there people that still believe in god? Mankind is the closest thing there is to something like that! I’m thankful for people in this world that can think so big.

The service is supposed to launch next Winter 2009, but you can sign up to be a beta tester

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Delete All Direct Messages of your Twitter Account at once (or at least try!)

Friday, February 13th, 2009

Since Twitter doesn’t provide with a “Delete All Direct Messages” functionality, Here’s a Python script that attempts to delete all the direct messages stored on your Twitter account.

Limitations
The only problem with it is that given the limitations of the Twitter REST API, I was forced to send a request per message to be deleted, and it seems that Twitter will only allow 100 requests per hour (per client).

So in theory you will be able to delete 100 an hour, although I have seen it delete over 400 messages Twitter gets all grumpy on me.

Usage
Just save the script as twitter_delete_direct_messages.py, open a terminal and run it:

python twitter_delete_direct_messages.py

After that just follow the instructions on screen and enjoy as messages get wiped out.

If you find this useful, you can thank me by following me on Twitter.

Get The Script

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Using a linear array as a bidimensional matrix

Tuesday, January 27th, 2009

Often times I find the need to use a list or linear array as if it was a table.

Everytime I need to do so, I always end up coding functions to convert a (x,y) coordinate to the real index n in the array.

Let me illustrate, with an example. You have a string that defines the elements of a game board, and you want to work using (x,y) coordinates.

s="xxxxx@xx@xxx@@xx"

If you were to look at it as a matrix (width=4), it’d be something like this

s="xxxx
   x@xx
   @xxx
   @@xx"

However, I can’t do
s[x,y], since it’s a linear array, it’s a string.

You need to convert from (x,y) to a number that represents an index in the array.

This is very simple:

width=4
def getNforXY(x,y):
  return x + width*y

What if you want to do it backwards. What if you need to know what’s the X and Y for a given index N in the string?

def getXYforN(n):
  y = int(n/width)
  x = n - width/y
  return (x,y)

Cheers

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

jQuery tag wrapping

Friday, December 19th, 2008

Many times you’ll be working on something in HTML that could be long and repetitive, and then for some reason you need to edit the entire thing to wrap each of the tags on some other tags, a common example would be to link many elements.

Take this example, there’s a bunch of photos, they’re all contained in divs that have a css class called “photos”, inside we just throw
a bunch of <img> tags, and all of a sudden our boss tells us he wans to have every image on that page linked to “http://domain.com/photos”. jQuery to the rescue, no need to wrap each <img> with <a href=”"> by hand, you can do it all in one line

So if the code looks like this:

       <div class="photos">
            <img src="http://domain.com/0670027481_m.jpg"/>
            <img src="http://domain.com/211161aa99_m.jpg"/>
            <img src="http://domain.com/173bb0cd6_m.jpg"/>
        </div>
        <div class="photos">
            <img src="http://domain.com/841fd90b5b_m.jpg"/>
            <img src="http://domain.com/52dda2cee5_m.jpg"/>
            <img src="http://domain.com/b569399599_m.jpg"/>
        </div>
        <div class="photos">
            <img src="http://domain.com/8806e863a4_m.jpg"/>
            <img src="http://domain.com/5e43aa95fe_m.jpg"/>
            <img src="http://domain.com/68a74a088c_m.jpg"/>
        </div>

        <div class="tshirt-photos">
            <img src="http://farm4.static.flickr.com/3149/3113619519_72ce82c545_m.jpg"/>
            <img src="http://farm4.static.flickr.com/3236/3105792155_99f2388869_m.jpg"/>
            <img src="http://farm3.static.flickr.com/2114/2372582266_765842fae9_m.jpg"/>
        </div>

With jQuery you can match all the <img> elements, and wrap them all with “<a href=”http://domain.com/photos”></a>” in a single line of code:

$(document).ready(function() { $(".photos img").wrap('<a href="http://domain.com/photos">') })

So to explain how it works, when the document is ready (when it’s finished loading) the function inside is called back, it will use the jQuery selector $(“.photos img”) to match all the <img> tags contained withing elements of css class “photos”, then it applies the wrap() function, which will wrap the matched elements with the given html tags.

About jQuery

jQuery is a lightweight JavaScript library that emphasizes interaction between JavaScript and HTML. It was released January 2006 at BarCamp NYC by John Resig.

Dual licensed under the MIT License and the GNU General Public License, jQuery is free and open source software.

jQuery contains the following features:

  • DOM element selections
  • DOM traversal and modification, (including support for CSS 1-3 and basic XPath)
  • Events
  • CSS manipulation
  • Effects and animations
  • Ajax
  • Extensibility
  • Utilities – such as browser version and the each function.
  • JavaScript Plugins

jQuery Documentation

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Python Script to Update WordPress in One Step

Wednesday, November 26th, 2008

During the past week, I think I had to update all my wordpress instances twice, and it’s become really annoying doing this manually. I’ve written a python script which I’ll share with you.

How I keep my wordpress updated by hand
I tend to keep my wp-content folder outside of my wordpress installation for 2 reasons:

1. I don’t like to loose my themes, plugins and customizations
2. I like to keep all my customization changes under subversion

So, if I had my wordpress installation say at:
/home/user/public_html/blog

I’d keep my wp-content folder for that here:

/home/user/public_html/wp-content-for-blog

So when I upgrade my blog, I always remove the original wp-content folder that comes along wordpress, and I symlink my hard worked on wp-content folder that lives outside to the freshly unzipped wordpress folder.

user@machine:~/public_html/blog$ ls -l
...
lrwxrwxr-x 1 user www    54 2008-11-26 09:29 wp-content -> /home/user/public_html/wp-content-for-blog
...

So what I endup doing all the time, is downloading the latest.zip to ~/public_html/, it will unzip under ~/public_html/wordpress, and then I’ll copy the current ~/public_html/blog/wp-config.php to ~/public_html/wordpress, then I’ll remove the default ~/public_html/wordpress/wp-content and symlink the outer wp-content with all my customizations, themes and plugins to it. Once done, I’ll make a backup of the old wordpress folder, and then I’ll rename wordpress folder to the name of the blog folder, and it’s all done.

It’s simple, but when you have to do it for 5 blogs, every week, it’s not fun anymore.

The Update Script

So here’s a script to do it in one step. If you’re not using my symlinked technique, this will do it for you, you only need to specify the full path to the folder where you want to keep your current wp-content folder outside the new installation before you apply the update, and the name of the folder where your current blog lives. The script below will have its configuration variables towards the beginning set so that they are in line with the example I’ve been talking about.

#!/usr/bin/python
#########################################################################################
#
# upgrade_wordpress.py - Script to automatically upgrade your wordpress installation.
#
# Requirements:
#   - Python 2.4 or older
#   - WordPress should already be installed
#   - CURL (sudo apt-get install curl)
#
# Author: Angel (Gubatron) Leon
# LICENSE: See the GPL2 license.
# 2008
#########################################################################################
import os

#########################################################################################
#Config (relative to the folder where this script will be run from)
#########################################################################################

#The current folder where the blog lives
BLOG_FOLDER='blog'

#
# The first time you run the script, it will try to make a copy of your
# current wp-content folder outside. Copy here the location of where
# the wp-content folder with your themes and plugins should exist.
#
# After it unzips, it will remove the default wp-content folder from
# the new installation, and it will symlink the external wp-content
# That way you don't ever have to worry about loosing your customizations
# and plugins.
#
WP_CONTENT_OUTSIDE_COPY_FOLDER="/home/user/public_html/wp-content-for-blog"

#This is where a backup of your current blog will be
BLOG_FOLDER_BACKUP_FOLDER=BLOG_FOLDER+'.old'

#Where to download the wordpress latest.zip from
WORDPRESS_LATEST_ZIP_URL='http://wordpress.org/latest.zip'

#### DO NOT MODIFY AFTER THESE LINES ####

def downloadWordpress(url=WORDPRESS_LATEST_ZIP_URL):
    if os.path.exists('latest.zip'):
        print "Removing old latest.zip"
        os.remove('latest.zip')

    #Try to download with CURL
    print "Attempting to download latest.zip from wordpress.org"
    os.system('curl %s -o latest.zip' % url)

    if not os.path.exists('latest.zip'):
        os.system('wget ' + url)

    return os.path.exists('latest.zip')

def dirExists(dirName):
    return os.path.exists(dirName) and os.path.isdir(dirName)

def backupBlog(currentBlogFolder=BLOG_FOLDER,
               wpContentOriginalFolder=WP_CONTENT_OUTSIDE_COPY_FOLDER,
               backupFolder=BLOG_FOLDER_BACKUP_FOLDER):

    #Remove any previous backups
    if os.path.exists(backupFolder) and os.path.isdir(backupFolder):
        print "Removing previous backup folder"
        os.system('rm -fr ' + backupFolder)

    #Copy the current blog folder into a backup folder just in case.
    #We won't do any database backups for now.
    print "Creating new backup folder"
    os.system('cp -r %s %s' % (currentBlogFolder,backupFolder))

    #Check for the copy of wp-content outside the blog, if it doesn't exist
    #we'll make it for the first time.
    if not dirExists(wpContentOriginalFolder):
        print "Creating outside copy of wp-content"
        os.system('cp -r %s %s' % (os.path.join(currentBlogFolder,'wp-content'),
                                   wpContentOriginalFolder))

    #Copy the latest wp-config.php outside to the current folder
    print "Copying your latest wp-config.php outside"
    os.system('cp %s .' % (os.path.join(currentBlogFolder,'wp-config.php')))

    backupFolderExists = dirExists(backupFolder)
    wpContentFolderExists = dirExists(wpContentOriginalFolder)
    configFileExists = os.path.exists('wp-config.php')

    return backupFolderExists and wpContentOriginalFolder and configFileExists

def upgradeBlog(currentBlogFolder=BLOG_FOLDER,
                backupFolder=BLOG_FOLDER_BACKUP_FOLDER,
                url=WORDPRESS_LATEST_ZIP_URL,
                wpContentOriginalFolder=WP_CONTENT_OUTSIDE_COPY_FOLDER):

    if not downloadWordpress(url):
        print "Could not download latest.zip, aborting."
        return False

    if not backupBlog(currentBlogFolder,wpContentOriginalFolder,backupFolder):
        print "Could not backup blog or wp-config.ph, aborting."
        return False

    if currentBlogFolder == 'wordpress':
        print "The current blog folder cannot be 'wordpress, aborting."
        return False

    #1. If a wordpress/ folder exists, wipe it.
    if dirExists('wordpress'):
        print "Removing old wordpress folder"
        os.system('rm -fr wordpress')

    if dirExists('%s.delete' % currentBlogFolder):
        print "Removing old %s.delete folder" % currentBlogFolder
        os.system('rm -fr %s.delete folder' % currentBlogFolder)

    #2. Unzip new copy
    os.system('unzip latest.zip')

    if not dirExists('wordpress'):
        print "Could not unzip the wordpress installation, aborting."
        return False

    #1. Copy wp-config.php into the new installation
    os.system('cp wp-config.php wordpress/')

    #2. Remove the default wp-content folder
    os.system('rm -fr wordpress/wp-content')

    #3. Symlink the original wp-content that lives outside
    os.system('ln -s %s wordpress/wp-content' % (wpContentOriginalFolder))

    #4. Verify symlink was created
    if not (os.path.exists('wordpress/wp-content') and os.path.islink('wordpress/wp-content')):
        print "Could not create symlink to wp-content, aborting."
        return False

    #5. Move original folder to folder.delete, and make this wordpress folder the current folder.
    os.system('mv %s %s.delete' % (currentBlogFolder,currentBlogFolder))

    if not dirExists(currentBlogFolder + ".delete"):
        print "Could not rename current folder for later deletion, aborting."
        return False

    #6. Rename the new installation as the current blog
    os.system('mv %s %s' % ('wordpress',currentBlogFolder))

    if dirExists('wordpress'):
        print "ALERT: The wordpress folder still exists."
        return False

    if not dirExists(currentBlogFolder):
        print "ALERT: The blog doesn't exist, recover from the backup folder %s please" % (backupFolder)
        return False

    #7 Cleanup
    os.system('rm -fr %s.delete' % (currentBlogFolder))

    return True

if __name__ == '__main__':
    upgradeBlog()

Requirements

  • shell access to the machine where you have your wordpress installed
  • a python interpreter installed
  • curl (sudo apt-get install curl) to download the zip. If you don’t have it it’ll attempt to use wget
  • Installation

  • Right outside your wordpress installation folder, create a new file called upgrade_wordpress.py
  • Copy and paste the script inside that file
  • Edit the configuration variables to point to the name of your wordpress installation folder, and give it a full path to where you want to keep your wp-content folder (including the name of the folder, so if you want to name it the same way, you could do for example /home/user/wp-content and it’ll be saved right under your home)
  • Usage:

    python upgrade_wordpress.py

    The script is very fault proof, it will always try to abort in case something is not going the way it’s expected. At the end of the day it’ll also leave a backup copy of your current blog in case something goes bad, you can always recover.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)

    Cola: Real-Time Remote Pair coding

    Tuesday, November 25th, 2008

    This is not new, but I hadn’t seen it, so maybe you didn’t either, I’ll let the video speak for itself, I’m speechless.

    Thanks to Daniel Chang for sharing this with me.


    Cola: Real-Time Shared Editing from Mustafa K. Isik on Vimeo.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)

    Java/Reflection notes: Invoking a static main() method from a dinamically loaded class.

    Saturday, November 22nd, 2008

    Maybe for some wild reason, your Java application will need to execute a pre launcher that won’t know about the Main class it’s supposed to invoke until it’s being executed. For example, you have distributed your Java application but you used pack200 to compress your jars, and your new application launcher will unpack everything, but up to this point, it can’t do an import of the main class, since the jar that contained it, wasn’t available to the virtual machine when java was invoked.

    So, your launcher class, finishes unpacking your jars, adds the jars to the current classloader, and now you need to invoke your Main.main(String[] args).

    This is how I managed to do it, using Java’s reflection mechanisms

        public final void startMain(String[] args) {
            //this will create a new class loader out of all jars available, see below on next
            //code section of this blog post
            addJars2Classpath();
    
            try {
                //Instantiate the main class, and execute it's static main method
                Class clazz = jarsClassloader.loadClass("com.mycomp.somepackage.Main");
                Class[] argTypes = { args.getClass(), };
                Object[] passedArgs = { args };
                Method main = clazz.getMethod("main",argTypes);
                main.invoke(null, passedArgs);
            } catch (Exception e) {
                //oh oh
                e.printStackTrace();
            }
    
        } //startMain
    

    In case you’re interested in how to add new Jars to the classpath during runtime, this is how I managed to do it:

        /**
         * Adds all the newly available jars to the classpath
         */
        public final void addJars2Classpath() throws Exception {
            //Create a new class loader with all the jars.
            Object[] jars = getFiles(getApplicationResourcesJavaFolder(), ".jar");
            URL[] jarUrls = new URL[jars.length];
    
            for (int i=0; i < jars.length; i++) {
                URL jarURL = null;
    
                try {
                    jarURL = new URL("jar:file:"+(String) jars[i]+"!/");
                } catch (Exception e) {
                    //LOG.error("Bad URL for jar ("+jarFile+"):\n"+e.toString()+" ("+jarURL+")\n");
                    return;
                }
    
                jarUrls[i] = jarURL;
            }
    
            //and this guy here, is the classloader used to load
            jarsClassloader = URLClassLoader.newInstance(jarUrls);
          } //addJar2Classpath
    
        /**
         * Get a Object<String> array that contains the names of the files
         * that end with 'type' on the given folderPath
         *
         * e.g
         *
         * String[] jarFiles = getFiles(".",".jar");
         *
         */
        public final Object[] getFiles(String folderPath, String type) {
            File f = new File(folderPath);
    
            String[] files = f.list();
    
            Vector results = new Vector();
    
            for (int i=0; i < files.length; i++) {
                if (files[i].endsWith(type)) {
                    results.add((String) files[i]);
                }
            }
    
            if (results.size() == 0)
                return null;
    
            return results.toArray();
        } //getFiles
    
    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)


  • Categories

  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • October 2009
  • September 2009
  • July 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • April 2007
  • March 2007
  • February 2007
  • January 2007
  • December 2006
  • November 2006
  • October 2006
  • September 2006
  • August 2006
  • July 2006
  • June 2006
  • May 2006
  • April 2006
  • March 2006
  • February 2006
  • January 2006
  • December 2005
  • November 2005
  • October 2005
  • September 2005
  • August 2005
  • July 2005
  • June 2005
  • May 2005
  • April 2005
  • March 2005
  • February 2005
  • January 2005
  • December 2004
  • November 2004
  • October 2004