Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-10 of 20 total  RSS 

A simple XHTML submit form for ProjectX

Preparing ProjectX API requests through the browser's address bar can get quite messy, however inputting the request through a simple form makes it much easier to read.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>ProjectX API</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  </head>
  <body>
    <h1>ProjectX API form</h1>
    <p>Enter the Project API XML to send a request to the server.</p>
    <form action="http://rorbuilder.info/api/projectx.cgi" method="post" id="projectx_form">
    <fieldset><legend>xml_project</legend><textarea id="xml_project" name="xml_project" cols="104" rows="20"></textarea></fieldset>
    <div><button type="submit">Submit</button></div>
    </form>
  <p>
    <a href="http://validator.w3.org/check?uri=referer"><img
        src="http://www.w3.org/Icons/valid-xhtml10"
        alt="Valid XHTML 1.0 Strict" height="31" width="88" style="float:right;  border:0 "/></a>
  </p>
  <p style="clear:float">last updated: 13th April 2008</p>
  
  </body>
</html>


The web page can be seen at http://rorbuilder.info/r/projectx-api/index.html
The following XML request value when submitted should return an XML result containing the results and the method executed.
<project name='whiteboardqueue'>
  <methods>
    <method name='get_user_id'>
      <params/>
    </method>
  </methods>
</project>

eg.
<result method="rtn_get_user_id">
  <get_user_id>36539</get_user_id>
</result>

Undo the last shape stored in the whiteboard message buffer

This ECMAScript implements an undo feature for the SVG whiteboard. When the user presses CTRL+Z the last shape in the message_buffer variable is removed.

  function undoLast() {
    ipos = getLastMethodPos(message_buffer,-1)
    if (ipos > 0)
      message_buffer = message_buffer.substring(0, ipos)
    else
      message_buffer = ''    
  }
  
  function getLastMethodPos(message, pos) {
    i = message.indexOf('<method', pos+1)
    if (i >= 0) 
      result = getLastMethodPos(message, i)
    else
      result = pos 
    return result;
  }


Here's an example of the messages (containing shapes) stored in the message_buffer
"<method name='create'><params><param var='type'>shape</param><param var='body'>
polyline%20x%3D%27524%27%20y%3D%27198%27%20fill%3D%27none%27%20stroke%3D%27red%27%20id%3D
%27348553%27%20stroke-width%3D%272%27%20points%3D%27524%2C198%20523%2C198%20522%2C198%20521%2C198%20
513%2C198%20511%2C198%20503%2C198%20495%2C200%20493%2C200%20485%2C204%20483%2C205%20475%2C207%20474%
2C208%20470%2C212%20466%2C216%20465%2C217%20464%2C219%20463%2C220%20463%2C222%20463%2C223%20463%2C22
5%20463%2C226%20463%2C228%20464%2C230%20465%2C231%20466%2C233%20467%2C234%20471%2C238%20472%2C238%20
478%2C242%20484%2C246%20485%2C247%20488%2C247%20489%2C248%20491%2C248%20493%2C249%20496%2C249%20497%
2C249%20505%2C249%20515%2C249%20521%2C247%20531%2C245%20533%2C245%20539%2C243%20547%2C243%20548%2C24
3%20550%2C242%20555%2C237%20556%2C237%20557%2C235%20558%2C234%20558%2C233%20559%2C231%20559%2C230%20
560%2C228%20560%2C226%20560%2C222%20559%2C221%20559%2C220%20559%2C219%20559%2C217%20559%2C216%20558%
2C215%20558%2C214%20556%2C208%20555%2C206%20555%2C205%20553%2C199%20549%2C191%20547%2C185%20546%2C18
4%20544%2C176%20540%2C170%20539%2C168%20535%2C162%20534%2C161%20528%2C155%20528%2C154%20524%2C148%20
518%2C144%20517%2C143%20511%2C139%20509%2C138%20501%2C134%20499%2C133%20491%2C129%20489%2C129%20479%
2C129%20469%2C129%20467%2C129%20459%2C129%20457%2C129%20454%2C129%20452%2C129%20446%2C131%20438%2C13
1%20437%2C132%20435%2C132%20435%2C133%20434%2C133%20434%2C134%20433%2C134%20433%2C135%27%23%3A
</param><param var='sender'>34855</param></params></method><method name='create'><params><param 
var='type'>shape</param><param var='body'>polyline%20x%3D%27457%27%20y%3D%27175%27%20fill%3D%27none
%27%20stroke%3D%27red%27%20id%3D
%27348554%27%20stroke-width%3D%272%27%20points%3D%27457%2C175%20456%2C175%20455%2C176%20454%2C176%20
453%2C177%20452%2C177%20451%2C177%20449%2C178%20448%2C179%20442%2C181%20440%2C183%20438%2C184%20438%
2C185%20437%2C186%20436%2C187%20435%2C189%20435%2C191%20434%2C193%20434%2C194%20433%2C195%20433%2C19
6%20431%2C200%20431%2C201%20431%2C203%20431%2C205%20431%2C206%20431%2C207%20431%2C208%20431%2C209%20
431%2C210%20431%2C211%20431%2C212%20431%2C213%20431%2C214%20431%2C215%20431%2C216%20431%2C217%20432%
2C223%20432%2C224%20432%2C225%20432%2C226%20433%2C226%20433%2C227%20433%2C228%20433%2C229%20434%2C22
9%20434%2C230%20435%2C231%20435%2C233%20435%2C234%20436%2C235%20437%2C236%20437%2C237%20438%2C237%20
438%2C238%20438%2C239%20438%2C240%20439%2C240%20439%2C241%20443%2C245%20444%2C246%20444%2C247%20445%
2C247%20446%2C248%20447%2C248%20448%2C248%20448%2C249%20449%2C249%20450%2C250%20451%2C251%20452%2C25
2%20454%2C253%20455%2C253%20461%2C255%20462%2C255%20464%2C256%20466%2C256%20467%2C257%20469%2C257%20
469%2C258%20471%2C259%20472%2C259%20474%2C260%20475%2C260%20477%2C261%20478%2C261%20480%2C262%20481%
2C262%20481%2C263%20482%2C263%20483%2C263%20484%2C263%20485%2C263%20486%2C263%20489%2C263%20491%2C26
3%20492%2C263%20495%2C263%20496%2C263%20502%2C261%20504%2C261%20507%2C261%20509%2C261%20510%2C261%20
511%2C261%20512%2C261%20513%2C261%20515%2C261%20517%2C261%20518%2C261%20520%2C260%20523%2C260%20524%
2C260%20526%2C259%20528%2C259%20529%2C259%20534%2C258%20535%2C258%20536%2C257%20537%2C257%20538%2C25
7%20540%2C257%27%23%3A</param><param var='sender'>34855</param></params></method>"


In the above example there are 2 methods calls ready to be sent to the server, the 2nd method would be removed after the undoLast() function had executed.

The methods are ready to be passed to the function getLatestMessages which passes the request through the ProjectX API, which then returns the results.

This code only removes the shape before it's sent to the server, I still need to write the code to delete a shape which is in the server whiteboardqueue, and remove the shape element from the web browser display (SVG DOM).

Instruct a shared whiteboard to save and refresh

The following code used with the ProjectX API informs the client web browser that the whiteboard will be refreshed in 5 seconds. It then archives the current whiteboard information, formats it, and sends a message to each web browser to refresh their view.

<project name="whiteboardqueue">
  <methods>
    <method name="create">
      <params>
        <param var="type">ecmascript</param>
        <param var="body">startRefresh(5)</param>
        <param var="sender">system</param>
      </params>
    </method>
    <method name="timer">
      <params>
        <param var="timer">5</param>
      </params>
    </method>
    <method name="archive_and_format">
      <params/>
    </method>
    <method name="create">
      <params>
        <param var="type">ecmascript</param>
        <param var="body">reloadDocument()</param>
        <param var="sender">system</param>
      </params>
    </method>
  </methods>
</project>


*update 1:14am*
The whiteboard demo [rorbuilder.info] allows the user to draw using the mouse within the web browser which renders SVG. Tested on Flock and Firefox.

*update 4:42pm 28 Mar 08*
You can also view the whiteboard message queue [rorbuilder.info].

*update 6:29pm Mar 08*
I've created a short url (http://rubyurl.com/vxHD) (to demonstrate the cleaning of the whiteboard) which redirects to this http://rorbuilder.info/api/projectx.cgi?xml_project=<project name="whiteboardqueue"><methods><method name="create"><params><param var="type">ecmascript</param><param var="body">startRefresh(5)</param><param var="sender">system</param></params></method><method name="timer"><params><param var="timer">5</param></params></method><method name="archive_and_format"><params/></method><method name="create"><params><param var="type">ecmascript</param><param var="body">reloadDocument()</param><param var="sender">system</param></params></method></methods></project>

I've

Post to Jaiku using PHP

This example uses the ProjectX API to post to Jaiku.com
<?php
  $msg = 'this is just a test message using the ProjectX API for posting to Jaiku';

  $xml_result =  simplexml_load_file('http://rorbuilder.info/api/projectx.cgi?xml_project=<project name="jaiku"><methods><method name="post"><params><param var="user" val="jrobertson"/><param var="msg" val="' . $msg . '"/><param var="location" val="London"/><param var="apikey" val="9ee6ffd165r364492"/></params></method></methods></project>');
  $method_result = $xml_result->post2jaiku;
  echo 'result' . $method_result;
?>


Reference: SimpleXML processing with PHP [ibm.com]

Post to both Jaiku and Twitter

This XML code is the ProjectX API to post to both Twitter and Jaiku. This is a follow-up example from Post to Jaiku using ProjectX API [dzone.com]

xml_project = <<PROJECT
<project name='micro_blog'>
  <methods>
    <method name='post2jaiku'>
      <params>
        <param var='user' val='YourJaikuUserName'/>
        <param var='msg' val='YourMessage'/>
        <param var='location' val='YourCity'/>
        <param var='apikey' val='YourApiKey'/>
      </params>
    </method>
    <method name='post2twitter'>
      <params>
        <param var='user' val='YourTwitterUserName'/>
        <param var='msg' val='YourMessage'/>
        <param var='password' val='YourPassword'/>
      </params>
    </method>    
  </methods>
</project>"
PROJECT

Post to Jaiku using ProjectX API

This Ruby code uses the ProjectX API on rorbuilder.info to send a post to Jaiku.

Prerequisites:
1) You have a Jaiku account. see http://jaiku.com/
2) You know your Jaiku API key. see http://api.jaiku.com/

#!/usr/bin/ruby
# file: projectx_client.rb

require 'net/http'
require 'rexml/document'
include REXML

class ProjectXClient
  attr :doc
  def initialize(raw_url)
    url = URI.escape(raw_url)
    xml_data = Net::HTTP.get_response(URI.parse(url)).body
    @doc = Document.new(xml_data)
  end
  
end

if __FILE__ == $0

xml_project = <<PROJECT
<project name='jaiku'>
  <methods>
    <method name='post'>
      <params>
        <param var='user' val='YourJaikuUserName'/>
        <param var='msg' val='YourMessage'/>
        <param var='location' val='YourCity'/>
        <param var='apikey' val='YourApiKey'/>
      </params>
    </method>
  </methods>
</project>"
PROJECT
  
  pxc = ProjectXClient.new("http://rorbuilder.info/api/projectx.cgi?xml_project=" + xml_project)
  doc = pxc.doc
  puts doc
    
end



You can also pass the url including xml into the address bar and it will post to Jaiku successfully.
eg.
http://rorbuilder.info/api/projectx.cgi?xml_project="<project name='jaiku'><methods><method name='post'><params><param var='user' val='jrobertson'/><param var='msg' val='testing 223'/><param var='location' val='London'/><param var='apikey' val='5ugr6ttr754y214445'/></params></method></methods></project>"

Note:
Your api key is not in any way stored by the website rorbuilder.info.
Rorbuilder.info is a 3rd party developer website which is not part of Jaiku.com.

MetaWeblog API in PHP

Implementation of the MetaWeblog API http://www.xmlrpc.com/metaWeblogApi in PHP.

<?php
/**
 * Skeleton file for MetaWeblog API http://www.xmlrpc.com/metaWeblogApi in PHP
 * Requires Keith Deven's XML-RPC Library http://keithdevens.com/software/xmlrpc and store it as xmlrpc.php in the same folder
 * Written by Daniel Lorch, based heavily on Keith Deven's examples on the Blogger API.
 */

require_once dirname(__FILE__) . '/xmlrpc.php';

function metaWeblog_newPost($params) {
  list($blogid, $username, $password, $struct, $publish) = $params;
  $title = $struct['title'];
  $description = $struct['description'];


  // YOUR CODE:
  $post_id = 0; // id of the post you just created


  XMLRPC_response(XMLRPC_prepare((string)$post_id), WEBLOG_XMLRPC_USERAGENT);
}

function metaWeblog_editPost($params) {
  list($postid, $username, $password, $struct, $publish) = $params;


  // YOUR CODE:
  $result = false; // whether or not the action succeeded


  XMLRPC_response(XMLRPC_prepare((boolean)$result), WEBLOG_XMLRPC_USERAGENT);
}

function metaWeblog_getPost($params) {
  list($postid, $username, $password) = $params;
  $post = array();


  // YOUR CODE:
  $post['userId'] = '1';
  $post['dateCreated'] = XMLRPC_convert_timestamp_to_iso8601(time());
  $post['title'] = 'Replace me';
  $post['content'] = 'Replace me, too';
  $post['postid'] = '1';


  XMLRPC_response(XMLRPC_prepare($post), WEBLOG_XMLRPC_USERAGENT);
}

function XMLRPC_method_not_found($methodName) {
  XMLRPC_error("2", "The method you requested, '$methodName', was not found.", WEBLOG_XMLRPC_USERAGENT);
}

$xmlrpc_methods = array(
  'metaWeblog.newPost'  => 'metaWeblog_newPost',
  'metaWeblog.editPost' => 'metaWeblog_editPost',
  'metaWeblog.getPost'  => 'metaWeblog_getPost'
);

$xmlrpc_request = XMLRPC_parse($HTTP_RAW_POST_DATA);
$methodName = XMLRPC_getMethodName($xmlrpc_request);
$params = XMLRPC_getParams($xmlrpc_request);

if(!isset($xmlrpc_methods[$methodName])) {
  XMLRPC_method_not_found($methodName);
} else {
  $xmlrpc_methods[$methodName]($params);
}
?>

tw.py

// Sets and views Twitter status

#!/usr/bin/env python

__author__="Andrew Pennebaker (andrew.pennebaker@gmail.com)"
__date__="17 Jun 2007 - 28 Jun 2007"
__copyright__="Copyright 2007 Andrew Pennebaker"
__license__="GPL"
__version__="0.0.1"
__credits__="Based on tweetyPy (http://muffinresearch.co.uk/archives/2007/03/24/tweetypy-python-based-cli-client-for-twitter/)"
__URL__="http://snippets.dzone.com/posts/show/4150"

import sys, getopt, getpass, urllib, urllib2

import configreader

STATUS_MODE="STATUS"
VIEW_MODE="VIEW"
COMMAND_MODE="COMMAND"

COMMANDS="""Command\t\tMeaning

d username\tDirect Text
@username\tReply
follow username\tReceive updates via phone or IM
leave username\tStop following username
leave all\tStop following all friends
remove username\tRemove username from friends list
delete username\tDelete username from friends list
get username\tGet the last update from username
get\tGet the most recent updates from all friends
nudge username\tTwitter aks what the person is currently up to
whois username\tGet username's bio
add phonenumber\tSend text invite. If already a member, invite will turn into a friend request.
accept username\tAccept username as a friend
deny username\tDeny username as friend"""

def usage():
	print "Usage: %s [options]" % (sys.argv[0])
	print "\nWithout any options, uses status mode. Leftover args are concatenated to form message."
	print "\n-u|--username <username> specified in tw.conf"
	print "-s|--status mode"
	print "-v|--view status"
	print "-l|--list-commands List Twitter commands"
	print "-c|--config <configfile>"
	print "-h|--help"

	sys.exit()

def set_status(settings, status):
	auth=urllib2.HTTPPasswordMgrWithDefaultRealm()
	auth.add_password(None, settings["rootauthurl"], settings["username"], settings["password"])
	authHandler=urllib2.HTTPBasicAuthHandler(auth)
	opener=urllib2.build_opener(authHandler)

	url="http://twitter.com/statuses/update.xml"
	post=urllib.urlencode({"status":status})

	request=urllib2.Request(url, post)
	request.add_header("User-Agent", settings["useragent"])

	try:
		response=opener.open(request)
	except IOError, e:
		raise "Could not connect."

def view_status(settings):
	url="http://twitter.com/"+settings["username"]
	message=""

	statusdelimeter1=settings["statusdelimeter1"]
	statusdelimeter2=settings["statusdelimeter2"]

	try:
		instream=urllib.urlopen(url)
		for line in instream:
			if statusdelimeter1 in line:
				message=line[
					line.index(statusdelimeter1)+len(statusdelimeter1):line.index(statusdelimeter2)
				]
				break
		instream.close()

		return message
				
	except IOError, e:
		raise "Could not connect."

def main():
	global STATUS_MODE
	global VIEW_MODE
	global COMMAND_MODE
	global COMMANDS

	sysArgs=sys.argv[1:]

	mode=STATUS_MODE

	settings={
		"config":"tw.conf",
		"username":"mcandre",
		"rootauthurl":"http://twitter.com/statuses/",
		"useragent":sys.argv[0]+" "+__version__,
		"statusdelimeter1":"<p class=\"entry-title entry-content\">",
		"statusdelimeter2":"</p>"
	}

	optlist, args=[], []
	try:
		optlist, args=getopt.getopt(sysArgs, "u:svlc:h", ["username=", "status", "view", "list-commands", "config=", "help"])
	except:
		usage()

	for option, value in optlist:
		if option=="-c" or option=="--config":
			settings["config"]=value

	try:
		configreader.load(open(settings["config"], "r"), settings)
	except IOError, e:
		pass

	for option, value in optlist:
		if option=="-h" or option=="--help":
			usage()

		elif option=="-u" or option=="--username":
			settings["username"]=value
		elif option=="-s" or option=="--status":
			mode=STATUS_MODE
		elif option=="-v" or option=="--view":
			mode=VIEW_MODE
		elif option=="-l" or option=="--list=commands":
			mode=COMMAND_MODE

	if mode==STATUS_MODE:
		if len(args)<1:
			usage()

		message=" ".join(args)

		settings["password"]=getpass.getpass()

		set_status(settings, message)
	elif mode==VIEW_MODE:
		print view_status(settings)
	elif mode==COMMAND_MODE:
		print COMMANDS

if __name__=="__main__":
	try:
		main()
	except KeyboardInterrupt, e:
		pass

Quick Flickr search in Ruby

// Examples for the three listed APIs weren't working. Instead of choosing one and debugging it, I chose to do something quick and dirty. "MY_API_KEY" and other params would need to be removed to make this more generic. A naive mapping of API method calls that take hashes, and returns an OpenStruct is an approach I'm considering, as it would likely break less often and require less code.

require 'net/http'
require 'rexml/document'
require 'ostruct'

class Flickr < OpenStruct
  include REXML

  def Flickr.search(text)
    doc = Document.new(
            Net::HTTP.get(
              URI.parse('http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=MY_API_KEY' +
                        '&extras=license,owner_name,original_format&license=4,5&per_page=20&sort=interestingness-desc' +
                        '&text=' + text)))
     throw "flickr error" unless doc.root.attributes['stat'] == "ok"
     doc.root.elements['photos'].get_elements('//photo').collect {|photo| photo << Flickr.new(photo) }
  end

  def initialize(e)
    super(e.attributes)
    self.new_ostruct_member("photo_id")
    self.photo_id = e.attributes['id']
  end

  def to_url(image_type="s")
    "http://farm#{farm}.static.flickr.com/#{server}/#{photo_id}_#{secret}_#{image_type}.jpg"
  end
end

Simple w3c Validator

// This function will return either a true or false (boolean) value, whether a certain site contains valid code based on w3 standards. Requires the Snoopy PHP class.
// Could be used in many situations where a simple "is valid" or "is not valid" result is required.

<?php
function w3Valid($url) {
	require("Snoopy.class.php");
	$snoopy = new Snoopy;

	$snoopy->fetchtext("http://validator.w3.org/check?uri=" . $url . "&output=soap12");
	$validator_output = $snoopy->results;

	if(preg_match("/false/", $validator_output)) {
		return false;
	} else {
		return true;
	}
}

?>
« Newer Snippets
Older Snippets »
Showing 1-10 of 20 total  RSS