SlideShare ist ein Scribd-Unternehmen logo
(Ab)Using the
MetaCPAN API for
 Fun and Profit
  Olaf Alders (OALDERS)
     @wundercounter
Architecture


• Built on ElasticSearch
• Uses Catalyst as a thin wrapper
• You don’t need to know this
Real life examples
iCPAN - iPhone
iCPAN - iPad
Android
What can we build?
What can we build?


• Do something with Github
What can we build?


• Do something with Github
• Get a list of all CPAN authors who
  have enabled the “hireable” flag in
  their Github profiles
Let’s Get Started
Let’s Get Started



• We want to fetch some data
Let’s Get Started



• We want to fetch some data
• We’ll use Sawyer’s MetaCPAN::API
#!/usr/bin/env perl

use strict;
use warnings;

use MetaCPAN::API;

my $mcpan = MetaCPAN::API->new();
my $author = $mcpan->author('MSTROUT');
{
    dir            =>   "id/M/MS/MSTROUT",
    email          =>   ["perl-stuff@trout.me.uk"],
    gravatar_url   =>   "https://secure.gravatar.com/avatar/...",
    name           =>   "Matt S Trout",
    pauseid        =>   "MSTROUT",
    website        =>   ["http://www.trout.me.uk/"],
}
MetaCPAN Explorer
my $author = $mcpan->author('MSTROUT');
my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        size => 1,
    },
);
{
    _shards => { failed => 0, successful => 5, total => 5 },
    hits => {
       hits => [
          {
             _id     => "KHAMPTON",
             _index => "cpan_v1",
             _score => 1,
             _source => {
                           city         => "Los Angeles",
                           country      => "US",
                           dir          => "id/K/KH/KHAMPTON",
                           email        => ["khampton@totalcinema.com", "kip.hampton@tamarou.com"],
                           gravatar_url => "http://www.gravatar.com/avatar/...",
                           name         => "Kip Hampton",
                           pauseid      => "KHAMPTON",
                           profile      => [
                                              { id => "ubu", name => "coderwall" },
                                              { id => "ubu", name => "github" },
                                              { id => "kiphampton", name => "twitter" },
                                           ],
                           region       => "CA",
                           updated      => "2011-07-22T20:42:06",
                           website      => ["http://totalcinema.com/"],
                        },
             _type   => "author",
          },
       ],
       max_score => 1,
       total => 9780,
    },
    timed_out => bless(do{(my $o = 0)}, "JSON::XS::Boolean"),
    took => 1,
}
my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        size => 1,
    },
);

# dump $result->{hits}->{hits}->[0]->{_source};
{
  city         =>   "Los Angeles",
  country      =>   "US",
  dir          =>   "id/K/KH/KHAMPTON",
  email        =>   ["khampton@totalcinema.com", "kip.hampton
@tamarou.com"],
  gravatar_url => "http://www.gravatar.com/avatar/...",
  name         => "Kip Hampton",
  pauseid      => "KHAMPTON",
  profile      => [
                     { id => "ubu", name => "coderwall" },
                     { id => "ubu", name => "github" },
                     { id => "kiphampton", name => "twitter" },
                  ],
    region     => "CA",
    updated    => "2011-07-22T20:42:06",
    website    => ["http://totalcinema.com/"],
}
my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        size   => 100,
    },
);
my $filter = {
        { term   => { 'author.profile.name' => 'stackoverflow', } },
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
    },
);
use Pithub;
my $p = Pithub->new;

AUTHOR:
foreach my $author ( @{ $result->{hits}->{hits} } ) {

    foreach my $profile ( @{ $author->{_source}->{profile} } ) {

        if ( $profile->{name} eq 'github' ) {

            my $username = $profile->{id};
            $username =~ s{https?://github.com/(w*)/?}{$1}i;
            next AUTHOR if !$username;

            if ( $p->users->get( user => $username )->content->{hireable} ) {
                # do something...
            }
            next AUTHOR;
        }
    }
}
Getting fancy
my $filter = {
    and => [
        { term   => { 'author.profile.name' => 'github', } },
        { term   => { 'author.country'      => 'US', } }
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
    },
);
my $filter = {
    and => [
        { term     => { 'author.profile.name' => 'github', } },
        { term     => { 'author.country'      => 'US', } },
        { exists   => { 'field'               => 'author.region' } },
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
    },
);
my $filter = {
    and => [
        { term      =>   {   'author.profile.name'   =>   'github', } },
        { term      =>   {   'author.country'        =>   'US', } },
        { exists    =>   {   'field'                 =>   'author.region' } },
        { missing   =>   {   'field'                 =>   'author.location' } },
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
    },
);

# “missing” isn’t really helpful in this search
# just an example of how you might use it
my $filter = {
    or => [
        { term      =>   {   'author.profile.name'   =>   'github', } },
        { term      =>   {   'author.country'        =>   'US', } },
        { exists    =>   {   'field'                 =>   'author.region' } },
        { missing   =>   {   'field'                 =>   'author.location' } },
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
    },
);
my $filter = {
    or => [
        { term      =>   {   'author.profile.name'   =>   'github', } },
        { term      =>   {   'author.country'        =>   'US', } },
        { exists    =>   {   'field'                 =>   'author.region' } },
        { missing   =>   {   'field'                 =>   'author.location' } },
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
        fields => [ 'pauseid', 'country' ],
    },
);
my $filter = {
    or => [
        { term      =>   {   'author.profile.name'   =>   'github', } },
        { term      =>   {   'author.country'        =>   'US', } },
        { exists    =>   {   'field'                 =>   'author.region' } },
        { missing   =>   {   'field'                 =>   'author.location' } },
    ]
};

my $result = $mcpan->post(
    'author',
    {   query => { match_all => {} },
        filter => $filter,
        size   => 100,
        sort   => [ { 'author.pauseid' => 'ASC' } ],
    },
);
Getting Help



• #metacpan or irc.perl.org
• https://metacpan.org/about/resources
Resources


• https://github.com/CPAN-API/cpan-
  api/wiki/Beta-API-docs
• http://www.slideshare.net/
  clintongormley/terms-of-endearment-
  the-elasticsearch-query-dsl-explained
Bonus Slides
Base URL



• http://api.metacpan.org/v0
Convenience Endpoints
Convenience Endpoints

• /author/DOY
• /distribution/Moose
• /release/Moose
• /module/Moose
• /pod/Moose
Exporting Pod


• /pod/Moose?content-type=text/html (default)
• /pod/Moose?content-type=text/plain
• /pod/Moose?content-type=text/x-pod
• /pod/Moose?content-type=text/x-markdown
The (real) Endpoints
The (real) Endpoints
• /author
The (real) Endpoints
• /author
• /distribution
The (real) Endpoints
• /author
• /distribution
• /favorite
The (real) Endpoints
• /author
• /distribution
• /favorite
• /rating
The (real) Endpoints
• /author
• /distribution
• /favorite
• /rating
• /release
The (real) Endpoints
• /author
• /distribution
• /favorite
• /rating
• /release
• /file
The (real) Endpoints
• /author
• /distribution
• /favorite
• /rating
• /release
• /file
Using a cache

use HTTP::Tiny::Mech;
use MetaCPAN::API;
use WWW::Mechanize::Cached;

my $mcpan = MetaCPAN::API->new(
    ua => HTTP::Tiny::Mech->new(
        mechua => WWW::Mechanize::Cached->new()
    )
);
Enable Compression


• use WWW::Mechanize::Gzip
• use WWW::Mechanize::Cached::Gzip
• Or set the appropriate request header
Use the scrolling API


• The scrolling API allows you to iterate
  over an arbitrary number of results
• Be aware that when you scroll, your
  docs will come back unsorted

Weitere ähnliche Inhalte

Was ist angesagt?

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
Chris Reynolds
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
Murray Steele
 
Inc
IncInc
PHP code examples
PHP code examplesPHP code examples
PHP code examples
programmingslides
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helper
slicejack
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
Jeroen Keppens
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
Andrew Shitov
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
wget.pl
wget.plwget.pl
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
Basuke Suzuki
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
ichikaway
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
Basuke Suzuki
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
Ricardo Signes
 
My shell
My shellMy shell
My shell
Ahmed Salah
 
全裸でワンライナー(仮)
全裸でワンライナー(仮)全裸でワンライナー(仮)
全裸でワンライナー(仮)
Yoshihiro Sugi
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
leo lapworth
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
kaushik_sathupadi
 
HappyKardashian.com for #FVCP
HappyKardashian.com for #FVCPHappyKardashian.com for #FVCP
HappyKardashian.com for #FVCP
Eric Michalsen
 

Was ist angesagt? (20)

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
 
My First Ruby
My First RubyMy First Ruby
My First Ruby
 
Inc
IncInc
Inc
 
PHP code examples
PHP code examplesPHP code examples
PHP code examples
 
WordPress Cuztom Helper
WordPress Cuztom HelperWordPress Cuztom Helper
WordPress Cuztom Helper
 
DPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark WorkshopDPC 2012 : PHP in the Dark Workshop
DPC 2012 : PHP in the Dark Workshop
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
wget.pl
wget.plwget.pl
wget.pl
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
 
My shell
My shellMy shell
My shell
 
全裸でワンライナー(仮)
全裸でワンライナー(仮)全裸でワンライナー(仮)
全裸でワンライナー(仮)
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
 
HappyKardashian.com for #FVCP
HappyKardashian.com for #FVCPHappyKardashian.com for #FVCP
HappyKardashian.com for #FVCP
 

Andere mochten auch

Mangling
Mangling Mangling
Mangling
Olaf Alders
 
The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)
Olaf Alders
 
The MetaCPAN VM Part II (Using the VM)
The MetaCPAN VM Part II (Using the VM)The MetaCPAN VM Part II (Using the VM)
The MetaCPAN VM Part II (Using the VM)
Olaf Alders
 
No Hugging, No Learning
No Hugging, No LearningNo Hugging, No Learning
No Hugging, No Learning
Olaf Alders
 
Ab(Using) the MetaCPAN API for Fun and Profit v2013
Ab(Using) the MetaCPAN API for Fun and Profit v2013Ab(Using) the MetaCPAN API for Fun and Profit v2013
Ab(Using) the MetaCPAN API for Fun and Profit v2013
Olaf Alders
 
Git submodule
Git submoduleGit submodule
Git submodule
Olaf Alders
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl Programmers
Dave Cross
 
Medium Perl
Medium PerlMedium Perl
Medium Perl
Dave Cross
 

Andere mochten auch (8)

Mangling
Mangling Mangling
Mangling
 
The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)The MetaCPAN VM for Dummies Part One (Installation)
The MetaCPAN VM for Dummies Part One (Installation)
 
The MetaCPAN VM Part II (Using the VM)
The MetaCPAN VM Part II (Using the VM)The MetaCPAN VM Part II (Using the VM)
The MetaCPAN VM Part II (Using the VM)
 
No Hugging, No Learning
No Hugging, No LearningNo Hugging, No Learning
No Hugging, No Learning
 
Ab(Using) the MetaCPAN API for Fun and Profit v2013
Ab(Using) the MetaCPAN API for Fun and Profit v2013Ab(Using) the MetaCPAN API for Fun and Profit v2013
Ab(Using) the MetaCPAN API for Fun and Profit v2013
 
Git submodule
Git submoduleGit submodule
Git submodule
 
Modern Perl for Non-Perl Programmers
Modern Perl for Non-Perl ProgrammersModern Perl for Non-Perl Programmers
Modern Perl for Non-Perl Programmers
 
Medium Perl
Medium PerlMedium Perl
Medium Perl
 

Ähnlich wie (Ab)Using the MetaCPAN API for Fun and Profit

Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
jhchabran
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
iMasters
 
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
Tatsuhiko Miyagawa
 
Php
PhpPhp
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
clkao
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
brian d foy
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
Wynn Netherland
 
Daily notes
Daily notesDaily notes
Daily notes
meghendra168
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
niklal
 
Ae internals
Ae internalsAe internals
Ae internals
mnikolenko
 
Php functions
Php functionsPhp functions
Php functions
JIGAR MAKHIJA
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
JH Lee
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
Michael Schwern
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
Mark
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
Tom Crinson
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
Kaz Watanabe
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
Jeff Eaton
 

Ähnlich wie (Ab)Using the MetaCPAN API for Fun and Profit (20)

Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
 
WTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio AkitaWTF Oriented Programming, com Fabio Akita
WTF Oriented Programming, com Fabio Akita
 
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
 
Php
PhpPhp
Php
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 
Daily notes
Daily notesDaily notes
Daily notes
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Ae internals
Ae internalsAe internals
Ae internals
 
Php functions
Php functionsPhp functions
Php functions
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
 

Kürzlich hochgeladen

Advanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docxAdvanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docx
adhitya5119
 
Film vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movieFilm vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movie
Nicholas Montgomery
 
How to Fix the Import Error in the Odoo 17
How to Fix the Import Error in the Odoo 17How to Fix the Import Error in the Odoo 17
How to Fix the Import Error in the Odoo 17
Celine George
 
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching AptitudeUGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
S. Raj Kumar
 
PCOS corelations and management through Ayurveda.
PCOS corelations and management through Ayurveda.PCOS corelations and management through Ayurveda.
PCOS corelations and management through Ayurveda.
Dr. Shivangi Singh Parihar
 
How to Manage Your Lost Opportunities in Odoo 17 CRM
How to Manage Your Lost Opportunities in Odoo 17 CRMHow to Manage Your Lost Opportunities in Odoo 17 CRM
How to Manage Your Lost Opportunities in Odoo 17 CRM
Celine George
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
Nguyen Thanh Tu Collection
 
clinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdfclinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdf
Priyankaranawat4
 
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdfবাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
eBook.com.bd (প্রয়োজনীয় বাংলা বই)
 
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
Diana Rendina
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
adhitya5119
 
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
PECB
 
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdfANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
Priyankaranawat4
 
Wound healing PPT
Wound healing PPTWound healing PPT
Wound healing PPT
Jyoti Chand
 
South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)
Academy of Science of South Africa
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
Nguyen Thanh Tu Collection
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
mulvey2
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
Colégio Santa Teresinha
 
How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17
Celine George
 
Digital Artefact 1 - Tiny Home Environmental Design
Digital Artefact 1 - Tiny Home Environmental DesignDigital Artefact 1 - Tiny Home Environmental Design
Digital Artefact 1 - Tiny Home Environmental Design
amberjdewit93
 

Kürzlich hochgeladen (20)

Advanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docxAdvanced Java[Extra Concepts, Not Difficult].docx
Advanced Java[Extra Concepts, Not Difficult].docx
 
Film vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movieFilm vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movie
 
How to Fix the Import Error in the Odoo 17
How to Fix the Import Error in the Odoo 17How to Fix the Import Error in the Odoo 17
How to Fix the Import Error in the Odoo 17
 
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching AptitudeUGC NET Exam Paper 1- Unit 1:Teaching Aptitude
UGC NET Exam Paper 1- Unit 1:Teaching Aptitude
 
PCOS corelations and management through Ayurveda.
PCOS corelations and management through Ayurveda.PCOS corelations and management through Ayurveda.
PCOS corelations and management through Ayurveda.
 
How to Manage Your Lost Opportunities in Odoo 17 CRM
How to Manage Your Lost Opportunities in Odoo 17 CRMHow to Manage Your Lost Opportunities in Odoo 17 CRM
How to Manage Your Lost Opportunities in Odoo 17 CRM
 
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
BÀI TẬP DẠY THÊM TIẾNG ANH LỚP 7 CẢ NĂM FRIENDS PLUS SÁCH CHÂN TRỜI SÁNG TẠO ...
 
clinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdfclinical examination of hip joint (1).pdf
clinical examination of hip joint (1).pdf
 
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdfবাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
বাংলাদেশ অর্থনৈতিক সমীক্ষা (Economic Review) ২০২৪ UJS App.pdf
 
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
Reimagining Your Library Space: How to Increase the Vibes in Your Library No ...
 
Main Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docxMain Java[All of the Base Concepts}.docx
Main Java[All of the Base Concepts}.docx
 
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
ISO/IEC 27001, ISO/IEC 42001, and GDPR: Best Practices for Implementation and...
 
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdfANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
ANATOMY AND BIOMECHANICS OF HIP JOINT.pdf
 
Wound healing PPT
Wound healing PPTWound healing PPT
Wound healing PPT
 
South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)South African Journal of Science: Writing with integrity workshop (2024)
South African Journal of Science: Writing with integrity workshop (2024)
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
 
MARY JANE WILSON, A “BOA MÃE” .
MARY JANE WILSON, A “BOA MÃE”           .MARY JANE WILSON, A “BOA MÃE”           .
MARY JANE WILSON, A “BOA MÃE” .
 
How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17
 
Digital Artefact 1 - Tiny Home Environmental Design
Digital Artefact 1 - Tiny Home Environmental DesignDigital Artefact 1 - Tiny Home Environmental Design
Digital Artefact 1 - Tiny Home Environmental Design
 

(Ab)Using the MetaCPAN API for Fun and Profit

  • 1. (Ab)Using the MetaCPAN API for Fun and Profit Olaf Alders (OALDERS) @wundercounter
  • 2. Architecture • Built on ElasticSearch • Uses Catalyst as a thin wrapper • You don’t need to know this
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17. What can we build?
  • 18. What can we build? • Do something with Github
  • 19. What can we build? • Do something with Github • Get a list of all CPAN authors who have enabled the “hireable” flag in their Github profiles
  • 21. Let’s Get Started • We want to fetch some data
  • 22. Let’s Get Started • We want to fetch some data • We’ll use Sawyer’s MetaCPAN::API
  • 23. #!/usr/bin/env perl use strict; use warnings; use MetaCPAN::API; my $mcpan = MetaCPAN::API->new(); my $author = $mcpan->author('MSTROUT');
  • 24. { dir => "id/M/MS/MSTROUT", email => ["perl-stuff@trout.me.uk"], gravatar_url => "https://secure.gravatar.com/avatar/...", name => "Matt S Trout", pauseid => "MSTROUT", website => ["http://www.trout.me.uk/"], }
  • 25.
  • 26.
  • 28. my $author = $mcpan->author('MSTROUT');
  • 29. my $result = $mcpan->post( 'author', { query => { match_all => {} }, size => 1, }, );
  • 30. { _shards => { failed => 0, successful => 5, total => 5 }, hits => { hits => [ { _id => "KHAMPTON", _index => "cpan_v1", _score => 1, _source => { city => "Los Angeles", country => "US", dir => "id/K/KH/KHAMPTON", email => ["khampton@totalcinema.com", "kip.hampton@tamarou.com"], gravatar_url => "http://www.gravatar.com/avatar/...", name => "Kip Hampton", pauseid => "KHAMPTON", profile => [ { id => "ubu", name => "coderwall" }, { id => "ubu", name => "github" }, { id => "kiphampton", name => "twitter" }, ], region => "CA", updated => "2011-07-22T20:42:06", website => ["http://totalcinema.com/"], }, _type => "author", }, ], max_score => 1, total => 9780, }, timed_out => bless(do{(my $o = 0)}, "JSON::XS::Boolean"), took => 1, }
  • 31. my $result = $mcpan->post( 'author', { query => { match_all => {} }, size => 1, }, ); # dump $result->{hits}->{hits}->[0]->{_source};
  • 32. { city => "Los Angeles", country => "US", dir => "id/K/KH/KHAMPTON", email => ["khampton@totalcinema.com", "kip.hampton @tamarou.com"], gravatar_url => "http://www.gravatar.com/avatar/...", name => "Kip Hampton", pauseid => "KHAMPTON", profile => [ { id => "ubu", name => "coderwall" }, { id => "ubu", name => "github" }, { id => "kiphampton", name => "twitter" }, ], region => "CA", updated => "2011-07-22T20:42:06", website => ["http://totalcinema.com/"], }
  • 33. my $result = $mcpan->post( 'author', { query => { match_all => {} }, size => 100, }, );
  • 34. my $filter = { { term => { 'author.profile.name' => 'stackoverflow', } }, }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, }, );
  • 35. use Pithub; my $p = Pithub->new; AUTHOR: foreach my $author ( @{ $result->{hits}->{hits} } ) { foreach my $profile ( @{ $author->{_source}->{profile} } ) { if ( $profile->{name} eq 'github' ) { my $username = $profile->{id}; $username =~ s{https?://github.com/(w*)/?}{$1}i; next AUTHOR if !$username; if ( $p->users->get( user => $username )->content->{hireable} ) { # do something... } next AUTHOR; } } }
  • 37. my $filter = { and => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } } ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, }, );
  • 38. my $filter = { and => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } }, { exists => { 'field' => 'author.region' } }, ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, }, );
  • 39. my $filter = { and => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } }, { exists => { 'field' => 'author.region' } }, { missing => { 'field' => 'author.location' } }, ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, }, ); # “missing” isn’t really helpful in this search # just an example of how you might use it
  • 40. my $filter = { or => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } }, { exists => { 'field' => 'author.region' } }, { missing => { 'field' => 'author.location' } }, ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, }, );
  • 41. my $filter = { or => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } }, { exists => { 'field' => 'author.region' } }, { missing => { 'field' => 'author.location' } }, ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, fields => [ 'pauseid', 'country' ], }, );
  • 42. my $filter = { or => [ { term => { 'author.profile.name' => 'github', } }, { term => { 'author.country' => 'US', } }, { exists => { 'field' => 'author.region' } }, { missing => { 'field' => 'author.location' } }, ] }; my $result = $mcpan->post( 'author', { query => { match_all => {} }, filter => $filter, size => 100, sort => [ { 'author.pauseid' => 'ASC' } ], }, );
  • 43. Getting Help • #metacpan or irc.perl.org • https://metacpan.org/about/resources
  • 44. Resources • https://github.com/CPAN-API/cpan- api/wiki/Beta-API-docs • http://www.slideshare.net/ clintongormley/terms-of-endearment- the-elasticsearch-query-dsl-explained
  • 48. Convenience Endpoints • /author/DOY • /distribution/Moose • /release/Moose • /module/Moose • /pod/Moose
  • 49.
  • 50. Exporting Pod • /pod/Moose?content-type=text/html (default) • /pod/Moose?content-type=text/plain • /pod/Moose?content-type=text/x-pod • /pod/Moose?content-type=text/x-markdown
  • 53. The (real) Endpoints • /author • /distribution
  • 54. The (real) Endpoints • /author • /distribution • /favorite
  • 55. The (real) Endpoints • /author • /distribution • /favorite • /rating
  • 56. The (real) Endpoints • /author • /distribution • /favorite • /rating • /release
  • 57. The (real) Endpoints • /author • /distribution • /favorite • /rating • /release • /file
  • 58. The (real) Endpoints • /author • /distribution • /favorite • /rating • /release • /file
  • 59.
  • 60. Using a cache use HTTP::Tiny::Mech; use MetaCPAN::API; use WWW::Mechanize::Cached; my $mcpan = MetaCPAN::API->new( ua => HTTP::Tiny::Mech->new( mechua => WWW::Mechanize::Cached->new() ) );
  • 61.
  • 62. Enable Compression • use WWW::Mechanize::Gzip • use WWW::Mechanize::Cached::Gzip • Or set the appropriate request header
  • 63. Use the scrolling API • The scrolling API allows you to iterate over an arbitrary number of results • Be aware that when you scroll, your docs will come back unsorted

Hinweis der Redaktion

  1. show of hands: \n1) have used the metacpan search site \n2) use it as their default search site \n3) have worked with the API\n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. CPAN visualization tool\n
  11. \n
  12. \n
  13. \n
  14. Exports Pod into a format you can import right into your Kindle app.\n
  15. \n
  16. Drop-in replacement for Perldoc. Read documentation for modules which you haven’t even installed. Genius.\n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. You can see that for the email and website fields, we allow you to provide a list rather than a single value. Now, for our example we need an author’s Github profile. Matt Trout does not provide this, so he’s a bad test case for our script.\n
  23. Things like StackOverflow, Twitter and Github usernames are all provided by authors voluntarily after logging in to MetaCPAN. In order to see what the profiles look like in a data structure, we need to find an author who has filled these fields.\n
  24. You can see from Mo’s example here that he has filled out some of his profile information. He’s a good test case. Note the MetaCPAN explorer link on the bottom left corner. These links can also be found on the module and release pages.\n
  25. This is a great way to explore the various endpoints of the API and practice crafting queries by hand. However, today we’re just concerned with the /author endpoint.\n
  26. \n
  27. \n
  28. You can see here that since we’re no longer using a convenience endpoint, the output is a little busier. What we generally care about here is the list provided inside of hits->{hits}. In each list item, we care about _source and _source->{profile} in particular.\n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n