Script to import HTML files into Zendesk Forums

 Weeks ago, I was given with a task to import bunch of HTML files into Zendesk Forum as articles. As there were thousands of files and it’s tough to copy paste them manually. I got to know that Zendesk offers a rich set of API’s to manage Forum and it’s contents. I have created a Python script to import bunch of offline HTML files into Zendesk Forum creating Topics/articles in a Forum under Categories

We can perform either of the following features in Forum section.

  • List Forums

  • Show Forum

  • Create Forum

  • Update Forum

  • Delete Forum

Example request available in the Zendesk developers page is using curl.

curl https://yoursubdomain.zendesk.com/api/v2/topics.json -H "Content-Type: application/json" -v -u email:password -X POST -d '{"topic": {"forum_id": 79161, "title": "My Topic", "body":"This is some code", "topic_type": "articles", "access": "logged in users" }'

The above example had a limitation of adding HTML code into<code>, which is impossible when we had thousands of files to be uploaded. Thus I wrote a Python script tweaking the above example, so that I can refer an external file to fetch HTML contents and import it as an individual Topic.

Source can be found here..

https://github.com/ijeyanthan/zendesk-import-into-forum

To know more, visit http://developer.zendesk.com/documentation/rest_api/forums.html for the list of possible JSON requests available in Zendesk.


Java program using Apache Tika to extract text from various formats into a String object

Apache Tika can get the plain text from so many formats like Microsoft's Office files and PDF etc.

The tika app jar file can output plain text from those files and print them into a file or console.

This is a sample java program that uses this tika jar file as library and uses the Parser Api to get the text into a String object.

TextExtractor.java

 

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.net.URL;

 

import org.apache.tika.detect.DefaultDetector;

import org.apache.tika.detect.Detector;

import org.apache.tika.io.TikaInputStream;

import org.apache.tika.metadata.Metadata;

import org.apache.tika.parser.AutoDetectParser;

import org.apache.tika.parser.ParseContext;

import org.apache.tika.parser.Parser;

import org.apache.tika.sax.BodyContentHandler;

 

import org.xml.sax.ContentHandler;

 

class TextExtractor { 

    private OutputStream outputstream;

    private ParseContext context;

    private Detector detector;

    private Parser parser;

    private Metadata metadata;

    private String extractedText;

 

    public TextExtractor() {

        context = new ParseContext();

        detector = new DefaultDetector();

        parser = new AutoDetectParser(detector);

        context.set(Parser.class, parser);

        outputstream = new ByteArrayOutputStream();

        metadata = new Metadata();

    }

 

    public void process(String filename) throws Exception {

        URL url;

        File file = new File(filename);

        if (file.isFile()) {

            url = file.toURI().toURL();

        } else {

            url = new URL(filename);

        }

        InputStream input = TikaInputStream.get(url, metadata);

        ContentHandler handler = new BodyContentHandler(outputstream);

        parser.parse(input, handler, metadata, context); 

        input.close();

    }

 

 

    public void getString() {

        //Get the text into a String object

        extractedText = outputstream.toString();

        //Do whatever you want with this String object.

        System.out.println(extractedText);

    }

 

    public static void main(String args[]) throws Exception {

        if (args.length == 1) {

            TextExtractor textExtractor = new TextExtractor();

            textExtractor.process(args[0]);

            textExtractor.getString();

        } else { 

            throw new Exception();

        }

    }

}

 

 

Compile:

javac -cp ".:tika-app-1.0.jar" TextExtractor.java

 

Run:

java -cp ".:tika-app-1.0.jar" TextExtractor SomeWordDocument.doc

Note: Replace ":" with ";" if you are in Windows

 

Posted via email from Art, Science & Technology

Python script to create files/folders from a template


I was following this jenkins plugin tutorial today http://javaadventure.blogspot.in/2008/01/writing-hudson-plug-in-part-1.html which required me to create several directory structures. I found it vexing to do them manually. So I got this idea to make a python program that creates directory structures by reading a template file.

We will have to pass it a template file that specifies the directory structure which will be created. The template file should look something like this:

foldername/
    filename.ext
    subfoldername/
        subsubfoldername/
            anotherfile.txt
    someotherfile.xml

It can be anything like that. There are only two syntax requirements.
1.Indentation must be uniform (like in a python program)
2.folder names must end with a '/' otherwise the program can't know which is folder and which is file.

Screenshot:

Pydir3

 

Code:

 

#!/usr/bin/python

import sys,os

 

#I'll be using this as a stack pushing and popping indent levels

indentlevels = [0]

 

#Opening the file specified in argument

f=open(sys.argv[1])

 

#If the argument is /hello/structure.txt PARENTPATH should be /hello/

PARENTPATH=os.path.abspath(f.name)

PARENTPATH=PARENTPATH[:PARENTPATH.rindex('/')+1]

 

#We'll be reading line by line. This variable is used to store previous line.

previous = ""

 

#Count no. of leading spaces in a line.

#Empty lines give a length of 1 considering '\n' so will return -1 to ignore later

def countSpaces(data):

    return len(data)-len(data.lstrip()) if (len(data)>1) else -1

 

#This function creates the files or folders

def touch(data):

    global PARENTPATH

    if (data.endswith('/')):

        os.mkdir(PARENTPATH+data)

    else:

        f=open(PARENTPATH+data,"w")

        f.close()

 

 

 

#Main program starts.. Iterate through lines

line=f.readline()

 

while line:

    #Get the indent level

    indentlevel = countSpaces(line)

 

    #Remove leading and trailing spaces and get only the string

    line=line.strip()

 

    #Ignore empty lines and continue the loop

    if (indentlevel == -1):

        line = f.readline()

        continue

 

    #If indent is increased,

    if(indentlevel > indentlevels[-1]):

 

        #Check whether the previous line ended with '/'.

        #Because we can put files and folders within a folder. Not possible within  a file

        if not previous.endswith('/'):

            print "SYNTAX ERROR.. You can indent a line further only if the above line specifies a folder (ends with /)"

            sys.exit()

 

 

        #add the new indentlevel to indentlevels

        indentlevels.append(indentlevel)

        #and append the above string as a folder level to the PARENTPATH

        PARENTPATH=PARENTPATH+previous

 

    #If indent level is reduced,

    elif(indentlevel < indentlevels[-1]):

 

        #pop the last element from the indentlevels

        indentlevels.pop() #ref1

 

        #If indent is reduced more than one step (eg. dirstruct4),

        #then pop the indentlevels until it's equal to indentlevel

        #and do the same for parent path

        while indentlevels[-1]>indentlevel:

            indentlevels.pop()

            PARENTPATH=PARENTPATH[:PARENTPATH[:-1].rindex('/')+1]  

            # Because I want /hai/bai/ to become /hai/

 

        #If this condition fails, then it means the file is not indented uniformly

        if not (indentlevel == indentlevels[-1]):

            print "SYNTAX ERROR.. INDENTATION MUST BE UNIFORM"

            sys.exit()

 

        #required for line '#ref1'

        PARENTPATH=PARENTPATH[:PARENTPATH[:-1].rindex('/')+1]  

 

    #else: #indentlevel == indentlevels[-1]

    touch(line)

 

    previous=line

    line=f.readline()

 

 

Try this sample dir structure:

project/

   SimpleM2Project/

       pom.xml

       src/

           main/

               java/

                   com/

                       onedash/

                           hello/

                               Hello.java

           test/

               java/

Posted via email from Art, Science & Technology

Inspiring Quotes from the author of "Learn Python the Hard Way"

I read this book "Learn Python the Hard Way" some time ago. Actually the book was very basic as it was intended for people new to programming so it's not my type of book. What I liked was at the end of the book, there was an epilogue called "Advice From An Old Programmer."

Link to that:

http://learnpythonthehardway.org/book/advice.html

I really really loved it. Following are my favorites:

My Manager used to tell this frequently:

Which programming language you learn and use doesn't matter. Do not get sucked into the religion surrounding programming languages as that will only blind you to their true purpose of being your tool for doing interesting things.

 

Programming is an art form. This is how I used to think always:

Programming as an intellectual activity is the only art form that allows you to create interactive art. You can create projects that other people can play with, and you can talk to them indirectly. No other art form is quite this interactive. Movies flow to the audience in one direction. Paintings do not move. Code goes both ways.

 

Sad truth:

People who can code in the world of technology companies are a dime a dozen and get no respect. People who can code in biology, medicine, government, sociology, physics, history, and mathematics are respected and can do amazing things to advance those disciplines.

 

Finally my most favorite part due to my personal experiences:

Finally, I'll say that learning to create software changes you and makes you different. Not better or worse, just different. You may find that people treat you harshly because you can create software, maybe using words like "nerd". Maybe you'll find that because you can dissect their logic that they hate arguing with you. You may even find that simply knowing how a computer works makes you annoying and weird to them.

To this I have just one piece of advice: they can go to hell. The world needs more weird people who know how things work and who love to figure it all out. When they treat you like this, just remember that this is your journey, not theirs. Being different is not a crime, and people who tell you it is are just jealous that you've picked up a skill they never in their wildest dreams could acquire.

You can code. They cannot. That is pretty damn cool.

Posted via email from Art, Science & Technology

Small metaprogram using Python

If you have used so many softwares, you might have come across some that shows some Tips dialog with a checkbox that says "Show tip on startup." If you get annoyed, you uncheck it. It won't appear next time.

Guess how it is programmed. There must be some kind of a properties file or database that stores some boolean (or any other form of data) to store this setting. And everytime the application is loaded, it checks for the variable unnecessarily wasting cycles. It won't remember that you said you don't want to see any tips. It's like an unintelligent being (which is what it is.. afterall it's just a set of instructions.) Metaprograms can be made to look intelligent (from developer's point of view.)

This program is a very basic example. It prints out Hello and Good Morning. It asks you whether you want to be greeted with Hello everytime. If you say no, then it removes the related code from itself. IT CHANGES ITSELF! (Does it sound like Matrix? I Robot? Bicentennial Man?) It changes itself like the frogs in Jurassic Park novel.

CODE:

def deleteHello():

    f = open("sixthsense.py","r")

    output = []

    for line in f:

        if not line.endswith("deleted#\n"):

            output.append(line)

    f.close()

    f = open("sixthsense.py","w")

    f.writelines(output)

    f.close()

 

 

print "Hello" #line that might be deleted#

raw_input()   #line that might be deleted#

print "Good Morning"

raw_input()

choice = raw_input("Should I greet you with Hello always? (y/N)")  #line that might be deleted#

if choice != "y":  #line that might be deleted#

   deleteHello()   #line that might be deleted#

Remember to copy the file before running as you know that it can change itself.

PS:

One interesting thing happened.. I made a foolish mistake.

Before this condition,

 if not line.endswith("deleted#\n"):

I actually used this line.

 if not "#line" in line:

That was really stupid. Because the condition line itself satisfies the condition and gets removed. :P 

Posted via email from Art, Science & Technology

A web crawler and twitter crawler using Python

I still haven't started studying Python properly but doing fun tasks with it and learning on the way. I have made a Web Crawler that when given a url crawls through the child links recursively in a depth first order.

Web Crawler Code:

 

 

import urllib,string,re,sys

DEPTH = 0

MAXDEPTH = 0

SITENO = 0

LINKS = []

if len(sys.argv) < 3:

    print "Usage: python crawl.py <url> <depth>"

    sys.exit()

else:

    MAXDEPTH = int(sys.argv[2])

def findLinks(url,parent,score):

    global DEPTH

    global SITENO

    global LINKS

    global MAXDEPTH

    DEPTH += 1

    if DEPTH > MAXDEPTH:

        DEPTH -= 1

        return

    SITENO += 1

    print "DEPTH: %d\tSiteNo: %d\tSite: %s\tParent: %d\tScore: %d" % (DEPTH,SITENO,url,parent,score)

    LINKS.append(url)

    body = urllib.urlopen(url).read()

    try:

        start=string.index(body,"<body")

        body = body[start:]

    except ValueError:

        pass

    links = re.findall('''href=["']([^"']+)["']''', body, re.I)

    links = [ link \

              for link in links \

              if (link.startswith("http://") and \

              (not (link.endswith(".xml") or link.endswith(".css") or link.endswith(".js"))) and \

              (link not in LINKS)) ]

    if not links:

        DEPTH -= 1

        return

    score *= len(links)

    parent = SITENO

    for link in links:

        findLinks(link,parent,score)

    DEPTH -= 1

findLinks(sys.argv[1],0,1)

 

 

Usage:

Run "python crawl.py http://en.wikipedia.org/ 4"

Or start the depth with 1, 2 and go on for a better understanding of the working. Don't give big depth unless your processor has enough juice. I couldn't run this in my pc. I ran it in a high speed server where I have a shell access. It will display a set of fields. Depth of root node will be 1. SiteNo is a unique identifier for each site. Parent id of a site refers to its parent's siteno. Score(just for fun) starts with 1 for the root node. Score of a child node is the score of its parent node multiplied by number of siblings.

 

Crawl

 

Now combining this with my previous twitter script, I wrote a twitter crawler that crawls through friend nodes in a similar networked tree fashion. But too bad, there's a limit of only 150 requests per hour per client on twitter.

Twitter Crawler Code:

import urllib,sys

try:

    import json

except ImportError:

    import simplejson as json

DEPTH = 0

MAXDEPTH = 0

IDNO = 0

NAMES = []

if len(sys.argv) < 3:

    print "Usage: python twittertree.py <username> <depth>"

    sys.exit()

else:

    MAXDEPTH = int(sys.argv[2])

def findFriends(name,parentidno):

    global DEPTH

    global MAXDEPTH

    global IDNO

    global NAMES

    DEPTH += 1

    if DEPTH > MAXDEPTH:

        DEPTH -= 1

        return

    IDNO += 1

    print "DEPTH: %d\tID_No: %d\tUser_ID: %s\tParent_ID_No: %d" % (DEPTH,IDNO,name,parentidno)

    NAMES.append(name)

    try:

        jsondata=json.loads(urllib.urlopen('https://api.twitter.com/1/friends/ids.json?screen_name='+name).read())

    except IOError:

        DEPTH -= 1

        return

    friendsidlist = []

    try:

        friendsidlist = ",".join(map(str,jsondata['ids'][:100]))

    except KeyError:

        print "Rate Limit exceeded.. Only 150 requests per hour allowed.."

        sys.exit()

    jsondata2 = json.loads(urllib.urlopen('https://api.twitter.com/1/users/lookup.json?user_id='+friendsidlist).read())

    friendsnamelist = []

    try:

        friendsnamelist = [each['screen_name'] for each in jsondata2 if each['screen_name'] not in NAMES]

    except TypeError:

        pass

    if not friendsnamelist:

        DEPTH -= 1

        return

    parentidno = IDNO

    for eachfriendname in friendsnamelist:

        findFriends(eachfriendname,parentidno)

    DEPTH -= 1

findFriends(sys.argv[1],0)

 

Run "python twittertree.py vigneshwaranr 2"

Posted via email from Art, Science & Technology

Screen scraping a site with Python and storing the results into a sqlite db

This is a small program. I was tasked with retrieving a small set of data from a webpage by screenscraping using python.

http://money.livemint.com/IID64/F132540/Financial/Ratios/Company.aspx

Eps
This is the data I should retrieve. I never learnt Python properly but I could do it. That is the beauty of Python. Python has an interface to sqlite - the smallest db engine - called "Pysqlite". The library to import is called "sqlite3"

dbconn = sqlite3.connect('db/tcs_eps.db')

dbc = dbconn.cursor()

dbc.execute("CREATE TABLE IF NOT EXISTS EPSTABLE(DATE TEXT,EPS TEXT)")

dbc.execute("DELETE FROM EPSTABLE")

 

 

This part of the code creates a connection to a database file. If the file doesn't exist, it will be created. But the directory path should exist otherwise it'll throw an error. Sqlite is a file based database system unlike the server-client based ones like mysql, db2 etc.. Then it'll create a table if it doesn't exist already (i.e. during first run). It'll truncate the data from the table otherwise next time, same set of data will repeat in my tables.

host = "money.livemint.com" 

epspage = "/IID64/F132540/Financial/Ratios/Company.aspx" 

print "Please wait.. It will take some time depending on your connection speed.."

con = httplib.HTTPConnection(host)

con.connect()

con.request("GET", epspage)

resp = con.getresponse()

data = resp.read()

 

This part of the code opens up a connection to the host and tries to GET the page and then it reads the "data" part of the response. (Response object has so many other stuffs like status, headers etc..)

This data is the code of our html page. Analysing the content, I figured out that I should remove the unnecessary data above and below our interested part. For that I need to find a unique string above and below our part so that I can index them and take the substring out. Those indices were "InnerTable" and "R5". They were unique and appear only once and above and below our part in the file.

 

start=string.index(data,"InnerTable")

stop=string.index(data,"R5")

data = data[start:stop]

There are some html entities in that page which I removed using 

data = re.sub(r'[&nbspamltg]*;','',data)

This is not necessary though but I did it for my sake.

 

months = ['Date']+re.findall(r'[a-zA-Z]{1,3}\d\d\d\d',data)

earnings = ['Earnings/share (Rs)']+re.findall(r'\d\d\.\d\d',data)

 

Using this regex, I find out the date pattern and earnings per share pattern and store them in two lists. (The regex in second line should be changed to match any number of digits. I'm such a poor regex coder.)

 

for month, earning in zip(months, earnings):

    dbc.execute('INSERT INTO EPSTABLE VALUES (?,?)' , (month,earning))

dbconn.commit()

for month,earning in dbc.execute('SELECT * FROM EPSTABLE'):

    print '%s\t\t\t\t\t%s' % (month, earning)

dbconn.close()

 

 

Traversing elements simultaneously through two lists, they are inserted into the table and committed. Then traversing through each row in table and printing them. This program is just for learning coding in python with sqlite.

Full Program:

import httplib,string,re,sqlite3

dbconn = sqlite3.connect('db/tcs_eps.db')

dbc = dbconn.cursor()

dbc.execute("CREATE TABLE IF NOT EXISTS EPSTABLE(DATE TEXT,EPS TEXT)")

dbc.execute("DELETE FROM EPSTABLE")

host = "money.livemint.com" 

epspage = "/IID64/F132540/Financial/Ratios/Company.aspx" 

print "Please wait.. It will take some time depending on your connection speed.."

con = httplib.HTTPConnection(host)

con.connect()

con.request("GET", epspage)

resp = con.getresponse()

data = resp.read()

print "=================================================="

start=string.index(data,"InnerTable")

stop=string.index(data,"R5")

data = data[start:stop]

data = re.sub(r'[&nbspamltg]*;','',data)

months = ['Date']+re.findall(r'[a-zA-Z]{1,3}\d\d\d\d',data)

earnings = ['Earnings/share (Rs)']+re.findall(r'\d\d\.\d\d',data)

for month, earning in zip(months, earnings):

    #print '%s\t\t\t\t\t%s' % (month, earning)

    dbc.execute('INSERT INTO EPSTABLE VALUES (?,?)' , (month,earning))

dbconn.commit()

 

for month,earning in dbc.execute('SELECT * FROM EPSTABLE'):

    print '%s\t\t\t\t\t%s' % (month, earning)

dbconn.close() 

Tcsscr

Posted via email from Art, Science & Technology

Bash script to find mutual friends in twitter

My manager gave me a simple(tough for me) assignment to learn..

Problem: Write a command line app using your favourite language that accepts 2 facebook ids and return a list of common friends between the 2 ids.

I couldn't! I could make a program that list my friends but not others because it's private information and it requires others to allow my application blah blah..

So I gave a try for twitter and I SUCCESSFULLY DID IT! ;) Because following and followers list are public in twitter.

Check out the script and screenshot

Script

#!/bin/bash

link1='https://api.twitter.com/1/friends/ids.json?screen_name='$1

link2='https://api.twitter.com/1/friends/ids.json?screen_name='$2

curl $link1 > .fol.tmp

curl $link2 > .fol2.tmp

cat .fol.tmp | sed 's/.*\[\([0-9,]*\)\].*/\1/' | sed 's/,/\n/g' | sort > .ids.tmp

cat .fol2.tmp | sed 's/.*\[\([0-9,]*\)\].*/\1/' | sed 's/,/\n/g' | sort > .ids2.tmp

#comm -12 .ids.tmp .ids2.tmp | tr '\n' ',' | sed 's/,$//' > .comids.tmp

#comm -12 is same as grep -xFf :)

grep -xFf .ids.tmp .ids2.tmp | tr '\n' ',' | sed 's/,$//' > .comids.tmp

comids=`cat .comids.tmp`

comidlink='https://api.twitter.com/1/users/lookup.json?user_id='$comids

curl $comidlink > .lookup.tmp

cat .lookup.tmp | tr ',' '\n' | grep '"name"' | sed 's/.*:\"\([^\"]*\)\"/\1/g'

rm .fol.tmp .fol2.tmp .ids.tmp .ids2.tmp .comids.tmp .lookup.tmp

Note: I'm an amateur programmer. This code may not be the most efficient but it does the job well.

Screenshot:

Mutualfriends2

Posted via email from Art, Science & Technology

Neembuu Uploader crossed 10k+ downloads and featured in a Japanese Magazine

Hi y'all,

I hadn't been updating on NU for a long time after getting job. Though I am sincerely committed to my employers, I will still be responsible to my previous projects that helped me improve in life. I will use my weekends on them. Shashaank (Neembuu Admin) has a lots of plans for Neembuu, Neembuu Uploader, JPFM, JD and Vuze all combined. Lots of works ahead ;-)

NU Stats:

Downloads: 10325 (at the time of writing this)
Top Country: France :)
You can always see the latest stats at http://neembuuuploader.sf.net/downloads.html

France overtook Russia as the top downloading country. Seems like we have a lot of fans there.

AND I am very happy now to announce that Neembuu Uploader has been featured in a Japanese Tech magazine called "iP!". A month ago I got this mail from them:

Dear Vigneshwaran Raveendran,

I am an editor of a Japanese magazine called "iP!", a magazine for
Windows users with original DVD-ROMs to offer data/software.
I would like to introduce your "Neembuu Uploader"to Japanese Windows users.
And I am glad that you would give me kind permission to put your soft
into our DVD-ROM.
If OK,I would like to introduce "Neembuu Uploader" continuously from now on.

Please let me  know when you have any questions or find any problems
for introducing your soft.
I'm looking forward to hearing from you soon.

Published information is the following.
Please correct it when the mistake is found.
<snipped> 

And I replied:

Dear Xxxxxxx Xxx,

I am really glad to know that my product "Neembuu Uploader" will be introduced in 
your magazine. You are ALLOWED to feature it in your magazine. Please make sure
that you include my name "Vigneshwaran Raveendran" and the homepage url 
http://neembuuuploader.sourceforge.net/ anywhere in the body of the content.

I have one request. I am living in India where I cannot get access to your "iP!" magazine.
So after the magazine is published, please send me a scanned image of the page where
"Neembuu Uploader" is featured.

Thank you

After a long time, yesterday they replied:

Vigneshwaran Raveendran様

お世話になっております。晋遊舎の静内です。
このたびはソフトウエアの掲載に
ご協力ありがとうございました。

無事に誌面が完成いたしましたのでお送りいたします。
引き続きまして、変わらぬご愛顧のほど、
どうぞよろしくお願い申し上げます。

(Translate if you don't know japanese)

They attached a pdf of the scanned magazine. I took this screenshot of the part where NU appears. Check it out:

28

Posted via email from Art, Science & Technology

The Ripple…(Story)



A man was sitting by a lake. He was throwing small pebbles into it from time to time. A young boy happened to cross by. He was intrigued to see that after every few minutes or so, the man would toss a pebble into the lake.
The boy went up to the man and said, "Good pastime, this stone throwing, he?" "Hmmm," said the man.He seemed to be deep in thought and obviously did not wish to be disturbed.

Sometime later, the man said softly, "Look at the water, it is absolutely still."The boy said, "Yeah, it is."
The man tossed a pebble into the water and continued, "Only till I toss a pebble into it now do you see the ripples?""Yeah," said the boy, "they spread further and further.""And soon, the water is still again," offered the man.The boy said, "Sure, it becomes quiet, after a while."The man continued, "What if we want to stop the ripples? The root cause of the ripples is the stone. Lets take the stone out. Go ahead and look for it." The boy put his hand into the water and tried to take the stone out. But he only succeeded in making more ripples. He was able to take the stone out, but the number of ripples that were made in the process were a lot more than before.The wise man said, "It is not possible to stop the movement of the water once a pebble has been thrown into it. But if we can stop ourselves from throwing the pebble in the first place, the ripples can be avoided altogether! So too, it is with our minds. If a thought enters into it, it creates ripples.

The only way to save the mind from getting disturbed is to block and ban the entry of every superfluous thought that could be a potential cause for disturbance. If a disturbance has entered into the mind, it will take its own time to die down. Too many conflicting thoughts just cause more and more disturbances. Once the disturbance has been caused it takes time to ebb out. Even trying to forcibly remove the thought may further increase the turmoil in the mind. Time surely is a great healer, but prevention is always better than cure."

MORAL: Before you allow a thought or a piece of information to enter your mind, put it through the triple filter test of authenticity, goodness and value.


Neembuu Uploader featured in "Linux For You" magazine

Loads of Thanks to my amazing inspiring super-awesome senior Jeyanth for informing about this matter and also to his colleague who informed him first.

Neembuu Uploader is featured in "Linux For You" magazine November 2011 edition page 12.

Image0498
(Sorry for the bad quality.. Someday I'm gonna buy Android phone with HD camera.. hmm..)

As soon as Jeyanth bro told me, I went out, bought this 100Rs magazine, searched. Without any suspense, it was in 12th page itself. The content seemed like taken from some review site I don't remember now. I'd have been more happy if it was featured in my favorite magazine "Digit". Expecting that to happen.

 

This is the front cover of this magazine.

Image0500

I have released version 2.5 last month but didn't blog about it. It was just a small update like iPhone 4S over iPhone 4. 5 more sites and 9 more translations.

 

All nice things happen to Neembuu Uploader but its creator don't have a satisfying job. How ironic?

Posted via email from Art, Science & Technology

Concept to implement a mouse-over equivalent for touch screen devices

If you used touchscreen devices, sometimes you might have felt that it would be nice to have something like the "mouse-over" events in computers. It would be a nice feature to have but after all these years neither Apple nor Google did anything about it. Recently I had this idea for "finger-over" in touch screen devices. I don't know Electronics Engineering so my concept may be wrong. Or may be it's already implemented. Watch out for my ugly (mspaint) drawings.

 

Concept1

Almost all touchscreen phones have proximity sensors. Replace it with 4 proximity sensor (or whatever best suited for the purpose) on 4 corners of the screen behind the screen. They should be of different frequencies and should point towards the center.

 

Concept2
Now if we put our finger 0.5-1.0cm above the screen, the waves emitted from the sensors will reflect back to them. In this diagram, it looks like sensor 4 will receive its reflection first followed by 3, 2 and 1.

 

Concept3

 

Now we can find the exact position of the finger using the differences from the waves. If the sensors are capable of generating a 3d imaging of the finger, then the tip of the finger can be found. Nowadays softwares can recognize faces so finding a tip of a finger wont be difficult. If 3d imaging is not possible, then atleast the tip of the finger can be found by setting a threshold limit (0.5-1.0cm as I said previously). That's all there is to it. 

Edit: This is not similar to what is already done in Microsoft Surface. If you put a glass of Mango juice, the surrounding surface changes to yellow. It looks like surface uses Optical camera on 4 corners to find the color but it depends on touch and not hover. It will work only if you put something "on" it.

 

Benefits to users:

If this is done, then users can enjoy the "finger-over" in touchscreen devices.

1. Websites that use mouseover event in javascript can be expected to work.

2. There is a new System bar in Icecream Sandwich that always appear below the screen. It would be nice if it appears only if finger tip is near the bottom of the screen. The system bar will not be visible, then appears translucently if finger is near the bottom the screen and fully visible when touched. For a nice effect, we can vary the degree of translucence directly proportional to the distance between the finger and the screen. This I really wish to happen.

3. Most obvious use. If user is clueless of what a button does, then he can simply hover the finger over the button for a while until a tooltip shows up.

 

Device Manufacturers:

This will be an extra headache for device manufacturers as it may be require 4 sensors below or adjacent to screen which increases the phone thickness, complex circuitry, reduced battery hours. But this can be an optional feature.

For developers:

Developers can expect methods like onFingerOver(), onFingerOver(customtimeout) :P

Such methods obviously execute before (and may be also after) click events.

Lets say that not all manufacturers support this hardware feature. In that case, the developers need not worry if they used FingerOver events for showing tooltip only. But if they use FingerOver events to display a panel or something like the system bar, then developers (or Android itself) should replace it with Swipe event(like notification area).


Nothing is impossible. Even if my concept is wrong, something like this will happen in the future. Let us see :)

Posted via email from Art, Science & Technology

Conspiracy Theory: Could Steve Jobs have died before Oct 5?

I have this conspiracy theory in my mind that Steve Jobs might have died on Oct 4 or before and Apple covered up the news because of their Oct 4 event or may be Steve Jobs himself asked them to cover up.

I followed the Apple's homepage for 3 days continuously.

Oct 4 - Details on iPhone 4 and that conference is going on.

Oct 5 - Details on iPhone 4S, links to download previous day keynotes.

Oct 6 - A small paragraph saying Steve Jobs has died

This was the source of information. All the blogs and newssites started to publish articles on "How Steve changed the world" and quotes by notable people. But still there is no clear detail on his death.

Anyways I loved Steve Jobs. Kindly send your thoughts to rememberingsteve@apple.com

Posted via email from Art, Science & Technology

Neembuu Uploader v2.4 - World's first software in Sourashtra!

NeembuuUploader v2.4 is arguably the world's first full-fledged software that can be used in Sourashtra language. The translation is provided by one of my best buddies Balaji Sivanath. (See screenshots below)

 

I just released v2.3 about 2 weeks ago(Sep2). v2.3 was a major update over v2.2. We tested it thoroughly but still somehow 2 bugs leaked out.. They escaped our test because they won't happen to any one in India. They are,

  1. System Locale Bug - Due to one single missing line in a catch block, NU wouldn't start if the system locale is set to anything other than English. I got complaints from Sweden and Denmark. This was a serious issue which could lose me a lot of non-English users..
  2. Bug in FileSonic and Wupload plugins - What we didn't know was both these sites redirect to .in domain (Just like Google.com redirects to .co.in) and in other countries, they redirect to corresponding domain. We coded directly against .in domain hoping it will work anywhere. But it worked well anywhere in India but not outside India.

NOW WE FIXED BOTH THESE ISSUES!!

We verified the fix with those troubled users. They were really cooperative. This is why we had to make the next release on such an early date.

What's new in this version?

The previous version's update notification dialog can explain a lot.

Beautifulupdatenotificationfrom2

Now NeembuuUploader supports 25 filehosting sites!! (previously v2.3 - 12 and before that v2.2 - 6).

Seems like we are following Moore's law by doubling our ability in each release ;)

Added more convenient controls in Upload History window.

We have a new settings window now! This is how it looks.. Not much options for now as we had to rush to release this.

Settingsdialogwindows

 

Translations:

We are getting atleast two translations everyday from developers all over the world. One person I am so proud to tell is my favorite Grandpa who provided me with Malay translation ;)

Version 2.4 supports Catalan, Sourashtra, Spanish and Tamil fully. Hindi, Malay and Vietnamese were incomplete at the time of release.

Today morning I received translation for Brazilian Portugese (pt_BR). Another two guys offered German and Greek. Their submission is pending.

I make sure that every translator is properly credited both in the software's About Dialog and Project site.

Check out this gallery of how NeembuuUploader looks in each language.

 

Brazilian Portugese - by Maykon da Silva Siqueira

Brazilianportugesewindows

 

Catalan - by Jordi Castells

Catalanwindows

 

Hindi (Incomplete) - by Shashaank Tulsyan (my mentor)

Hindiwindows

 

Malay (Incomplete) - by Natesan Vellaichamy (my grandpa)

Malaywindows

 

Sourashtra!! - by Balaji Sivanath (my best buddy)

Sourashtramac

 

Spanish - by Jordi Castells

Spanishwindows

 

Tamil - by Vigneshwaran Raveendran (myself :P )

Tamilwindows3

 

Vietnamese (Incomplete) - by Nguyen Kien

Vietnamesewindows
~Fin~

Posted via email from Art, Science & Technology

New WebSite built for Neembuu Uploader

Didn't know my Neembuu Uploader will get popular so didn't create a site for it.. Thanks to help of my new team and reviews by various blogs, It crossed 4000 downloads. So spent 1.5 days and built a new website for Neembuu Uploader with loads of Passion.

Now it's up at http://neembuuuploader.sf.net/

 

The Site is very beautiful and matches the theme (unlike my previous http://jjsplit.sf.net which doesn't look so good).

 

Home Page

Site

The whole site is green themed. (JJSplit site was red themed. Probably my next site's theme will be blue... lol.)

Used a tag line from Dinesh : "A smart way to upload"

In the home page there'll be 3 small images which can rotate around if you click on either sides.

There's a Facebook's recommend and Twitter's tweet plugin at the bottom. But I put Google's +1 button on the top right as an always-on-top button.

During the first launch, the screenshot images will be preloaded into your cache. Once the site is fully loaded, click on the "Screenshots" link on the top right. It'll show a slideshow of 12 screenshots in a the same way as Facebook doing now but with a dark background and a panning effect.

Site6

 

Features

Site2
On the left side of Features page, there'll be a list of currently supported hosts and a list of hosts that will be supported in the future. 

On the right side, I've written a brief explanations of Features supported by NU. It took me more than an hour to find the perfect 48x icons for each features.

 

Support

Site3
Same stuff you'll find in other sites. A list of common annoying questions and a link to Contact page.

 

Downloads

Site4

On left column, list of new features added in the latest version.

On right column, a download button that will link to my sourceforge directory where people can download the latest version of Neembuu Uploader.

Like VLC guys, I have "live download statistics" that will display the total number of downloads, top os by downloads and top country by downloads. These are retrieved from SF with help of their downloadstats JSON API and AJAX on my side. (Downloads from sites other than SF are not calculated).

I have also listed links to CNET and Softpedia's Neembuu Uploader product page as Trusted Mirrors.

Also listed here are reviews to my product by various blogs. Special thanks to WebUpd8.org for always being the first to review.

 

Contact Us

Site5
Here my team details are mentioned and a Contact Form for contacting us for any support.

Hope you love my site as I do ;)

Posted via email from Art, Science & Technology

Neembuu Uploader v2.3 - Major update with new team

I had spent 2 weeks working on this without much sleep and food. The product came beautiful. I have learnt so much stuffs while working on this. I'm sure this time, this version alone gonna cross 10000 downloads in next few months.

Until 2.2 I have been playing solo. Now 3 friends contributed for me.

This is the Neembuu Uploader Team now.

Dinesh Sivaji: Plugins for DepositFiles, FileFactory, FileSonic, MediaFire, MegaUpload, Wupload
Muthu Krishnan: New Beautiful Icon
Shashaank Tulsyan (my sempai): Translation Framework (for future releases)
Vigneshwaran Raveendran: Framework for Accounts and Uploaders, User Interface and Controls, Plugins for remaining sites.

 

What's Neembuu Uploader?

For new readers, Neembuu Uploader v2.3 is a free and opensource Java application that uploads files simultaneously to multiple filehosts and lets you manage the download and delete URLs. Currently 12 major hosts are supported.

What's new in version 2.3?

  • New Hosts added with login support!: DepositFiles, FileFactory, FileSonic, MediaFire, MegaUpload, Wupload.
  • Right click menu to copy, export or go to selected links and to stop an upload.
  • Ability to remove and change the order of uploads.
  • Saves state and queued uploads on exit

Some Screenshots:

Accounts window:

Windows_04_accounts_manager

 

Drag and Drop files:

Linux_01_drag_and_drop

 

Select Hosts:

Windows_02_select_hosts

 

Start Uploading (Main Window):

Mac_04_uploading

 

Upload History:

Mac_05_upload_history

 

Download Neembuu Uploader v2.3 from here

Posted via email from Art, Science & Technology

My Steve Jobs Photo collection

This post is dedicated to one of my favorite people Steve Jobs who is stepping down from Apple CEO to Chairman today.

I love Steve Jobs... (but I love Google more though).. You've gotta love such people who can change the lifestyle of all other people (thanks especially to his iPhone.) Years back, I read his story on Digit Magazine's FastTrack on Apple. I was really impressed with him and Apple. I was a Microsoft fanboy until then. After learning they copied all stuffs from Apple, I changed.

Another best thing of him is his presentation skills which is top notch.

You've gotta see these two videos and see if you can do a solo presentation like that. He's full of passion.

Even after two major surgeries, he's still in bad shape now. Praying for his good health.

I have some of his good photos I'd like to share. See this gallery.

Posted via email from Art, Science & Technology

CheckyButton! A combination of JCheckBox and JButton

I liked the checkbox+pulldown menu combination in Gmail. I have been dreaming of creating fascinating new type of controls including this one even before it came out. Last night I have been thinking about how to add a requested feature in Neembuu Uploader that clears the list of rows of completed downloads whenever the user wishes or always automatically. I got this idea for such control that combines both the actions of a button and checkbox in a single control.

Something like this:
Checky2

And creating it in Swing is very simple. Just extend the JButton and add a JCheckBox into it. As simple as that!

 

 

Create a CheckyButton class like this:

Checkybutton
Then in your frame or other class, import this class and construct it like a normal JButton(String text).

//Add our Checky Button

        final CheckyButton cb = new CheckyButton("Clear Completed");

        cb.setSize(100,20);

Then add the action listeners for both Button part and Checkbox part of our CheckyButton

//Add an Action Listener for "Button" part of CheckyButton

        cb.addActionListener(new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                JOptionPane.showMessageDialog(null, "JButton Clicked :)");

            }

        });

 

        //Add an Action Listener for "Checkbox" part of CheckyButton

        cb.getCheckBox().addActionListener(new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                if(cb.getCheckBox().isSelected())

                    JOptionPane.showMessageDialog(null, "Checkbox selected");

                else

                    JOptionPane.showMessageDialog(null, "Checkbox not selected");

            }

        });

And finally add this CheckyButton to your frame or any other container using their add(Component comp) method.

Done!

This is a test screenshot of one of the possible ways Neembuu Uploader might look like in next version:

Neembuuuploader2

 

Posted via email from Art, Science & Technology

Film Info and Reviews for Opera

As you may know, I've made and blogged about this same extension previously for Chrome and then for Firefox. Now I have made it available for Opera geeks too. (P.S. Having some technical problems with Safari Developer Certificate installation. Otherwise I could have made this extension for Safari too completing a collection. Sigh!)

I have released the version 1.0 some 10 days ago. It was an exact replica of the chrome extension. And then the best thing happened. Some user named Basilla from Russia requested for a feature in extension that enables users to add their own favorite movie sites as 11th option.

I hadn't think about that. I narrow-mindedly thought that these 10 sites will be enough. But that user being Russian wanted to have "Kinopoisk.ru" site in the extension. So I have added that feature (for both Chrome and Opera) and released v2.0 on August 8. Now it has around 181 users.

Short Desc: View complete info and reviews of a film from upto 10 sites of your choice such as Wikipedia, IMDB, RottenTomatoes, Roger Ebert etc

Screenshot:

Scr1
Scr5

 

Get it from here: https://addons.opera.com/addons/extensions/details/film-info-and-reviews/2.0/

Posted via email from Art, Science & Technology

Morning Pages, IMDB to Wikipedia for Chrome

I've not been blogging for a while. I've made 3 more extensions - 2 for Chrome and 1 for Opera (next post).

Morning Pages

I saw this thread today morning.

I would love an extension that when you open chrome for the first time 
in a day it opens your preset homepages and then every time after that 
it only opens your main homepage. 
For example everyday i check youtube, crackberry and hotmail but only 
once so i would like an extension that brings these up for the first 
load only and every time i launch chrome after that for the rest of 
the day i would like only google to come up. 

I found the idea interesting and also useful to me. So I have made it under the name "Morning Pages."

I will be having Facebook, Twitter, OMG-facts and Google Plus for my morning pages.

Here's a screenshot of the options page

Scr1
 

 

Get it from http://bit.ly/MorningPagesExtension

 

IMDB to Wikipedia

You get it from the title what this extension does.

Displays a small floating wiki globe over movie/actor pages in IMDB that links to equivalent page in Wikipedia (Support 6 languages)

Sample screenshots:

Scr1r

Scr2r

 

Posted via email from Art, Science & Technology