• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Building a desktop app with HTTP::Engine, SQLite and jQuery
 

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

on

  • 25,400 views

 

Statistics

Views

Total Views
25,400
Views on SlideShare
8,997
Embed Views
16,403

Actions

Likes
8
Downloads
118
Comments
1

15 Embeds 16,403

http://www.squidoo.com 15824
http://coderwall.com 255
http://remediecode.org 176
http://translate.googleusercontent.com 73
http://webcache.googleusercontent.com 23
http://web.archive.org 19
http://www.mefeedia.com 14
http://www.slideshare.net 12
http://fanyi.youdao.com 1
http://www.google.com.ph 1
http://ww 1
http://answers.onstartups.com 1
http://shieldproxy.com 1
http://localhost:3000 1
http://www.google.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • link to the video?
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Building a desktop app with HTTP::Engine, SQLite and jQuery Building a desktop app with HTTP::Engine, SQLite and jQuery Presentation Transcript

    • Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::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.org Slides/Video in OSDC.TW Wednesday, June 24, 2009
    • Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
    • Desktop GUI apps Wednesday, June 24, 2009
    • MFC/.NET Visual C++,VB Wednesday, June 24, 2009
    • wxWidgets Wednesday, June 24, 2009
    • Objective-C Cocoa (PyObjC/RubyCocoa) Wednesday, June 24, 2009
    • Adobe AIR Wednesday, June 24, 2009
    • I’m a Perl guy who 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
    • PhoneGap Wednesday, June 24, 2009
    • HTML5 geolocation, 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 Miyagawa YAPC::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 Rack Python’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 Ajax backend 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
    • Authentication Special Headers Switch to JSONRPC Wednesday, June 24, 2009
    • Bonjour (based on HTTP::Server::Simple::Bonjour) Wednesday, June 24, 2009
    • Auto Discovery Share subscriptions Wednesday, June 24, 2009
    • Wednesday, June 24, 2009
    • Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
    • SQL DB choices Wednesday, June 24, 2009
    • MySQL/PostgreSQL Good 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 schema Few 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, MongoDB TokyoTyrant (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::Class Rose::DB::Object Wednesday, June 24, 2009
    • Rose::DB::Object (I wanted some excuse) Wednesday, June 24, 2009
    • See Also: KiokuDB Wednesday, June 24, 2009
    • KiokuDB DBI / SQLite backend Key-Value JSPON Wednesday, June 24, 2009
    • Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
    • Just use normal HTML and 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 stuff like Drag & Drop Wednesday, June 24, 2009
    • jQuery.blockUI jQuery.scrollTo jQuery.jgrowl Wednesday, June 24, 2009
    • Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::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
    • Fluid Prism Wednesday, June 24, 2009
    • Wednesday, June 24, 2009
    • Customize Userscripts / Userstyles Wednesday, June 24, 2009
    • Fluid hooks Growl integration Dock menu Wednesday, June 24, 2009
    • Wednesday, June 24, 2009
    • Client-Server Decoupled via APIs Wednesday, June 24, 2009
    • More Clients More “Views” Wednesday, June 24, 2009
    • iPhone Wednesday, June 24, 2009
    • Wednesday, June 24, 2009
    • Wednesday, June 24, 2009
    • 120 lines of HTML/JS using iUI project Wednesday, June 24, 2009
    • Server as “app” Wednesday, June 24, 2009
    • Packaging a server Wednesday, June 24, 2009
    • local::lib build & install all deps Wednesday, June 24, 2009
    • Also: Shipwright Wednesday, June 24, 2009
    • Platypus Make .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