building a desktop app with http::engine, sqlite and jquery

Post on 20-Jan-2015

22.754 Views

Category:

Business

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

Tatsuhiko Miyagawa

Wednesday, June 24, 2009

Wednesday, June 24, 2009

Software Engineer, TypePad

Wednesday, June 24, 2009

cpan: MIYAGAWA

Wednesday, June 24, 2009

Acme-DateTime-Duration-Numeric Acme-Module-Authors Acme-Sneeze Acme-Sneeze-JP Apache-ACEProxy Apache-AntiSpam Apache-Clickable Apache-CustomKeywords Apache-DefaultCharset Apache-GuessCharset Apache-JavaScript-

DocumentWrite Apache-No404Proxy Apache-Profiler Apache-Session-CacheAny Apache-Session-Generate-ModUniqueId Apache-Session-Generate-ModUsertrack Apache-Session-PHP Apache-Session-Serialize-YAML Apache-Singleton Apache-StickyQuery Archive-Any-Create Attribute-Profiled Attribute-Protected Attribute-Unimplemented Bundle-Sledge CGI-

Untaint-email CPAN-Mini-Growl Catalyst-Plugin-Authentication-Credential-AOL Catalyst-Plugin-Authentication-Credential-OpenID Catalyst-Plugin-JSONRPC Catalyst-View-JSON Catalyst-View-Jemplate Class-DBI-AbstractSearch Class-DBI-

Extension Class-DBI-Pager Class-DBI-Replication Class-DBI-SQLite Class-DBI-View Class-Trigger Convert-Base32 Convert-DUDE Convert-RACE Data-YUID Date-Japanese-Era Date-Range-Birth DateTime-Span-Birthdate Device-KeyStroke-Mobile Dunce-time Email-Find Email-Valid-Loose Encode-DoubleEncodedUTF8 Encode-First Encode-JP-Mobile Encode-JavaScript-

UCS Encode-Punycode File-Find-Rule-Digest File-Spotlight Geo-Coder-Google HTML-AutoPagerize HTML-Entities-ImodePictogram HTML-RelExtor HTML-ResolveLink HTML-Selector-XPath HTML-XSSLint HTTP-MobileAgent HTTP-ProxyPAC HTTP-Server-Simple-Authen HTTP-Server-Simple-Bonjour IDNA-Punycode Inline-Basic Inline-TT JSON-Syck

Kwiki-Emoticon Kwiki-Export Kwiki-Footnote Kwiki-OpenSearch Kwiki-OpenSearch-Service Kwiki-TypeKey Kwiki-URLBL LWP-UserAgent-Keychain Lingua-JA-Hepburn-Passport Log-Dispatch-Config Log-Dispatch-DBI MSIE-MenuExt Mac-

Macbinary Mail-Address-MobileJp Mail-ListDetector-Detector-Fml Module-Install-Repository Net-DAAP-Server-AAC Net-IDN-Nameprep Net-IPAddr-Find Net-Twitter-OAuth Net-YahooMessenger NetAddr-IP-Find P2P-Transmission-Remote PHP-Session POE-Component-Client-AirTunes POE-Component-Client-Lingr POE-Component-YahooMessenger Path-

Class-URI Plagger RPC-XML-Parser-LibXML Template-Plugin-Clickable Template-Plugin-Comma Template-Plugin-FillInForm Template-Plugin-HTML-Template Template-Plugin-JavaScript Template-Plugin-MobileAgent Template-Plugin-ResolveLink

Template-Plugin-Shuffle Template-Provider-Encoding Term-Encoding Term-TtyRec Test-Synopsis Text-Emoticon Text-Emoticon-GoogleTalk Text-Emoticon-MSN Text-Emoticon-Yahoo Text-MessageFormat TheSchwartz-Simple Time-Duration-Parse Time-Duration-ja URI-Find-UTF8 URI-git URI-tag URI-urn-uuid Video-Subtitle-SRT WWW-Baseball-NPB WWW-Blog-Metadata-MobileLinkDiscovery WWW-Blog-Metadata-OpenID WWW-Blog-Metadata-OpenSearch WWW-Cache-Google

WWW-Mechanize-AutoPager WWW-Mechanize-DecodedContent WWW-NicoVideo-Download WWW-OpenSearch WWW-Shorten-RevCanonical WWW-Shorten-Simple Web-Scraper Web-oEmbed WebService-Bloglines WebService-ChangesXml WebService-Google-Suggest WebService-Lingr XML-Atom XML-Atom-Lifeblog XML-Atom-Stream XML-

Liberal XML-OPML-LibXML abbreviation autobox-DateTime-Duration capitalization plagger

Wednesday, June 24, 2009

twitter.com/miyagawa(Slides will be linked. Follow me!)

Wednesday, June 24, 2009

Remedie

Wednesday, June 24, 2009

remediecode.orgSlides/Video in OSDC.TW

Wednesday, June 24, 2009

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

Desktop GUI apps

Wednesday, June 24, 2009

MFC/.NETVisual C++, VB

Wednesday, June 24, 2009

wxWidgets

Wednesday, June 24, 2009

Objective-CCocoa

(PyObjC/RubyCocoa)

Wednesday, June 24, 2009

Adobe AIR

Wednesday, June 24, 2009

I’m a Perl guywho knows JavaScript.

Wednesday, June 24, 2009

Web Developers!Wednesday, June 24, 2009

Web app!

Wednesday, June 24, 2009

“Web 2.0 iPhone App”Steve Jobs at WWDC 2007

Wednesday, June 24, 2009

Wednesday, June 24, 2009

PhoneGapWednesday, June 24, 2009

HTML5geolocation, videos

local storage

Wednesday, June 24, 2009

HTML5 = Future??? = 2009

Wednesday, June 24, 2009

micro Web app = 2009

Wednesday, June 24, 2009

(2 min Demo video)Wednesday, June 24, 2009

How I built this

Wednesday, June 24, 2009

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

“The most important project in Perl recently”

- jrockway

Wednesday, June 24, 2009

Based on Catalyst::Engine

Wednesday, June 24, 2009

Ruby’s RackPython’s WSGI

Wednesday, June 24, 2009

use HTTP::Engine;my $engine = HTTP::Engine‐>new(    interface => {        module => 'ServerSimple',        args   => {            host => 'localhost',            port => 9898,        },    request_handler => \&handle_request,});

$engine‐>run;

Wednesday, June 24, 2009

sub handle_request {    my $req = shift;    return HTTP::Engine::Response‐>new(        body => “Hello World”,    );}

Wednesday, June 24, 2009

Standalone, ServerSimple, POE, FastCGI, mod_perl

Wednesday, June 24, 2009

Desktop app:ServerSimple

POE (non-blocking)

Wednesday, June 24, 2009

Serve static files(HTML/CSS/JS)

Wednesday, June 24, 2009

sub handle_request {    my($self, $req) = @_;

    my $path = $req‐>path;    my $res = HTTP::Engine::Response‐>new;

    if ($path =~ s!^/static/!!) {        $self‐>serve_static_file($path, $req, $res);    };

    return $res;}

Wednesday, June 24, 2009

use Path::Class;sub serve_static_file {    my($self, $path, $req, $res) = @_;

    my $root = $self‐>conf‐>{root};    my $file = file($root, "static", $path);

    my $size  = ‐s _;    my $mtime = (stat(_))[9];    my $ext = ($file =~ /\.(\w+)$/)[0];    $res‐>content_type( MIME::Types‐>new‐>mimeTypeOf($ext)        || "text/plain" );    # ...    open my $fh, "<:raw", $file        or die "$file: $!";    $res‐>headers‐>header('Last‐Modified' =>         HTTP::Date::time2str($mtime));    $res‐>headers‐>header('Content‐Length' => $size);    $res‐>body( join '', <$fh> );}

Wednesday, June 24, 2009

See Also:HTTP::Engine::Middleware::Static

Wednesday, June 24, 2009

Implement Ajaxbackend actions(JSON-REST)

Wednesday, June 24, 2009

sub handle_request {    my($self, $req) = @_;

    my $path = $req‐>path;

    my $res = HTTP::Engine::Response‐>new;

    if ($path =~ s!^/rpc/!!) {        $self‐>dispatch_rpc($path, $req, $res);    }}

Wednesday, June 24, 2009

sub dispatch_rpc {    my($self, $path, $req, $res) = @_;

    my @class  = split '/', $path;    my $method = pop @class;    die "Access to non‐public methods" if $method =~ /^_/;

    my $rpc_class = $self‐>load_rpc_class(\@class);    my $rpc = $rpc_class‐>new( conf => $self‐>conf );    my $result = eval { $rpc‐>$method($req, $res) };

    unless ( $res‐>body ) {        $res‐>status(200);        $res‐>content_type("application/json; charset=utf‐8");        $res‐>body( Remedie::JSON‐>encode($result) );    }}

Wednesday, June 24, 2009

Problem (1):Dirty API routing

Wednesday, June 24, 2009

Path::Router, Path::Dispatcher,HTTP::Dispatcher, JSORB

Wednesday, June 24, 2009

Problem (2):Vulnerable (CSRF)

Wednesday, June 24, 2009

AuthenticationSpecial Headers

Switch to JSONRPC

Wednesday, June 24, 2009

Bonjour(based on HTTP::Server::Simple::Bonjour)

Wednesday, June 24, 2009

Auto DiscoveryShare subscriptions

Wednesday, June 24, 2009

Wednesday, June 24, 2009

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

SQL DB choices

Wednesday, June 24, 2009

MySQL/PostgreSQLGood for Web apps.

Wednesday, June 24, 2009

SQLite:file-based, type-less

Transactional

Wednesday, June 24, 2009

SQLite:best for desktop apps

Wednesday, June 24, 2009

SQLite for desktop:Firefox, Mail.app, iCal

Wednesday, June 24, 2009

End-users don’t want to run *SQL server

Wednesday, June 24, 2009

Bonus:Easy backup,

Dropbox sync

Wednesday, June 24, 2009

DB Schema

Wednesday, June 24, 2009

You don’t need DBA.Make it simple, flexible and extensible.

Wednesday, June 24, 2009

Remedie schemaFew indexes

JSON key-values

Wednesday, June 24, 2009

CREATE TABLE channel (  id      INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,  type    INTEGER NOT NULL,  parent  INTEGER NOT NULL,  ident   TEXT NOT NULL,  name    TEXT NOT NULL,  props   TEXT);

CREATE UNIQUE INDEX channel_ident ON channel (ident);

Wednesday, June 24, 2009

CREATE TABLE item (  id         INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,  channel_id INTEGER NOT NULL,  type       INTEGER NOT NULL,  ident      TEXT NOT NULL,  name       TEXT NOT NULL,  status     INTEGER NOT NULL,  props      TEXT);

CREATE INDEX item_status ON item (status)

CREATE UNIQUE INDEX item_ident ON item (channel_id, ident);

Wednesday, June 24, 2009

Key-Value is HOT

Wednesday, June 24, 2009

CouchDB, MongoDBTokyoTyrant(Need servers though)

Wednesday, June 24, 2009

SQLite for Key-Value

Wednesday, June 24, 2009

ORM?

Wednesday, June 24, 2009

Anything you like.

Wednesday, June 24, 2009

DBIx::ClassRose::DB::Object

Wednesday, June 24, 2009

Rose::DB::Object(I wanted some excuse)

Wednesday, June 24, 2009

See Also:KiokuDB

Wednesday, June 24, 2009

KiokuDBDBI / SQLite backend

Key-Value JSPON

Wednesday, June 24, 2009

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

Just use normal HTMLand CSS to design UI

Wednesday, June 24, 2009

Manipulate DOM$.ajax to do Ajax

Wednesday, June 24, 2009

DOM Manipulation sucks.

Wednesday, June 24, 2009

jQuery.flydom

Wednesday, June 24, 2009

$("#channel‐pane").createAppend(  'div', { className: 'channel‐header',           id: 'channel‐header‐' + channel.id  }, [    'div', { className: 'channel‐header‐thumb' }, [       'img', { src: "/static/images/feed.png",                alt: channel.name }, null    ],  ]);

Wednesday, June 24, 2009

jQuery.hotkeys

Wednesday, June 24, 2009

$(document).bind(‘keydown’, ‘shift+n’, function(ev){   // ‘N’ is entered});

Wednesday, June 24, 2009

jQuery.contextMenu

Wednesday, June 24, 2009

Wednesday, June 24, 2009

jQuery.corners

Wednesday, June 24, 2009

Wednesday, June 24, 2009

$.event.trigger$(document).bind

Wednesday, June 24, 2009

jQuery UI

Wednesday, June 24, 2009

Fancy stufflike Drag & Drop

Wednesday, June 24, 2009

jQuery.blockUIjQuery.scrollTojQuery.jgrowl

Wednesday, June 24, 2009

Building a desktop app with HTTP::Engine, SQLite & jQuery

Tatsuhiko MiyagawaYAPC::NA 2009 Pittsburgh

Wednesday, June 24, 2009

More like“Desktop app”

Wednesday, June 24, 2009

Client-Server

Wednesday, June 24, 2009

Web Client as “app”

Wednesday, June 24, 2009

Site Specific Browser

Wednesday, June 24, 2009

FluidPrism

Wednesday, June 24, 2009

Wednesday, June 24, 2009

CustomizeUserscripts / Userstyles

Wednesday, June 24, 2009

Fluid hooksGrowl integration

Dock menu

Wednesday, June 24, 2009

Wednesday, June 24, 2009

Client-ServerDecoupled via APIs

Wednesday, June 24, 2009

More ClientsMore “Views”

Wednesday, June 24, 2009

iPhone

Wednesday, June 24, 2009

Wednesday, June 24, 2009

Wednesday, June 24, 2009

120 lines of HTML/JSusing iUI project

Wednesday, June 24, 2009

Server as “app”

Wednesday, June 24, 2009

Packaging a server

Wednesday, June 24, 2009

local::libbuild & install all deps

Wednesday, June 24, 2009

Also:Shipwright

Wednesday, June 24, 2009

PlatypusMake .app

Wednesday, June 24, 2009

Download .zip, copy .app to /Applications, Run it.

Wednesday, June 24, 2009

Also:github.com/miyagawa/perl-app-builder

Wednesday, June 24, 2009

Summary

• micro web server as a desktop app

• HTTP::Engine, JSONRPC and router

• SQLite to store key-value

• jQuery plugins to enable desktop UIs

• More tools to make it really “.app”

Wednesday, June 24, 2009

That’s it!Questions?

Wednesday, June 24, 2009

Thank you!twitter.com/miyagawa

Wednesday, June 24, 2009

top related