10 posts categorized "bling"

01/20/2010

Bling v0.7 Released - Google App Engine Edition

Bling now runs in the cloud, hosted on google app engine.  Although I've only been playing with Groovy for the past couple of months, I thought it would be interesting to try and write a web application.  It seemed like a good evolution path for bling as most folks looking for a service to send out xmlrpc pings will most likely not download Groovy, the XMLRPC module, and the HTTPBuilder module as a first choice.   Although still written with Groovy and HTTPBuilder, Bling now uses Gaelyk as a web application framework.  

No new functionality was added except Bling now sends pings out to Ping-o-matic and FeedBurner again.  It can be reached by pointing your browser to tools.techstacks.com/bling/.  Please let me know what you think.  I am still working on developing a feedback page so this blog is the only mechanism in place right now for questions, comments, concerns, or any other types of feedback for this application.

It is still a little rough around the edges but it works.  It is a port of the bling command line script to a templates and groovlet-based web application.  After submitting, the results page responds back with "Thanks" or "Failed" responses just like the script, which I will probably look at cleaning up.  The stylesheet used on the site is OK but not good enough for me to redesign this blog around.  It takes roughly 10 seconds to get the response once submitted, which I need to see if there is a way to cut that down.  Despite these items, it is the first web application I've ever written and I'm still pretty happy about it.  The previous article I wrote, "Making XMLRPC Requests with Google App Engine Java", details a technique I used to work around an inability to use the XMLRPC module built into Groovy and instead all requests are built on HTTPBuilder's HttpUrlClient.  

The bling command line client will remain on the downloads site.  There will now be two links for bling—one for the console-based version and one for the web application version.

12/22/2009

Bling v0.6 Released

A few weeks ago, Feedburner pings began throwing an exception:  "Request Throttled. Try again later" so this new release of Bling removes Feedburner from the list of XMLRPC services.

It also seemed that shortly after introducing BlogBuzzMachine into Bling's list, they decided to throw an exception that they should only be pinged using Feedburner's Pingshot service. So, if you are a user of Feedburner, like I am, and you enable the Pingshot service, you will be sending notifications out to BlogBuzzMachine. Therefore, BlogBuzzMachine has been removed.

So, the number of services currently receiving pings via Bling is at 19 along with the 5 search engines getting sitemap pings.

There is one new feature included in this release. A "debug" command-line option has been added. If you pass a -d or --debug (for POSIX compliance!) argument to bling, failed pings will include the reason for the failure from the xmlrpc service.

The main bling page has been updated and you can grab a copy from the downloads page. Please let me know of any problems in the comments. Thanks for taking a look and using it!

#!/usr/bin/env groovy

import groovy.net.xmlrpc.*
import groovy.util.slurpersupport.GPathResult
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.URLENC

def cli = new CliBuilder(usage: 'bling [-d,--debug]')
  cli.d(longOpt:'debug', required:false, type: GString, 'Run with verbose error messages')

def opt =  cli.parse(args)
  if (!opt) return

// You'll want to make this next section your own
def blogTitle = "YOUR_BLOG_TITLE_HERE"
def blogURL = "YOUR_BLOG_URL_HERE"
// def feedURL = "YOUR_BLOG_FEED_URL_HERE"
// New in Bling version 0.5:
// URL for Sitemap Pings
def sitemapURL = "YOUR_BLOG_SITEMAP_URL_HERE"

// Set up a map (hash) of popular rpc endpoints
// It is too bad for my syntax highlighter, but some of 
// the blogs containing periods in their names necessitated
// placing them in quotes.  

def trackbacks = [
  Google:'http://blogsearch.google.com/ping/RPC2',
  Weblogs:'http://rpc.weblogs.com/RPC2',
  Moreover:'http://api.moreover.com/RPC2',
  Syndic8:'http://ping.syndic8.com/xmlrpc.php' ,
  BlogRolling:'http://rpc.blogrolling.com/pinger/',
  NewsGator:'http://services.newsgator.com/ngws/xmlrpcping.aspx',
  Bloglines:'http://www.bloglines.com/ping',
  'Blo.gs':'http://ping.blo.gs/',
  BlogCatalog:'http://rpc.blogcatalog.com/',
  PubSub:'http://xping.pubsub.com/ping/',
  'MyBlog.jp':'http://ping.myblog.jp/',
  Goo:'http://blog.goo.ne.jp/XMLRPC',
  BlogPeople:'http://www.blogpeople.net/servlet/weblogUpdates',
  Twingly:'http://rpc.twingly.com/',
  Spinn3r:'http://rpc.spinn3r.com/open/RPC2',
  PostRank:'http://api.postrank.com/v2/ping',
  WasaLive:'http://www.wasalive.com/ping/',
  IceRocket:'http://rpc.icerocket.com:10080/',
  FeedBlitz:'http://www.feedblitz.com/f/f.fbz?XmlPing'
  ]

def searchengines = [
  Ask:'http://submissions.ask.com/ping?sitemap=',
  Bing:'http://www.bing.com/webmaster/ping.aspx?siteMap=',
  Google:'http://www.google.com/webmasters/tools/ping?sitemap=',
  Yahoo:'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=Bling&url=',
  Moreover:'http://api.moreover.com/ping?u='
  ]

// Set up canned responses to make the outputted responses nicer.
// Previously, the output used the literal response from the endpoint
// which did not look all that nice in a terminal window.

def weal = "Thanks for the ping!"
def woe = "Ping Failed"

// Here is the section responsible for iterating through each ping
// url in the trackbacks map.

println "====XMLRPC PING RESULTS===="

trackbacks.each {
  try{
    def url = it.value
    def proxy = new XMLRPCServerProxy(url)
    response = proxy.weblogUpdates.ping(blogTitle, blogURL)
      response.data instanceof GPathResult

    if (!response.flerror)
        println "  ${it.key}".padRight(20) + "${weal}"
      else if (!opt.d)
        println "  ${it.key}".padRight(20) + "${woe}"
      else 
        println "  ${it.key}".padRight(20) + "${woe} - Reason: ${response.message}"

    }catch(ConnectException ex) {
      println "  ${it.key}".padRight(20) + "${woe}"     
    }catch(IOException ex){
      println "  ${it.key}".padRight(20) + "${woe}"
    }
}
println "==========================="
println "====SITEMAP PING RESULTS==="

searchengines.each {
    def url = it.value + sitemapURL
    def http = new HTTPBuilder( url )
      http.request( GET, URLENC ) { req ->
        headers.'User-Agent' = 'Bling/0.6'
        headers.'Referer' = 'http://blog.techstacks.com/bling.html'

      response.success = { resp, html ->
        println " ${it.key}".padRight(20) + "${weal}"
      }
      response.failure = { resp, html ->
        println " ${it.key}".padRight(20) + "${woe}"
      }
  }
}

println "==========================="

11/29/2009

Bling v0.5 Released - Now with Sitemap Pings!

This release of Bling introduces a new feature: Sitemap Pings. Five search engine services are included: Ask, Bing, Google, Moreover, and Yahoo!.  In addition to the groovy xmlrpc module that has been required for this script to work since it was first released, I've also included the HTTPBuilder module, which is used to send the sitemap pings to each search engine.

A new variable has been added to the script: sitemapURL.  You will need to replace the default text between the quotes with the fully-qualified path to your own site's sitemap.xml file.  You do not need to worry about url-encoding the URL path—bling does that for you.  For example, mine is located at http://blog.techstacks.com/sitemap.xml. The Wikipedia article I link to above contains background on Sitemaps or you can go directly to the sitemaps.org website to view the actual protocol.

No changes have been made to the services that bling sends xmlrpc pings to in this release.  A future release will probably end up removing some additional services that have been failing for me every time I run this tool. 

Source code is below.  The main bling page has been updated and this version has been posted to the download site.

#!/usr/bin/env groovy

import groovy.net.xmlrpc.*
import groovy.util.slurpersupport.GPathResult
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.URLENC

// You'll want to make this next section your own
def blogTitle = "YOUR_BLOG_TITLE_HERE"
def blogURL = "YOUR_BLOG_URL_HERE"
// New in Bling version 0.5:
// URL for Sitemap Pings
def sitemapURL = "YOUR_BLOG_SITEMAP_URL_HERE"

// Set up a map (hash) of popular rpc endpoints
// It is too bad for my syntax highlighter, but some of 
// the blogs containing periods in their names necessitated
// placing them in quotes.  

def trackbacks = [
  Google:'http://blogsearch.google.com/ping/RPC2',
  Weblogs:'http://rpc.weblogs.com/RPC2',
  FeedBurner:'http://ping.feedburner.com/',
  Moreover:'http://api.moreover.com/RPC2',
  Syndic8:'http://ping.syndic8.com/xmlrpc.php' ,
  BlogRolling:'http://rpc.blogrolling.com/pinger/',
  NewsGator:'http://services.newsgator.com/ngws/xmlrpcping.aspx',
  Bloglines:'http://www.bloglines.com/ping',
  'Blo.gs':'http://ping.blo.gs/',
  BlogCatalog:'http://rpc.blogcatalog.com/',
  PubSub:'http://xping.pubsub.com/ping/',
  'MyBlog.jp':'http://ping.myblog.jp/',
  Goo:'http://blog.goo.ne.jp/XMLRPC',
  BlogPeople:'http://www.blogpeople.net/servlet/weblogUpdates',
  Twingly:'http://rpc.twingly.com/',
  Spinn3r:'http://rpc.spinn3r.com/open/RPC2',
  PostRank:'http://api.postrank.com/v2/ping',
  WasaLive:'http://www.wasalive.com/ping/',
  BlogBuzzMachine:'http://rpc.blogbuzzmachine.com/RPC2',
  IceRocket:'http://rpc.icerocket.com:10080/',
  FeedBlitz:'http://www.feedblitz.com/f/f.fbz?XmlPing'
  ]

def searchengines = [
  Ask:'http://submissions.ask.com/ping?sitemap=',
  Bing:'http://www.bing.com/webmaster/ping.aspx?siteMap=',
  Google:'http://www.google.com/webmasters/tools/ping?sitemap=',
  Yahoo:'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=Bling&url=',
  Moreover:'http://api.moreover.com/ping?u='
  ]

// Set up canned responses to make the outputted responses nicer.
// Previously, the output used the literal response from the endpoint
// which did not look all that nice in a terminal window.
def weal = "Thanks for the ping!"
def woe = "PING ATTEMPT FAILED."

// Here is the section responsible for iterating through each ping
// url in the trackbacks map.

println "====XMLRPC PING RESULTS===="

trackbacks.each {
  try{
    def url = it.value
    def proxy = new XMLRPCServerProxy(url)
    response = proxy.weblogUpdates.ping(blogTitle, blogURL)
      response.data instanceof GPathResult

    if (!response.flerror)
        println "  ${it.key}".padRight(25) + "${weal}"
      else
        println "  ${it.key}".padRight(25) + "${woe}"

    }catch(ConnectException ex) {
      println "  ${it.key}".padRight(25) + "${woe}"     
    }catch(IOException ex){
      println "  ${it.key}".padRight(25) + "${woe}"
    }
}
println "==========================="
println "\n"
println "====SITEMAP PING RESULTS==="

searchengines.each {
    def url = it.value + sitemapURL
    def http = new HTTPBuilder( url )
      http.request( GET, URLENC ) { req ->
        headers.'User-Agent' = 'Bling/0.5'
        headers.'Referer' = 'http://blog.techstacks.com/bling.html'

      response.success = { resp, html ->
        println " ${it.key}".padRight(25) + "${weal}"
      }
      response.failure = { resp, html ->
        println " ${it.key}".padRight(25) + "${woe}"
      }
  }
}

println "==========================="