Web Design

98rock log disabled

Tuesday, February 19th, 2013

Due to recent updates on the 98rock website I can no longer access the new log page without a proxy (U.S. copyright protection at its best) When I have time to view the new log page I will update my script. I will also release a download of the old database for anyone that is interested.

My experiene with HitTail

Tuesday, December 18th, 2012

Recently I just finished a free trial with HitTail.

For those that don’t know what HitTail is:

HitTail tells you, in real-time, the most promising search terms you should target based on your existing traffic. We do this using a sophisticated algorithm tuned by analyzing over 1.2 billion keywords.

I used it on silabsoft.org just to see if it would be useful to purchase for other sites. Overall the tool seems pretty useful I did get at least one keyword that I was able to focus and snag the top position on Google for that keyword. It’s also priced reasonably for smaller websites However if you have a larger website you might find the price to be a bit steep. Installation was an absolute breeze especially for WordPress users as they have taken the time to write a simple plugin that makes the installation almost idiot proof. The sites back end is easy to understand and read and the suggestions are placed in a nice table for you to view. They even sent me an email everything they had a new keyword to suggest to me. They also include a service to write articles for each of your suggested keywords. I didn’t try this as the price is much higher than I can afford for this shitty little website but I would consider it for some of the other websites I run. Overall with Google Analytics and Webmaster Tools I think HitTail is a essential asset for a small website looking to increase organic search traffic.

For those of you interested in checking them out you can do so by going to http://HitTail.com

Code Golfing

Thursday, August 9th, 2012

Recently I was directed the the code golf on stackexchange: http://codegolf.stackexchange.com/  it’s pretty interesting to read other people submissions. I decided to take a crack at the 12 days of christmas submission http://codegolf.stackexchange.com/questions/4191/12-days-of-christmas-lyrics

 

My answer in JavaScript

 

var l=["first","second","third","fourth","fifth","sixth","seventh","eight","ninth","tenth","eleventh","twelfth","Two turtle doves","Three french hens","Four calling birds","Five golden rings","Six geese-a-laying","Seven swans-a-swimming","Eight maids-a-milking","Nine ladies dancing","Ten lords-a-leaping","Eleven pipers piping","Twelve drummers drumming"];var b = "<br/>";for(var i=0;i<12;i++){var p="On the "+l[i]+"day of Christmas"+b+"My true love gave to me"+b;for(var x=i;x>0;x--)p+=l[11+x]+b;if(i>0)p+="and ";p+="a partridge in a pear tree"+b+b;document.write(p);}

98Rock Playlist scraping

Sunday, June 24th, 2012

Recently I had a conversation with a friend about how I was sick of hearing the same songs all the time on a local radio station (yeah I internet radio) and I decided I wanted to see just how many songs are actually played during a day. After a quick write and a few hours fixing a few small bugs I finally have a fully functioning version to use.

<?php
 
define('PLAYLIST_URL', 'http://www.98rock.com/iplaylist/playlist.html?last10=1');
define('PLAYLIST_ROW', 'tr[class^=playlist_row2]');
define('PLAYLIST_ARTIST', 'td[class^=playlist_artist]');
define('DEFAULT_SEPERATOR', '-');
 
 
define('DATABASE_HOST', '127.0.0.1');
define('DATABASE_USERNAME', '');
define('DATABASE_PASSWORD', '');
define('DATABASE_NAME', '');
 
define('TABLE_PREFIX', '');
define('TABLE_ARTIST', 'artist');
define('TABLE_SONG', 'song');
define('TABLE_PLAYLOG', 'playlog');
 
include_once('simple_html_dom.php');
 
function scraping_98rock() {
    $process = curl_init(PLAYLIST_URL);
    curl_setopt($process, CURLOPT_HEADER, 0);
    curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($process, CURLOPT_CONNECTTIMEOUT, 1);
    $resp = curl_exec($process);
    curl_close($process);
    $html = str_get_html($resp);
    if ($html == null) {
        die("Could not access the playlist!");
    }
    foreach ($html->find(PLAYLIST_ROW) as $song) {
 
        $data = explode(DEFAULT_SEPERATOR, trim($song->find(PLAYLIST_ARTIST, 0)->plaintext));
        $item['artist'] = $data[0];
        $item['song'] = $data[1];
        $ret[] = $item;
    }
 
// clean up memory
    $html->clear();
    unset($html);
 
    return $ret;
}
 
$ret = scraping_98rock();
$link = mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD);
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
mysql_select_db(DATABASE_NAME);
 
 
$songs = array();
for($i =9; $i >-1; $i--) {
    $rank++;
    $result = mysql_query("SELECT * FROM " . TABLE_PREFIX . TABLE_ARTIST . " WHERE name = '" . mysql_real_escape_string($ret[$i]['artist']) . "'");
    if (!$result) {
        die('Could not query:' . mysql_error());
    }
    $artist = mysql_fetch_row($result);
    if (!$artist) {
        mysql_query("INSERT into " . TABLE_PREFIX . TABLE_ARTIST . " (name) VALUES ('" . mysql_real_escape_string($ret[$i]['artist']) . "')");
        echo "artist inserted: " . $ret[$i]['artist'] . "\n";
    }
    if (!$artist) {
        $result = mysql_query("SELECT * FROM " . TABLE_PREFIX . TABLE_ARTIST . " WHERE name = '" . mysql_real_escape_string($ret[$i]['artist']) . "'");
        if (!$result) {
            die('Could not query:' . mysql_error());
        }
        $artist = mysql_fetch_row($result);
    }
    $result = mysql_query("SELECT * FROM ".TABLE_PREFIX.TABLE_SONG." WHERE name = '" . mysql_real_escape_string($ret[$i]['song']) . "'");
    if (!$result) {
        die('Could not query:' . mysql_error());
    }
    $song = mysql_fetch_row($result);
    if (!$song) {
        mysql_query("INSERT into ".TABLE_PREFIX.TABLE_SONG." (name,artist_id) VALUES ('" . mysql_real_escape_string($ret[$i]['song']) . "','" . mysql_real_escape_string($artist[0]) . "')");
        echo "song inserted: " . $ret[$i]['song'] . "\n";
    }
    if (!$song) {
        $result = mysql_query("SELECT * FROM ".TABLE_PREFIX.TABLE_SONG." WHERE name = '" . mysql_real_escape_string($ret[$i]['song']) . "'");
        if (!$result) {
            die('Could not query:' . mysql_error());
        }
        $song = mysql_fetch_row($result);
    }
 
    if (!$song || !$artist) {
        echo "DANGER $artist - $song \n";
        continue;
    }
    array_push($songs, array("song" => $song[0], "artist" => $artist[0]));
}
$result = mysql_query("SELECT * FROM ".TABLE_PREFIX.TABLE_PLAYLOG." ORDER BY id DESC LIMIT 10");
if (!$result) {
    die('Could not query:' . mysql_error());
}
while ($last = mysql_fetch_array($result)) {
    for ($i = 0; $i < 10; $i++) {
        if ($songs[$i]['song'] == $last['song_id'] && $songs[$i]['artist'] == $last['artist_id']) {
            unset($songs[$i]);
            continue;
        }
    }
}
for ($i = 0; $i < 10; $i++) {
    if (isset($songs[$i])) {
        $result = mysql_query("INSERT into ".TABLE_PREFIX.TABLE_PLAYLOG." (song_id,artist_id) VALUES ('" . $songs[$i]['song'] . "','" . $songs[$i]['artist'] . "')");
        if (!$result) {
            die('Could not query:' . mysql_error());
        }
        echo "Inserted: ".$s['song']." into playlog";
    }
}
mysql_close($link);
?>

I will be leaving this running from today at 15 minute intervals I will update results later in the week.

Light Chaser

Saturday, May 12th, 2012

If you havn’t visted http://gamedev.moparscape.org then you probably don’t know that lately I have been working on an html5 javascript clone of a game I used to have as a child called lights out. The game was rather simple all you had to do was turn off all the lights to progress to the next level. Currently the game is a work in progress and has a few minor bugs (don’t try to turn on all the lights) but it is playable. Please let me know if you find any bugs or just want to make some comments on improvements. Also you can view the source on my github account.

WordPress Runescape Highscore Widget Initial Release

Tuesday, April 24th, 2012

After working on the better-github-widget plugin I was inspired to write my own simple widget for WordPress. I choose to make one that would allow me to grab and display My characters Runescape highscore details using JSON.  Everything seems to be working at the moment it has the ability to either show or hide the activity data (mini games) If you have any suggestions to make it better please feel free to leave my a comment.

 

wpp1 Wordpress Runescape Highscore Widget Initial Releasewpp2 Wordpress Runescape Highscore Widget Initial Release

 

The Github: https://github.com/silabsoft/rs-highscore-widget

The WordPress plugin repository: http://wordpress.org/extend/plugins/runescape-highscores-widget/

Simple Runescape highscores json callback output

Tuesday, April 24th, 2012

I wrote this for a Runescape highscore plugin I had been working on. It allows me to grab the Runescape lite highscores and output it in a JSON callback format. Special thanks for http://recursive-design.com/blog/2008/03/11/format-json-with-php/ for writing a pretty JSON indent method as the current version of PHP on this web server does not support JSON_PRETTY_PRINT.

<?php
header('Content-type: application/javascript');
$player = isset($_GET['player']) ? $_GET['player'] :"zezima";
$callback = isset($_GET['callback']) ? $_GET['callback'] :"runescape.parseHighscores";
const TOTAL_ACTIVITIES = 38;
const TOTAL_SKILLS = 25;
 
    $name = array("Overall","Attack","Defence","Strength","Constitution","Ranged","Prayer","Magic","Cooking","Woodcutting","Fletching","Fishing","Firemaking","Crafting","Smithing","Mining","Herblore","Agility","Thieving","Slayer","Farming","Runecrafting","Hunter","Construction","Summoning","Dungeoneering","Duel Tournament","Bounty Hunters","Bounty Hunter Rogues","Fist of Guthix","Mobilising Armies","B.A Attackers","B.A Defenders","B.A Collectors","B.A Healers","Castle Wars Games","Conquest","Dominion Tower");
    $url ='http://hiscore.runescape.com/index_lite.ws?player='.$_GET['player'];
    $process = curl_init($url);
    curl_setopt($process, CURLOPT_HEADER, 0);
    curl_setopt($process, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($process,CURLOPT_CONNECTTIMEOUT,1);
    $resp = curl_exec($process);
    $resp = explode("\n", $resp);
    curl_close($process);
    for($i = 0; $i < 38; $i++){
    $s = explode( "," , $resp[$i]);
        $skillData[$i] = $i < TOTAL_SKILLS ? array("id" =>(int)$i,"isSkill" => (boolean)true,"name" => $name[$i],"rank" => (int)$s[0],"level" => (int)$s[1],"experience" => (int)$s[2]) : array("id" =>(int)$i,"isSkill" => (boolean)false,"name" => $name[$i],"rank" => (int)$s[0],"score" => (int)$s[1]);
    }
 
   $data = json_encode($skillData);// because my host sucks and does not use PHP 5.4 so I can't use the FANCY JSON OUTPUT so I have to use the indent method for debugging.
   echo $callback .'({'."\n  ".'"data":'. indent($data).'})';
 
 
 
 
 //Method from: http://recursive-design.com/blog/2008/03/11/format-json-with-php/
 function indent($json) {
 
    $result      = '';
    $pos         = 0;
    $strLen      = strlen($json);
    $indentStr   = '  ';
    $newLine     = "\n";
    $prevChar    = '';
    $outOfQuotes = true;
 
    for ($i=0; $i<=$strLen; $i++) {
 
        // Grab the next character in the string.
        $char = substr($json, $i, 1);
 
        // Are we inside a quoted string?
        if ($char == '"' && $prevChar != '\\') {
            $outOfQuotes = !$outOfQuotes;
 
        // If this character is the end of an element,
        // output a new line and indent the next line.
        } else if(($char == '}' || $char == ']') && $outOfQuotes) {
            $result .= $newLine;
            $pos --;
            for ($j=0; $j<$pos; $j++) {
                $result .= $indentStr;
            }
        }
 
        // Add the character to the result string.
        $result .= $char;
 
        // If the last character was the beginning of an element,
        // output a new line and indent the next line.
        if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
            $result .= $newLine;
            if ($char == '{' || $char == '[') {
                $pos ++;
            }
 
            for ($j = 0; $j < $pos; $j++) {
                $result .= $indentStr;
            }
        }
 
        $prevChar = $char;
    }
 
    return $result;
}
 
?>

Example output: http://silabsoft.org/rs-web/highscore.php?player=zezima

GitHub:https://github.com/silabsoft/rs-web

A small fix for the better-github-widget plugin

Wednesday, April 18th, 2012

This WordPress plugin is an awesome little widget that displays your github projects. It does have two small markup errors that I had to fix to make it pass W3C validation.

 

The two very small problems include:

  1. required attribute “alt” not specified – This is found on the octocat image it has no ALT value which is required to be valid. It’s also good to have in case the image really can’t be found! a simple fix was to just add alt=”github Octocat”
  2. end tag for element “a” which is not open – This one seems to be more like a typo than a bug but its still present in the current release of the plugin.  What I found was that  link was accidentally closed prior to displaying the username text

 

I have reported these two small problems to the authors github and hope he will push a fixed version. However I have also included source with fixes already implemented right here for anyone that needs.

 

<?php
/*
Plugin Name: Better GitHub Widget
Plugin URI: http://github.com/fracek/better-github-widget
Description: Display your GitHub projects
Author: Francesco Ceccon
Version: 0.5
Author URI: http://francesco-cek.com
*/
 
/**
* Adds Foo_Widget widget.
*/
class Better_GitHub_Widget extends WP_Widget {
 
    /**
* PHP 4 constructor
*/
    function Better_GitHub_Widget() {
        Better_GitHub_Widget::__construct();
    }
 
    /**
* PHP 5 constructor
*/
    function __construct() {
        $widget_ops = array('classname' => 'better-gh-widget', 'description' => __('Display your GitHub projects'));
        parent::__construct(
'better-gh-widget', // Base ID
'Better GitHub Widget', // Name
            $widget_ops
);
    }
 
    /**
* Front-end display of widget.
*
* @see WP_Widget::widget()
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
    public function widget( $args, $instance ) {
        extract($args);
        $username = $instance['username'];
        $count = $instance['count'];
        $title = 'GitHub';
 
        echo $before_widget;
        echo $before_title . $title . $after_title;
 
        // Octocat image
        echo '<img width="128px" src="' . plugins_url('octocat.png', __FILE__) . '"';
       echo ' style="display: block; margin: 0px auto;" alt="github Octocat"/>';
 
        // username @ GitHub
        echo '<p style="text-align: center; ">';
        echo '';
        echo $username . ' @ GitHub</p>';
 
        // the list of repos
        echo '<ul id="gh-repos">';
        echo '<li id="gh-loading">Status updating...</li>';
        echo '</ul>';
        echo '<script src="' . plugins_url('github.js', __FILE__) . '" type="text/javascript"> </script>';
?>
<script type="text/javascript">
github.showRepos({
user: '<?php echo $username; ?>',
count: <?php echo $count; ?>,
skip_forks: true,
});
</script>
<?php
        echo $after_widget;
    }
 
    /**
* Sanitize widget form values as they are saved.
*
* @see WP_Widget::update()
*
* @param array $new_instance Values just sent to be saved.
* @param array $old_instance Previously saved values from database.
*
* @return array Updated safe values to be saved.
*/
    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['username'] = strip_tags($new_instance['username']);
        $instance['count'] = strip_tags($new_instance['count']);
 
        return $instance;
    }
 
    /**
* Back-end widget form.
*
* @see WP_Widget::form()
*
* @param array $instance Previously saved values from database.
*/
    public function form( $instance ) {
        // Assigns values
        $instance = wp_parse_args( (array) $instance, array( 'username' => '', 'count' => ''));
        $username = strip_tags($instance['username']);
        $count = strip_tags($instance['count']);
 
        echo '<p><label for="'. $this->get_field_id('username') . '">' . __('Username') . ':';
        echo '<input class="widefat" id="' . $this->get_field_id('username') . '" ';
        echo 'name="' . $this->get_field_name('username') . '" type="text" ';
        echo 'value="' . attribute_escape($username) . '" />';
        echo '</label></p>';
 
        echo '<p><label for="' . $this->get_field_id('count') . '">' . __('Number of projects to show') . ':';
        echo '<input class="widefat" id="' . $this->get_field_id('count') . '" ';
        echo 'name="' . $this->get_field_name('count') . '" type="number" ';
        echo 'value="' . attribute_escape($count) . '" />';
        echo '<br><small>' . __('Set to 0 to display all your projects</small>');
        echo '</label></p>';
    }
 
} // class Foo_Widget
add_action( 'widgets_init', create_function( '', 'register_widget( "better_github_widget" );' ) );
?>

WordPress and XHTML 1.0 Transitional

Wednesday, April 18th, 2012

Many people ignore W3C markup validation. I am not one of them, so when I checked if my site was valid only to find that WordPress on a fresh install had an error I was rather annoyed.

The error found: there is no attribute “role”:

You have used the attribute named above in your document, but the document type you are using does not support that attribute for this element. This error is often caused by incorrect use of the “Strict” document type with a document that uses frames (e.g. you must use the “Transitional” document type to get the “target” attribute), or by using vendor proprietary extensions such as “marginheight” (this is usually fixed by using CSS to achieve the desired effect instead).

This error may also result if the element itself is not supported in the document type you are using, as an undefined element will have no supported attributes; in this case, see the element-undefined error message for further information.

 

After doing some searching on Google it seems that this problem has been around in WordPress for awhile now. It also seems they are not interested in fixing it. However some people have stated that the easiest way to fix it is to implement your own searchform.php without the role attribute. This is easier said then done as most themes do not modify this file and have no reason to include it in a distribution.  So after doing a little poking around I was able to find what was included in the template file and change it to suite my sites needs

 

<form method="get" id="searchform" action="<?php echo esc_url( home_url( '/' ) ); ?>">
	<div>
		<label class="screen-reader-text" for="s">Search For:</label>
		<input type="text" name="s" id="s" value="Search..." />
		<input type="submit" class="submit" name="submit" id="searchsubmit" value="Search" />
	</div>
</form>

As a result I am now able to proudly display the W3C Valid Icon!

Webfish Angler

Tuesday, April 17th, 2012

Some of you may have noticed I changed my wordpress theme to Webfish Angler.  This particular theme sparked my interest as its simple and clean yet stylish enough for my taste.  Installing any theme with wordpress is rather painless. This particular theme had a header and footer image with easy options to turn them off!  If I had to gripe about anything with this theme it would be the lack of a description tag. Normally I wouldn’t notice things like this but recently I have been playing with an addon for firefox called SEO Doctor which displays a green yellow or red flag based on your sites SEO score.  SEO Doctor gave my site a yellow flag as the theme did not include a meta description tag.  To be completely fair this seems to be more of an issue with the standard wordpress rather than the theme developers  as wordpress by default does not give a section for descriptions.  Regardless adding a quick line to the header of the template fixed all the problems and gave the site a green flag.

 

 

<meta name='description' content='Simply put this site is just a pile of Silab'/>