Sunday, March 29, 2009

a webkit-based web browser part II


yup! it's my web browser part II! I was thinking about iphone browser features and how to make a browser like it. It's for small devices, not like a normal firefox one. The screen is smaller, without a fully functional keyboard, and probably user only use fingers. I saw a video from Apple iphone website and found their nice features. Eg.'zoom-in, zoom-out', 'finger scrolling', 'vertical & horizontal placing', and a easy bookmark menu!

A. finger scrolling:
i found a very cool article in Qt blog and Ariya Hidayat implemented a Flick Charm example. Also, Akos Polster updated it to a python version. They save all my work. Only few lines, then i can see this beauty. User needn't use mouse wheel to scroll pages and can scroll/drag page by mouse gestures. If it's a touch screen, then it would be user fingers. You can check ariya's video in youtube.


WebBrowser = QtWebKit.QWebView(Frame3)
charm = FlickCharm()
charm.activateOn(WebBrowser)

B. Text zoom-in & zoom-out:
I put 3 zooming buttons on the tool bar and also make hot keys. User can zoom-in, zoom-out, zoom to fit-in page by clicking a button.


def on_actionZoomIn_triggered(self):
current = self.WebBrowser.textSizeMultiplier()
self.WebBrowser.setTextSizeMultiplier(current+0.1)

C. Full page zooming:
There is another zooming function and it can zoom-in the whole web page (including images and fonts). I use a MouseDoubleClick event to set the page view to 0.5 or 1.0. When user read a web page, they can use this function to see a thumbnail image.


def mouseDoubleClickEvent(self,mouseEvent):
if self.zoomFactor() == 1.0:
self.setZoomFactor(0.5)
else:
self.setZoomFactor(1.0)
QtWebKit.QWebView.mouseDoubleClickEvent(self,mouseEvent)



D. bookmark menu:
I made 2 buttons on tool bar. One is to show bookmark list and the other one is to add the current page to a bookmark. User can click one bookmark in list and load it in browser. Also, user can double-click to delete a bookmark. I use python-sqlite to store bookmark data to a db.

I have to distinguish MousePressEvent and MouseDoubleClickEvent, since they have different meaning in my design. I use a timer, when I get a MousePressEvent. It would load a bookmark page after 300 millisecond. Also, if we get a double-clicked event, it would stop that timer. Then, I can know it's to delete a bookmark, not to load it.

E. enable plug-in: (Flash player)
I just found that i cannot see video in YouTube website from Qt version 4.4. Therefore, I have to upgrade it to version 4.5, even PyQt 4.5 is still development snapshots. Qt4.5 new feature: Netscape plug in (NPAPI) support, enabling you to to incorporate Flash™ content in your Qt applications. :)

*download & install Qt4.5

wget http://dist.trolltech.com/developer/download/qt-embedded-linux-eval-src-4.5.0.tar.gz
tar zxvf qt-x11-eval-src-4.5.0.tar.gz
cd qt-x11-eval-src-4.5.0/
./configure & make & sudo make install

*install sip 4.8 and pyqt4.5 (Development Snapshots!!)

wget http://www.riverbankcomputing.co.uk/static/Downloads/sip4/sip-4.8-snapshot-20090327.tar.gz
tar zxvf sip-4.8-snapshot-20090327.tar.gz
cd sip-4.8-snapshot-20090327
python configure.py
make & make install

wget http://www.riverbankcomputing.co.uk/static/Downloads/PyQt4/PyQt-x11-gpl-4.5-snapshot-20090328.tar.gz
tar zxvf PyQt-x11-gpl-4.5-snapshot-20090328.tar.gz
cd PyQt-x11-gpl-4.5-snapshot-20090328
python configure.py --qmake=/usr/local/Trolltech/Qt-4.5.0/bin/qmake
make & make install

Put one more line!

web = QtWebKit.QWebView()
web.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True)

DONE! I can watch a video from my tiny pyqt browser. The complete source code are here.

Wednesday, March 25, 2009

write a web browser by python

Probably half year ago, I wrote a web browser application by python and the source code is just few hundred lines. That example is based on python-qt4 and webkit. If you install related qt4 and python-qt packages, you can see a lot of cool qt examples. Browser is one of them. Since I cannot run the original python one, it needs a window IE activeqt component. Therefore, I modified few lines and then I can run this example in GTA02 and my desktop. I was trying to run this example in EeePC tonight. It took me about 3 minutes work.

There are two browser examples in qt. One is by cpp and the other one is by python!

Install qt4:
sudo apt-get install qt4-demos

Check where is qt4-demos:
dpkg -L qt4-demos

Run a c++ web browser:
./usr/lib/qt4/demos/browser/browser




Install python-qt4 related packages:
sudo apt-get install python-qt4 python-qt4-dev python-qt4-doc

Check where is python-qt4-doc
dpkg -L python-qt4-doc

Run a python web browser:
cd /usr/share/doc/python-qt4-doc/examples
find -name '*browser*
python activeqt/webbrowser/webbrowser.py

ERROR: The Windows commercial version of PyQt is required to run this example.

Download my pyqt-browser:
wget http://pyqt-browser.googlecode.com/files/webbrowser.tar.gz
tar zxvf webbrowser.tar.gz
python webbrowser/webbrowser.py




here is browser python code: or download it!

#!/usr/bin/env python

import sys
from PyQt4 import QtCore, QtGui, QtWebKit
from ui_mainwindow import Ui_MainWindow

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Maintain the list of browser windows so that they do not get garbage
# collected.
_window_list = []

def __init__(self):
QtGui.QMainWindow.__init__(self)

MainWindow._window_list.append(self)

self.setupUi(self)

self.lblAddress = QtGui.QLabel("", self.tbAddress)
self.tbAddress.insertWidget(self.actionGo, self.lblAddress)
self.addressEdit = QtGui.QLineEdit(self.tbAddress)
self.tbAddress.insertWidget(self.actionGo, self.addressEdit)

self.addressEdit.setFocusPolicy(QtCore.Qt.StrongFocus)

self.connect(self.addressEdit, QtCore.SIGNAL("returnPressed()"),
self.actionGo, QtCore.SLOT("trigger()"))

self.connect(self.actionBack, QtCore.SIGNAL("triggered()"),
self.WebBrowser, QtCore.SLOT("back()"))

self.connect(self.actionForward, QtCore.SIGNAL("triggered()"),
self.WebBrowser, QtCore.SLOT("forward()"))

self.connect(self.actionStop, QtCore.SIGNAL("triggered()"),
self.WebBrowser, QtCore.SLOT("stop()"))

self.connect(self.actionRefresh, QtCore.SIGNAL("triggered()"),
self.WebBrowser, QtCore.SLOT("reload()"))

self.pb = QtGui.QProgressBar(self.statusBar())
self.pb.setTextVisible(False)
self.pb.hide()
self.statusBar().addPermanentWidget(self.pb)
self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))


@QtCore.pyqtSignature("")
def on_actionHome_triggered(self):
self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))

def on_WebBrowser_urlChanged(self, url):
self.addressEdit.setText(url.toString())

def on_WebBrowser_titleChanged(self, title):
#print 'titleChanged',title.toUtf8()
self.setWindowTitle(title)

def on_WebBrowser_loadStarted(self):
#print 'loadStarted'
#self.misc.keyboard_show()

self.pb.show()
self.pb.setRange(0, 100)
self.pb.setValue(1)

def on_WebBrowser_loadFinished(self, flag):
#print 'loadFinished'
if flag is True:
self.pb.hide()
self.statusBar().removeWidget(self.pb)

def on_WebBrowser_loadProgress(self, status):
self.pb.show()
self.pb.setRange(0, 100)
self.pb.setValue(status)

@QtCore.pyqtSignature("")
def on_actionGo_triggered(self):
#print "on_actionGo_triggered"

self.WebBrowser.load(QtCore.QUrl(self.addressEdit.text()))
self.addressEdit.setText(self.addressEdit.text())

@QtCore.pyqtSignature("")
def on_actionHome_triggered(self):
#print "on_actionHome_triggered"
self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))
self.addressEdit.setText("http://www.google.com")


if __name__ == "__main__":
a = QtGui.QApplication(sys.argv)
w = MainWindow()

w.show()
sys.exit(a.exec_())

Friday, March 20, 2009

Taipei App Engine Sprint 2009

I went to Google Taipei office to join an event 'Taipei App Engine Sprint' with my team mate 'olv' and 'tick'. We heard this news from 'Ping Yeh' in Tossug and got the invitation from him. It's a whole day event and we would like to build a web site by google app-engine in a day. There were about 20 people and we separated to 5 groups. My team name is 'Dabajianshan' and actually it's a conference room name in their office. They name all conference rooms by famous sightseeing place in Taiwan. Also, we found a new team mate 'Daniel Lin' and he knows web applications much much more than our three Linux engineers.



We launched a new web site 'Sight History'. Using Picasa Web Albums, we can search all their photos by keyword and group those photos by different time lines. Thanks a lot for Google Service APIs, they provide very useful, convenient, comprehensive API services and good readme documents. That is probably the main reason why we can build this site in a day (less than 10 hours). There are only two tricky points. The first one is 'community search'. With this API, we can search photos uploaded by Picasa users, as long as they are in a public album. This function is quite amazing and it means we can search whole Picasa Web Albums in Internet. BTW, Google has a limitation for their Google Data Service API searching function and we can only retrieve 1000 records. When I make a search in Picasa Web Albums, the total results are over 100,0000 photos most of time. I am so glad even only 1000 images are still quite meaningful for our search.
The second one is 'grouping photos by a time line'. Like search 'Cherry Blossom', we can get a lot of cherry images, and you would see most of them 'shot time' are in March and April. Why only in these two months? That is because Cherry blossom time is March in Japan, and April in East States. We also display the images in a Google Map and we can see where are these photos from. For users, they are easy to tell 'when' and 'where' to see Cheery Blossom!!!


Furthermore, we group Picasa web photos not only by 'month', but also by 'day' and 'hour'. Like search '阿里山日出', it's a very famous mountain in Taiwan and people visit it coz of beautiful sunrise. By our search, we can see what time most people can see sunrise in this place. That is a very interested searching result. I can see the images in 3AM-4AM, most of people start to take the train or start to leave hotels. The most images are in 4AM-6AM, then I can tell people can see pretty sunrise in this time slot.


In the end of day, our team won the first place in Taipei App Engine Sprint. I got a very cute 'Google App-Engine' t-shirt and a certification from Google. :)

Here is our web site: http://sighthistory.appspot.com

Download the source code: http://gitorious.org/projects/dabajianshan

You can clone this repository with the following command:
git clone git://gitorious.org/dabajianshan/mainline.git

PS. some photos about this event in my picasa web album

Sunday, March 1, 2009

asterisk & media wiki configuration notes

Asterisk

A. Installation

1. using an iso image 'AsteriskNOW' to install the whole package with linux OS
http://www.asterisknow.org/
We can find the documents and download the lastest version from their website. After installing AsteriskNOW step by step to a machine, we can configure it by any web browser, only need to remember the URL, ID, and password.

2. self install on linux machine (like Debian, Ubuntu, Fedora...etc)
we could reference to these documents
http://www.asteriskguru.com/tutorials/asterisk_gui.html
http://www.howtoforge.com/asterisk_pbx_linux

(1) create a working folder:
# mkdir /usr/src/asterisk

(2) download all needed packages
from website as below:
http://downloads.digium.com/pub/

(3) installing libpri

# wget http://downloads.digium.com/pub/libpri/libpri-1.4.2.tar.gz
# tar xzvf libpri-1.4.2.tar.gz
# cd libpri-1.4.2
# make clean
# make
# make install


(4) installing zaptel

# wget http://downloads.digium.com/pub/zaptel/zaptel-1.4.6.tar.gz
# tar xzvf zaptel-1.4.6.tar.gz
# make clean
# make
# make install

PS. if you met the problem like missing Linux kernel header file, you may download your Linux header

files:
# cat /proc/version
# apt-get install linux-headers-2.6.20-16-386

(5) installing asterisk

# wget http://downloads.digium.com/pub/asterisk/asterisk-1.4-current.tar.gz
# tar xzvf asterisk-1.4-current.tar.gz
# ./configure
# make clean
# make
# make install


(6) installing asterisk-addons

# wget http://downloads.digium.com/pub/asterisk/asterisk-addons-1.4.4.tar.gz
# tar xzvf asterisk-addons-1.4.4.tar.gz
# ./configure
# make clean
# make
# make install

(7) installing asterisk-gui

# svn checkout http://svn.digium.com/svn/asterisk-gui/trunk
# make clean
# make
# make install
# make checkconfig [it can detect all config file status ]

(8) modify 2 confiure files, then we can use astersik gui web interfaces
# vi /etc/asterisk/manager.conf

a. modifiy these two lines
enabled = yes
webenabled = yes

b. add a user
[administrator]
secret = 123456
read = system,call,log,verbose,command,agent,user,config
write = system,call,log,verbose,command,agent,user,config

# vi /etc/asterisk/http.conf
a. modify these lines
enabled=yes
enablestatic=yes
bindaddr= 0.0.0.0

(9) use asterisk CPI prompt to execute shell commands
# asterisk -vvvvvr
erin-laptop*CLI> restart now (it will restart asterisk now)

(10) open a browser to verify asterisk
http://127.0.0.1:8088/asterisk/static/config/cfgbasic.html
http://127.0.0.1:8088/asterisk/static/config/cfgadvanced.html

B. Configuration

we can change the configuration from asterisk site, like adding the extension number, or change voicemail number....etc

C. Softphone

A softphone is a software program for making telephone calls over the Internet
http://en.wikipedia.org/wiki/Softphone

1. SJphone: http://www.sjlabs.com/sjp.html
download windows version
http://www.sjphone.org/softphone/SJphone-1.65.2637.exe
user guide for windows
http://www.sjphone.org/doc/SJphone_User_Guide.pdf

2. X-Lite: http://www.counterpath.com/xlite-overview.html
3. google talk: http://www.google.com/talk/intl/zh-TW/
4. Zoiper: http://www.zoiper.com/
it provides different OS version, including Linux, Windows, and Mac OS.

MediaWiki

A. Installation

the installations notes is from here:
http://lifehacker.com/software/wikipedia/geek-to-live-set-up-your-personal-wikipedia-163707.php

all download files are from SourceForge:

1. install WAMP:
WAMP is an all-in-one PHP/MySQL/Apache installation for Windows.
http://www.wampserver.com/en/download.php

2. Install MediaWiki, the software that powers Wikipedia.
http://prdownloads.sourceforge.net/wikipedia/mediawiki-1.5.8.tar.gz?download

Sysop account name: WikiSysop
passwd: erin

3. mysql database:
user ID: root
passwd: erin

B. Configuration
here is a very detailed configuration settings README
http://www.mediawiki.org/wiki/Manual:Configuration_settings

How to: Install Apache, PHP, PEAR, MySQL & phpMyAdmin for Windows XP
http://www.sematopia.com/?p=28

C. Sending email
Set email configuration for mediawiki & wamp:

1. modify settings in C:\wamp\www\mediawiki\LocalSettings.php
$wgEnableEmail = true;
$wgEnableUserEmail = true;

2. modify SMTP mode settings in C:\wamp\www\mediawiki\include\DefaultSettings.php

$wgSMTP = array(
"host" => ' gmail.google.com',
"IDHost" => ' gmail.google.com ',
"port" => "25",
"auth" => false,
#"username" => "my_user_name",
#"password" => "my_password"
);

3. add PEAR in C:\wamp\www\mediawiki\LocalSettings.php

$IP = "C:\\wamp\\www\\mediawiki";
$setPHPPEAR = "C:\\wamp\\php\\PEAR";
ini_set( "include_path", ".;$IP;$IP/includes;$IP/languages;$setPHPPEAR;" );

if you meet the problem like cannot find Mail.php or Net_SMTP.php, it's probably coz of PEAR modules.

4. check the pear folder first, it should be in C:\wamp\php\PEAR

5. run go-pear in windows command prompt
> cd c:\wamp\php
> go-pear.bat

6. install Mail and NET_SMTP modules in pear
> cd c:\wamp\php\
> pear install mail
> pear install NET_SMTP

7. restart all services in wamp