Official ObjectGraph Blog
Monday, February 04, 2008
Announcing PageChat.com
PageChat.com is an innovative tool to communicate with anyone by dynamically creating chat rooms.
You could also use page chat to communicate with others about various topics of interest. Integrate our chat rooms with your websites/blogs to create a unique experience for your audience to chat with each other while on the same page.
We are currently releasing this version as a public beta and these are upcoming features:- Sharing Files
- Guest View
- Youtube integration
Labels: chat, pagechat.com, python
posted by gavi at 11:34 PM | 3 comments |
Monday, January 21, 2008
O'Rielly Maker: Make fun O'Rielly Book Covers
Make funny book covers that resemble O'Reilly books using the link below.
http://www.oreillymaker.com
We just launched it yesterday and there are already some really funny ones.
Check these out.posted by gavi at 8:53 AM | 6 comments |
Wednesday, November 07, 2007
Zen of Python
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
posted by Kiichi Takeuchi at 7:53 AM | 1 comments |
Sunday, October 21, 2007
iPhone Cake 2.0
posted by Kiichi Takeuchi at 1:14 PM | 2 comments |
Monday, October 15, 2007
django vs rails - Funny
posted by gavi at 5:11 PM | 0 comments |
Tuesday, September 25, 2007
PyScraper: The Python Screen Scraper
I wrote a light weight python based screen scraper, which seems to be working great.
Some of the features:
- Session Management when using cookies
- Seperate functions for get,post and downloading large files
- Automatic handling of redirections
Here is the code for it.
import httplib,urllib,random,sys,re,os from urlparse import urlparse class PyScraper: def __init__(self): self.cookie="" self.currenturl="" self.urlhist=[] def __str__(self): ret='' for item in self.urlhist: ret=ret+item+'->' return ret def download(self,url,localfolder): bufsize = 1024 self.urlhist.append(url) o=urlparse(url) scheme,hostname,path,q,query,position=o head,fname = os.path.split(path) if(query!=''): path=path+"?"+query conn=httplib.HTTPConnection(hostname) conn.request('GET', path,None,{'Cookie':self.cookie}) resp=conn.getresponse() total=int(resp.getheader('content-length')) f = open(localfolder+"/"+fname,'wb') sofar = 0 while 1: data = resp.read(bufsize) f.write(data) sofar += len(data) perc = (float(sofar)/float(total)) count = int(perc * 20) sys.stdout.write("\r%-30s|%-20s|%3d percent" % (fname,'#'*count,perc*100)) sys.stdout.flush() #sys.stdout.write("\r" + str(sofar) + " / " + str(total))total if len(data)==0: break f.close() if(resp.getheader('set-cookie')!=None): self.cookie=resp.getheader('set-cookie') conn.close() if(resp.status==302 or resp.status ==301): return self.get(resp.getheader('location')) return data def get(self,url): self.urlhist.append(url) o=urlparse(url) scheme,hostname,path,q,query,position=o if(query!=''): path=path+"?"+query conn=httplib.HTTPConnection(hostname) conn.request('GET', path,None,{'Cookie':self.cookie}) resp=conn.getresponse() data= resp.read() if(resp.getheader('set-cookie')!=None): self.cookie=resp.getheader('set-cookie') conn.close() if(resp.status==302 or resp.status ==301): return self.get(resp.getheader('location')) return data def post(self,url,data): self.urlhist.append(url) o=urlparse(url) scheme,hostname,path,q,query,position=o conn=httplib.HTTPConnection(hostname) conn.request('POST', path,data, {'Content-Type':'application/x-www-form-urlencoded','Cookie':self.cookie}) resp=conn.getresponse() data= resp.read() if(resp.getheader('set-cookie')!=None): self.cookie=resp.getheader('set-cookie') conn.close() if(resp.status==302 or resp.status ==301): return self.post(resp.getheader('location'),data) return data
Here is some snippet of code on how to use it.
from pyscraper import PyScraper p=PyScraper() data=p.get("http://www.yahoo.com/") print data
posted by gavi at 9:31 AM | 2 comments |
Tuesday, August 07, 2007
ObjectGraph AJAX Dictionary AIR version
I recently start learning Adobe AIR . AIR is a platform that allows you to run your web application on your desktop too. It seems there are two major ways to implement AIR: Flex or JavaScript. I downloaded a free online book from here, and I used Aptana for the IDE, but you can basically build AIR application with your favorite text editor & command-line.
After my Hello-World experience, I tried to port our online AJAX dictionary. I could translate this web application in 25 minutes. In terms of coding, only one part was changed, which is url for XMLHttpRequest method. It was relative path to send request, but I changed this to absolute url since it will send requests from your desktop. This was easy, and rest of changes are window width, removing links & unnecessary scripts.
Click here to download the .air application. Please install the runtime from here.
Additional Note:
In order to distribute AIR application, you need following MIME type in your server for .air extention.
application/vnd.adobe.air-application-installer-package+zip
Japanese characters are OK in AIR, but the font lost the sharpness. Maybe it's default font or rendering engine of its browser.
Labels: ajax
posted by Kiichi Takeuchi at 5:29 PM | 2 comments |
Wednesday, July 25, 2007
iPhone Dictionary
Just finished learning about the viewport metatag and implemeted this for dictionary on iPhone. Usage: Just type a few words and click on the reference.
http://www.objectgraph.com/dictionary/iphone.html
Labels: iphone ajax dictionary
posted by gavi at 11:34 AM | 2 comments |
Tuesday, July 24, 2007
onkeyup and iPhone
I got my iPhone a while ago and only now started looking at some development. Naturally i am trying to get our AJAX Dictionary to work on iPhone.
But looks like iPhone does not support the onkeyup event in Javascript. Actually it does not support a bunch of keyboard events (there is no real physical keyboard on iphone, so its hard to distinquish keyup, keydown etc), so i am thiking of just putting a button after the text is inputted.
There is an onchange event but it only triggers if you focus outside the textbox. Here is the first version of it.
http://www.objectgraph.com/dictionary/iphone.html
Labels: iphone development
posted by gavi at 12:59 PM | 0 comments |
Friday, July 06, 2007
Graphviz
Today I found something cool for drawing graphs. Its called GraphViz, You can download it from
It can output in various formats including SVG, PNG and GIF. But PNG and GIF dont have aliasing enabled, so they are pretty crappy.
For an example, look here. An image generated using PNG output
http://www.linkulu.com/random/?format=png&numnodes=10&size=5,5
Now look @ an another random graph with SVG output
http://www.linkulu.com/random/?format=svg&numnodes=10&size=5,5
Here is the python code to generate the graphs. I used Django ofcourse
def randomGraph(request): #Defaults for Generating random graphs random.seed() numnodes=5 format="svg" size="2,2" mime="image/svg+xml" if "format" in request.GET: infor=request.GET["format"] if(infor=="png"): mime="image/png" format="png" elif(infor=="gif"): mime="image/gif" format="gif" if "size" in request.GET: size=request.GET["size"] if "numnodes" in request.GET: numnodes=int(request.GET["numnodes"]) dot="""digraph G{ size ="%s"; orientation=portrait; {{{dot}}} }""" % (size) nodes=[] shapes=['ellipse','box','circle','record','triangle','doublecircle'] styles=['bold','dotted','normal'] colors=['cadetblue2','dimgray','dodgerblue1','beige','aliceblue','ghostwhite', 'greenyellow','hotpink4','lightgoldenrod2'] st="" for i in range(numnodes): nodes.append("a"+str(i)); for node in nodes: s1=random.randint(0,len(shapes)-1) c1=random.randint(0,len(colors)-1) st=st+" %s [shape=%s fillcolor=%s style=filled];\n" %(node,shapes[s1],colors[c1]) for i in range(numnodes): r1=random.randint(0,numnodes-1) r2=random.randint(0,numnodes-1) s2=random.randint(0,len(styles)-1) st=st+nodes[r1]+"->"+nodes[r2]+" [style=%s];\n" %(styles[s2]) dot=dot.replace("{{{dot}}}",st) tmpout, filename = mkstemp() pobj=Popen('dot -T%s -o %s' % (format,filename),shell=True,stdin=PIPE,stdout=PIPE) fin = pobj.stdin fout = pobj.stdout fin.write(dot) fin.flush() fin.close() pobj.wait() fout = os.fdopen(tmpout, 'r') jpeg = fout.read() fout.close() os.remove(filename) #jpeg=dot return HttpResponse(content=jpeg, mimetype='%s' % (mime))
Labels: graphviz python
posted by gavi at 4:09 PM | 2 comments |
Sunday, July 01, 2007
Looks like iPhone crash reports!
Just connected my iPhone to sync it and charge it (BTW the battery claims are totally false - you get may be 4 hours with wifi), Here is the screen shot.
Here is a file in the details..
Process: Exited process [24] Path: Exited process Version: N/A (N/A) Code Type: 0000000C (Native) Effective UID: 0 Parent Process: mach_kernel [Unknown] Date/Time: 2007-07-01 19:41:17.651 -0400 OS Version: OS X 1.0 (1A543a) Report Version: 6 Exception Type: 00000020 Exception Codes: 0x8badf00d Crashed Thread: Unknown Backtrace not available Unknown thread crashed with unknown flavor: 4, state_count: 1 Binary Images:
Labels: iphone bug
posted by gavi at 11:11 PM | 0 comments |
iPhone Bug?
Just got hands on my own iPhone after learning they were still available on 5th Avenue Store, I just could not resist it being only 20 blocks away!
First this device rocks. Very easy activation and extremely easy to use.
Every application seems to be stable and working great. But there seems to a problem when multitasking listening to music and browsing the web at the same time. My friend Horinaga found this bug and i was able to reproduce it.
It could be a quick software fix! Anyway i love the iPhone.
Labels: iphone bug
posted by gavi at 10:21 PM | 0 comments |
Saturday, May 19, 2007
Japanese Pages
We would like to announce the first internationalization of our webpages. I'm also glad to announce our good page ranking in Google Japan. If you just search "英和辞書"(English Japanese Dictionary) in google.co.jp, our Ajax dictionary will show up on the first page.
Labels: website
posted by Kiichi Takeuchi at 4:25 PM | 0 comments |
Saturday, April 28, 2007
Creating ISO on Mac OSX
I use a Thinkpad X60s that does not have a CD Drive and occasionally need to install software (This time i was trying out Dragon Naturally Speaking 9 which comes in 2 CD's). I also have a Mac Mini and i use it to create the iso images that could be later mounted on my PC using daemon tools.
Here are the steps
First find out what is your CD Drive
df -h Filesystem Size Used Avail Capacity Mounted on /dev/disk0s2 74G 62G 12G 83% / devfs 97K 97K 0B 100% /dev fdesc 1.0K 1.0K 0B 100% /dev512K 512K 0B 100% /.vol automount -nsl [207] 0B 0B 0B 100% /Network automount -fstab [235] 0B 0B 0B 100% /automount/Servers automount -static [235] 0B 0B 0B 100% /automount/static /dev/disk1s0 624M 624M 0B 100% /Volumes/DNS9_CD1
- After inserting a CD Mac OS X automatically mounts it. Unmount it using
diskutil unmountDisk /dev/disk1s0
Then run the command
dd if=/dev/disk1s0 of=disk1.iso bs=2048
Test the ISO image by mounting it using Finder.
posted by gavi at 12:52 PM |
DIY: Building your own live camera with Macmini
OK, I have huge headache today, and this happens to me every year when the season is changing. I took a day-off and I woke up late around noon, then I just decided to have some fun.
What you need:
- Macam driver (if your web camera is not supported)
- VideoScript - Automate capture images
- JDK - Any version to compile applet
Installing Driver:
I got a nice & small Logitech Web Camera yesterday, and I just wanted to use this for my Skype which is installed on my macmini in living room. I mounted this on my Sony's LCD, and launched Skype but nothing showed up. According to Logitech's website, the driver for MacOSX is not supported yet. So I found a opensource driver it's called Macam. I downloaded, and the installation was easy (don't forget to install the component in order to use from other applications). Now Skype shows me configuration for the video, and I could see my face. Then I remember that I used to broadcast my living room. OK, let's do it again.
Building Applet:
Since my Hello World experience was in Java, I spend some time with Applet in long time ago. An applet program to stream from jpg file might be nice. This is the program:
import java.awt.*; import java.applet.Applet; public class WebCamClient extends Applet { private Image mImg; private int mIsStarted = 1; private int mInterval = 10000; // in millisec private String mFile = "webcam.jpg"; public void start() { mIsStarted = 1; } public void stop() { mIsStarted = 0; } public void paint ( Graphics g ) { mImg = getImage( getDocumentBase(),mFile); MediaTracker mt = new MediaTracker(this); mImg = getImage( getDocumentBase(),mFile); mt.addImage(mImg,0); try { showStatus("loading ..."); mt.waitForAll(); } catch (InterruptedException e){ System.err.println("ERROR: "+e); } g.drawImage( mImg,0,0,this); mImg.flush(); showStatus("Showing every "+mInterval+" milliseconds"); if ( mIsStarted == 1 ) { repaint(); //repaint(mInterval); // this does not guarantee delay // Wait for next cycle try { Thread.sleep(mInterval); } catch (InterruptedException e){ System.err.println("ERROR: "+e); } } } public void update(Graphics g) { paint(g); } }
Good, this program grab webcam.jpg in the same directory and just show it in every 10 seconds. I stored this file in
/Users/kiichi/work/java/webcam/WebCamClient.java
and just compile like:
javac WebCamClient.java
Writting HTML Files:
All you have to do is write am index.html to load this applet in your browser:
Let's prepare for html refresh version too:
Automating Video Capture:
I spend a little bit time for researching automating video capturing and I found VideoScript. This script does a lot of jobs; however, I would like to use the simplest feature to capture the image. When you download the package, it comes with a small editor so that you can run&check your script. This is how it looks like:
set vs to videosource; repeat 4 times every 1 seconds // min is 4 sec set f to frame of vs; set file "/Users/kiichi/work/java/webcam/webcam.jpg" to f;
In the beginning, I just had a black screen. I tested a sample script to generate QuickTime movie, and it works fine, so what's wrong with the still image? The forum told me the reason because the camera takes a couple of seconds to calibrate the exposure. That's why I inserted the second line to wait 4 seconds. I saved it as update.vs and just run like:
videoscript -f update.vs
This gave me a clear image!
I think, it's ready to go. I had two choices to broadcast my living room. 1. Upload this picture to remote. 2. Open port 80 and let other people look at my Macmini. For today. I decided #1 so that I don't overwhelm my connection speed.
Scheduling FTP upload:
Mac OSX is just another UNIX system, so it might have cron to schedule my jobs. I found crontab under /etc/crontab (or /private/etc/crontab). I did
sudo gvim
to edit crontab. What I added is this line
* * * * * kiichi sh /Users/kiichi/work/java/webcam/update.sh
this means, run update.sh for every minutes.
This is inside update.sh
#!/bin/bash videoscript -f /Users/kiichi/work/java/webcam/update.vs FTPSERVER='your ftp url goes here' FTPUSER='username' FTPPASS='password' SOURCE='/Users/kiichi/work/java/webcam/webcam.jpg' DEST='.' TARGET='webcam.jpg' ftp -ni $FTPSERVER <<EOF user $FTPUSER $FTPPASS cd $DEST binary put $SOURCE $TARGET quit EOF exit 0
It's all set. cron suppose to pickup this script, and this script takes care of generating image and upload on ftp. If you access my streaming web page, the applet automatically refreshes those images. Since this script does not hold the device, when you have Skype call, it will sends a black image that says "Web camera is used by another program" for my ftp.
In the future, this is the todo list:
- Archiving images
- Streaming from the local machine - you can write a VideoScript to hold the device, and dump image for every second within the for-loop.
- Add date and time stamp
- Motion Detection
Download Source Code:
Labels: DIY
posted by Kiichi Takeuchi at 1:59 AM | 1 comments |
Monday, April 09, 2007
Guide to use screencasting to save time of programmers for free
You might think, "I'm coding guy, not movie guy", but I know what you hate if you are a programmer: Documentation and Training. I was impressed by some OSS communities, Like Ruby On Rails guys, because they demonstrated the power of screencast in their movies. After I start using screencast softwares, it released me from tons of burdens to explain how-to-use-it for my end users. I save time for training, and user's undersdanding level increases.
Wink
Wink is a completed package in order to publish your movie tutorial. This is basic steps:
- Create a New Project
- Select capture area. At this point, you are able to choose rectangle area or each window. This window selection is very neat because it allows me to choose inside tab of my browser.
- Hit Shift-Pause to start. Do the same thing to stop.
- Edit the movie if you need. You are able to add speech bubbles, rounded rectangle, arrows, and so on.
- Render and publish. You might save this project as *.wnk file.
I had some problems to capture my secondaly monitor, but it works pretty well if you use it in regular way. A lot of features are included in this software, but it's designed to use in minimal steps.
CamStudio
I had some problems to play video on FireFox 2.0, however it's quick and easy. Recording steps are minimized.
- Hit the record button
- Select the capture area and go. It will start recording right after you release button from the rectangle area.
- When you stopp it, it will ask you where to save.
After finding Wink, I just use this when I need to dump my screen cast into avi, but it still useful and extream minimized steps to use.
posted by Kiichi Takeuchi at 9:22 AM | 2 comments |
Saturday, March 10, 2007
CSS Cross Browser Initialization
Yahoo YUI developer explains how to absorb gap between various browsers. They recommend to include this css in beginning of your css first.
Click here to get Yahoo YUI website.
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td { margin:0; padding:0; } table { border-collapse:collapse; border-spacing:0; } fieldset,img { border:0; } address,caption,cite,code,dfn,em,strong,th,var { font-style:normal; font-weight:normal; } ol,ul { list-style:none; } caption,th { text-align:left; } h1,h2,h3,h4,h5,h6 { font-size:100%; font-weight:normal; } q:before,q:after { content:''; } abbr,acronym { border:0; }
posted by Kiichi Takeuchi at 8:21 PM | 0 comments |
Tuesday, March 06, 2007
Seven Habits For Effective Text Editing
This is very basic but powerful principal he offers:
1. Detect inefficiency
2. Find a quicker way
3. Make it a habit
Google Video
You can download hi-resolution avi version and his keynote here
This is not only about bunch of vim tricks but there are a lot of hints to increase your productivity. Even if you are emacs guy, it's worth to review his presentation.
posted by Kiichi Takeuchi at 7:08 PM | 0 comments |
Saturday, March 03, 2007
New Dictionary Launched
I just got some time to fix the CSS and launch ObjectGraph.com with a new design. I learned a lot about CSS during this transformation process.
But the best part is i got a chance to launch the new much improved interface to the ever popular dictionary
Check it out here
http://www.objectgraph.com/dictionary.htmlposted by gavi at 11:53 PM | 1 comments |
Tuesday, February 27, 2007
ObjectGraph.com running in a virtual server
With some downtime, i was able to completely move ObjectGraph.com to a virtual server running on an AMD 64 X2 with 4GB of RAM. Looks like dictionary is running very fast after the upgrade.
posted by gavi at 8:57 PM | 0 comments |