Is Mojolicious web only?

07b86e788c12e66f05d3bb7099aa1967?s=47 Renee
March 07, 2019

Is Mojolicious web only?

07b86e788c12e66f05d3bb7099aa1967?s=128

Renee

March 07, 2019
Tweet

Transcript

  1. None
  2. Is Mojolicious web only?

  3. None
  4. Reinventing the wheel

  5. Parser for ... JSON, HTML, HTTP

  6. Object orientation

  7. Moose, Mouse, Mu, Moo, Mo

  8. Mojo::Base -base

  9. #!/usr/bin/env perl use Mojolicious::Lite; push @{ app->plugins->namespaces }, 'PerlServices::Plugin'; plugin

    'Ticket' => app->config->{otrs}; app->defaults( bodyclass => 'start', active => 'home', ); get '/' => 'static/index'; get '/imprint' => 'static/imprint'; get '/privacy' => 'static/privacy'; get '/jobs' => 'static/jobs'; under '/otrs' => sub { shift->stash(bodyclass => 'otrs', active => 'otrs'); return 1; }; get '/' => 'static/otrs'; get '/support' => 'static/otrs-support'; get '/development' => 'static/otrs-development'; under '/perl' => sub { shift->stash(bodyclass => 'perl', active => 'perl'); return 1; } get '/' => 'static/perl'; under '/academy' => sub { shift->stash(bodyclass => 'schulung',active => 'academy'); return 1; }; get '/' => 'static/academy'; under '/' => sub { my $c = shift; $c->stash( errors => {}, values => {}, ); return 1; }; get '/kontakt.cgi' => 'contact/form'; post '/kontakt.cgi' => \&_send_contact_request; post '/get-in-touch' => \&_send_contact_request; under '/'; any '/*anything' => sub { my $c = shift; $c->redirect_to( '/' ); }; app->start;
  10. Mojo == Web ?

  11. None
  12. None
  13. $ perl -Mojo -E ' say g("https://act.yapc.eu/gpw2019/talk/7601") ->dom ->at("#talk_abstract") ->text

    '
  14. $ perl -Mojo -E ' say g("https://act.yapc.eu/gpw2019/talk/7601") ->dom ->at("#talk_abstract") ->text

    '
  15. $ perl -Mojo -E ' say g("https://act.yapc.eu/gpw2019/talk/7601") ->dom ->at("#talk_abstract") ->text

    ' Mojolicious ist ein tolles Webframework f�r Perl. Aber kann es auch mehr? Ein paar Anwendungsf�lle werde ich im Vortrag zeigen...
  16. $ perl -Mojo -E ' say p("https://api.hetzner.cloud/v1/servers" => { Authorization

    => "Bearer <APITOKEN>" } => json => { name => "Testserver$$", server_type => "cx11", location => "nbg1", image => "ubuntu-18.04" }) ->json("/server/public_net/ipv4/ip")' 116.203.66.1
  17. use Mojo::DOM; use Mojo::File qw(path); my $file = path('./Badge-4er-tmpl.pure.svg'); my

    @user_pages = _get_gpw_users(); my $page_nr = 0; for my $page ( @user_pages ) { my $dom = Mojo::DOM->new( $file->slurp ); for my $i ( 0 .. 3 ) { say sprintf "Set name %s...", $name; $dom->find('#firstname-' . ($i+1) )->first->content( $firstname ); $dom->find('#lastname-' . ($i+1) )->first->content( $page->[$i]->[2] ); } path('./Badges/Badge.page' . ++$page_nr . '.svg')->spurt( "$dom" ); }
  18. use Mojo::DOM; use Mojo::File qw(path); my $file = path('./Badge-4er-tmpl.pure.svg'); my

    @user_pages = _get_gpw_users(); my $page_nr = 0; for my $page ( @user_pages ) { my $dom = Mojo::DOM->new( $file->slurp ); for my $i ( 0 .. 3 ) { say sprintf "Set name %s...", $name; $dom->find('#firstname-' . ($i+1) )->first->content( $firstname ); $dom->find('#lastname-' . ($i+1) )->first->content( $page->[$i]->[2] ); } path('./Badges/Badge.page' . ++$page_nr . '.svg')->spurt( "$dom" ); }
  19. use Mojo::DOM; use Mojo::File qw(path); my $file = path('./Badge-4er-tmpl.pure.svg'); my

    @user_pages = _get_gpw_users(); my $page_nr = 0; for my $page ( @user_pages ) { my $dom = Mojo::DOM->new( $file->slurp ); for my $i ( 0 .. 3 ) { say sprintf "Set name %s...", $name; $dom->find('#firstname-' . ($i+1) )->first->content( $firstname ); $dom->find('#lastname-' . ($i+1) )->first->content( $page->[$i]->[2] ); } path('./Badges/Badge.page' . ++$page_nr . '.svg')->spurt( "$dom" ); }
  20. CLI

  21. $ perl -Mojo -E ' say g("https://act.yapc.eu/gpw2019/talk/7601") ->dom ->at("#talk_abstract") ->text

    ' Mojolicious ist ein tolles Webframework f�r Perl. Aber kann es auch mehr? Ein paar Anwendungsf�lle werde ich im Vortrag zeigen...
  22. $ mojo get https://act.yapc.eu/gpw2019/talk/7601 \ '#talk_abstract' text Mojolicious ist ein

    tolles Webframework für Perl. Aber kann es auch mehr? Ein paar Anwendungsfälle werde ich im Vortrag zeigen...
  23. $ mojo get https://act.yapc.eu/gpw2019/talks 'td > a[href^="/gpw2019/talk"] > b' text

    Supercharging Math Modules with Databases WebPerl - Perl im Browser! und goto ist sooo nützlich Eine nützliche Quelle für Perl-Code: MySQL Workbench Mojolicious nur für's Web? Schaun wir mal... Darf der das? Regelbasierte Autorisierung in Catalyst Parsen mit Zuversicht Finding humans to turn into developers Gitlab und Perl – Ein Erfahrungsbericht II Mein Jahr mit der DSGVO Moving Mountains With Perl Emacs für Perl-Sourcen: Kleine Tricks Willkommen in München - Welcome to Munich Auf Wiedersehen - vielleicht beim 22. Deutschen Perl-Workshop? Einführung in Encoding mit Perl Was ich beim Advent Of Code 2018 gelernt habe Vue.js for Perl hackers Deploying Perl Apps using Docker, Gitlab & Kubernetes Hacker haben unsere Login-Daten. Was tun wir? Du kannst den Planeten retten. Wie wäre es mit heute Nachmittag? Fun with Macros The Camel Paradox Was ich über SQL gelernt habe Git Tips & Tricks Perl meetup HOWTO session TPF Update node.js in perl - event driven programming including promises via perl/POE static linking of perl OBS - Streamline the delivery of your perl project Perl 6 one-liners Creating a compiler in Perl 6 Perl und SSL für Fortgeschrittene Gatekeepers Perl erweitern mit Nim Freifunk - was ist das und wie entsteht die Software Escape analysis and related optimizations for Perl 6 Understanding react, supply, and whenever PullRequest Club Neuigkeiten von Coocook.org Perl at the Chaos Communication Congress Join all the things with DBIC Scanley Cybrick - APT für jedermann EPO Recording Kits Debugging ist bunt! PerlCon 2019
  24. mojo version mojo generate lite_app ...

  25. App::Cmd MooX::Cmd ...

  26. Mojolicious::Commands

  27. gpw add 2019 gpw update 2019 gpw show 2019 gpw

    talks 2019 gpw talk 7106
  28. WIP

  29. #!/usr/bin/perl use Mojolicious::Lite; app->plugin( JSONConfig => { file => app->home->child('..',

    'conf', 'gpw.json'), }); app->plugins->namespaces(['App::GPW::Plugin']); app->commands->namespaces(['App::GPW::Cmd']); app->plugin( 'Utils' ); Mojo::IOLoop->start if !Mojo::IOLoop->is_running; my $gpw = $app;
  30. package App::GPW; use Mojo::Base 'Mojolicious', -strict; sub startup { my

    $app = shift; $app->plugin( JSONConfig => { file => $app->home->child('conf', 'gpw.json'), }); $app->plugins->namespaces(['App::GPW::Plugin']); $app->commands->namespaces(['App::GPW::Cmd']); $app->plugin( 'Utils' ); } 1;
  31. package App::GPW; use Mojo::Base 'Mojolicious', -strict; sub startup { my

    $app = shift; $app->plugin( JSONConfig => { file => $app->home->child('conf', 'gpw.json'), }); $app->plugins->namespaces(['App::GPW::Plugin']); $app->commands->namespaces(['App::GPW::Cmd']); $app->plugin( 'Utils' ); } 1;
  32. package App::GPW::Plugin::Utils; use Mojo::Base 'Mojolicious::Plugin', -signatures; # … infrastructure code

    … sub register ( $self, $app, $config ) { for my $attr ( qw(...) ) { next if !$config->{$attr}; $self->$attr( $config->{$attr} ); } $app->helper( 'gpw.directory' => sub { $self->_directory( @_ ); } ); $app->helper( 'gpw.workshop' => sub { $self->_new_workshop( @_ ); } ); } 1;
  33. package App::GPW::Plugin::Utils; use Mojo::Base 'Mojolicious::Plugin', -signatures; # … infrastructure code

    … sub register ( $self, $app, $config ) { for my $attr ( qw(...) ) { next if !$config->{$attr}; $self->$attr( $config->{$attr} ); } $app->helper( 'gpw.directory' => sub { $self->_directory( @_ ); } ); $app->helper( 'gpw.workshop' => sub { $self->_new_workshop( @_ ); } ); } 1;
  34. package App::GPW; use Mojo::Base 'Mojolicious', -strict; sub startup { my

    $app = shift; $app->plugin( JSONConfig => { file => $app->home->child('conf', 'gpw.json'), }); $app->plugins->namespaces(['App::GPW::Plugin']); $app->commands->namespaces(['App::GPW::Cmd']); $app->plugin( 'Utils' ); } 1;
  35. package App::GPW::Cmd::add; use Mojo::Base 'Mojolicious::Command', -signatures; use Try::Tiny; sub run

    ($self, @args) { my $app = $self->app; my $year = shift @args; $app->log->debug( "Add $year workshop" ); my $error; try { $app->gpw->workshop( $year ); } catch { $error = $_; $app->log->warn( "Cannot add gpw: $_" ); }; return 0 if $error; return 1; } 1;
  36. $ perl bin/gpw add 2018 [2019-03-04 19:33:25.42306] [10000] [debug] Add

    2018 workshop [2019-03-04 19:33:25.42345] [10000] [debug] Get list of talks... [2019-03-04 19:33:25.44091] [10000] [debug] Create directory for 2018 [2019-03-04 19:33:25.44129] [10000] [debug] Selector: /gpw2018 [2019-03-04 19:33:25.44219] [10000] [debug] Get event info from github [2019-03-04 19:33:25.44227] [10000] [debug] URL: https://r... [2019-03-04 19:33:26.16024] [10000] [debug] { "end" => "2018-04-07 17:00:00", "name" => "Deutscher Perl-Workshop 2018", "start" => "2018-04-03 09:00:00" } [2019-03-04 19:33:27.75339] [10000] [debug] Get talk 7271... [2019-03-04 19:33:27.75420] [10000] [debug] Get talk 7272... [2019-03-04 19:33:27.75457] [10000] [debug] Get talk 7280... [2019-03-04 19:33:27.75490] [10000] [debug] Get talk 7277... [2019-03-04 19:33:27.75522] [10000] [debug] Get talk 7299… $
  37. $ MOJO_MODE=production perl bin/gpw add 2018 $

  38. Mojo „infrastructure“

  39. package App::GPW::Plugin::Utils; use Mojo::Base 'Mojolicious::Plugin', -signatures; use Mojo::File qw(path); use

    Mojo::JSON qw(encode_json); use Mojo::UserAgent; use Config::Tiny; use File::HomeDir; has base_url => sub { 'https://act.yapc.eu/' }; has github_url => sub { 'https://raw.githubusercontent.com/Act-Conferences/' }; has conference => sub { 'gpw' }; has talks_path => sub { '/talks' }; has talk_path => sub { '/talk' };
  40. sub _get_act_info_from_github ($self, $c, $year ) { my $url =

    … ; my $app = $c->app; $app->log->debug( "Get event info from github" ); $app->log->debug( "URL: $url" ); $app->ua->get( $url => {} => sub { my ($ua, $tx) = @_; return if $tx->res->is_error; # ... $self->_directory( $c, $year )->child( 'conference.json' )->spurt( encode_json \%info ); }, ); return 1; }
  41. sub _get_act_info_from_github ($self, $c, $year ) { my $url =

    … ; my $app = $c->app; $app->log->debug( "Get event info from github" ); $app->log->debug( "URL: $url" ); $app->ua->get( $url => {} => sub { my ($ua, $tx) = @_; return if $tx->res->is_error; # ... $self->_directory( $c, $year )->child( 'conference.json' )->spurt( encode_json \%info ); }, ); return 1; }
  42. Reusable for web

  43. package App::GPW::Controller::Conf; use Mojo::Base 'Mojolicious::Controller', -signatures; use Try::Tiny; sub list

    ($c) { my $confs = $c->gpw->list; $c->stash( confs => $confs ); return $c->render( 'index' ); } sub add ($c) { my $year = $c->param('year'); my $app = $c->app; my $success = $app->commands->run('add', $year); return $c->reply->exception if !$success; return $c->redirect_to( $c->url_for('conf-list') ); }
  44. package App::GPW::Controller::Conf; use Mojo::Base 'Mojolicious::Controller', -signatures; use Try::Tiny; sub list

    ($c) { my $confs = $c->gpw->list; $c->stash( confs => $confs ); return $c->render( 'index' ); } sub add ($c) { my $year = $c->param('year'); my $app = $c->app; my $success = $app->commands->run('add', $year); return $c->reply->exception if !$success; return $c->redirect_to( $c->url_for('conf-list') ); }
  45. Mojolicious is not web only...

  46. Questions?

  47. https://github.com/reneeb/App-GPW

  48. Thank you!