SlideShare une entreprise Scribd logo
1  sur  112
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Tatsuhiko Miyagawa
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9Ilya Grigorik
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpmsom_nangia
 
Web frameworks don't matter
Web frameworks don't matterWeb frameworks don't matter
Web frameworks don't matterTomas Doran
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webWallace Reis
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in PerlNaveen Gupta
 
"Swoole: double troubles in c", Alexandr Vronskiy
"Swoole: double troubles in c", Alexandr Vronskiy"Swoole: double troubles in c", Alexandr Vronskiy
"Swoole: double troubles in c", Alexandr VronskiyFwdays
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mrubyHiroshi SHIBATA
 
DevOps tools for everyone - Vagrant, Puppet and Webmin
DevOps tools for everyone - Vagrant, Puppet and WebminDevOps tools for everyone - Vagrant, Puppet and Webmin
DevOps tools for everyone - Vagrant, Puppet and Webminpostrational
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with PerlDave Cross
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.catPablo Godel
 
Webinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.jsWebinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.jsMongoDB
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Zend by Rogue Wave Software
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyLaunchAny
 

Tendances (20)

Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011Deploying Plack Web Applications: OSCON 2011
Deploying Plack Web Applications: OSCON 2011
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Psgi Plack Sfpm
Psgi Plack SfpmPsgi Plack Sfpm
Psgi Plack Sfpm
 
Web frameworks don't matter
Web frameworks don't matterWeb frameworks don't matter
Web frameworks don't matter
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento web
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Web Development in Perl
Web Development in PerlWeb Development in Perl
Web Development in Perl
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
"Swoole: double troubles in c", Alexandr Vronskiy
"Swoole: double troubles in c", Alexandr Vronskiy"Swoole: double troubles in c", Alexandr Vronskiy
"Swoole: double troubles in c", Alexandr Vronskiy
 
How to test code with mruby
How to test code with mrubyHow to test code with mruby
How to test code with mruby
 
DevOps tools for everyone - Vagrant, Puppet and Webmin
DevOps tools for everyone - Vagrant, Puppet and WebminDevOps tools for everyone - Vagrant, Puppet and Webmin
DevOps tools for everyone - Vagrant, Puppet and Webmin
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
Modern Web Development with Perl
Modern Web Development with PerlModern Web Development with Perl
Modern Web Development with Perl
 
Deploying Symfony | symfony.cat
Deploying Symfony | symfony.catDeploying Symfony | symfony.cat
Deploying Symfony | symfony.cat
 
Webinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.jsWebinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.js
 
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018) Speed up web APIs with Expressive and Swoole (PHP Day 2018)
Speed up web APIs with Expressive and Swoole (PHP Day 2018)
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 

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

Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AnglePablo Godel
 
And the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceAnd the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceBen Scofield
 
Xopus Application Framework
Xopus Application FrameworkXopus Application Framework
Xopus Application FrameworkJady Yang
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebMikel Torres Ugarte
 
関西アンカンファレンス PHP ではじめるテストコード
関西アンカンファレンス PHP ではじめるテストコード関西アンカンファレンス PHP ではじめるテストコード
関西アンカンファレンス PHP ではじめるテストコードShinya Ohyanagi
 
Intro to PHP Testing
Intro to PHP TestingIntro to PHP Testing
Intro to PHP TestingRan Mizrahi
 
Node js实践
Node js实践Node js实践
Node js实践jay li
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Building Smart Workflows - Dan Diebolt
Building Smart Workflows - Dan DieboltBuilding Smart Workflows - Dan Diebolt
Building Smart Workflows - Dan DieboltQuickBase, Inc.
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectJonathan Wage
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Ondřej Machulda
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch
 

Similaire à Building a desktop app with HTTP::Engine, SQLite and jQuery (20)

Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New Angle
 
And the Greatest of These Is ... Space
And the Greatest of These Is ... SpaceAnd the Greatest of These Is ... Space
And the Greatest of These Is ... Space
 
Xopus Application Framework
Xopus Application FrameworkXopus Application Framework
Xopus Application Framework
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 
関西アンカンファレンス PHP ではじめるテストコード
関西アンカンファレンス PHP ではじめるテストコード関西アンカンファレンス PHP ではじめるテストコード
関西アンカンファレンス PHP ではじめるテストコード
 
Intro to PHP Testing
Intro to PHP TestingIntro to PHP Testing
Intro to PHP Testing
 
Node js实践
Node js实践Node js实践
Node js实践
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 
HTML 5 - Overview
HTML 5 - OverviewHTML 5 - Overview
HTML 5 - Overview
 
Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Sprockets
SprocketsSprockets
Sprockets
 
Building Smart Workflows - Dan Diebolt
Building Smart Workflows - Dan DieboltBuilding Smart Workflows - Dan Diebolt
Building Smart Workflows - Dan Diebolt
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 

Plus de Tatsuhiko Miyagawa

Plus de Tatsuhiko Miyagawa (17)

Carton CPAN dependency manager
Carton CPAN dependency managerCarton CPAN dependency manager
Carton CPAN dependency manager
 
cpanminus at YAPC::NA 2010
cpanminus at YAPC::NA 2010cpanminus at YAPC::NA 2010
cpanminus at YAPC::NA 2010
 
CPAN Realtime feed
CPAN Realtime feedCPAN Realtime feed
CPAN Realtime feed
 
Asynchronous programming with AnyEvent
Asynchronous programming with AnyEventAsynchronous programming with AnyEvent
Asynchronous programming with AnyEvent
 
Remedie OSDC.TW
Remedie OSDC.TWRemedie OSDC.TW
Remedie OSDC.TW
 
Why Open Matters It Pro Challenge 2008
Why Open Matters It Pro Challenge 2008Why Open Matters It Pro Challenge 2008
Why Open Matters It Pro Challenge 2008
 
20 modules i haven't yet talked about
20 modules i haven't yet talked about20 modules i haven't yet talked about
20 modules i haven't yet talked about
 
Web::Scraper for SF.pm LT
Web::Scraper for SF.pm LTWeb::Scraper for SF.pm LT
Web::Scraper for SF.pm LT
 
Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8
 
Web::Scraper
Web::ScraperWeb::Scraper
Web::Scraper
 
XML::Liberal
XML::LiberalXML::Liberal
XML::Liberal
 
Test::Base
Test::BaseTest::Base
Test::Base
 
Hacking Vox and Plagger
Hacking Vox and PlaggerHacking Vox and Plagger
Hacking Vox and Plagger
 
Plagger the duct tape of internet
Plagger the duct tape of internetPlagger the duct tape of internet
Plagger the duct tape of internet
 
Tilting Google Maps and MissileLauncher
Tilting Google Maps and MissileLauncherTilting Google Maps and MissileLauncher
Tilting Google Maps and MissileLauncher
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
How we build Vox
How we build VoxHow we build Vox
How we build Vox
 

Dernier

Business Model Canvas (BMC)- A new venture concept
Business Model Canvas (BMC)-  A new venture conceptBusiness Model Canvas (BMC)-  A new venture concept
Business Model Canvas (BMC)- A new venture conceptP&CO
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876dlhescort
 
RSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataRSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataExhibitors Data
 
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...daisycvs
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...Aggregage
 
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLJAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLkapoorjyoti4444
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...amitlee9823
 
Falcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business GrowthFalcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business GrowthFalcon investment
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...amitlee9823
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwaitdaisycvs
 
Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1kcpayne
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsP&CO
 
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangaloreamitlee9823
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...amitlee9823
 
Famous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st CenturyFamous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st Centuryrwgiffor
 
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...Sheetaleventcompany
 
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Sheetaleventcompany
 

Dernier (20)

Business Model Canvas (BMC)- A new venture concept
Business Model Canvas (BMC)-  A new venture conceptBusiness Model Canvas (BMC)-  A new venture concept
Business Model Canvas (BMC)- A new venture concept
 
Falcon Invoice Discounting platform in india
Falcon Invoice Discounting platform in indiaFalcon Invoice Discounting platform in india
Falcon Invoice Discounting platform in india
 
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
Call Girls in Delhi, Escort Service Available 24x7 in Delhi 959961-/-3876
 
RSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataRSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors Data
 
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
Quick Doctor In Kuwait +2773`7758`557 Kuwait Doha Qatar Dubai Abu Dhabi Sharj...
 
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
The Path to Product Excellence: Avoiding Common Pitfalls and Enhancing Commun...
 
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRLJAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
JAYNAGAR CALL GIRL IN 98274*61493 ❤CALL GIRLS IN ESCORT SERVICE❤CALL GIRL
 
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
Call Girls Jp Nagar Just Call 👗 7737669865 👗 Top Class Call Girl Service Bang...
 
Falcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business GrowthFalcon Invoice Discounting: Empowering Your Business Growth
Falcon Invoice Discounting: Empowering Your Business Growth
 
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
Nelamangala Call Girls: 🍓 7737669865 🍓 High Profile Model Escorts | Bangalore...
 
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
(Anamika) VIP Call Girls Napur Call Now 8617697112 Napur Escorts 24x7
 
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai KuwaitThe Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
The Abortion pills for sale in Qatar@Doha [+27737758557] []Deira Dubai Kuwait
 
Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1Katrina Personal Brand Project and portfolio 1
Katrina Personal Brand Project and portfolio 1
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and pains
 
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service BangaloreCall Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
Call Girls Hebbal Just Call 👗 7737669865 👗 Top Class Call Girl Service Bangalore
 
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
Call Girls Kengeri Satellite Town Just Call 👗 7737669865 👗 Top Class Call Gir...
 
Famous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st CenturyFamous Olympic Siblings from the 21st Century
Famous Olympic Siblings from the 21st Century
 
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
Call Girls Zirakpur👧 Book Now📱7837612180 📞👉Call Girl Service In Zirakpur No A...
 
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
Chandigarh Escorts Service 📞8868886958📞 Just📲 Call Nihal Chandigarh Call Girl...
 

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

  • 1. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 6. 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
  • 7. twitter.com/miyagawa (Slides will be linked. Follow me!) Wednesday, June 24, 2009
  • 9. remediecode.org Slides/Video in OSDC.TW Wednesday, June 24, 2009
  • 10. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 12. MFC/.NET Visual C++,VB Wednesday, June 24, 2009
  • 14. Objective-C Cocoa (PyObjC/RubyCocoa) Wednesday, June 24, 2009
  • 16. I’m a Perl guy who knows JavaScript. Wednesday, June 24, 2009
  • 19. “Web 2.0 iPhone App” Steve Jobs at WWDC 2007 Wednesday, June 24, 2009
  • 22. HTML5 geolocation, videos local storage Wednesday, June 24, 2009
  • 23. HTML5 = Future ??? = 2009 Wednesday, June 24, 2009
  • 24. micro Web app = 2009 Wednesday, June 24, 2009
  • 25. (2 min Demo video) Wednesday, June 24, 2009
  • 26. How I built this Wednesday, June 24, 2009
  • 27. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 28. “The most important project in Perl recently” - jrockway Wednesday, June 24, 2009
  • 29. Based on Catalyst::Engine Wednesday, June 24, 2009
  • 30. Ruby’s Rack Python’s WSGI Wednesday, June 24, 2009
  • 31. 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
  • 32. sub handle_request {     my $req = shift;     return HTTP::Engine::Response‐>new(         body => “Hello World”,     ); } Wednesday, June 24, 2009
  • 33. Standalone, ServerSimple, POE, FastCGI, mod_perl Wednesday, June 24, 2009
  • 34. Desktop app: ServerSimple POE (non-blocking) Wednesday, June 24, 2009
  • 35. Serve static files (HTML/CSS/JS) Wednesday, June 24, 2009
  • 36. 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
  • 37. 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
  • 38. See Also: HTTP::Engine::Middleware::Static Wednesday, June 24, 2009
  • 39. Implement Ajax backend actions (JSON-REST) Wednesday, June 24, 2009
  • 40. 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
  • 41. 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
  • 42. Problem (1): Dirty API routing Wednesday, June 24, 2009
  • 43. Path::Router, Path::Dispatcher, HTTP::Dispatcher, JSORB Wednesday, June 24, 2009
  • 44. Problem (2): Vulnerable (CSRF) Wednesday, June 24, 2009
  • 45. Authentication Special Headers Switch to JSONRPC Wednesday, June 24, 2009
  • 46. Bonjour (based on HTTP::Server::Simple::Bonjour) Wednesday, June 24, 2009
  • 47. Auto Discovery Share subscriptions Wednesday, June 24, 2009
  • 49. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 50. SQL DB choices Wednesday, June 24, 2009
  • 51. MySQL/PostgreSQL Good for Web apps. Wednesday, June 24, 2009
  • 52. SQLite: file-based, type-less Transactional Wednesday, June 24, 2009
  • 53. SQLite: best for desktop apps Wednesday, June 24, 2009
  • 54. SQLite for desktop: Firefox, Mail.app, iCal Wednesday, June 24, 2009
  • 55. End-users don’t want to run *SQL server Wednesday, June 24, 2009
  • 56. Bonus: Easy backup, Dropbox sync Wednesday, June 24, 2009
  • 58. You don’t need DBA. Make it simple, flexible and extensible. Wednesday, June 24, 2009
  • 59. Remedie schema Few indexes JSON key-values Wednesday, June 24, 2009
  • 60. 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
  • 61. 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
  • 63. CouchDB, MongoDB TokyoTyrant (Need servers though) Wednesday, June 24, 2009
  • 67. DBIx::Class Rose::DB::Object Wednesday, June 24, 2009
  • 68. Rose::DB::Object (I wanted some excuse) Wednesday, June 24, 2009
  • 69. See Also: KiokuDB Wednesday, June 24, 2009
  • 70. KiokuDB DBI / SQLite backend Key-Value JSPON Wednesday, June 24, 2009
  • 71. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 72. Just use normal HTML and CSS to design UI Wednesday, June 24, 2009
  • 73. Manipulate DOM $.ajax to do Ajax Wednesday, June 24, 2009
  • 76. $("#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
  • 78. $(document).bind(‘keydown’, ‘shift+n’, function(ev){    // ‘N’ is entered }); Wednesday, June 24, 2009
  • 83. $.event.trigger $(document).bind Wednesday, June 24, 2009
  • 85. Fancy stuff like Drag & Drop Wednesday, June 24, 2009
  • 86. jQuery.blockUI jQuery.scrollTo jQuery.jgrowl Wednesday, June 24, 2009
  • 87. Building a desktop app with HTTP::Engine, SQLite & jQuery Tatsuhiko Miyagawa YAPC::NA 2009 Pittsburgh Wednesday, June 24, 2009
  • 88. More like “Desktop app” Wednesday, June 24, 2009
  • 90. Web Client as “app” Wednesday, June 24, 2009
  • 92. Fluid Prism Wednesday, June 24, 2009
  • 94. Customize Userscripts / Userstyles Wednesday, June 24, 2009
  • 95. Fluid hooks Growl integration Dock menu Wednesday, June 24, 2009
  • 97. Client-Server Decoupled via APIs Wednesday, June 24, 2009
  • 98. More Clients More “Views” Wednesday, June 24, 2009
  • 102. 120 lines of HTML/JS using iUI project Wednesday, June 24, 2009
  • 105. local::lib build & install all deps Wednesday, June 24, 2009
  • 106. Also: Shipwright Wednesday, June 24, 2009
  • 107. Platypus Make .app Wednesday, June 24, 2009
  • 108. Download .zip, copy .app to /Applications, Run it. Wednesday, June 24, 2009
  • 109. Also: github.com/miyagawa/perl-app-builder Wednesday, June 24, 2009
  • 110. 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
  • 111. That’s it! Questions? Wednesday, June 24, 2009
  • 112. Thank you! twitter.com/miyagawa Wednesday, June 24, 2009