Archive

Archive for the ‘Programming’ Category

Bing sitemaps are pending forever

December 9th, 2011

Recently I realized that Bing also has started to offer Sitemap functionality to let webmasters easily give a heads up to the search engine. Apparently Yahoo also has started to redirect webmasters to Bing Webmaster Tools after the transition to use Bing services. I got excited and submitted the whole list of my sitemaps via Bing Webmaster Tools, but.. After a week the statuses of all files were still “Pending”. Thinking that it should not take that long and googling around a while, this forum page says it all. There is a problem with Bing sitemap functionality and there is still no ETA for a fix. Come on Microsoft guys, it should not be that hard to overcome such a problem. Put the files in a queue, download’em, parse’em and use that valuable data. Is it that hard to implement a fix in the next release? Does anybody know what is the average release cycle duration at Microsoft?

Programming , , ,

Clash of the Classes: Using ActiveMQ with Play Framework

November 29th, 2011

Recently I have my hands on Play Framework and I am quite happy with all the features such as change the code and refresh the page attitude, stateless model for REST applications and easy method for unit and functional testing. In one of the projects I needed to access one of ActiveMQ instances I have, to this end I have included the required Java libraries (activemq-all-5.5.0.jar and javax.jms.jar), deployed the code to my test environment, clicked refresh.. and saw that pretty error page of Play Framework.

Oops: NoSuchMethodError
An unexpected error occured caused by exception NoSuchMethodError:
org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;

Checking the Play console output below, apparently the problem was that Play Framework is using slf4j library for logging and ActiveMQ 5.5.0 jar file includes a newer version of it as well.

SLF4J: The requested version 1.6 by your slf4j binding is not compatible with [1.5.5, 1.5.6, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11]
SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details.

The solution here is to step back and use one of ActiveMQ 5.4.x libraries that do not include the SLF4J library in it. I have used activemq-all-5.4.1.jar in this case successfully. It would be great if ActiveMQ guys could strip SLF4J from the package and let the developers add the library externally.

Java , , ,

My first iPhone App has arrived at the AppStore

August 12th, 2011

This is my personal project which is meant to let people have a community where they can ask questions and get useful answers.

It is the result of an idea I had a few months ago after struggling to find a way to ask all my friends about something that I was planning to buy. But in the end I have given up because there was no medium that I can easily ask and get answers fast that has most basic privacy options and notification abilities. Although that cost me many sleepless nights, I believe that this will be useful to people having the same problems.

Here is the very first version, which may include some obscure bugs. In a few weeks I’ll be pushing a more robust release. It can be downloaded from AppStore, just search for “Viewbeat”. Enjoy!



Viewbeat – Simple way to ask questions and get useful answers

Viewbeat - Simple way to ask questions and get useful answers


iPhone , , , ,

An extensions library for Sencha Touch

June 24th, 2011

Some of you may already know Sencha Touch but for those who are in mobile application development and haven’t heard of it yet, it is a mobile application development framework designed especially for devices with touch screens. It provides all the basic touch screen events and a whole bunch of components to use to create interactive applications. You can even convert your mobile apps into native apps via the magical PhoneGap and submit them to AppStore or Android Store. (Blackberry is also supported but… who cares?)

Even though lots of components are provided out-of-box, you still need to tweak a little bit to create the exact components you need. As documentation lacks some really useful information and even with all the tutorials provided it is not an easy task to put every bit together and create an application with Sencha Touch. After weeks of suffering, I managed to develop an application completely based on this framework and here I share some of the outcome.

This library is meant to be an example to extend provided Sencha Touch components to create more complex behaviors. Components found in this library are generally based on or inspired by components in Sencha Touch library and are meant to be a guide to people learning how to put things to work with Sencha Touch. I hope it may save someone’s life :)

DidiTouch Javascript extensions library for Sencha Touch

And to the guys working on this framework at Sencha,

Keep up the good work, and please, more and better documentation!..

Javascript , ,

Querying Google Contacts API via PHP

March 23rd, 2011

For the last few days I have been going through Google API documentations for one of the projects I have been working on to get Google Contact details of a Google user. To the developer’s luck, the documentation about Google API is very well prepared but due to the fact that authentication with oAuth is a painful process, things get scary while accessing Google API. (Even requesting access is a nightmare :)

I have handled the authentication by Zend Framework oAuth component which made things pretty easy. But it took me almost 2 days to figure out how to fetch contact details of the user via Google Contacts API with the access token that I receive. oAuth playground is a nice utility to compare the values you create and should be created. It was the time that I realized that access token was url encoded twice while generating base string. I do not know why, but you can check the playground and the slash character is encoded two times. First encoding translates / to %2F, and second one translates %2F to %252F.

Anyway, here is a sample code in PHP to make things easier for anyone interested. Good luck!

$timestamp = time();
 
$contactsURL = "https://www.google.com/m8/feeds/contacts/default/full/";
$oauth_nonce = md5(uniqid(rand(), true));
$sign_method = 'HMAC-SHA1';
$oauth_version = '1.0';
 
$oauth_consumer_key = 'aaaaaaaaaaa'; // the key you receive from Google
$oauth_consumer_secret = 'bbbbbbbbbbbb';  // the secret you receive from Google
$oauth_token = 'cccccccccccccccc'; // the token you receive at the end of authentication
$oauth_token_secret = 'ddddddddddddd';  // the token secret you receive at the end of authentication
 
// be careful that access token is urlencoded here, 
// and going to be urlencoded once more while creating base_string
 
$baseParams = array("oauth_consumer_key" => $oauth_consumer_key,
                    "oauth_nonce" => $oauth_nonce,
                    "oauth_signature_method" => $sign_method,
                    "oauth_timestamp" => $timestamp,
                    "oauth_token" => urlencode($oauth_token),
                    "oauth_version" => $oauth_version
                    );
 
$baseArr = array();
foreach ($baseParams as $key => $value)
    $baseArr[] = $key . "=" . $value;
 
$base_string = "GET&".urlencode($contactsURL)."&".urlencode(implode("&", $baseArr));
 
$key = urlencode($oauth_consumer_secret) . '&' . urlencode($oauth_token_secret);
$sig = base64_encode(hash_hmac('sha1', $base_string, $key, true));
 
$queryParams = array("oauth_version" => $oauth_version,
                        "oauth_nonce" => $oauth_nonce,
                        "oauth_timestamp" => $timestamp,
                        "oauth_consumer_key" => $oauth_consumer_key,
                        "oauth_token" => $oauth_token,
                        "oauth_signature_method" => $sign_method,
                        "oauth_signature" =>$sig
                    );
 
// http_build_query url encodes every parameter and creates well-formed query string
 
$queryURL = $contactsURL."?".http_build_query($queryParams);
 
echo file_get_contents($queryURL);

PHP, Programming , , , ,

Exploding by multiple delimiter values in PHP

January 26th, 2011

There are 2 ways to explode a string into array by multiple delimiter values. First method includes an intermediate step to convert all delimiters to a uniform delimiter value, then exploding by it.

$arrDelimiters = array("&", "or", "and");
$inputText = "a or b & c and d";
 
$uniformText = str_replace($arrDelimiters, "-|-", $inputText);
$arrValues = explode("-|-", $uniformText);
 
print_r($arrValues);

prints out

Array
(
    [0] => a 
    [1] =>  b 
    [2] =>  c 
    [3] =>  d
)

Second method is faster than the first as it uses preg_split to split the text into pieces.

print_r(preg_split("/and|or|&/", "a or b & c and d"));

prints out

Array
(
    [0] => a 
    [1] =>  b 
    [2] =>  c 
    [3] =>  d
)

PHP, Programming , ,

A Trigger Plugin for Hudson Monitoring Folder Changes

November 29th, 2010

For a quick look at Hudson plugin development, you can have a look at this page.

This is a post about developing a trigger for Hudson which will monitor changes in folders (and subfolders if set to do so) and trigger build process.

All trigger plugins are subclasses of hudson.triggers.trigger.

The methods that can be overriden are:

public void start(Item project, boolean newInstance): Called when the trigger is loaded into the memory and started.
public void run(): Executes the triggered task. This method is called when the Trigger is instantiated with a cron string and the crontab matches the current time.
public void stop(): This method is called when the plugin is unloaded from the memory. This happens when the Hudson is going to restart/shut down or when the project configuration has changed.

The descriptor class is used to describe (hence the name) the plugin to Hudson environment. It should extend TriggerDescriptor for plugins extending trigger class and annotated with @Extension. isApplicable method should return true to allow user to configure this trigger in project configurations. getDisplayName method should return the name that will be shown on plugins page of Hudson.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class FolderChangedTrigger<Job> extends Trigger {
 
    …
 
    @Override
    public DescriptorImpl getDescriptor() {
        return (DescriptorImpl)super.getDescriptor();
    }
 
    @Extension
    public static class DescriptorImpl extends TriggerDescriptor
    {
        @Override
        public boolean isApplicable(Item item) {
            return true;
        }
 
        @Override
        public String getDisplayName() {
            return "Folder Changed Trigger";
        }
 
    }
 
    …
 
    @Override
    public void start(Item project, boolean newInstance) {
        super.start(project, newInstance);
        _project = project;
        _fileMap = new HashMap<String, Long>();
    }
 
    …
 
}

The constructor should take non-transient fields and annotated with @DataBoundConstructor. This annotation makes it possible for Stapler class to find the constructor which should the values from configuration page of project in Hudson be used with. Constructor of upper class is called with a cron timer string to make Hudson run the trigger on every minute.

1
2
3
4
5
6
7
    @DataBoundConstructor
    public FolderChangedTrigger(String folderToMonitor, boolean recursiveCheck, String excludedFilesExp) throws ANTLRException {
        super("* * * * *");
        this._folderToMonitor = folderToMonitor;
        this._recursiveCheck = recursiveCheck;
        this._excludedFilesExp = excludedFilesExp;
    }

In overriden run method it just checks the folders (and subfolders if set to do so), and depending on a change in the structure it gets the Hudson build queue instance and schedules a build for the project it runs for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    @Override
    public void run()
    {
        if (_folderToMonitor != null && _folderToMonitor.length() > 0)
        {
            File folder = new File(_folderToMonitor);
 
            if (folder.isDirectory())
            {
                RecursiveFileMonitor rfm = new RecursiveFileMonitor();
                if (rfm.check(_folderToMonitor))
                {
                    Queue qu = Queue.getInstance();
                    qu.schedule((AbstractProject) _project);
                }
            }
        }
    }

The jelly files are configuration views of your plugin.

global.jelly contains the global configuration view which is shown on the Hudson management page and includes parameters that is going to be used for all Hudson projects. In our plugin we do not have such a file, as our configuration parameters should be set on a project-wide basis.

Config.jelly contains configuration parameters for one Hudson project. The values of these parameters are populated from the plugin object through properties. FolderToMonitor and excludedFilesExp fields are populated by calls to getFolderToMonitor and getExcludedfilesExp respectively while RecursiveCheck is set by a call to isRecursivecheck.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
  <f:entry title="Folder" field="folderToMonitor">
    <f:textbox name="folderToMonitor" value="${folderToMonitor}"
        checkUrl="'/fieldCheck?errorText=${h.jsStringEscape(h.encode('%Folder is mandatory.'))}&value='+encode(this.value)"
        help="/plugin/folder-changed-trigger/help-folderToMonitor.html"/>
  </f:entry>
 
  <f:entry title="Recursive check" field="recursiveCheck">
    <f:checkbox name="recursiveCheck" checked="${recursiveCheck}" help="/plugin/folder-changed-trigger/help-recursiveCheck.html"/>
  </f:entry>
 
  <f:entry title="Excluded Files" field="excludedFilesExp">
    <f:textbox name="excludedFilesExp" value="${excludedFilesExp}" help="/plugin/folder-changed-trigger/help-excludedFilesExp.html"/>
  </f:entry>
</j:jelly>

For each entry in config.jelly file a help file can be set which will display a help icon on the right of the parameter. When this button is clicked the given help file is shown inside a panel. The path to help files are /plugin/$PLUGIN_NAME/help-propertyName.html where $PLUGIN_NAME is the name of your plugin. Help files are pure static html files, like shown below.

1
<div> The folder to be monitored for changes. </div>

The version of the plugin can be set inside the pom file created by maven.

1
2
3
4
  <groupId>com.burcsade</groupId>
  <artifactId>folder-changed-trigger</artifactId>
  <version>1.0</version>
  <packaging>hpi</packaging>

It is also possible to make it clear the required release of Hudson that the plugin should run on in pom file.

1
2
3
4
5
6
  <parent>
    <groupId>org.jvnet.hudson.plugins</groupId>
    <artifactId>plugin</artifactId>
    <version>1.343</version><!-- which version of Hudson is this plugin built against? -->
    <relativePath>../pom.xml</relativePath>
  </parent>

index.jelly file is used for give a brief description of the plugin in plugins list page.

1
2
3
<div>
  This plugin monitors a specified folder and triggers the build process depending on found added/modified/removed files.
</div>

Full source code and compiled plugin file can be downloaded by clicking on the link below.

Hudson Folder Changed Trigger

You can start using the plugin right away by installing the hpi file found inside target folder. Source files are located in src folder.

If you have any comments, feel free to submit.

Java, Programming , , , , ,

Hudson Plugin Development

November 29th, 2010

Hudson monitors execution of repeated tasks such as cron jobs or build and test actions in a development environment. It can execute tasks depending on changes on file system or various source code management applications, log their output historically and act according to the output of these tasks. It provides an easy-to-use interface and an API to extend its abilities by writing plugins when the wide range of plugins offered at Husdon-CI website is not enough.

More information can be found at Official Hudson Wiki.

I am currently using Hudson to manage repeated tasks (previously run by cron) and monitor their outputs on my projects. It is not a rocket science to develop a plugin when it is needed.

To develop plugins for Hudson, Maven has to be installed and ready to use. It is because Hudson development team has decided to use Maven to give developers a concrete starting point with ability to test their code instantly. Once you have Maven 2.0.9 or newer up and running (it can be downloaded at Maven download page), add the following to the Maven settings file. (found in ~/.m2/settings.xml on Linux and %USERPROFILE%\.m2\settings.xml on Windows)

1
2
3
4
5
<settings>
  <pluginGroups>
    <pluginGroup>org.jvnet.hudson.tools</pluginGroup>
  </pluginGroups>
</settings>

This will let the user to use shorter mvn commands for creating, building and testing plugins.
After that, change directory to your favorite development workspace, and enter the command below to create a template for your new plugin.

1
$ mvn -cpu hpi:create

This will ask for groupid and artifactid (to be clear, they are simply package name and project name) then create a template for you to start with.

Netbeans v6.7 and up can utilize its own Maven support to open Hudson plugin project you created. Maven projects are listed with a Maven project logo in open project dialog and can be opened directly in Netbeans.

To test the plugin, you can use the command below to start an instance of Hudson that includes your newly created plugin running on.

1
$ mvn hpi:run

If you need to launch Hudson on another port then 8080, just configure it so

1
$ mvn hpi:run -Djetty.port=8081

To create a distribution package for your plugin, use the command below.

1
$ mvn package

This should create the hpi file in target folder which can be added to your Hudson installation through Hudson management page. To install the plugin go to the ‘Manage Plugins’ page at the Hudson management. Just click on the Advanced tab and upload the compiled hpi file. Installed plugins can be listed and toggled by clicking the ‘Installed’ tab.

More information about plugin development for Hudson can be found at Extend Hudson

Java, Programming , , , ,

Fixed width buttons in JQuery buttonset()

November 3rd, 2010

JQuery has a really nice feature to convert checkbox and radio button groups into good looking button sets. But when you have a set of buttons positioned vertically, they may look ugly because of their varying width values. To make them fixed size just add styling to the labels of checkboxes as seen below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    <div class="input select" id="tutor_availability">
        <label for="availability">Available days:</label>
        <input type="checkbox" name="data[Ad][availability][]" value="1" id="AdAvailability1"/><label for="AdAvailability1" style="width:100px">Monday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="2" id="AdAvailability2" /><label for="AdAvailability2" style="width:100px">Tuesday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="4" id="AdAvailability4" /><label for="AdAvailability4" style="width:100px">Wednesday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="8" id="AdAvailability8" /><label for="AdAvailability8" style="width:100px">Thursday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="16" id="AdAvailability16" /><label for="AdAvailability16" style="width:100px">Friday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="32" id="AdAvailability32" /><label for="AdAvailability32" style="width:100px">Saturday</label>
        <input type="checkbox" name="data[Ad][availability][]" value="64" id="AdAvailability64" /><label for="AdAvailability64" style="width:100px">Sunday</label>
    </div>
 
    <script type="text/javascript">
            $(function() {
                $("#tutor_availability").buttonset();
            });
    </script>

JQuery, Programming , , ,

Flix Cloud and S3 makes video sharing really easy

March 22nd, 2010

Being quite busy with implementing a video sharing feature on Sheet Music Trade, I have found that On2 had done a good job with Flix Cloud. Its REST based API makes video processing a real simple job and with Amazon S3 storage and Flow Player it seems that anyone with some level of programming can create a video sharing community nowadays. The days of struggling with FFMpeg (and php-ffmpeg for image extraction) are not very far away (still using this setup for one of the largest video sharing communities in Turkey), I feel that I won’t think about using Flix Cloud twice from now on.

Flix Cloud PHP is a great PHP sample library for encoding videos on Flix Cloud and Amazon S3 PHP Class is also a great source for managing files programmatically on S3.

Internet, PHP, Programming , , , , ,