From c51d807935de353bbfe1a1d7db6b26a9bee4deed Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 10 Jun 2016 13:47:41 -0400
Subject: [PATCH 01/25] Bumps MetaCPAN::Client version to 1.015000

---
 cpanfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cpanfile b/cpanfile
index c98f47a..8a77029 100644
--- a/cpanfile
+++ b/cpanfile
@@ -7,7 +7,7 @@ requires 'HTTP::Tiny::Mech';
 requires 'IO::Socket::SSL';
 requires 'JSON';
 requires 'MetaCPAN::API::Tiny';
-requires 'MetaCPAN::Client', '>= 1.005000';
+requires 'MetaCPAN::Client', '>= 1.015000';
 requires 'Search::Elasticsearch';
 requires 'WWW::Mechanize::Cached';
 requires 'WWW::Mechanize::Cached::GZip';

From 30553ccd3d808d4e86886d3012ac0d99481f25ff Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 18 Nov 2016 11:25:21 -0600
Subject: [PATCH 02/25] Upgrade to v1

---
 README.md                                     | 142 ++++++++++++++++--
 cpanfile                                      |   5 +-
 lib/MetaCPAN/Util.pm                          |   7 +-
 scripts/author/1-fetch-single-author-curl.sh  |   3 +
 .../author/1-fetch-single-author-es.pl        |   4 +-
 .../1-fetch-single-author-www-mech-cached.pl  |   2 +-
 .../1-fetch-single-author.pl}                 |   2 +-
 .../1a-search-authors.pl}                     |   2 +-
 .../author/1b-scroll-all-authors-es.pl        |   2 +-
 .../1c-scroll-all-authors-with-twitter-es.pl  |   7 +-
 .../author/2-twitter-or-github-es.pl          |  14 +-
 scripts/by-topic/1-fetch-author-curl.sh       |   1 -
 scripts/by-topic/2-fetch-author-mcpan-api.pl  |   1 -
 scripts/by-topic/3-fetch-author-es.pl         |   1 -
 scripts/by-topic/4-scrolling-es.pl            |   1 -
 scripts/by-topic/5-autocomplete-www-mech.pl   |   1 -
 scripts/by-topic/6-a-module-is-a-file-es.pl   |   1 -
 .../distribution/1-bugs-for-dist-es.pl        |   2 +-
 .../author/1-fetch-single-author-curl.sh      |   3 -
 .../1-fetch-single-author-mcpan-api-tiny.pl   |  12 --
 .../endpoints/favorite/3-leaderboard-es.pl    |  44 ------
 .../endpoints/module/2-fetch-all-modules.pl   |  80 ----------
 ...-single-pod-doc-as-html-www-mech-cached.pl |  12 --
 ...h-single-pod-doc-as-plain-text-www-mech.pl |  11 --
 .../release/2-author-upload-leaderboard-es.pl |  41 -----
 .../release/3-author-uploads-one-author-es.pl |  27 ----
 .../favorite/1-last-50-favorited-dists-es.pl  |   2 +-
 .../1a-last-100-favorited-dists-by-user-es.pl |   2 +-
 .../favorite/2-favorites-previous-month-es.pl |   5 +-
 scripts/favorite/3-leaderboard-es.pl          |  33 ++++
 .../4-leaderboard-previous-month-es.pl        |   9 +-
 .../favorite/5-plus-plus-your-favorites-es.pl |  20 ++-
 .../favorite/6-list-plussers-by-module.pl     |  10 +-
 .../file/1-get-files-in-dist-es.pl            |   8 +-
 .../file/2-get-dists-with-cpanfile.pl         |   2 +-
 .../file/3-find-files-in-top-level-by-name.pl |   3 +-
 scripts/{endpoints => }/file/4-main-search.pl |  14 +-
 .../module/1-fetch-single-module-es.pl        |   2 +-
 scripts/module/3-fetch-modules-in-release.pl  |  30 ++++
 .../1-fetch-single-pod-doc-as-html.pl}        |   2 +-
 .../1a-fetch-single-pod-doc-as-plain-text.pl} |   2 +-
 scripts/{endpoints => }/pod/README            |   0
 .../{endpoints => }/release/1-pkg2url-es.pl   |   8 +-
 .../release/1a-module2url-es.pl               |  15 +-
 .../release/2-author-upload-leaderboard-es.pl |  23 +++
 .../release/3-author-uploads-one-author-es.pl |  26 ++++
 .../release/4-latest-release-versions-es.pl   |   2 +-
 ...-latest-release-versions-bool-filter-es.pl |  14 +-
 .../release/5-latest-releases-by-author-es.pl |   8 +-
 .../6-latest-releases-with-git-repo-es.pl     |  11 +-
 .../{endpoints => }/release/7-all-releases.pl |  11 +-
 .../release/all-releases-by-author.pl         |   5 +-
 .../search/autocomplete/www-mech.pl           |   7 +-
 .../reverse_dependencies/by-dist-www-mech.pl  |   8 +-
 .../by-release-version-mech.pl                |   7 +-
 55 files changed, 344 insertions(+), 373 deletions(-)
 create mode 100755 scripts/author/1-fetch-single-author-curl.sh
 rename scripts/{endpoints => }/author/1-fetch-single-author-es.pl (82%)
 rename scripts/{endpoints => }/author/1-fetch-single-author-www-mech-cached.pl (73%)
 rename scripts/{endpoints/author/1-fetch-single-author-mcpan-api.pl => author/1-fetch-single-author.pl} (72%)
 rename scripts/{endpoints/author/1a-search-authors-mcpan-api.pl => author/1a-search-authors.pl} (85%)
 rename scripts/{endpoints => }/author/1b-scroll-all-authors-es.pl (98%)
 rename scripts/{endpoints => }/author/1c-scroll-all-authors-with-twitter-es.pl (81%)
 rename scripts/{endpoints => }/author/2-twitter-or-github-es.pl (77%)
 delete mode 120000 scripts/by-topic/1-fetch-author-curl.sh
 delete mode 120000 scripts/by-topic/2-fetch-author-mcpan-api.pl
 delete mode 120000 scripts/by-topic/3-fetch-author-es.pl
 delete mode 120000 scripts/by-topic/4-scrolling-es.pl
 delete mode 120000 scripts/by-topic/5-autocomplete-www-mech.pl
 delete mode 120000 scripts/by-topic/6-a-module-is-a-file-es.pl
 rename scripts/{endpoints => }/distribution/1-bugs-for-dist-es.pl (90%)
 delete mode 100755 scripts/endpoints/author/1-fetch-single-author-curl.sh
 delete mode 100755 scripts/endpoints/author/1-fetch-single-author-mcpan-api-tiny.pl
 delete mode 100755 scripts/endpoints/favorite/3-leaderboard-es.pl
 delete mode 100755 scripts/endpoints/module/2-fetch-all-modules.pl
 delete mode 100755 scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-www-mech-cached.pl
 delete mode 100755 scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-www-mech.pl
 delete mode 100755 scripts/endpoints/release/2-author-upload-leaderboard-es.pl
 delete mode 100755 scripts/endpoints/release/3-author-uploads-one-author-es.pl
 rename scripts/{endpoints => }/favorite/1-last-50-favorited-dists-es.pl (94%)
 rename scripts/{endpoints => }/favorite/1a-last-100-favorited-dists-by-user-es.pl (96%)
 rename scripts/{endpoints => }/favorite/2-favorites-previous-month-es.pl (84%)
 create mode 100755 scripts/favorite/3-leaderboard-es.pl
 rename scripts/{endpoints => }/favorite/4-leaderboard-previous-month-es.pl (75%)
 rename scripts/{endpoints => }/favorite/5-plus-plus-your-favorites-es.pl (76%)
 rename scripts/{endpoints => }/favorite/6-list-plussers-by-module.pl (83%)
 rename scripts/{endpoints => }/file/1-get-files-in-dist-es.pl (70%)
 rename scripts/{endpoints => }/file/2-get-dists-with-cpanfile.pl (97%)
 rename scripts/{endpoints => }/file/3-find-files-in-top-level-by-name.pl (89%)
 rename scripts/{endpoints => }/file/4-main-search.pl (89%)
 rename scripts/{endpoints => }/module/1-fetch-single-module-es.pl (90%)
 create mode 100644 scripts/module/3-fetch-modules-in-release.pl
 rename scripts/{endpoints/pod/1-fetch-single-pod-doc-as-html-mcpan-api.pl => pod/1-fetch-single-pod-doc-as-html.pl} (72%)
 rename scripts/{endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-mcpan-api.pl => pod/1a-fetch-single-pod-doc-as-plain-text.pl} (80%)
 rename scripts/{endpoints => }/pod/README (100%)
 rename scripts/{endpoints => }/release/1-pkg2url-es.pl (64%)
 rename scripts/{endpoints => }/release/1a-module2url-es.pl (59%)
 create mode 100755 scripts/release/2-author-upload-leaderboard-es.pl
 create mode 100755 scripts/release/3-author-uploads-one-author-es.pl
 rename scripts/{endpoints => }/release/4-latest-release-versions-es.pl (98%)
 rename scripts/{endpoints => }/release/4a-latest-release-versions-bool-filter-es.pl (72%)
 rename scripts/{endpoints => }/release/5-latest-releases-by-author-es.pl (85%)
 rename scripts/{endpoints => }/release/6-latest-releases-with-git-repo-es.pl (61%)
 rename scripts/{endpoints => }/release/7-all-releases.pl (66%)
 rename scripts/{endpoints => }/release/all-releases-by-author.pl (75%)
 rename scripts/{endpoints => }/search/autocomplete/www-mech.pl (80%)
 rename scripts/{endpoints => }/search/reverse_dependencies/by-dist-www-mech.pl (61%)
 rename scripts/{endpoints => }/search/reverse_dependencies/by-release-version-mech.pl (62%)

diff --git a/README.md b/README.md
index d48c534..28eb6f8 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,141 @@
-metacpan-examples
-=================
-
-Sample code to get you up and running quickly.  If you are new to MetaCPAN,
-please use the scripts/endpoints/author examples to get yourself started.  If
-you are searching for a specific topic, try scripts/topic as your starting
-point.
-
-The purpose of this repository is to showcase how to use the MetaCPAN API.
-There are examples using raw curl as well as the following Perl modules:
-MetaCPAN::API, MetaCPAN::API::Tiny, WWW::Mechanize and ElasticSearch.  Scripts
-are all found in /scripts.  You can run the Perl scripts in the usual manner,
+# metacpan-examples
+
+This repository contains sample code to get you up and running quickly with the MetaCPAN API.
+
+## Please use MetaCPAN::Client
+
+There are many different ways and clients which you can use to access the API.  However, *we strongly encourage you* to start by using the MetaCPAN::Client module.  If you have compelling reasons to use a different client, feel free to do so, but please be aware that MetaCPAN::Client is fully supported by MetaCPAN.  You will likely save yourself (and us) much debugging time if you begin with this module rather than rolling your own Elasticsearch queries.  If MetaCPAN::Client *doesn't* do something which you need it to do, please open a GitHub issue to let us know about it.
+
+There are some examples to be found here which use `curl`, `WWW::Mechanize`, `Search::Elasticsearch` etc.  These are useful for reference, but please do take `MetaCPAN::Client` as your starting point. 
+
+## Getting Started
+
+Scripts are all found in /scripts.  You can run the Perl scripts in the usual manner,
 but if you want to get up and running quickly, you are encouraged to run your
 scripts via Carton.  The workflow is:
 
     cpanm Carton
     carton install
-    bin/carton scripts/endpoints/author/1-fetch-single-author-mcpan-api.pl
+    bin/carton scripts/author/1a-search-authors.pl
 
 Or, you can use Carton directly:
 
-    carton exec perl -Ilib scripts/endpoints/author/1-fetch-single-author-mcpan-api.pl
+    carton exec perl -Ilib scripts/author/1a-search-authors.pl
 
-Using the carton wrapper in bin will save you a few keystrokes and will
+Using the `bin/carton` will save you a few keystrokes and will
 automatically add new libs to the path in future, if they are required.  Use
 the workflow you are most comfortable with.
 
 Please open issues for examples you would like to see and send pull requests
 for examples you've already written.
+
+## Upgrading from v0
+
+The MetaCPAN API v1 is now available.  v0 will be deprecated after a 6 month window.  This window closes on or after June 1, 2017.  Here's a guide to converting your scripts.
+
+## Elasticsearch version
+
+v1 of the MetaCPAN API uses [Elasticsearch v2.4.0](https://www.elastic.co/guide/en/elasticsearch/reference/2.4/index.html) (v0 was at 0.20.2).  There are many breaking changes in this upgrade, since it spans almost 4 years.
+
+The MetaCPAN API versions will increase with breaking changes, but we will not use the same versioning as Elasticsearch itself.
+
+### Data Structure Changes
+
+Elasticsearch 1.x changed the data structure returned when fields are used.
+For example before one could get a `ArrayRef[ HashRef [ Str ] ]` where now
+that will come in the form of `ArrayRef[ HashRef [ ArrayRef [ Str ] ] ]`.
+
+Our convenience endpoints revert this behaviour, but if you're crafting your own searches, you should be aware that the structure of your fields data may have changed.
+
+### Client-specific Changes
+
+#### MetaCPAN::Client
+
+v0:
+
+```perl
+use MetaCPAN::Client->new();
+```
+
+v1:
+
+```perl
+use MetaCPAN::Client->new( version => 'v1' );
+```
+
+#### Search::Elasticsearch
+
+v0:
+
+```perl
+use Search::Elasticsearch;
+my $es = Search::Elasticsearch->new(
+    cxn_pool => 'Static::NoPing',
+    nodes    => 'api.metacpan.org',
+    trace_to => 'Stdout',
+);
+```
+
+v1:
+
+```perl
+use Search::Elasticsearch;
+my $es = Search::Elasticsearch->new(
+    cxn_pool         => 'Static::NoPing',
+    nodes            => 'https://fastapi.metacpan.org',
+    send_get_body_as => 'POST',
+    trace_to         => 'Stdout',
+);
+```
+
+* The URL of the v1 API is https://fastapi.metacpan.org  Note that not only is the host name new, but we've also switched to https.
+
+* You'll need to set `send_get_body_as => 'POST'`.  This is because v1 does not accept `GET` with a body.
+
+##### $es->search
+
+```perl
+my $faves = $es->search(
+    index => 'v0',
+    type  => 'favorite',
+    body  => {
+        query  => { match_all => {} },
+        facets => {
+            dist => {
+                terms => { field => 'favorite.distribution', size => 10 },
+            },
+        },
+    },
+    size => 0,
+);
+```
+
+```perl
+my $faves = es()->search(
+    index => 'v1',
+    type  => 'favorite',
+    body  => {
+        aggs => {
+            dist => {
+                terms => { field => 'distribution', size => 10 },
+            },
+        },
+    },
+);
+``` 
+
+* The index is now `v1`
+* `match_all` is the default query type, so it's not required to specify it
+* `facets` have been replaced by `aggs`
+* The data structure returned for `facets` does not mirror the `aggs` return values, so you'll need to rework your logic when checking the return values.
+* When searching on a type (`favorite` in this case), do not prefix the key with the type name.  So, as seen above, `field => 'favorite.distribution'` is now `field => 'distribution'`
+
+#### GET via command line or browser
+
+v0: `http://api.metacpan.org/v0/author/MSTROUT`
+
+v1: `https://fastapi.metacpan.org/v1/author/MSTROUT`
+
+* Note the new host name
+* Note that we now use HTTPS
+* Note that the path begins with v0 rather than v1
\ No newline at end of file
diff --git a/cpanfile b/cpanfile
index 8a77029..bc5132f 100644
--- a/cpanfile
+++ b/cpanfile
@@ -5,10 +5,9 @@ requires 'Data::Printer::Filter::URI';
 requires 'DateTime';
 requires 'HTTP::Tiny::Mech';
 requires 'IO::Socket::SSL';
-requires 'JSON';
+requires 'JSON::MaybeXS';
 requires 'MetaCPAN::API::Tiny';
-requires 'MetaCPAN::Client', '>= 1.015000';
-requires 'Search::Elasticsearch';
+requires 'MetaCPAN::Client', '>= 1.028003';
 requires 'WWW::Mechanize::Cached';
 requires 'WWW::Mechanize::Cached::GZip';
 
diff --git a/lib/MetaCPAN/Util.pm b/lib/MetaCPAN/Util.pm
index 280ee5b..636a871 100644
--- a/lib/MetaCPAN/Util.pm
+++ b/lib/MetaCPAN/Util.pm
@@ -8,9 +8,10 @@ use Sub::Exporter -setup => { exports => ['es'] };
 
 sub es {
     return Search::Elasticsearch->new(
-        cxn_pool => 'Static::NoPing',
-        nodes    => 'api.metacpan.org',
-        trace_to => 'Stdout',
+        cxn_pool         => 'Static::NoPing',
+        nodes            => 'https://fastapi.metacpan.org',
+        send_get_body_as => 'POST',
+        trace_to         => 'Stdout',
     );
 }
 
diff --git a/scripts/author/1-fetch-single-author-curl.sh b/scripts/author/1-fetch-single-author-curl.sh
new file mode 100755
index 0000000..34edd3c
--- /dev/null
+++ b/scripts/author/1-fetch-single-author-curl.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+curl https://fastapi.metacpan.org/v1/author/MSTROUT
diff --git a/scripts/endpoints/author/1-fetch-single-author-es.pl b/scripts/author/1-fetch-single-author-es.pl
similarity index 82%
rename from scripts/endpoints/author/1-fetch-single-author-es.pl
rename to scripts/author/1-fetch-single-author-es.pl
index fa3f2b9..9058553 100755
--- a/scripts/endpoints/author/1-fetch-single-author-es.pl
+++ b/scripts/author/1-fetch-single-author-es.pl
@@ -8,12 +8,12 @@
 
 my $es = Search::Elasticsearch->new(
     cxn_pool => 'Static::NoPing',
-    nodes    => 'api.metacpan.org',
+    nodes    => 'fastapi.metacpan.org',
     trace_to => 'Stdout',
 );
 
 my $author = $es->get(
-    index => 'v0',
+    index => 'v1',
     type  => 'author',
     id    => 'MSTROUT',
 );
diff --git a/scripts/endpoints/author/1-fetch-single-author-www-mech-cached.pl b/scripts/author/1-fetch-single-author-www-mech-cached.pl
similarity index 73%
rename from scripts/endpoints/author/1-fetch-single-author-www-mech-cached.pl
rename to scripts/author/1-fetch-single-author-www-mech-cached.pl
index 12e8db0..dd3342a 100755
--- a/scripts/endpoints/author/1-fetch-single-author-www-mech-cached.pl
+++ b/scripts/author/1-fetch-single-author-www-mech-cached.pl
@@ -6,6 +6,6 @@
 
 use WWW::Mechanize::Cached::GZip;
 my $mech = WWW::Mechanize::Cached::GZip->new;
-$mech->get('http://api.metacpan.org/v0/author/MSTROUT');
+$mech->get('https://fastapi.metacpan.org/v1/author/MSTROUT');
 
 say $mech->content;
diff --git a/scripts/endpoints/author/1-fetch-single-author-mcpan-api.pl b/scripts/author/1-fetch-single-author.pl
similarity index 72%
rename from scripts/endpoints/author/1-fetch-single-author-mcpan-api.pl
rename to scripts/author/1-fetch-single-author.pl
index fe543ea..d2e5ea1 100755
--- a/scripts/endpoints/author/1-fetch-single-author-mcpan-api.pl
+++ b/scripts/author/1-fetch-single-author.pl
@@ -6,7 +6,7 @@
 use Data::Printer;
 use MetaCPAN::Client;
 
-my $mcpan  = MetaCPAN::Client->new();
+my $mcpan  = MetaCPAN::Client->new( version => 'v1' );
 my $author = $mcpan->author('MSTROUT');
 
 p $author;
diff --git a/scripts/endpoints/author/1a-search-authors-mcpan-api.pl b/scripts/author/1a-search-authors.pl
similarity index 85%
rename from scripts/endpoints/author/1a-search-authors-mcpan-api.pl
rename to scripts/author/1a-search-authors.pl
index b2d76cb..2525ec6 100755
--- a/scripts/endpoints/author/1a-search-authors-mcpan-api.pl
+++ b/scripts/author/1a-search-authors.pl
@@ -7,7 +7,7 @@
 use Data::Printer;
 use MetaCPAN::Client;
 
-my $mc = MetaCPAN::Client->new;
+my $mc = MetaCPAN::Client->new( version => 'v1' );
 
 my $search = $mc->author( { name => 'Olaf *' } );
 
diff --git a/scripts/endpoints/author/1b-scroll-all-authors-es.pl b/scripts/author/1b-scroll-all-authors-es.pl
similarity index 98%
rename from scripts/endpoints/author/1b-scroll-all-authors-es.pl
rename to scripts/author/1b-scroll-all-authors-es.pl
index 6b7bb57..8b7f5c9 100755
--- a/scripts/endpoints/author/1b-scroll-all-authors-es.pl
+++ b/scripts/author/1b-scroll-all-authors-es.pl
@@ -9,7 +9,7 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v0',
+    index       => 'v1',
     type        => 'author',
     size        => 100,
     body        => {
diff --git a/scripts/endpoints/author/1c-scroll-all-authors-with-twitter-es.pl b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
similarity index 81%
rename from scripts/endpoints/author/1c-scroll-all-authors-with-twitter-es.pl
rename to scripts/author/1c-scroll-all-authors-with-twitter-es.pl
index cbbdd9c..3a2c477 100755
--- a/scripts/endpoints/author/1c-scroll-all-authors-with-twitter-es.pl
+++ b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
@@ -9,16 +9,15 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v0',
+    index       => 'v1',
     type        => 'author',
     size        => 100,
     body        => {
         query => {
             filtered => {
-                query => { term => { 'author.profile.name' => 'twitter' } },
+                filter => { match => { 'profile.name' => 'twitter' } },
             },
-            match_all => {}
-        }
+        },
     },
 );
 
diff --git a/scripts/endpoints/author/2-twitter-or-github-es.pl b/scripts/author/2-twitter-or-github-es.pl
similarity index 77%
rename from scripts/endpoints/author/2-twitter-or-github-es.pl
rename to scripts/author/2-twitter-or-github-es.pl
index 157f5cb..6149d3a 100755
--- a/scripts/endpoints/author/2-twitter-or-github-es.pl
+++ b/scripts/author/2-twitter-or-github-es.pl
@@ -9,32 +9,30 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v0',
+    index       => 'v1',
     type        => 'author',
     size        => 100,
     body        => {
         query => {
-            match_all => {},
-            filtered  => {
+            filtered => {
                 filter => {
                     or => [
                         {
                             and => [
                                 {
                                     term => {
-                                        'author.profile.name' => 'twitter'
+                                        'profile.name' => 'twitter'
                                     }
                                 },
-                                { term => { 'author.country' => 'US' } }
+                                { term => { 'country' => 'US' } }
                             ]
                         },
                         {
                             and => [
                                 {
-                                    term =>
-                                        { 'author.profile.name' => 'github' }
+                                    term => { 'profile.name' => 'github' }
                                 },
-                                { term => { 'author.country' => 'CA' } }
+                                { term => { 'country' => 'CA' } }
                             ]
                         },
                     ],
diff --git a/scripts/by-topic/1-fetch-author-curl.sh b/scripts/by-topic/1-fetch-author-curl.sh
deleted file mode 120000
index c3c7c68..0000000
--- a/scripts/by-topic/1-fetch-author-curl.sh
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/author/1-fetch-single-author-curl.sh
\ No newline at end of file
diff --git a/scripts/by-topic/2-fetch-author-mcpan-api.pl b/scripts/by-topic/2-fetch-author-mcpan-api.pl
deleted file mode 120000
index 5f2eecc..0000000
--- a/scripts/by-topic/2-fetch-author-mcpan-api.pl
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/author/1-fetch-single-author-mcpan-api.pl
\ No newline at end of file
diff --git a/scripts/by-topic/3-fetch-author-es.pl b/scripts/by-topic/3-fetch-author-es.pl
deleted file mode 120000
index 3d3ca4f..0000000
--- a/scripts/by-topic/3-fetch-author-es.pl
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/author/1-fetch-single-author-es.pl
\ No newline at end of file
diff --git a/scripts/by-topic/4-scrolling-es.pl b/scripts/by-topic/4-scrolling-es.pl
deleted file mode 120000
index 85542d8..0000000
--- a/scripts/by-topic/4-scrolling-es.pl
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/author/1b-scroll-all-authors-es.pl
\ No newline at end of file
diff --git a/scripts/by-topic/5-autocomplete-www-mech.pl b/scripts/by-topic/5-autocomplete-www-mech.pl
deleted file mode 120000
index 40b1914..0000000
--- a/scripts/by-topic/5-autocomplete-www-mech.pl
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/search/autocomplete/www-mech.pl
\ No newline at end of file
diff --git a/scripts/by-topic/6-a-module-is-a-file-es.pl b/scripts/by-topic/6-a-module-is-a-file-es.pl
deleted file mode 120000
index 92d034e..0000000
--- a/scripts/by-topic/6-a-module-is-a-file-es.pl
+++ /dev/null
@@ -1 +0,0 @@
-../endpoints/favorite/5-plus-plus-your-favorites-es.pl
\ No newline at end of file
diff --git a/scripts/endpoints/distribution/1-bugs-for-dist-es.pl b/scripts/distribution/1-bugs-for-dist-es.pl
similarity index 90%
rename from scripts/endpoints/distribution/1-bugs-for-dist-es.pl
rename to scripts/distribution/1-bugs-for-dist-es.pl
index 39c0e88..55dc1a5 100755
--- a/scripts/endpoints/distribution/1-bugs-for-dist-es.pl
+++ b/scripts/distribution/1-bugs-for-dist-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $dist = es()->get(
-    index => 'v0',
+    index => 'v1',
     type  => 'distribution',
     id    => 'Moose',
 );
diff --git a/scripts/endpoints/author/1-fetch-single-author-curl.sh b/scripts/endpoints/author/1-fetch-single-author-curl.sh
deleted file mode 100755
index 5822761..0000000
--- a/scripts/endpoints/author/1-fetch-single-author-curl.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-curl http://api.metacpan.org/v0/author/MSTROUT
diff --git a/scripts/endpoints/author/1-fetch-single-author-mcpan-api-tiny.pl b/scripts/endpoints/author/1-fetch-single-author-mcpan-api-tiny.pl
deleted file mode 100755
index b4866a1..0000000
--- a/scripts/endpoints/author/1-fetch-single-author-mcpan-api-tiny.pl
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use Data::Printer;
-use MetaCPAN::API::Tiny;
-
-my $mcpan  = MetaCPAN::API::Tiny->new();
-my $author = $mcpan->author('MSTROUT');
-
-p $author;
diff --git a/scripts/endpoints/favorite/3-leaderboard-es.pl b/scripts/endpoints/favorite/3-leaderboard-es.pl
deleted file mode 100755
index 1811b2a..0000000
--- a/scripts/endpoints/favorite/3-leaderboard-es.pl
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use Data::Printer;
-use DateTime;
-use MetaCPAN::Util qw( es );
-
-my $now = DateTime->now;
-my $then = $now->clone->subtract( months => 1 );
-
-my $faves = es()->search(
-    index => 'v0',
-    type  => 'favorite',
-    body  => {
-        query  => { match_all => {} },
-        facets => {
-            dist => {
-                terms => { field => 'favorite.distribution', size => 40 },
-            },
-        },
-    },
-    size => 0,
-);
-
-my @dists = map { $_->{terms} } $faves->{facets}->{dist};
-
-p @dists;
-
-=pod
-
-=DESCRIPTION
-
-Because of the way facets are calculated, you may find that the numbers you get
-towards the end of the list are not 100% accurate.  You can test this by
-checking the results for position #10 with a size of 10 versus a size of 20.
-So, if you need exact numbers for the leaderboard (and why wouldn't you?), you
-should set a size greater than what you actually require.  You can experiment
-with the size a bit to see the size required for the first X results to remain
-consistent.  Just with some quick testing, it looks like a size of 40 is a good
-number in order to get consistent numbers for the top 10 results.
-
-=cut
diff --git a/scripts/endpoints/module/2-fetch-all-modules.pl b/scripts/endpoints/module/2-fetch-all-modules.pl
deleted file mode 100755
index c44da81..0000000
--- a/scripts/endpoints/module/2-fetch-all-modules.pl
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use feature qw( state );
-
-use Data::Printer filters => { -external => ['JSON'] };
-use MetaCPAN::Util qw( es );
-
-# distributions which MetaCPAN has chosen not to include in its search index
-# feel free to include these in your searches if you wish
-my @ROGUE_DISTRIBUTIONS
-    = qw(kurila perl_debug perl-5.005_02+apache1.3.3+modperl pod2texi perlbench spodcxx);
-
-my $scroller = es()->scroll_helper(
-    index => 'v0',
-    type  => 'file',
-    body  => {
-        query  => { match_all => {} },
-        filter => {
-            and => [
-                {
-                    not => {
-                        filter => {
-                            or => [
-                                map {
-                                    { term => { 'file.distribution' => $_ } }
-                                } @ROGUE_DISTRIBUTIONS
-                            ]
-                        }
-                    }
-                },
-                { term => { status => 'latest' } },
-                {
-                    or => [
-
-                        # we are looking for files that have no authorized
-                        # property (e.g. .pod files) and files that are
-                        # authorized
-                        { missing => { field => 'file.authorized' } },
-                        { term => { 'file.authorized' => \1 } },
-                    ]
-                },
-                {
-                    or => [
-                        {
-                            and => [
-                                { exists => { field => 'file.module.name' } },
-                                { term => { 'file.module.indexed' => \1 } }
-                            ]
-                        },
-                        {
-                            and => [
-                                { exists => { field => 'documentation' } },
-                                { term => { 'file.indexed' => \1 } }
-                            ]
-                        }
-                    ]
-                }
-            ]
-        },
-
-        sort   => [                  { "date" => "desc" } ],
-        fields => [ 'documentation', 'module' ],
-    },
-    size => 10,
-);
-
-# note that this search returns the names both of files which are pure
-# documentation and also and arrayref of modules.  keep in mind that one file
-# can contain many modules.  so, depending on your use case, you may want to
-# deal with the documentation scalar, the module arrayref or even both.
-
-while ( my $result = $scroller->next ) {
-    state $counter = 0;
-    $counter++;
-    p $result->{fields};
-    last if $counter == 10;
-}
-
diff --git a/scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-www-mech-cached.pl b/scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-www-mech-cached.pl
deleted file mode 100755
index 66c485d..0000000
--- a/scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-www-mech-cached.pl
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use feature qw( say );
-
-use WWW::Mechanize::Cached::GZip;
-my $mech = WWW::Mechanize::Cached::GZip->new;
-
-$mech->get('http://api.metacpan.org/v0/pod/Carton');
-
-say $mech->content;
diff --git a/scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-www-mech.pl b/scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-www-mech.pl
deleted file mode 100755
index 659ba5b..0000000
--- a/scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-www-mech.pl
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use feature qw( say );
-
-use HTTP::Tiny;
-
-my $http = HTTP::Tiny->new(
-    default_headers => { 'Content-Type' => 'text/plain' } );
-say $http->get('http://api.metacpan.org/v0/pod/Carton')->{content};
diff --git a/scripts/endpoints/release/2-author-upload-leaderboard-es.pl b/scripts/endpoints/release/2-author-upload-leaderboard-es.pl
deleted file mode 100755
index 2fbb6fe..0000000
--- a/scripts/endpoints/release/2-author-upload-leaderboard-es.pl
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use Data::Printer;
-use DateTime;
-use MetaCPAN::Util qw( es );
-
-my $now = DateTime->now;
-my $then = $now->clone->subtract( months => 1 );
-
-my $faves = es()->search(
-    index => 'v0',
-    type  => 'release',
-    body  => {
-        query  => { match_all => {} },
-        facets => {
-            author => { terms => { field => 'release.author', size => 40 }, },
-        },
-    },
-    size => 0,
-);
-
-my @dists = map { $_->{terms} } $faves->{facets}->{dist};
-
-p @dists;
-
-=pod
-
-=DESCRIPTION
-
-Because of the way facets are calculated, you may find that the numbers you get
-towards the end of the list are not 100% accurate.  You can test this by
-checking the results for position #10 with a size of 10 versus a size of 20.
-So, if you need exact numbers for the leaderboard (and why wouldn't you?), you
-should set a size greater than what you actually require.  You can experiment
-with the size a bit to see the size required for the first X results to remain
-consistent.
-
-=cut
diff --git a/scripts/endpoints/release/3-author-uploads-one-author-es.pl b/scripts/endpoints/release/3-author-uploads-one-author-es.pl
deleted file mode 100755
index 1871b2e..0000000
--- a/scripts/endpoints/release/3-author-uploads-one-author-es.pl
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-use feature qw( say );
-
-use DateTime;
-use MetaCPAN::Util qw( es );
-
-my $uploads = es()->search(
-    index => 'v0',
-    type  => 'release',
-    body  => {
-        query => {
-            filtered => {
-                query  => { match_all => {} },
-                filter => { term      => { 'release.author' => 'OALDERS' } },
-            },
-        },
-        facets => {
-            author => { terms => { field => 'release.author', size => 40 }, },
-        },
-    },
-    size => 0,
-);
-
-say $uploads->{facets}->{author}->{terms}->[0]->{count};
diff --git a/scripts/endpoints/favorite/1-last-50-favorited-dists-es.pl b/scripts/favorite/1-last-50-favorited-dists-es.pl
similarity index 94%
rename from scripts/endpoints/favorite/1-last-50-favorited-dists-es.pl
rename to scripts/favorite/1-last-50-favorited-dists-es.pl
index 1c266a1..7345056 100755
--- a/scripts/endpoints/favorite/1-last-50-favorited-dists-es.pl
+++ b/scripts/favorite/1-last-50-favorited-dists-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $faves = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'favorite',
     body  => {
         query => { match_all => {} },
diff --git a/scripts/endpoints/favorite/1a-last-100-favorited-dists-by-user-es.pl b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
similarity index 96%
rename from scripts/endpoints/favorite/1a-last-100-favorited-dists-by-user-es.pl
rename to scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
index acbb712..9cb9e97 100755
--- a/scripts/endpoints/favorite/1a-last-100-favorited-dists-by-user-es.pl
+++ b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
@@ -11,7 +11,7 @@
 die "usage: ./bin/carton $0 \$user_id" if !$id;
 
 my $faves = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'favorite',
     body  => {
         query => {
diff --git a/scripts/endpoints/favorite/2-favorites-previous-month-es.pl b/scripts/favorite/2-favorites-previous-month-es.pl
similarity index 84%
rename from scripts/endpoints/favorite/2-favorites-previous-month-es.pl
rename to scripts/favorite/2-favorites-previous-month-es.pl
index 7335310..8668084 100755
--- a/scripts/endpoints/favorite/2-favorites-previous-month-es.pl
+++ b/scripts/favorite/2-favorites-previous-month-es.pl
@@ -11,15 +11,14 @@
 my $then = $now->clone->subtract( months => 1 );
 
 my $faves = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'favorite',
     body  => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
                     range => {
-                        'favorite.date' =>
+                        date =>
                             { from => $then->datetime, to => $now->datetime }
                     },
                 },
diff --git a/scripts/favorite/3-leaderboard-es.pl b/scripts/favorite/3-leaderboard-es.pl
new file mode 100755
index 0000000..801e58b
--- /dev/null
+++ b/scripts/favorite/3-leaderboard-es.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Data::Printer;
+use MetaCPAN::Util qw( es );
+
+my $faves = es()->search(
+    index => 'v1',
+    type  => 'favorite',
+    body  => {
+        aggs => {
+            dist => {
+                terms => { field => 'distribution', size => 10 },
+            },
+        },
+    },
+);
+
+my @counts = map { +{ $_->{key} => $_->{doc_count} } }
+    @{ $faves->{aggregations}->{dist}->{buckets} };
+p @counts;
+
+__END__
+=pod
+
+=head1 DESCRIPTION
+
+Get the 10 distributions with the most ++ clicks, sorted by descending
+popularity.
+
+=cut
diff --git a/scripts/endpoints/favorite/4-leaderboard-previous-month-es.pl b/scripts/favorite/4-leaderboard-previous-month-es.pl
similarity index 75%
rename from scripts/endpoints/favorite/4-leaderboard-previous-month-es.pl
rename to scripts/favorite/4-leaderboard-previous-month-es.pl
index 782b1f7..ebe64b8 100755
--- a/scripts/endpoints/favorite/4-leaderboard-previous-month-es.pl
+++ b/scripts/favorite/4-leaderboard-previous-month-es.pl
@@ -11,23 +11,22 @@
 my $then = $now->clone->subtract( months => 1 );
 
 my $faves = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'favorite',
     body  => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
                     range => {
-                        'favorite.date' =>
+                        date =>
                             { from => $then->datetime, to => $now->datetime }
                     },
                 },
             },
         },
-        facets => {
+        aggs => {
             dist => {
-                terms => { field => 'favorite.distribution', size => 50 },
+                terms => { field => 'distribution', size => 50 },
             },
         },
     },
diff --git a/scripts/endpoints/favorite/5-plus-plus-your-favorites-es.pl b/scripts/favorite/5-plus-plus-your-favorites-es.pl
similarity index 76%
rename from scripts/endpoints/favorite/5-plus-plus-your-favorites-es.pl
rename to scripts/favorite/5-plus-plus-your-favorites-es.pl
index 4898361..47d8e3b 100755
--- a/scripts/endpoints/favorite/5-plus-plus-your-favorites-es.pl
+++ b/scripts/favorite/5-plus-plus-your-favorites-es.pl
@@ -4,8 +4,8 @@
 use warnings;
 
 use Data::Printer;
-use HTTP::Tiny;
-use JSON;
+use HTTP::Tiny ();
+use JSON::MaybeXS qw( encode_json );
 use MetaCPAN::Util qw( es );
 
 my $token   = shift @ARGV;
@@ -15,22 +15,21 @@
     unless @modules;
 
 my $module = es()->search(
-    index  => 'v0',
+    index  => 'v1',
     type   => 'file',
     fields => 'release',
     size   => scalar @modules,
     body   => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
                     bool => {
 
                         # a module is a file
                         must => [
-                            { term  => { 'file.authorized'  => 'true' } },
-                            { terms => { 'file.module.name' => \@modules } },
-                            { term  => { 'file.status'      => 'latest' } }
+                            { term  => { 'authorized'  => 'true' } },
+                            { terms => { 'module.name' => \@modules } },
+                            { term  => { 'status'      => 'latest' } }
                         ]
                     },
                 },
@@ -43,14 +42,13 @@
     = map { $_->{fields}->{release} } @{ $module->{hits}->{hits} };
 
 my $release = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'release',
     size  => scalar @release_names,
     body  => {
         query => {
             filtered => {
-                query => { match_all => {} },
-                filter => { terms => { 'release.name' => \@release_names } },
+                filter => { terms => { 'name' => \@release_names } },
             },
         },
     },
@@ -72,7 +70,7 @@ sub plus_plus {
     my $res    = $ua->post(
         "https://api.metacpan.org/user/favorite?access_token=$token",
         {
-            content => to_json($params),
+            content => encode_json($params),
             headers => { 'content-type' => 'application/json' }
         },
     );
diff --git a/scripts/endpoints/favorite/6-list-plussers-by-module.pl b/scripts/favorite/6-list-plussers-by-module.pl
similarity index 83%
rename from scripts/endpoints/favorite/6-list-plussers-by-module.pl
rename to scripts/favorite/6-list-plussers-by-module.pl
index f0ba8ff..7837f9c 100755
--- a/scripts/endpoints/favorite/6-list-plussers-by-module.pl
+++ b/scripts/favorite/6-list-plussers-by-module.pl
@@ -16,16 +16,14 @@
 my $module = MetaCPAN::Client->new->module($module_name);
 
 my $plussers = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'favorite',
     size  => 1000,
     body  => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
-                    term =>
-                        { 'favorite.distribution' => $module->distribution }
+                    term => { 'distribution' => $module->distribution }
                 },
             },
         },
@@ -37,14 +35,14 @@
 my $total = @ids;
 
 my $authors = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'author',
     size  => scalar @ids,
     body  => {
         query => {
             filtered => {
                 query  => { match_all => {} },
-                filter => { terms     => { 'author.user' => \@ids } },
+                filter => { terms     => { 'user' => \@ids } },
             },
         },
         fields => [ 'pauseid', 'name' ],
diff --git a/scripts/endpoints/file/1-get-files-in-dist-es.pl b/scripts/file/1-get-files-in-dist-es.pl
similarity index 70%
rename from scripts/endpoints/file/1-get-files-in-dist-es.pl
rename to scripts/file/1-get-files-in-dist-es.pl
index 0d8aa71..7c94a00 100755
--- a/scripts/endpoints/file/1-get-files-in-dist-es.pl
+++ b/scripts/file/1-get-files-in-dist-es.pl
@@ -8,7 +8,7 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'file',
     size  => 300,
     body  => {
@@ -18,11 +18,9 @@
                 filter => {
                     bool => {
                         must => {
-                            term =>
-                                { 'file.release' => 'HTML-Restrict-2.1.5' },
+                            term => { 'release' => 'HTML-Restrict-2.1.5' },
                         },
-                        must_not =>
-                            { term => { 'file.directory' => 'true' }, },
+                        must_not => { term => { 'directory' => 'true' }, },
                     },
                 },
             },
diff --git a/scripts/endpoints/file/2-get-dists-with-cpanfile.pl b/scripts/file/2-get-dists-with-cpanfile.pl
similarity index 97%
rename from scripts/endpoints/file/2-get-dists-with-cpanfile.pl
rename to scripts/file/2-get-dists-with-cpanfile.pl
index c9f7f3e..b61cf55 100755
--- a/scripts/endpoints/file/2-get-dists-with-cpanfile.pl
+++ b/scripts/file/2-get-dists-with-cpanfile.pl
@@ -8,7 +8,7 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'file',
     size  => 10,
     body  => {
diff --git a/scripts/endpoints/file/3-find-files-in-top-level-by-name.pl b/scripts/file/3-find-files-in-top-level-by-name.pl
similarity index 89%
rename from scripts/endpoints/file/3-find-files-in-top-level-by-name.pl
rename to scripts/file/3-find-files-in-top-level-by-name.pl
index c9f7f3e..9abed96 100755
--- a/scripts/endpoints/file/3-find-files-in-top-level-by-name.pl
+++ b/scripts/file/3-find-files-in-top-level-by-name.pl
@@ -8,13 +8,12 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'file',
     size  => 10,
     body  => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
                     and => [
                         { term => { 'path'      => 'cpanfile' } },
diff --git a/scripts/endpoints/file/4-main-search.pl b/scripts/file/4-main-search.pl
similarity index 89%
rename from scripts/endpoints/file/4-main-search.pl
rename to scripts/file/4-main-search.pl
index 337dcad..88e15ba 100644
--- a/scripts/endpoints/file/4-main-search.pl
+++ b/scripts/file/4-main-search.pl
@@ -4,7 +4,7 @@
 use warnings;
 
 use Data::Printer;
-use JSON qw( decode_json );
+use JSON::MaybeXS qw( decode_json );
 use MetaCPAN::Util qw( es );
 
 my $search_term = shift @ARGV || 'HTML-Re';
@@ -13,7 +13,7 @@
 }
 
 my $result = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'file',
     body  => {
         query => {
@@ -24,7 +24,7 @@
                         should => [
                             {
                                 term => {
-                                    "file.documentation" => {
+                                    "documentation" => {
                                         boost => 20,
                                         value => $search_term,
                                     }
@@ -32,7 +32,7 @@
                             },
                             {
                                 term => {
-                                    "file.module.name" => {
+                                    "module.name" => {
                                         boost => 20,
                                         value => $search_term,
                                     },
@@ -48,10 +48,10 @@
                                                 default_operator => "AND",
                                                 fields           => [
                                                     "documentation.analyzed^2",
-                                                    "file.module.name.analyzed^2",
+                                                    "module.name.analyzed^2",
                                                     "distribution.analyzed",
                                                     "documentation.camelcase",
-                                                    "file.module.name.camelcase",
+                                                    "module.name.camelcase",
                                                     "distribution.camelcase",
                                                 ],
                                                 query       => $search_term,
@@ -78,7 +78,7 @@
                 },
                 negative => {
                     term => {
-                        "file.mime" => { value => "text/x-script.perl" }
+                        "mime" => { value => "text/x-script.perl" }
                     }
                 }
             }
diff --git a/scripts/endpoints/module/1-fetch-single-module-es.pl b/scripts/module/1-fetch-single-module-es.pl
similarity index 90%
rename from scripts/endpoints/module/1-fetch-single-module-es.pl
rename to scripts/module/1-fetch-single-module-es.pl
index 46bd1fe..28d671f 100755
--- a/scripts/endpoints/module/1-fetch-single-module-es.pl
+++ b/scripts/module/1-fetch-single-module-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $module = es()->get(
-    index => 'v0',
+    index => 'v1',
     type  => 'module',
     id    => 'HTML::Restrict',
 );
diff --git a/scripts/module/3-fetch-modules-in-release.pl b/scripts/module/3-fetch-modules-in-release.pl
new file mode 100644
index 0000000..95438c8
--- /dev/null
+++ b/scripts/module/3-fetch-modules-in-release.pl
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client ();
+my $client = MetaCPAN::Client->new( version => 'v1' );
+
+my $dist = shift @ARGV;
+
+die "usage: ./bin/carton $0 Moose" unless $dist;
+
+my $modules = $client->module(
+    {
+        all => [
+            { authorized   => 'true' },
+            { binary       => 'false' },
+            { distribution => $dist },
+            { indexed      => 'true' },
+            { status       => 'latest' },
+        ]
+    }
+);
+
+while ( my $module = $modules->next ) {
+    next unless $module->module;
+    for my $pkg ( @{ $module->module } ) {
+        say $pkg->{name};
+    }
+}
+
diff --git a/scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-mcpan-api.pl b/scripts/pod/1-fetch-single-pod-doc-as-html.pl
similarity index 72%
rename from scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-mcpan-api.pl
rename to scripts/pod/1-fetch-single-pod-doc-as-html.pl
index 3de9771..4ea6c9c 100755
--- a/scripts/endpoints/pod/1-fetch-single-pod-doc-as-html-mcpan-api.pl
+++ b/scripts/pod/1-fetch-single-pod-doc-as-html.pl
@@ -6,6 +6,6 @@
 
 use MetaCPAN::Client;
 
-my $mcpan    = MetaCPAN::Client->new;
+my $mcpan    = MetaCPAN::Client->new( version => 'v1' );
 my $html_pod = $mcpan->pod('Carton');
 say $html_pod->html;
diff --git a/scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-mcpan-api.pl b/scripts/pod/1a-fetch-single-pod-doc-as-plain-text.pl
similarity index 80%
rename from scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-mcpan-api.pl
rename to scripts/pod/1a-fetch-single-pod-doc-as-plain-text.pl
index bbfe287..5bdd370 100755
--- a/scripts/endpoints/pod/1a-fetch-single-pod-doc-as-plain-text-mcpan-api.pl
+++ b/scripts/pod/1a-fetch-single-pod-doc-as-plain-text.pl
@@ -4,7 +4,7 @@
 use warnings;
 use feature qw( say );
 
-use MetaCPAN::Client;
+use MetaCPAN::Client( version => 'v1' );
 
 my $mcpan    = MetaCPAN::Client->new;
 my $html_pod = $mcpan->pod('Carton');
diff --git a/scripts/endpoints/pod/README b/scripts/pod/README
similarity index 100%
rename from scripts/endpoints/pod/README
rename to scripts/pod/README
diff --git a/scripts/endpoints/release/1-pkg2url-es.pl b/scripts/release/1-pkg2url-es.pl
similarity index 64%
rename from scripts/endpoints/release/1-pkg2url-es.pl
rename to scripts/release/1-pkg2url-es.pl
index 836cb66..8bde427 100755
--- a/scripts/endpoints/release/1-pkg2url-es.pl
+++ b/scripts/release/1-pkg2url-es.pl
@@ -8,17 +8,15 @@
 
 my $es = Search::Elasticsearch->new(
     cxn_pool => 'Static::NoPing',
-    nodes    => 'api.metacpan.org',
+    nodes    => 'https://fastapi.metacpan.org',
     trace_to => 'Stdout',
 );
 
 my $release = $es->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'release',
     body  => {
-        query => { match_all => {} },
-        filter =>
-            { term => { 'release.archive' => 'Acme-Hoge-0.03.tar.gz' } },
+        filter => { term => { 'archive' => 'Acme-Hoge-0.03.tar.gz' } },
     },
 );
 
diff --git a/scripts/endpoints/release/1a-module2url-es.pl b/scripts/release/1a-module2url-es.pl
similarity index 59%
rename from scripts/endpoints/release/1a-module2url-es.pl
rename to scripts/release/1a-module2url-es.pl
index 5e82240..5f00475 100755
--- a/scripts/endpoints/release/1a-module2url-es.pl
+++ b/scripts/release/1a-module2url-es.pl
@@ -8,20 +8,20 @@
 
 my $es = Search::Elasticsearch->new(
     cxn_pool => 'Static::NoPing',
-    nodes    => 'api.metacpan.org',
+    nodes    => 'https://fastapi.metacpan.org',
     trace_to => 'Stdout',
 );
 
 my $module = $es->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'file',
     body  => {
         query  => { match_all => {} },
         filter => {
             and => [
-                { term => { 'file.authorized'     => 'true' } },
-                { term => { 'file.module.name'    => 'Acme::Hoge' } },
-                { term => { 'file.module.version' => '0.03' } }
+                { term => { 'authorized'     => 'true' } },
+                { term => { 'module.name'    => 'Acme::Hoge' } },
+                { term => { 'module.version' => '0.03' } }
             ]
         },
     },
@@ -30,11 +30,10 @@
 my $release_name = $module->{hits}{hits}[0]{_source}{release};
 
 my $release = $es->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'release',
     body  => {
-        query  => { match_all => {} },
-        filter => { term      => { 'release.name' => $release_name } },
+        filter => { term => { 'name' => $release_name } },
     },
 );
 
diff --git a/scripts/release/2-author-upload-leaderboard-es.pl b/scripts/release/2-author-upload-leaderboard-es.pl
new file mode 100755
index 0000000..65d498d
--- /dev/null
+++ b/scripts/release/2-author-upload-leaderboard-es.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Data::Printer;
+use MetaCPAN::Util qw( es );
+
+my $uploads = es()->search(
+    index => 'v1',
+    type  => 'release',
+    body  => {
+        query => { match_all => {} },
+        aggs  => {
+            author => { terms => { field => 'author', size => 10 }, },
+        },
+    },
+);
+
+my @authors = map { +{ $_->{key} => $_->{doc_count} } }
+    @{ $uploads->{aggregations}->{author}->{buckets} };
+
+p @authors;
diff --git a/scripts/release/3-author-uploads-one-author-es.pl b/scripts/release/3-author-uploads-one-author-es.pl
new file mode 100755
index 0000000..9f54c7d
--- /dev/null
+++ b/scripts/release/3-author-uploads-one-author-es.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Util qw( es );
+
+my $uploads = es()->search(
+    index => 'v1',
+    type  => 'release',
+    body  => {
+        query => {
+            filtered => {
+                filter => { term => { 'author' => 'OALDERS' } },
+            },
+        },
+        aggs => {
+            author => { terms => { field => 'author', size => 40 }, },
+        },
+    },
+    size => 0,
+);
+
+use DDP;
+p $uploads;
diff --git a/scripts/endpoints/release/4-latest-release-versions-es.pl b/scripts/release/4-latest-release-versions-es.pl
similarity index 98%
rename from scripts/endpoints/release/4-latest-release-versions-es.pl
rename to scripts/release/4-latest-release-versions-es.pl
index e35e144..6fbc2ae 100755
--- a/scripts/endpoints/release/4-latest-release-versions-es.pl
+++ b/scripts/release/4-latest-release-versions-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
-    index  => 'v0',
+    index  => 'v1',
     type   => 'release',
     fields => [ 'distribution', 'version' ],
     size   => 3,
diff --git a/scripts/endpoints/release/4a-latest-release-versions-bool-filter-es.pl b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
similarity index 72%
rename from scripts/endpoints/release/4a-latest-release-versions-bool-filter-es.pl
rename to scripts/release/4a-latest-release-versions-bool-filter-es.pl
index 8a89aaa..41d6221 100755
--- a/scripts/endpoints/release/4a-latest-release-versions-bool-filter-es.pl
+++ b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
@@ -7,29 +7,27 @@
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
-    index  => 'v0',
+    index  => 'v1',
     type   => 'release',
     fields => [ 'distribution', 'version' ],
     size   => 3,
     body   => {
         query => {
             filtered => {
-                query  => { match_all => {} },
                 filter => {
                     bool => {
                         must => [
-                            { term => { 'release.status' => 'latest' } },
+                            { term => { 'status' => 'latest' } },
                             {
                                 terms => {
-                                    'release.distribution' => [
-                                        'Moose', 'MetaCPAN-API',
-                                        'DBIx-Class'
+                                    'distribution' => [
+                                        'Moose',      'MetaCPAN-Client',
+                                        'DBIx-Class', 'Moo',
                                     ]
                                 },
                             },
                         ],
-                        must_not =>
-                            { term => { 'release.author' => 'ETHER' } },
+                        must_not => { term => { 'author' => 'ETHER' } },
                     },
                 },
             },
diff --git a/scripts/endpoints/release/5-latest-releases-by-author-es.pl b/scripts/release/5-latest-releases-by-author-es.pl
similarity index 85%
rename from scripts/endpoints/release/5-latest-releases-by-author-es.pl
rename to scripts/release/5-latest-releases-by-author-es.pl
index 82181b0..f3cfa71 100755
--- a/scripts/endpoints/release/5-latest-releases-by-author-es.pl
+++ b/scripts/release/5-latest-releases-by-author-es.pl
@@ -10,7 +10,7 @@
 die "usage: $0 PAUSEID" if !$author;
 
 my $latest = es()->search(
-    index  => 'v0',
+    index  => 'v1',
     type   => 'release',
     fields => [ 'distribution', 'provides', 'version' ],
     size   => 500,
@@ -20,13 +20,13 @@
                 query  => { match_all => {} },
                 filter => {
                     and => [
-                        { term => { 'release.status' => 'latest' } },
-                        { term => { 'release.author' => [$author] }, },
+                        { term => { 'status' => 'latest' } },
+                        { term => { 'author' => $author }, },
                     ],
                 },
             },
         },
-        sort => [ { 'release.date' => 'desc' } ],
+        sort => [ { 'date' => 'desc' } ],
     },
 );
 
diff --git a/scripts/endpoints/release/6-latest-releases-with-git-repo-es.pl b/scripts/release/6-latest-releases-with-git-repo-es.pl
similarity index 61%
rename from scripts/endpoints/release/6-latest-releases-with-git-repo-es.pl
rename to scripts/release/6-latest-releases-with-git-repo-es.pl
index 868b39a..334a4e1 100755
--- a/scripts/endpoints/release/6-latest-releases-with-git-repo-es.pl
+++ b/scripts/release/6-latest-releases-with-git-repo-es.pl
@@ -8,24 +8,23 @@
 use MetaCPAN::Util qw( es );
 
 my @must = (
-    { term => { 'release.resources.repository.type' => 'git' }, },
-    { term => { status                              => 'latest' } },
-    { term => { authorized                          => 'true' } },
+    { term => { 'resources.repository.type' => 'git' }, },
+    { term => { status                      => 'latest' } },
+    { term => { authorized                  => 'true' } },
 );
 
 my $scroller = es()->scroll_helper(
     body => {
         query => {
             filtered => {
-                query  => { match_all => {} },
-                filter => { bool      => { must => \@must } },
+                filter => { bool => { must => \@must } },
             },
         },
     },
     fields      => [ 'author', 'date', 'distribution', 'name', 'resources' ],
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v0',
+    index       => 'v1',
     type        => 'release',
     size        => 500,
 );
diff --git a/scripts/endpoints/release/7-all-releases.pl b/scripts/release/7-all-releases.pl
similarity index 66%
rename from scripts/endpoints/release/7-all-releases.pl
rename to scripts/release/7-all-releases.pl
index e0e3529..be0c5ca 100755
--- a/scripts/endpoints/release/7-all-releases.pl
+++ b/scripts/release/7-all-releases.pl
@@ -10,15 +10,10 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v0',
+    index       => 'v1',
     type        => 'release',
-    size        => 1000,
-    body        => {
-        query => {
-            match_all => {}
-        },
-        fields => ['download_url'],
-    }
+    size        => 1_000,
+    body        => { fields => ['download_url'] },
 );
 
 my @urls;
diff --git a/scripts/endpoints/release/all-releases-by-author.pl b/scripts/release/all-releases-by-author.pl
similarity index 75%
rename from scripts/endpoints/release/all-releases-by-author.pl
rename to scripts/release/all-releases-by-author.pl
index f720cf2..b9f11d3 100755
--- a/scripts/endpoints/release/all-releases-by-author.pl
+++ b/scripts/release/all-releases-by-author.pl
@@ -7,13 +7,12 @@
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
-    index => 'v0',
+    index => 'v1',
     type  => 'release',
     body  => {
         query => {
             filtered => {
-                query  => { match_all => {} },
-                filter => { term      => { 'release.author' => 'OALDERS' } },
+                filter => { term => { 'author' => 'OALDERS' } },
             },
         },
         fields => [ 'author', 'archive', 'date' ],
diff --git a/scripts/endpoints/search/autocomplete/www-mech.pl b/scripts/search/autocomplete/www-mech.pl
similarity index 80%
rename from scripts/endpoints/search/autocomplete/www-mech.pl
rename to scripts/search/autocomplete/www-mech.pl
index 73ab2e5..ecf34e7 100755
--- a/scripts/endpoints/search/autocomplete/www-mech.pl
+++ b/scripts/search/autocomplete/www-mech.pl
@@ -5,14 +5,15 @@
 use feature qw( say );
 
 use Data::Printer;
-use JSON qw( decode_json );
-use WWW::Mechanize::GZip;
+use JSON::MaybeXS qw( decode_json );
+use WWW::Mechanize::GZip ();
 
 my $mech = WWW::Mechanize::GZip->new;
 
 my $search_term = shift @ARGV || 'HTML::Re';
 
-$mech->get("http://api.metacpan.org/v0/search/autocomplete?q=$search_term");
+$mech->get(
+    "https://fastapi.metacpan.org/v1/search/autocomplete?q=$search_term");
 say $mech->content;
 
 my $results = decode_json( $mech->content );
diff --git a/scripts/endpoints/search/reverse_dependencies/by-dist-www-mech.pl b/scripts/search/reverse_dependencies/by-dist-www-mech.pl
similarity index 61%
rename from scripts/endpoints/search/reverse_dependencies/by-dist-www-mech.pl
rename to scripts/search/reverse_dependencies/by-dist-www-mech.pl
index 8e650ef..c04967b 100755
--- a/scripts/endpoints/search/reverse_dependencies/by-dist-www-mech.pl
+++ b/scripts/search/reverse_dependencies/by-dist-www-mech.pl
@@ -4,11 +4,13 @@
 use warnings;
 
 use Data::Printer;
-use JSON qw( decode_json );
-use WWW::Mechanize::GZip;
+use JSON::MaybeXS qw( decode_json );
+use WWW::Mechanize::GZip ();
+
 my $mech = WWW::Mechanize::GZip->new;
 
-$mech->get("http://api.metacpan.org/v0/search/reverse_dependencies/carton");
+$mech->get(
+    "https://fastapi.metacpan.org/v1/search/reverse_dependencies/carton");
 
 my $results = decode_json( $mech->content );
 
diff --git a/scripts/endpoints/search/reverse_dependencies/by-release-version-mech.pl b/scripts/search/reverse_dependencies/by-release-version-mech.pl
similarity index 62%
rename from scripts/endpoints/search/reverse_dependencies/by-release-version-mech.pl
rename to scripts/search/reverse_dependencies/by-release-version-mech.pl
index 3873047..2994064 100755
--- a/scripts/endpoints/search/reverse_dependencies/by-release-version-mech.pl
+++ b/scripts/search/reverse_dependencies/by-release-version-mech.pl
@@ -4,12 +4,13 @@
 use warnings;
 
 use Data::Printer;
-use JSON qw( decode_json );
-use WWW::Mechanize;
+use JSON::MaybeXS qw( decode_json );
+use WWW::Mechanize ();
+
 my $mech = WWW::Mechanize->new;
 
 $mech->get(
-    "http://api.metacpan.org/v0/search/reverse_dependencies/MIYAGAWA/carton-v0.9.13"
+    'https://fastapi.metacpan.org/v1/search/reverse_dependencies/MIYAGAWA/carton-v0.9.13'
 );
 
 my $results = decode_json( $mech->content );

From 9ac021761e91575334c0490ca0de6c2421b9b083 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 18 Nov 2016 17:24:05 -0600
Subject: [PATCH 03/25] Add script for size of CPAN unpacked.

---
 scripts/file/4-main-search.pl                |  0
 scripts/file/5-size-of-cpan.pl               | 30 ++++++++++++++++++++
 scripts/module/3-fetch-modules-in-release.pl |  0
 scripts/pod/README                           |  0
 4 files changed, 30 insertions(+)
 mode change 100644 => 100755 scripts/file/4-main-search.pl
 create mode 100755 scripts/file/5-size-of-cpan.pl
 mode change 100644 => 100755 scripts/module/3-fetch-modules-in-release.pl
 mode change 100644 => 100755 scripts/pod/README

diff --git a/scripts/file/4-main-search.pl b/scripts/file/4-main-search.pl
old mode 100644
new mode 100755
diff --git a/scripts/file/5-size-of-cpan.pl b/scripts/file/5-size-of-cpan.pl
new file mode 100755
index 0000000..be250a1
--- /dev/null
+++ b/scripts/file/5-size-of-cpan.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw( say );
+
+use Data::Printer;
+use MetaCPAN::Util qw( es );
+
+my $search = es()->search(
+    index => 'v1',
+    type  => 'file',
+    body  => {
+        aggs => {
+            size => { sum => { field => 'stat.size' } }
+        },
+        size => 0,
+    },
+);
+
+say $search->{aggregations}{size}{value};
+
+__END__
+=pod
+
+=head1 DESCRIPTION
+
+Get the size of CPAN + BackPAN, when it's unpacked.
+
+=cut
diff --git a/scripts/module/3-fetch-modules-in-release.pl b/scripts/module/3-fetch-modules-in-release.pl
old mode 100644
new mode 100755
diff --git a/scripts/pod/README b/scripts/pod/README
old mode 100644
new mode 100755

From 29b8f4749f4d259ad52aca71ee73e2c4357d4a23 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 18 Nov 2016 18:33:12 -0600
Subject: [PATCH 04/25] Adds 2-dists-with-rt-source.pl

---
 scripts/distribution/2-dists-with-rt-source.pl | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100755 scripts/distribution/2-dists-with-rt-source.pl

diff --git a/scripts/distribution/2-dists-with-rt-source.pl b/scripts/distribution/2-dists-with-rt-source.pl
new file mode 100755
index 0000000..d591ac1
--- /dev/null
+++ b/scripts/distribution/2-dists-with-rt-source.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $mc = MetaCPAN::Client->new( version => 'v1' );
+
+my $search = $mc->all( 'distributions',
+    { es_filter => { exists => { field => 'bugs.rt.source' } } } );
+
+while ( my $dist = $search->next ) {
+    p $dist;
+}

From 6af0200b2749c1c372ebfc3d116880e8f59677d3 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 18 Nov 2016 18:33:31 -0600
Subject: [PATCH 05/25] Moves size of CPAN example to use MetaCPAN::Client.

---
 scripts/file/5-size-of-cpan.pl | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/scripts/file/5-size-of-cpan.pl b/scripts/file/5-size-of-cpan.pl
index be250a1..5689597 100755
--- a/scripts/file/5-size-of-cpan.pl
+++ b/scripts/file/5-size-of-cpan.pl
@@ -2,23 +2,19 @@
 
 use strict;
 use warnings;
-use feature qw( say );
 
 use Data::Printer;
-use MetaCPAN::Util qw( es );
-
-my $search = es()->search(
-    index => 'v1',
-    type  => 'file',
-    body  => {
-        aggs => {
-            size => { sum => { field => 'stat.size' } }
-        },
-        size => 0,
-    },
-);
+use MetaCPAN::Client ();
+
+my $mc = MetaCPAN::Client->new( version => 'v1' );
 
-say $search->{aggregations}{size}{value};
+my $file = $mc->all(
+    'files',
+    {
+        aggregations => { aggs => { sum => { field => 'stat.size' } } },
+    }
+);
+p $file->aggregations;
 
 __END__
 =pod

From 9be29fbd7ec65a60edc968e732930f23c4185346 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 18 Nov 2016 21:11:21 -0600
Subject: [PATCH 06/25] Bumps MetaCPAN::Client version.

---
 cpanfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cpanfile b/cpanfile
index bc5132f..3753f1b 100644
--- a/cpanfile
+++ b/cpanfile
@@ -7,7 +7,7 @@ requires 'HTTP::Tiny::Mech';
 requires 'IO::Socket::SSL';
 requires 'JSON::MaybeXS';
 requires 'MetaCPAN::API::Tiny';
-requires 'MetaCPAN::Client', '>= 1.028003';
+requires 'MetaCPAN::Client', '>= 2.000000';
 requires 'WWW::Mechanize::Cached';
 requires 'WWW::Mechanize::Cached::GZip';
 

From 1a6102f3e823c93d189b394f267c3d7274d6874c Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Sat, 19 Nov 2016 19:49:28 -0600
Subject: [PATCH 07/25] s/v1/cpan/

---
 README.md                                            | 12 +++++++-----
 lib/MetaCPAN/Util.pm                                 |  2 +-
 scripts/author/1-fetch-single-author-es.pl           |  2 +-
 scripts/author/1b-scroll-all-authors-es.pl           |  2 +-
 .../author/1c-scroll-all-authors-with-twitter-es.pl  |  2 +-
 scripts/author/2-twitter-or-github-es.pl             |  2 +-
 scripts/distribution/1-bugs-for-dist-es.pl           |  2 +-
 scripts/favorite/1-last-50-favorited-dists-es.pl     |  2 +-
 .../1a-last-100-favorited-dists-by-user-es.pl        |  2 +-
 scripts/favorite/2-favorites-previous-month-es.pl    |  2 +-
 scripts/favorite/3-leaderboard-es.pl                 |  2 +-
 scripts/favorite/4-leaderboard-previous-month-es.pl  |  2 +-
 scripts/favorite/5-plus-plus-your-favorites-es.pl    |  4 ++--
 scripts/favorite/6-list-plussers-by-module.pl        |  4 ++--
 scripts/file/1-get-files-in-dist-es.pl               |  2 +-
 scripts/file/2-get-dists-with-cpanfile.pl            |  2 +-
 scripts/file/3-find-files-in-top-level-by-name.pl    |  2 +-
 scripts/file/4-main-search.pl                        |  2 +-
 scripts/module/1-fetch-single-module-es.pl           |  2 +-
 scripts/release/1-pkg2url-es.pl                      |  2 +-
 scripts/release/1a-module2url-es.pl                  |  4 ++--
 scripts/release/2-author-upload-leaderboard-es.pl    |  2 +-
 scripts/release/3-author-uploads-one-author-es.pl    |  2 +-
 scripts/release/4-latest-release-versions-es.pl      |  2 +-
 .../4a-latest-release-versions-bool-filter-es.pl     |  2 +-
 scripts/release/5-latest-releases-by-author-es.pl    |  2 +-
 .../release/6-latest-releases-with-git-repo-es.pl    |  2 +-
 scripts/release/7-all-releases.pl                    |  2 +-
 scripts/release/all-releases-by-author.pl            |  2 +-
 29 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/README.md b/README.md
index 28eb6f8..2cdb167 100644
--- a/README.md
+++ b/README.md
@@ -82,13 +82,15 @@ v1:
 use Search::Elasticsearch;
 my $es = Search::Elasticsearch->new(
     cxn_pool         => 'Static::NoPing',
-    nodes            => 'https://fastapi.metacpan.org',
+    nodes            => 'https://fastapi.metacpan.org/v1',
     send_get_body_as => 'POST',
     trace_to         => 'Stdout',
 );
 ```
 
-* The URL of the v1 API is https://fastapi.metacpan.org  Note that not only is the host name new, but we've also switched to https.
+* The node URL of the v1 API is https://fastapi.metacpan.org/v1  Note that not
+  only is the host name new, but we've also switched to https and also added
+  the version to the path.
 
 * You'll need to set `send_get_body_as => 'POST'`.  This is because v1 does not accept `GET` with a body.
 
@@ -112,7 +114,7 @@ my $faves = $es->search(
 
 ```perl
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         aggs => {
@@ -124,7 +126,7 @@ my $faves = es()->search(
 );
 ``` 
 
-* The index is now `v1`
+* The index name is now `cpan`
 * `match_all` is the default query type, so it's not required to specify it
 * `facets` have been replaced by `aggs`
 * The data structure returned for `facets` does not mirror the `aggs` return values, so you'll need to rework your logic when checking the return values.
@@ -138,4 +140,4 @@ v1: `https://fastapi.metacpan.org/v1/author/MSTROUT`
 
 * Note the new host name
 * Note that we now use HTTPS
-* Note that the path begins with v0 rather than v1
\ No newline at end of file
+* Note that the path begins with v1 rather than v0
diff --git a/lib/MetaCPAN/Util.pm b/lib/MetaCPAN/Util.pm
index 636a871..b140451 100644
--- a/lib/MetaCPAN/Util.pm
+++ b/lib/MetaCPAN/Util.pm
@@ -9,7 +9,7 @@ use Sub::Exporter -setup => { exports => ['es'] };
 sub es {
     return Search::Elasticsearch->new(
         cxn_pool         => 'Static::NoPing',
-        nodes            => 'https://fastapi.metacpan.org',
+        nodes            => 'https://fastapi.metacpan.org/v1',
         send_get_body_as => 'POST',
         trace_to         => 'Stdout',
     );
diff --git a/scripts/author/1-fetch-single-author-es.pl b/scripts/author/1-fetch-single-author-es.pl
index 9058553..5d61d79 100755
--- a/scripts/author/1-fetch-single-author-es.pl
+++ b/scripts/author/1-fetch-single-author-es.pl
@@ -13,7 +13,7 @@
 );
 
 my $author = $es->get(
-    index => 'v1',
+    index => 'cpan',
     type  => 'author',
     id    => 'MSTROUT',
 );
diff --git a/scripts/author/1b-scroll-all-authors-es.pl b/scripts/author/1b-scroll-all-authors-es.pl
index 8b7f5c9..85c23a0 100755
--- a/scripts/author/1b-scroll-all-authors-es.pl
+++ b/scripts/author/1b-scroll-all-authors-es.pl
@@ -9,7 +9,7 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v1',
+    index       => 'cpan',
     type        => 'author',
     size        => 100,
     body        => {
diff --git a/scripts/author/1c-scroll-all-authors-with-twitter-es.pl b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
index 3a2c477..a9d1c69 100755
--- a/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
+++ b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
@@ -9,7 +9,7 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v1',
+    index       => 'cpan',
     type        => 'author',
     size        => 100,
     body        => {
diff --git a/scripts/author/2-twitter-or-github-es.pl b/scripts/author/2-twitter-or-github-es.pl
index 6149d3a..439a732 100755
--- a/scripts/author/2-twitter-or-github-es.pl
+++ b/scripts/author/2-twitter-or-github-es.pl
@@ -9,7 +9,7 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v1',
+    index       => 'cpan',
     type        => 'author',
     size        => 100,
     body        => {
diff --git a/scripts/distribution/1-bugs-for-dist-es.pl b/scripts/distribution/1-bugs-for-dist-es.pl
index 55dc1a5..9cb0ec9 100755
--- a/scripts/distribution/1-bugs-for-dist-es.pl
+++ b/scripts/distribution/1-bugs-for-dist-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $dist = es()->get(
-    index => 'v1',
+    index => 'cpan',
     type  => 'distribution',
     id    => 'Moose',
 );
diff --git a/scripts/favorite/1-last-50-favorited-dists-es.pl b/scripts/favorite/1-last-50-favorited-dists-es.pl
index 7345056..695eb78 100755
--- a/scripts/favorite/1-last-50-favorited-dists-es.pl
+++ b/scripts/favorite/1-last-50-favorited-dists-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         query => { match_all => {} },
diff --git a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
index 9cb9e97..2d7904a 100755
--- a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
+++ b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
@@ -11,7 +11,7 @@
 die "usage: ./bin/carton $0 \$user_id" if !$id;
 
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         query => {
diff --git a/scripts/favorite/2-favorites-previous-month-es.pl b/scripts/favorite/2-favorites-previous-month-es.pl
index 8668084..ca45c40 100755
--- a/scripts/favorite/2-favorites-previous-month-es.pl
+++ b/scripts/favorite/2-favorites-previous-month-es.pl
@@ -11,7 +11,7 @@
 my $then = $now->clone->subtract( months => 1 );
 
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         query => {
diff --git a/scripts/favorite/3-leaderboard-es.pl b/scripts/favorite/3-leaderboard-es.pl
index 801e58b..a6b33b8 100755
--- a/scripts/favorite/3-leaderboard-es.pl
+++ b/scripts/favorite/3-leaderboard-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         aggs => {
diff --git a/scripts/favorite/4-leaderboard-previous-month-es.pl b/scripts/favorite/4-leaderboard-previous-month-es.pl
index ebe64b8..d38e9a5 100755
--- a/scripts/favorite/4-leaderboard-previous-month-es.pl
+++ b/scripts/favorite/4-leaderboard-previous-month-es.pl
@@ -11,7 +11,7 @@
 my $then = $now->clone->subtract( months => 1 );
 
 my $faves = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     body  => {
         query => {
diff --git a/scripts/favorite/5-plus-plus-your-favorites-es.pl b/scripts/favorite/5-plus-plus-your-favorites-es.pl
index 47d8e3b..26ee015 100755
--- a/scripts/favorite/5-plus-plus-your-favorites-es.pl
+++ b/scripts/favorite/5-plus-plus-your-favorites-es.pl
@@ -15,7 +15,7 @@
     unless @modules;
 
 my $module = es()->search(
-    index  => 'v1',
+    index  => 'cpan',
     type   => 'file',
     fields => 'release',
     size   => scalar @modules,
@@ -42,7 +42,7 @@
     = map { $_->{fields}->{release} } @{ $module->{hits}->{hits} };
 
 my $release = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     size  => scalar @release_names,
     body  => {
diff --git a/scripts/favorite/6-list-plussers-by-module.pl b/scripts/favorite/6-list-plussers-by-module.pl
index 7837f9c..c30b9d5 100755
--- a/scripts/favorite/6-list-plussers-by-module.pl
+++ b/scripts/favorite/6-list-plussers-by-module.pl
@@ -16,7 +16,7 @@
 my $module = MetaCPAN::Client->new->module($module_name);
 
 my $plussers = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'favorite',
     size  => 1000,
     body  => {
@@ -35,7 +35,7 @@
 my $total = @ids;
 
 my $authors = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'author',
     size  => scalar @ids,
     body  => {
diff --git a/scripts/file/1-get-files-in-dist-es.pl b/scripts/file/1-get-files-in-dist-es.pl
index 7c94a00..30d5431 100755
--- a/scripts/file/1-get-files-in-dist-es.pl
+++ b/scripts/file/1-get-files-in-dist-es.pl
@@ -8,7 +8,7 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'file',
     size  => 300,
     body  => {
diff --git a/scripts/file/2-get-dists-with-cpanfile.pl b/scripts/file/2-get-dists-with-cpanfile.pl
index b61cf55..5f6d7d6 100755
--- a/scripts/file/2-get-dists-with-cpanfile.pl
+++ b/scripts/file/2-get-dists-with-cpanfile.pl
@@ -8,7 +8,7 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'file',
     size  => 10,
     body  => {
diff --git a/scripts/file/3-find-files-in-top-level-by-name.pl b/scripts/file/3-find-files-in-top-level-by-name.pl
index 9abed96..48d9b85 100755
--- a/scripts/file/3-find-files-in-top-level-by-name.pl
+++ b/scripts/file/3-find-files-in-top-level-by-name.pl
@@ -8,7 +8,7 @@
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'file',
     size  => 10,
     body  => {
diff --git a/scripts/file/4-main-search.pl b/scripts/file/4-main-search.pl
index 88e15ba..80f8905 100755
--- a/scripts/file/4-main-search.pl
+++ b/scripts/file/4-main-search.pl
@@ -13,7 +13,7 @@
 }
 
 my $result = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'file',
     body  => {
         query => {
diff --git a/scripts/module/1-fetch-single-module-es.pl b/scripts/module/1-fetch-single-module-es.pl
index 28d671f..633ccbe 100755
--- a/scripts/module/1-fetch-single-module-es.pl
+++ b/scripts/module/1-fetch-single-module-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $module = es()->get(
-    index => 'v1',
+    index => 'cpan',
     type  => 'module',
     id    => 'HTML::Restrict',
 );
diff --git a/scripts/release/1-pkg2url-es.pl b/scripts/release/1-pkg2url-es.pl
index 8bde427..f649693 100755
--- a/scripts/release/1-pkg2url-es.pl
+++ b/scripts/release/1-pkg2url-es.pl
@@ -13,7 +13,7 @@
 );
 
 my $release = $es->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     body  => {
         filter => { term => { 'archive' => 'Acme-Hoge-0.03.tar.gz' } },
diff --git a/scripts/release/1a-module2url-es.pl b/scripts/release/1a-module2url-es.pl
index 5f00475..9767f0b 100755
--- a/scripts/release/1a-module2url-es.pl
+++ b/scripts/release/1a-module2url-es.pl
@@ -13,7 +13,7 @@
 );
 
 my $module = $es->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'file',
     body  => {
         query  => { match_all => {} },
@@ -30,7 +30,7 @@
 my $release_name = $module->{hits}{hits}[0]{_source}{release};
 
 my $release = $es->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     body  => {
         filter => { term => { 'name' => $release_name } },
diff --git a/scripts/release/2-author-upload-leaderboard-es.pl b/scripts/release/2-author-upload-leaderboard-es.pl
index 65d498d..4f538eb 100755
--- a/scripts/release/2-author-upload-leaderboard-es.pl
+++ b/scripts/release/2-author-upload-leaderboard-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     body  => {
         query => { match_all => {} },
diff --git a/scripts/release/3-author-uploads-one-author-es.pl b/scripts/release/3-author-uploads-one-author-es.pl
index 9f54c7d..a7c93eb 100755
--- a/scripts/release/3-author-uploads-one-author-es.pl
+++ b/scripts/release/3-author-uploads-one-author-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     body  => {
         query => {
diff --git a/scripts/release/4-latest-release-versions-es.pl b/scripts/release/4-latest-release-versions-es.pl
index 6fbc2ae..67d74df 100755
--- a/scripts/release/4-latest-release-versions-es.pl
+++ b/scripts/release/4-latest-release-versions-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
-    index  => 'v1',
+    index  => 'cpan',
     type   => 'release',
     fields => [ 'distribution', 'version' ],
     size   => 3,
diff --git a/scripts/release/4a-latest-release-versions-bool-filter-es.pl b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
index 41d6221..6fef45d 100755
--- a/scripts/release/4a-latest-release-versions-bool-filter-es.pl
+++ b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
-    index  => 'v1',
+    index  => 'cpan',
     type   => 'release',
     fields => [ 'distribution', 'version' ],
     size   => 3,
diff --git a/scripts/release/5-latest-releases-by-author-es.pl b/scripts/release/5-latest-releases-by-author-es.pl
index f3cfa71..e9d7916 100755
--- a/scripts/release/5-latest-releases-by-author-es.pl
+++ b/scripts/release/5-latest-releases-by-author-es.pl
@@ -10,7 +10,7 @@
 die "usage: $0 PAUSEID" if !$author;
 
 my $latest = es()->search(
-    index  => 'v1',
+    index  => 'cpan',
     type   => 'release',
     fields => [ 'distribution', 'provides', 'version' ],
     size   => 500,
diff --git a/scripts/release/6-latest-releases-with-git-repo-es.pl b/scripts/release/6-latest-releases-with-git-repo-es.pl
index 334a4e1..63638ed 100755
--- a/scripts/release/6-latest-releases-with-git-repo-es.pl
+++ b/scripts/release/6-latest-releases-with-git-repo-es.pl
@@ -24,7 +24,7 @@
     fields      => [ 'author', 'date', 'distribution', 'name', 'resources' ],
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v1',
+    index       => 'cpan',
     type        => 'release',
     size        => 500,
 );
diff --git a/scripts/release/7-all-releases.pl b/scripts/release/7-all-releases.pl
index be0c5ca..688cfc3 100755
--- a/scripts/release/7-all-releases.pl
+++ b/scripts/release/7-all-releases.pl
@@ -10,7 +10,7 @@
 my $scroller = es()->scroll_helper(
     search_type => 'scan',
     scroll      => '5m',
-    index       => 'v1',
+    index       => 'cpan',
     type        => 'release',
     size        => 1_000,
     body        => { fields => ['download_url'] },
diff --git a/scripts/release/all-releases-by-author.pl b/scripts/release/all-releases-by-author.pl
index b9f11d3..32a5e42 100755
--- a/scripts/release/all-releases-by-author.pl
+++ b/scripts/release/all-releases-by-author.pl
@@ -7,7 +7,7 @@
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
-    index => 'v1',
+    index => 'cpan',
     type  => 'release',
     body  => {
         query => {

From bfe51181ed579453a37aaa93a336e568d5f12e4c Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Sat, 10 Dec 2016 23:08:48 -0500
Subject: [PATCH 08/25] Add a MetaCPAN::Client example for getting all
 releases.

---
 scripts/release/7-all-releases-es.pl | 22 ++++++++++++++++++++++
 scripts/release/7-all-releases.pl    | 20 +++++---------------
 2 files changed, 27 insertions(+), 15 deletions(-)
 create mode 100755 scripts/release/7-all-releases-es.pl
 mode change 100755 => 100644 scripts/release/7-all-releases.pl

diff --git a/scripts/release/7-all-releases-es.pl b/scripts/release/7-all-releases-es.pl
new file mode 100755
index 0000000..688cfc3
--- /dev/null
+++ b/scripts/release/7-all-releases-es.pl
@@ -0,0 +1,22 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw( say );
+
+use Data::Printer;
+use MetaCPAN::Util qw( es );
+
+my $scroller = es()->scroll_helper(
+    search_type => 'scan',
+    scroll      => '5m',
+    index       => 'cpan',
+    type        => 'release',
+    size        => 1_000,
+    body        => { fields => ['download_url'] },
+);
+
+my @urls;
+while ( my $result = $scroller->next ) {
+    push @urls, $result->{fields}->{download_url};
+}
diff --git a/scripts/release/7-all-releases.pl b/scripts/release/7-all-releases.pl
old mode 100755
new mode 100644
index 688cfc3..c00dbfd
--- a/scripts/release/7-all-releases.pl
+++ b/scripts/release/7-all-releases.pl
@@ -1,22 +1,12 @@
-#!/usr/bin/env perl
-
 use strict;
 use warnings;
 use feature qw( say );
 
-use Data::Printer;
-use MetaCPAN::Util qw( es );
+use MetaCPAN::Client ();
 
-my $scroller = es()->scroll_helper(
-    search_type => 'scan',
-    scroll      => '5m',
-    index       => 'cpan',
-    type        => 'release',
-    size        => 1_000,
-    body        => { fields => ['download_url'] },
-);
+my $mc              = MetaCPAN::Client->new;
+my $release_results = $mc->all('releases');
 
-my @urls;
-while ( my $result = $scroller->next ) {
-    push @urls, $result->{fields}->{download_url};
+while ( my $release = $release_results->next ) {
+    say $release->download_url;
 }

From e92ed5a44a98c6f94ec7212ad324288de3c30935 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Sat, 10 Dec 2016 23:11:11 -0500
Subject: [PATCH 09/25] Rename an es script.

---
 scripts/release/7-all-releases.pl                                 | 0
 .../{all-releases-by-author.pl => all-releases-by-author-es.pl}   | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 scripts/release/7-all-releases.pl
 rename scripts/release/{all-releases-by-author.pl => all-releases-by-author-es.pl} (100%)

diff --git a/scripts/release/7-all-releases.pl b/scripts/release/7-all-releases.pl
old mode 100644
new mode 100755
diff --git a/scripts/release/all-releases-by-author.pl b/scripts/release/all-releases-by-author-es.pl
similarity index 100%
rename from scripts/release/all-releases-by-author.pl
rename to scripts/release/all-releases-by-author-es.pl

From 78c12ec410c3499b078a74e5ea451b6cbe0c1ed9 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Sat, 10 Dec 2016 23:12:00 -0500
Subject: [PATCH 10/25] Rename all releases by author script.

---
 ...ll-releases-by-author-es.pl => 8-all-releases-by-author-es.pl} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename scripts/release/{all-releases-by-author-es.pl => 8-all-releases-by-author-es.pl} (100%)

diff --git a/scripts/release/all-releases-by-author-es.pl b/scripts/release/8-all-releases-by-author-es.pl
similarity index 100%
rename from scripts/release/all-releases-by-author-es.pl
rename to scripts/release/8-all-releases-by-author-es.pl

From 871587716328b017732c82a569b059313568cb48 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Sat, 10 Dec 2016 23:28:34 -0500
Subject: [PATCH 11/25] Adds more release examples.

---
 scripts/release/10-all-latest-releases.pl     | 12 +++++++++++
 .../11-all-latest-releases-by-NEILB.pl        | 14 +++++++++++++
 ...t-releases-by-NEILB-with-git-repository.pl | 20 +++++++++++++++++++
 .../9-all-releases-excluding-backpan.pl       | 12 +++++++++++
 4 files changed, 58 insertions(+)
 create mode 100755 scripts/release/10-all-latest-releases.pl
 create mode 100755 scripts/release/11-all-latest-releases-by-NEILB.pl
 create mode 100755 scripts/release/12-all-latest-releases-by-NEILB-with-git-repository.pl
 create mode 100755 scripts/release/9-all-releases-excluding-backpan.pl

diff --git a/scripts/release/10-all-latest-releases.pl b/scripts/release/10-all-latest-releases.pl
new file mode 100755
index 0000000..db8334b
--- /dev/null
+++ b/scripts/release/10-all-latest-releases.pl
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client ();
+
+my $mc = MetaCPAN::Client->new;
+my $release_results = $mc->release( { status => 'latest' } );
+
+while ( my $release = $release_results->next ) {
+    say $release->download_url;
+}
diff --git a/scripts/release/11-all-latest-releases-by-NEILB.pl b/scripts/release/11-all-latest-releases-by-NEILB.pl
new file mode 100755
index 0000000..851663d
--- /dev/null
+++ b/scripts/release/11-all-latest-releases-by-NEILB.pl
@@ -0,0 +1,14 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client ();
+
+my $mc = MetaCPAN::Client->new;
+my $release_results
+    = $mc->release(
+    { all => [ { author => 'NEILB', }, { status => 'latest' } ] } );
+
+while ( my $release = $release_results->next ) {
+    say $release->download_url;
+}
diff --git a/scripts/release/12-all-latest-releases-by-NEILB-with-git-repository.pl b/scripts/release/12-all-latest-releases-by-NEILB-with-git-repository.pl
new file mode 100755
index 0000000..79973f3
--- /dev/null
+++ b/scripts/release/12-all-latest-releases-by-NEILB-with-git-repository.pl
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client ();
+
+my $mc              = MetaCPAN::Client->new;
+my $release_results = $mc->release(
+    {
+        all => [
+            { author                      => 'NEILB', },
+            { status                      => 'latest' },
+            { 'resources.repository.type' => 'git' }
+        ]
+    }
+);
+
+while ( my $release = $release_results->next ) {
+    say $release->resources->{repository}->{url};
+}
diff --git a/scripts/release/9-all-releases-excluding-backpan.pl b/scripts/release/9-all-releases-excluding-backpan.pl
new file mode 100755
index 0000000..4418ae6
--- /dev/null
+++ b/scripts/release/9-all-releases-excluding-backpan.pl
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client ();
+
+my $mc = MetaCPAN::Client->new;
+my $release_results = $mc->release( { not => { status => 'backpan' } } );
+
+while ( my $release = $release_results->next ) {
+    say $release->download_url;
+}

From 391927beb9e416fa71bf3bbb2e599c30a7a6986b Mon Sep 17 00:00:00 2001
From: Mickey Nasriachi <mickey@cpan.org>
Date: Sun, 11 Dec 2016 10:50:56 +0100
Subject: [PATCH 12/25] load MetaCPAN::Util in example scripts

---
 scripts/author/1-fetch-single-author-es.pl            | 10 +++-------
 scripts/author/1b-scroll-all-authors-es.pl            |  1 +
 .../author/1c-scroll-all-authors-with-twitter-es.pl   |  1 +
 scripts/author/2-twitter-or-github-es.pl              |  1 +
 scripts/distribution/1-bugs-for-dist-es.pl            |  1 +
 scripts/favorite/1-last-50-favorited-dists-es.pl      |  1 +
 .../1a-last-100-favorited-dists-by-user-es.pl         |  1 +
 scripts/favorite/2-favorites-previous-month-es.pl     |  1 +
 scripts/favorite/3-leaderboard-es.pl                  |  1 +
 scripts/favorite/4-leaderboard-previous-month-es.pl   |  1 +
 scripts/favorite/5-plus-plus-your-favorites-es.pl     |  1 +
 scripts/favorite/6-list-plussers-by-module.pl         |  1 +
 scripts/file/1-get-files-in-dist-es.pl                |  1 +
 scripts/file/2-get-dists-with-cpanfile.pl             |  1 +
 scripts/file/3-find-files-in-top-level-by-name.pl     |  1 +
 scripts/file/4-main-search.pl                         |  1 +
 scripts/module/1-fetch-single-module-es.pl            |  1 +
 scripts/release/1-pkg2url-es.pl                       | 11 +++--------
 scripts/release/1a-module2url-es.pl                   | 11 ++++-------
 scripts/release/2-author-upload-leaderboard-es.pl     |  2 ++
 scripts/release/3-author-uploads-one-author-es.pl     |  1 +
 scripts/release/4-latest-release-versions-es.pl       |  2 ++
 .../4a-latest-release-versions-bool-filter-es.pl      |  1 +
 scripts/release/5-latest-releases-by-author-es.pl     |  2 ++
 scripts/release/6-latest-releases-with-git-repo-es.pl |  1 +
 scripts/release/7-all-releases-es.pl                  |  2 ++
 scripts/release/8-all-releases-by-author-es.pl        |  1 +
 27 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/scripts/author/1-fetch-single-author-es.pl b/scripts/author/1-fetch-single-author-es.pl
index 5d61d79..1fb7187 100755
--- a/scripts/author/1-fetch-single-author-es.pl
+++ b/scripts/author/1-fetch-single-author-es.pl
@@ -4,15 +4,11 @@
 use warnings;
 
 use Data::Printer;
-use Search::Elasticsearch;
 
-my $es = Search::Elasticsearch->new(
-    cxn_pool => 'Static::NoPing',
-    nodes    => 'fastapi.metacpan.org',
-    trace_to => 'Stdout',
-);
+use lib './lib';
+use MetaCPAN::Util qw( es );
 
-my $author = $es->get(
+my $author = es->get(
     index => 'cpan',
     type  => 'author',
     id    => 'MSTROUT',
diff --git a/scripts/author/1b-scroll-all-authors-es.pl b/scripts/author/1b-scroll-all-authors-es.pl
index 85c23a0..b24b0a3 100755
--- a/scripts/author/1b-scroll-all-authors-es.pl
+++ b/scripts/author/1b-scroll-all-authors-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $scroller = es()->scroll_helper(
diff --git a/scripts/author/1c-scroll-all-authors-with-twitter-es.pl b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
index a9d1c69..1b1e0fe 100755
--- a/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
+++ b/scripts/author/1c-scroll-all-authors-with-twitter-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $scroller = es()->scroll_helper(
diff --git a/scripts/author/2-twitter-or-github-es.pl b/scripts/author/2-twitter-or-github-es.pl
index 439a732..32b8837 100755
--- a/scripts/author/2-twitter-or-github-es.pl
+++ b/scripts/author/2-twitter-or-github-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 use feature qw( say );
 
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $scroller = es()->scroll_helper(
diff --git a/scripts/distribution/1-bugs-for-dist-es.pl b/scripts/distribution/1-bugs-for-dist-es.pl
index 9cb0ec9..631ad5b 100755
--- a/scripts/distribution/1-bugs-for-dist-es.pl
+++ b/scripts/distribution/1-bugs-for-dist-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $dist = es()->get(
diff --git a/scripts/favorite/1-last-50-favorited-dists-es.pl b/scripts/favorite/1-last-50-favorited-dists-es.pl
index 695eb78..5901d91 100755
--- a/scripts/favorite/1-last-50-favorited-dists-es.pl
+++ b/scripts/favorite/1-last-50-favorited-dists-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $faves = es()->search(
diff --git a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
index 2d7904a..608935b 100755
--- a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
+++ b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $id = shift @ARGV;
diff --git a/scripts/favorite/2-favorites-previous-month-es.pl b/scripts/favorite/2-favorites-previous-month-es.pl
index ca45c40..252760f 100755
--- a/scripts/favorite/2-favorites-previous-month-es.pl
+++ b/scripts/favorite/2-favorites-previous-month-es.pl
@@ -5,6 +5,7 @@
 
 use Data::Printer;
 use DateTime;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $now = DateTime->now;
diff --git a/scripts/favorite/3-leaderboard-es.pl b/scripts/favorite/3-leaderboard-es.pl
index a6b33b8..2b68b35 100755
--- a/scripts/favorite/3-leaderboard-es.pl
+++ b/scripts/favorite/3-leaderboard-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $faves = es()->search(
diff --git a/scripts/favorite/4-leaderboard-previous-month-es.pl b/scripts/favorite/4-leaderboard-previous-month-es.pl
index d38e9a5..d516095 100755
--- a/scripts/favorite/4-leaderboard-previous-month-es.pl
+++ b/scripts/favorite/4-leaderboard-previous-month-es.pl
@@ -5,6 +5,7 @@
 
 use Data::Printer;
 use DateTime;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $now = DateTime->now;
diff --git a/scripts/favorite/5-plus-plus-your-favorites-es.pl b/scripts/favorite/5-plus-plus-your-favorites-es.pl
index 26ee015..f611fa8 100755
--- a/scripts/favorite/5-plus-plus-your-favorites-es.pl
+++ b/scripts/favorite/5-plus-plus-your-favorites-es.pl
@@ -6,6 +6,7 @@
 use Data::Printer;
 use HTTP::Tiny ();
 use JSON::MaybeXS qw( encode_json );
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $token   = shift @ARGV;
diff --git a/scripts/favorite/6-list-plussers-by-module.pl b/scripts/favorite/6-list-plussers-by-module.pl
index c30b9d5..49a4127 100755
--- a/scripts/favorite/6-list-plussers-by-module.pl
+++ b/scripts/favorite/6-list-plussers-by-module.pl
@@ -5,6 +5,7 @@
 use feature qw( say );
 
 use MetaCPAN::Client;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 binmode( STDOUT, ":utf8" );
diff --git a/scripts/file/1-get-files-in-dist-es.pl b/scripts/file/1-get-files-in-dist-es.pl
index 30d5431..f80f37d 100755
--- a/scripts/file/1-get-files-in-dist-es.pl
+++ b/scripts/file/1-get-files-in-dist-es.pl
@@ -5,6 +5,7 @@
 use feature qw( say );
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
diff --git a/scripts/file/2-get-dists-with-cpanfile.pl b/scripts/file/2-get-dists-with-cpanfile.pl
index 5f6d7d6..224837e 100755
--- a/scripts/file/2-get-dists-with-cpanfile.pl
+++ b/scripts/file/2-get-dists-with-cpanfile.pl
@@ -5,6 +5,7 @@
 use feature qw( say );
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
diff --git a/scripts/file/3-find-files-in-top-level-by-name.pl b/scripts/file/3-find-files-in-top-level-by-name.pl
index 48d9b85..aeafec4 100755
--- a/scripts/file/3-find-files-in-top-level-by-name.pl
+++ b/scripts/file/3-find-files-in-top-level-by-name.pl
@@ -5,6 +5,7 @@
 use feature qw( say );
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $files = es()->search(
diff --git a/scripts/file/4-main-search.pl b/scripts/file/4-main-search.pl
index 80f8905..40f8c0d 100755
--- a/scripts/file/4-main-search.pl
+++ b/scripts/file/4-main-search.pl
@@ -5,6 +5,7 @@
 
 use Data::Printer;
 use JSON::MaybeXS qw( decode_json );
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $search_term = shift @ARGV || 'HTML-Re';
diff --git a/scripts/module/1-fetch-single-module-es.pl b/scripts/module/1-fetch-single-module-es.pl
index 633ccbe..6698c11 100755
--- a/scripts/module/1-fetch-single-module-es.pl
+++ b/scripts/module/1-fetch-single-module-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $module = es()->get(
diff --git a/scripts/release/1-pkg2url-es.pl b/scripts/release/1-pkg2url-es.pl
index f649693..9d5f94a 100755
--- a/scripts/release/1-pkg2url-es.pl
+++ b/scripts/release/1-pkg2url-es.pl
@@ -4,15 +4,10 @@
 use warnings;
 use feature qw( say );
 
-use Search::Elasticsearch;
+use lib './lib';
+use MetaCPAN::Util qw( es );
 
-my $es = Search::Elasticsearch->new(
-    cxn_pool => 'Static::NoPing',
-    nodes    => 'https://fastapi.metacpan.org',
-    trace_to => 'Stdout',
-);
-
-my $release = $es->search(
+my $release = es->search(
     index => 'cpan',
     type  => 'release',
     body  => {
diff --git a/scripts/release/1a-module2url-es.pl b/scripts/release/1a-module2url-es.pl
index 9767f0b..9ffd498 100755
--- a/scripts/release/1a-module2url-es.pl
+++ b/scripts/release/1a-module2url-es.pl
@@ -6,13 +6,10 @@
 
 use Search::Elasticsearch;
 
-my $es = Search::Elasticsearch->new(
-    cxn_pool => 'Static::NoPing',
-    nodes    => 'https://fastapi.metacpan.org',
-    trace_to => 'Stdout',
-);
+use lib './lib';
+use MetaCPAN::Util qw( es );
 
-my $module = $es->search(
+my $module = es->search(
     index => 'cpan',
     type  => 'file',
     body  => {
@@ -29,7 +26,7 @@
 
 my $release_name = $module->{hits}{hits}[0]{_source}{release};
 
-my $release = $es->search(
+my $release = es->search(
     index => 'cpan',
     type  => 'release',
     body  => {
diff --git a/scripts/release/2-author-upload-leaderboard-es.pl b/scripts/release/2-author-upload-leaderboard-es.pl
index 4f538eb..c71bd65 100755
--- a/scripts/release/2-author-upload-leaderboard-es.pl
+++ b/scripts/release/2-author-upload-leaderboard-es.pl
@@ -4,6 +4,8 @@
 use warnings;
 
 use Data::Printer;
+
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
diff --git a/scripts/release/3-author-uploads-one-author-es.pl b/scripts/release/3-author-uploads-one-author-es.pl
index a7c93eb..062a860 100755
--- a/scripts/release/3-author-uploads-one-author-es.pl
+++ b/scripts/release/3-author-uploads-one-author-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 use feature qw( say );
 
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(
diff --git a/scripts/release/4-latest-release-versions-es.pl b/scripts/release/4-latest-release-versions-es.pl
index 67d74df..a53d8b1 100755
--- a/scripts/release/4-latest-release-versions-es.pl
+++ b/scripts/release/4-latest-release-versions-es.pl
@@ -4,6 +4,8 @@
 use warnings;
 
 use Data::Printer;
+
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
diff --git a/scripts/release/4a-latest-release-versions-bool-filter-es.pl b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
index 6fef45d..a5c0a09 100755
--- a/scripts/release/4a-latest-release-versions-bool-filter-es.pl
+++ b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $latest = es()->search(
diff --git a/scripts/release/5-latest-releases-by-author-es.pl b/scripts/release/5-latest-releases-by-author-es.pl
index e9d7916..9f6dbff 100755
--- a/scripts/release/5-latest-releases-by-author-es.pl
+++ b/scripts/release/5-latest-releases-by-author-es.pl
@@ -4,6 +4,8 @@
 use warnings;
 
 use Data::Printer;
+
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $author = shift @ARGV;
diff --git a/scripts/release/6-latest-releases-with-git-repo-es.pl b/scripts/release/6-latest-releases-with-git-repo-es.pl
index 63638ed..34cbd2c 100755
--- a/scripts/release/6-latest-releases-with-git-repo-es.pl
+++ b/scripts/release/6-latest-releases-with-git-repo-es.pl
@@ -5,6 +5,7 @@
 use feature qw( say );
 
 use Data::Printer;
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my @must = (
diff --git a/scripts/release/7-all-releases-es.pl b/scripts/release/7-all-releases-es.pl
index 688cfc3..80ecb56 100755
--- a/scripts/release/7-all-releases-es.pl
+++ b/scripts/release/7-all-releases-es.pl
@@ -5,6 +5,8 @@
 use feature qw( say );
 
 use Data::Printer;
+
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $scroller = es()->scroll_helper(
diff --git a/scripts/release/8-all-releases-by-author-es.pl b/scripts/release/8-all-releases-by-author-es.pl
index 32a5e42..ede3d9a 100755
--- a/scripts/release/8-all-releases-by-author-es.pl
+++ b/scripts/release/8-all-releases-by-author-es.pl
@@ -4,6 +4,7 @@
 use warnings;
 use feature qw( say );
 
+use lib './lib';
 use MetaCPAN::Util qw( es );
 
 my $uploads = es()->search(

From 357f3d1d7499e0432bfbbfb6bb0d91302009ad48 Mon Sep 17 00:00:00 2001
From: Mickey Nasriachi <mickey@cpan.org>
Date: Sun, 4 Jun 2017 18:11:41 +0200
Subject: [PATCH 13/25] update scroller_helper/query

---
 scripts/release/6-latest-releases-with-git-repo-es.pl | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/scripts/release/6-latest-releases-with-git-repo-es.pl b/scripts/release/6-latest-releases-with-git-repo-es.pl
index 34cbd2c..42b7bea 100755
--- a/scripts/release/6-latest-releases-with-git-repo-es.pl
+++ b/scripts/release/6-latest-releases-with-git-repo-es.pl
@@ -17,12 +17,10 @@
 my $scroller = es()->scroll_helper(
     body => {
         query => {
-            filtered => {
-                filter => { bool => { must => \@must } },
-            },
+            bool => { must => \@must },
         },
     },
-    fields      => [ 'author', 'date', 'distribution', 'name', 'resources' ],
+    _source     => [ 'author', 'date', 'distribution', 'name', 'resources' ],
     search_type => 'scan',
     scroll      => '5m',
     index       => 'cpan',

From b2c3e9dbd8441b0bbbabedb38fca3dcc5aa1c927 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 23 Feb 2018 13:47:49 -0500
Subject: [PATCH 14/25] Add a script to aggregate author upload permissions

---
 scripts/permission/aggregate-author-perms.pl | 82 ++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 scripts/permission/aggregate-author-perms.pl

diff --git a/scripts/permission/aggregate-author-perms.pl b/scripts/permission/aggregate-author-perms.pl
new file mode 100644
index 0000000..767a8e9
--- /dev/null
+++ b/scripts/permission/aggregate-author-perms.pl
@@ -0,0 +1,82 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use CLDR::Number ();
+use Cpanel::JSON::XS qw( decode_json );
+use Data::Printer;
+use List::Compare ();
+use Math::Round qw( nearest );
+use Parse::CPAN::Packages::Fast ();
+use WWW::Mechanize::Cached      ();
+
+use CLDR::Number;
+my $cldr = CLDR::Number->new( locale => 'en' );
+my $decf = $cldr->decimal_formatter;
+my $perf = $cldr->percent_formatter(minimum_fraction_digits => 2);
+
+my @maxmind_authors = (
+    'OALDERS',  'EILARA', 'TJMATHER', 'MATEU', 'OSCHWALD', 'RSRCHBOY',
+    'FLORA',    'MARKF',  'RUBEN',    'WDS',   'KLPTWO',   'PCRONIN',
+    'ANDYJACK', 'MAXMIND',
+);
+my @maxmind_redacted_authors = (
+    'OALDERS', 'EILARA', 'TJMATHER', 'MATEU',  'OSCHWALD', 'RSRCHBOY',
+    'MARKF',   'RUBEN',  'WDS',      'KLPTWO', 'PCRONIN',
+    'ANDYJACK',
+);
+my @pts_authors = (
+    'ABELJTE', 'ANDK', 'ARC', 'ARISTOTLE', 'ATOOMIC', 'BINGOS', 'BOOK',
+    'ELBEHO',    'ELIZABETH', 'ETHER', 'GARU',   'HAARG',   'HMBRAND', 'INGY',
+    'ISHIGAKI',  'JBERGER',   'LEEJO', 'LEONT',  'LLAP',    'MICKEY',
+    'MITHALDU',  'MOHAWK',    'NEILB', 'NINE',   'OALDERS', 'PJCJ',
+    'PREACTION', 'SARGIE',    'SKAJI', 'SREZIC', 'TADZIK',  'TINITA',
+    'TODDR', 'UGEXE', 'WOLFSAGE', 'XSAWYERX',
+);
+
+my $parser = Parse::CPAN::Packages::Fast->new('02packages.details.txt');
+crunch_numbers( 'MM+PTS', [ @maxmind_authors, @pts_authors ] );
+crunch_numbers( 'PTS', \@pts_authors );
+crunch_numbers( 'DROLSKY', ['DROLSKY'] );
+crunch_numbers( 'MM', \@maxmind_authors );
+crunch_numbers( 'ETHER+FLORA', [ 'ETHER', 'FLORA' ] );
+crunch_numbers( 'ETHER',       ['ETHER'] );
+crunch_numbers( 'FLORA',       ['FLORA'] );
+crunch_numbers( 'MM-FLORA', \@maxmind_redacted_authors );
+crunch_numbers( 'OALDERS', ['OALDERS'] );
+
+sub crunch_numbers {
+    my $title   = shift;
+    my $authors = shift;
+    my %perms   = get_permissions($authors);
+    my $lc = List::Compare->new( [ $parser->packages ], [ keys %perms ] );
+    my @covered = $lc->get_intersection;
+
+    my $percent = nearest(
+        0.0001,
+        scalar @covered / ( scalar $parser->packages )
+    );
+
+    say join '|', $title, $decf->format( scalar keys %perms ),
+        $decf->format( scalar @covered ), $perf->format($percent);
+}
+
+sub get_permissions {
+    my $authors = shift;
+    my $mech    = WWW::Mechanize::Cached->new;
+
+    my %modules;
+
+    my $base_url = 'http://fastapi.metacpan.org/v1/permission/by_author';
+    foreach my $author ( @{$authors} ) {
+        my $url = "$base_url/$author";
+        $mech->get($url);
+        my $perms = decode_json( $mech->content );
+
+        foreach my $perm ( @{ $perms->{permissions} } ) {
+            push @{ $modules{ $perm->{module_name} } }, $author;
+        }
+    }
+
+    return %modules;
+}

From 8de991db8038d43115c6b48cb70206d07f414bbd Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Fri, 23 Feb 2018 13:48:16 -0500
Subject: [PATCH 15/25] Add script to get all releases in last 24 hours

---
 .../13-all-releases-in-last-24-hours.pl       | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 scripts/release/13-all-releases-in-last-24-hours.pl

diff --git a/scripts/release/13-all-releases-in-last-24-hours.pl b/scripts/release/13-all-releases-in-last-24-hours.pl
new file mode 100644
index 0000000..7792f11
--- /dev/null
+++ b/scripts/release/13-all-releases-in-last-24-hours.pl
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+use feature qw( say );
+
+use DateTime         ();
+use MetaCPAN::Client ();
+
+my $now = DateTime->now;
+my $then = DateTime->now->subtract( days => 1 );
+
+my $mc = MetaCPAN::Client->new;
+
+my $release_set = $mc->all(
+    'releases',
+    {
+        es_filter => {
+            range => { date => { from => $then->datetime } },
+        },
+    }
+);
+
+while ( my $release = $release_set->next ) {
+    say $release->download_url;
+}

From efe4c1242f11917500bab7c3f36f14624e3ea8d5 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Wed, 6 Feb 2019 13:19:09 -0500
Subject: [PATCH 16/25] Update permissions aggregator to use PTS groups

---
 .gitignore                                   |   5 +-
 scripts/permission/aggregate-author-perms.pl | 148 +++++++++++++++----
 2 files changed, 125 insertions(+), 28 deletions(-)
 mode change 100644 => 100755 scripts/permission/aggregate-author-perms.pl

diff --git a/.gitignore b/.gitignore
index 521ef88..6a014ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
-*.swp
+02packages.details.txt
 .carton
-.tidyall.d/
 cpanfile.snapshot
 local
+*.swp
+.tidyall.d/
diff --git a/scripts/permission/aggregate-author-perms.pl b/scripts/permission/aggregate-author-perms.pl
old mode 100644
new mode 100755
index 767a8e9..e8decbb
--- a/scripts/permission/aggregate-author-perms.pl
+++ b/scripts/permission/aggregate-author-perms.pl
@@ -1,3 +1,5 @@
+#!/usr/bin/env perl
+
 use strict;
 use warnings;
 use feature qw( say );
@@ -5,15 +7,15 @@
 use CLDR::Number ();
 use Cpanel::JSON::XS qw( decode_json );
 use Data::Printer;
-use List::Compare ();
+use List::Compare  ();
+use LWP::UserAgent ();
 use Math::Round qw( nearest );
 use Parse::CPAN::Packages::Fast ();
 use WWW::Mechanize::Cached      ();
 
-use CLDR::Number;
 my $cldr = CLDR::Number->new( locale => 'en' );
 my $decf = $cldr->decimal_formatter;
-my $perf = $cldr->percent_formatter(minimum_fraction_digits => 2);
+my $perf = $cldr->percent_formatter( minimum_fraction_digits => 2 );
 
 my @maxmind_authors = (
     'OALDERS',  'EILARA', 'TJMATHER', 'MATEU', 'OSCHWALD', 'RSRCHBOY',
@@ -22,40 +24,134 @@
 );
 my @maxmind_redacted_authors = (
     'OALDERS', 'EILARA', 'TJMATHER', 'MATEU',  'OSCHWALD', 'RSRCHBOY',
-    'MARKF',   'RUBEN',  'WDS',      'KLPTWO', 'PCRONIN',
-    'ANDYJACK',
+    'MARKF',   'RUBEN',  'WDS',      'KLPTWO', 'PCRONIN',  'ANDYJACK',
 );
-my @pts_authors = (
-    'ABELJTE', 'ANDK', 'ARC', 'ARISTOTLE', 'ATOOMIC', 'BINGOS', 'BOOK',
-    'ELBEHO',    'ELIZABETH', 'ETHER', 'GARU',   'HAARG',   'HMBRAND', 'INGY',
-    'ISHIGAKI',  'JBERGER',   'LEEJO', 'LEONT',  'LLAP',    'MICKEY',
-    'MITHALDU',  'MOHAWK',    'NEILB', 'NINE',   'OALDERS', 'PJCJ',
-    'PREACTION', 'SARGIE',    'SKAJI', 'SREZIC', 'TADZIK',  'TINITA',
-    'TODDR', 'UGEXE', 'WOLFSAGE', 'XSAWYERX',
+
+my %PTS = (
+    'qa2010' => [
+        'CHORNY',   'HMBRAND',  'RURBAN',   'MARCEL',
+        'BOOK',     'BDFOY',    'ANDYA',    'POTYL',
+        'DAXIM',    'ABELTJE',  'OVID',     'HORNBURG',
+        'DOMM',     'MIYAGAWA', 'PJCJ',     'BARBIE',
+        'FLORA',    'RJBS',     'JKUTEJ',   'SREZIC',
+        'MSCHWERN', 'SZABGAB',  'RGIERSIG', 'SQUEEK',
+        'PEPL'
+    ],
+    'qa2011' => [
+        'RGE',      'HMBRAND', 'MARCEL', 'SCHWIGON',
+        'LEONT',    'BOOK',    'BDFOY',  'ANDYA',
+        'AVAR',     'POTYL',   'DAXIM',  'ABELTJE',
+        'SMUELLER', 'OVID',    'DOLMEN', 'WESJDJ',
+        'SAPER',    'ADAMK',   'PJCJ',   'FLORA',
+        'ABIGAIL',  'RJBS',    'PERLER', 'DGL',
+        'JKUTEJ',   'WONKO',   'ADIE',   'BURAK'
+    ],
+    'qa2012' => [
+        'XAV',      'HMBRAND',   'CHESSKIT', 'NPEREZ',
+        'RGARCIA',  'ELIZABETH', 'DAGOLDEN', 'SCHWIGON',
+        'LEONT',    'BOOK',      'BDFOY',    'ANDYA',
+        'HAGGAI',   'GETTY',     'DAXIM',    'DDUMONT',
+        'ABELTJE',  'OVID',      'ELBEHO',   'WOLFSAGE',
+        'DOLMEN',   'WESJDJ',    'PAUAMMA',  'SAPER',
+        'OALDERS',  'MIYAGAWA',  'PJCJ',     'BARBIE',
+        'FLORA',    'VPIT',      'RJBS',     'DGL',
+        'ISHIGAKI', 'WONKO',     'SREZIC',   'MSCHWERN',
+        'GARU',     'RIBASUSHI', 'ADIE',     'APEIRON',
+        'ANDK'
+    ],
+    'qa2013' => [
+        'PERRETTDL', 'SJN',      'TBSLIVER',  'JROBINSON',
+        'MITHALDU',  'HMBRAND',  'ELIZABETH', 'DAGOLDEN',
+        'SCHWIGON',  'JKEENAN',  'LEONT',     'BOOK',
+        'BANNAN',    'ANDYA',    'DREBOLO',   'PDCAWLEY',
+        'GETTY',     'BINGOS',   'ABELTJE',   'REHSACK',
+        'BYTEROCK',  'WOLFSAGE', 'DOLMEN',    'BBUSS',
+        'PJCJ',      'BARBIE',   'ARC',       'RJBS',
+        'DGL',       'ISHIGAKI', 'RIBASUSHI', 'JMASTROS',
+        'ANDK',      'NEWELLC'
+    ],
+    'qa2014' => [
+        'SJN',       'ETHER',    'MITHALDU', 'HMBRAND',
+        'ELIZABETH', 'DAGOLDEN', 'SCHWIGON', 'LEONT',
+        'BOOK',      'DAMS',     'MSTROUT',  'ABELTJE',
+        'TIMB',      'FROGGS',   'OVID',     'REHSACK',
+        'ELBEHO',    'WOLFSAGE', 'DOLMEN',   'SAPER',
+        'OALDERS',   'PJCJ',     'BARBIE',   'RJBS',
+        'ISHIGAKI',  'NEILB',    'SREZIC',   'RIBASUSHI',
+        'HAARG',     'ANDK'
+    ],
+    'qa2015' => [
+        'SJN',       'ETHER',     'MITHALDU',  'HMBRAND',
+        'ELIZABETH', 'DAGOLDEN',  'SCHWIGON',  'LEONT',
+        'EXODIST',   'BOOK',      'TADZIK',    'TINITA',
+        'ABELTJE',   'INGY',      'FROGGS',    'REHSACK',
+        'WOLFSAGE',  'DOLMEN',    'OALDERS',   'WOLLMERS',
+        'MIYAGAWA',  'PJCJ',      'BARBIE',    'BARTOLIN',
+        'RJBS',      'ISHIGAKI',  'NEILB',     'SREZIC',
+        'DRTECH',    'RIBASUSHI', 'LICHTKIND', 'ARISTOTLE',
+        'ANDK',      'NINE'
+    ],
+    'qa2016' => [
+        'ETHER',    'HMBRAND', 'LLAP',      'ELIZABETH',
+        'SCHWIGON', 'JKEENAN', 'LEONT',     'EXODIST',
+        'BOOK',     'TADZIK',  'MICKEY',    'BINGOS',
+        'ABELTJE',  'TIMB',    'JBERGER',   'WOLFSAGE',
+        'DOLMEN',   'OALDERS', 'PJCJ',      'BARBIE',
+        'ARC',      'RJBS',    'ISHIGAKI',  'XSAWYERX',
+        'NEILB',    'SREZIC',  'ARISTOTLE', 'SARGIE',
+        'ANDK'
+    ],
+    'qa2017' => [
+        'ETHER',     'MITHALDU', 'HMBRAND',   'LEEJO',
+        'LLAP',      'SKAJI',    'ELIZABETH', 'LEONT',
+        'UGEXE',     'BOOK',     'TODDR',     'PREACTION',
+        'TADZIK',    'MICKEY',   'BINGOS',    'TINITA',
+        'ABELTJE',   'INGY',     'JBERGER',   'ELBEHO',
+        'WOLFSAGE',  'OALDERS',  'MIYAGAWA',  'PJCJ',
+        'ARC',       'ETJ',      'ISHIGAKI',  'XSAWYERX',
+        'NEILB',     'SREZIC',   'GARU',      'ATOOMIC',
+        'ARISTOTLE', 'HAARG',    'ANDK',      'NINE'
+    ],
 );
 
+my $ua = LWP::UserAgent->new;
+$ua->mirror( 'https://cpan.metacpan.org/modules/02packages.details.txt',
+    '02packages.details.txt' );
+
 my $parser = Parse::CPAN::Packages::Fast->new('02packages.details.txt');
-crunch_numbers( 'MM+PTS', [ @maxmind_authors, @pts_authors ] );
-crunch_numbers( 'PTS', \@pts_authors );
-crunch_numbers( 'DROLSKY', ['DROLSKY'] );
-crunch_numbers( 'MM', \@maxmind_authors );
-crunch_numbers( 'ETHER+FLORA', [ 'ETHER', 'FLORA' ] );
-crunch_numbers( 'ETHER',       ['ETHER'] );
-crunch_numbers( 'FLORA',       ['FLORA'] );
-crunch_numbers( 'MM-FLORA', \@maxmind_redacted_authors );
-crunch_numbers( 'OALDERS', ['OALDERS'] );
+
+say join '|',
+    (
+    q{},
+    q{},
+    'Modules with maint',
+    'Modules in 02packages',
+    '% of modules in 02packages',
+    );
+say join '---', ( ('|') x 5 );
+
+for my $author ( sort @{$PTS{qa2017}} ) {
+    crunch_numbers( $author, [$author]);
+}
+
+for my $group_name ( sort keys %PTS ) {
+    crunch_numbers( $group_name, $PTS{$group_name} );
+}
 
 sub crunch_numbers {
     my $title   = shift;
     my $authors = shift;
-    my %perms   = get_permissions($authors);
+
+    # The modules which these authors have release permissions on.
+    my %perms = get_permissions($authors);
+
     my $lc = List::Compare->new( [ $parser->packages ], [ keys %perms ] );
+
+    # The permissioned modules which actually appear in 02packages.
     my @covered = $lc->get_intersection;
 
-    my $percent = nearest(
-        0.0001,
-        scalar @covered / ( scalar $parser->packages )
-    );
+    my $percent
+        = nearest( 0.0001, scalar @covered / ( scalar $parser->packages ) );
 
     say join '|', $title, $decf->format( scalar keys %perms ),
         $decf->format( scalar @covered ), $perf->format($percent);

From 9ed5824cfea80cca1c730bd43d251517c0d72386 Mon Sep 17 00:00:00 2001
From: Olaf Alders <olaf@wundersolutions.com>
Date: Thu, 23 May 2019 01:08:11 -0400
Subject: [PATCH 17/25] Add example to find all author Twitter accounts

---
 scripts/author/twitter.pl | 46 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100755 scripts/author/twitter.pl

diff --git a/scripts/author/twitter.pl b/scripts/author/twitter.pl
new file mode 100755
index 0000000..c6a6508
--- /dev/null
+++ b/scripts/author/twitter.pl
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw( say );
+
+use MetaCPAN::Client;
+
+my $mc = MetaCPAN::Client->new( version => 'v1' );
+
+# Search for authors with a listed Twitter account
+my $search = $mc->author( { 'profile.name' => 'twitter' } );
+
+my @handles;
+while ( my $author = $search->next ) {
+
+    # grep matching author profiles to extract only the Twitter id
+    my @profiles = grep { $_->{name} eq 'twitter' } @{ $author->profile };
+
+    foreach my $profile (@profiles) {
+        my $id = $profile->{id};
+
+        # not every handle returned by the API is prefixed by "@", so
+        # we'll add it when it's missing
+        $id = '@' . $id unless $id =~ m{\A@};
+        push @handles, $id;
+    }
+}
+
+# print a case-insensitive alpha-sorted list for humans to enjoy
+say $_ for sort { "\L$a" cmp "\L$b" } @handles;
+
+=pod
+
+=head1 SYNOPSIS
+
+To create your own Twitter list of CPAN authors install and configure
+L<https://github.com/sferik/t>
+
+Then run:
+
+    t list create cpan-authors
+    perl scripts/author/twitter.pl | xargs t list add cpan-authors
+    t list cpan-authors members
+
+=cut

From 8b48ccbe1a8cdc7d015c9b6581c20b8aa55ab60f Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Sun, 26 Sep 2021 02:44:48 -0400
Subject: [PATCH 18/25] Update a couple favorite scripts for current API

---
 scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl | 2 +-
 scripts/favorite/4-leaderboard-previous-month-es.pl        | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
index 608935b..41ed3cc 100755
--- a/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
+++ b/scripts/favorite/1a-last-100-favorited-dists-by-user-es.pl
@@ -18,7 +18,7 @@
         query => {
             filtered => {
                 query  => { match_all => {} },
-                filter => { term      => { 'favorite.user' => $id } }
+                filter => { term      => { 'user' => $id } }
             },
         },
         sort => [ { date => 'desc' } ],
diff --git a/scripts/favorite/4-leaderboard-previous-month-es.pl b/scripts/favorite/4-leaderboard-previous-month-es.pl
index d516095..f8e1cc5 100755
--- a/scripts/favorite/4-leaderboard-previous-month-es.pl
+++ b/scripts/favorite/4-leaderboard-previous-month-es.pl
@@ -8,7 +8,7 @@
 use lib './lib';
 use MetaCPAN::Util qw( es );
 
-my $now = DateTime->now;
+my $now  = DateTime->now;
 my $then = $now->clone->subtract( months => 1 );
 
 my $faves = es()->search(
@@ -34,6 +34,6 @@
     size => 0,
 );
 
-my @dists = map { $_->{terms} } $faves->{facets}->{dist};
+my @dists = @{ $faves->{aggregations}{dist}{buckets} };
 
 p @dists;

From 2338c0d89db5646601bdaeb539a58ee3b7b5b8fe Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Sun, 10 Jul 2022 07:20:51 -0400
Subject: [PATCH 19/25] Use 2.x Elasticsearch client

---
 cpanfile             | 3 +++
 lib/MetaCPAN/Util.pm | 1 +
 2 files changed, 4 insertions(+)

diff --git a/cpanfile b/cpanfile
index 3753f1b..8d18c66 100644
--- a/cpanfile
+++ b/cpanfile
@@ -8,6 +8,9 @@ requires 'IO::Socket::SSL';
 requires 'JSON::MaybeXS';
 requires 'MetaCPAN::API::Tiny';
 requires 'MetaCPAN::Client', '>= 2.000000';
+requires 'Search::Elasticsearch';
+requires 'Search::Elasticsearch::Client::2_0::Direct';
+requires 'Sub::Exporter';
 requires 'WWW::Mechanize::Cached';
 requires 'WWW::Mechanize::Cached::GZip';
 
diff --git a/lib/MetaCPAN/Util.pm b/lib/MetaCPAN/Util.pm
index b140451..58983e4 100644
--- a/lib/MetaCPAN/Util.pm
+++ b/lib/MetaCPAN/Util.pm
@@ -8,6 +8,7 @@ use Sub::Exporter -setup => { exports => ['es'] };
 
 sub es {
     return Search::Elasticsearch->new(
+        client           => '2_0::Direct',
         cxn_pool         => 'Static::NoPing',
         nodes            => 'https://fastapi.metacpan.org/v1',
         send_get_body_as => 'POST',

From e38287a50ced066e66bd9e05f841099c3e5ad2da Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Sun, 10 Jul 2022 07:25:53 -0400
Subject: [PATCH 20/25] Update API endpoint to POST favorite

---
 scripts/favorite/5-plus-plus-your-favorites-es.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/favorite/5-plus-plus-your-favorites-es.pl b/scripts/favorite/5-plus-plus-your-favorites-es.pl
index f611fa8..1ae1e10 100755
--- a/scripts/favorite/5-plus-plus-your-favorites-es.pl
+++ b/scripts/favorite/5-plus-plus-your-favorites-es.pl
@@ -69,7 +69,7 @@ sub plus_plus {
     my $params = shift;
     my $ua     = HTTP::Tiny->new;
     my $res    = $ua->post(
-        "https://api.metacpan.org/user/favorite?access_token=$token",
+        "https://fastapi.metacpan.org/v1/user/favorite?access_token=$token",
         {
             content => encode_json($params),
             headers => { 'content-type' => 'application/json' }

From 694bd8a8adf9e7b962e30d311f80b40ced0dd455 Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Sun, 10 Jul 2022 07:32:32 -0400
Subject: [PATCH 21/25] Update search params for finding latest releases

---
 scripts/release/4-latest-release-versions-es.pl              | 4 ++--
 scripts/release/4a-latest-release-versions-bool-filter-es.pl | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/release/4-latest-release-versions-es.pl b/scripts/release/4-latest-release-versions-es.pl
index a53d8b1..4ac4f55 100755
--- a/scripts/release/4-latest-release-versions-es.pl
+++ b/scripts/release/4-latest-release-versions-es.pl
@@ -19,10 +19,10 @@
                 query  => { match_all => {} },
                 filter => {
                     and => [
-                        { term => { 'release.status' => 'latest' } },
+                        { term => { 'status' => 'latest' } },
                         {
                             terms => {
-                                'release.distribution' =>
+                                'distribution' =>
                                     [ 'Moose', 'MetaCPAN-API', 'DBIx-Class' ]
                             },
                         },
diff --git a/scripts/release/4a-latest-release-versions-bool-filter-es.pl b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
index a5c0a09..fbfcc2f 100755
--- a/scripts/release/4a-latest-release-versions-bool-filter-es.pl
+++ b/scripts/release/4a-latest-release-versions-bool-filter-es.pl
@@ -11,7 +11,7 @@
     index  => 'cpan',
     type   => 'release',
     fields => [ 'distribution', 'version' ],
-    size   => 3,
+    size   => 4,
     body   => {
         query => {
             filtered => {

From 9f347c8746552777e7196667725242ea2f575d70 Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Wed, 13 Jul 2022 23:26:49 -0400
Subject: [PATCH 22/25] Add debug flag $ENV{METACPAN_EXAMPLES_DEBUG}

This makes the output less verbose by default.
---
 lib/MetaCPAN/Util.pm | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/lib/MetaCPAN/Util.pm b/lib/MetaCPAN/Util.pm
index 58983e4..e6905f4 100644
--- a/lib/MetaCPAN/Util.pm
+++ b/lib/MetaCPAN/Util.pm
@@ -3,6 +3,8 @@ package MetaCPAN::Util;
 use strict;
 use warnings;
 
+use constant DEBUG => !!$ENV{METACPAN_EXAMPLES_DEBUG};
+
 use Search::Elasticsearch;
 use Sub::Exporter -setup => { exports => ['es'] };
 
@@ -12,8 +14,35 @@ sub es {
         cxn_pool         => 'Static::NoPing',
         nodes            => 'https://fastapi.metacpan.org/v1',
         send_get_body_as => 'POST',
-        trace_to         => 'Stdout',
+        ( trace_to => 'Stdout' ) x !!(DEBUG),
     );
 }
 
 1;
+
+=head1 NAME
+
+MetaCPAN::Util - Utilities for accessing MetaCPAN
+
+=head1 DESCRIPTION
+
+Provides shared utility code for examples.
+
+=head1 FUNCTIONS
+
+=head2 es
+
+Returns a L<Search::Elasticsearch> client configured for use with the
+MetaCPAN API endpoint.
+
+=head1 ENVIRONMENT
+
+=over 4
+
+=item C<METACPAN_EXAMPLES_DEBUG>
+
+When set to C<1>, enables output of verbose debugging information.
+
+=back
+
+=cut

From 2fe28fc64ccef55df9bf6cb1712c3086bd9c9248 Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Wed, 24 Aug 2022 22:45:52 -0400
Subject: [PATCH 23/25] Use new endpoint for dist reverse dependencies

Connects with <https://github.com/metacpan/metacpan-api/pull/688>.
---
 scripts/{search => }/reverse_dependencies/by-dist-www-mech.pl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
 rename scripts/{search => }/reverse_dependencies/by-dist-www-mech.pl (62%)

diff --git a/scripts/search/reverse_dependencies/by-dist-www-mech.pl b/scripts/reverse_dependencies/by-dist-www-mech.pl
similarity index 62%
rename from scripts/search/reverse_dependencies/by-dist-www-mech.pl
rename to scripts/reverse_dependencies/by-dist-www-mech.pl
index c04967b..c1196d8 100755
--- a/scripts/search/reverse_dependencies/by-dist-www-mech.pl
+++ b/scripts/reverse_dependencies/by-dist-www-mech.pl
@@ -10,10 +10,10 @@
 my $mech = WWW::Mechanize::GZip->new;
 
 $mech->get(
-    "https://fastapi.metacpan.org/v1/search/reverse_dependencies/carton");
+    "https://fastapi.metacpan.org/v1/reverse_dependencies/dist/Carton");
 
 my $results = decode_json( $mech->content );
 
 my @dists
-    = map { $_->{_source}->{distribution} } @{ $results->{hits}->{hits} };
+    = map { $_->{distribution} } @{ $results->{data} };
 p @dists;

From 30d3faa0569db5afe967db115e20f2f7b2ceeda7 Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Wed, 24 Aug 2022 22:46:32 -0400
Subject: [PATCH 24/25] Remove release reverse dependencies example

There is no new endpoint for this script to use.
---
 .../by-release-version-mech.pl                | 20 -------------------
 1 file changed, 20 deletions(-)
 delete mode 100755 scripts/search/reverse_dependencies/by-release-version-mech.pl

diff --git a/scripts/search/reverse_dependencies/by-release-version-mech.pl b/scripts/search/reverse_dependencies/by-release-version-mech.pl
deleted file mode 100755
index 2994064..0000000
--- a/scripts/search/reverse_dependencies/by-release-version-mech.pl
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env perl
-
-use strict;
-use warnings;
-
-use Data::Printer;
-use JSON::MaybeXS qw( decode_json );
-use WWW::Mechanize ();
-
-my $mech = WWW::Mechanize->new;
-
-$mech->get(
-    'https://fastapi.metacpan.org/v1/search/reverse_dependencies/MIYAGAWA/carton-v0.9.13'
-);
-
-my $results = decode_json( $mech->content );
-
-my @dists
-    = map { $_->{_source}->{distribution} } @{ $results->{hits}->{hits} };
-p @dists;

From 26b4f5b4f1f959fc380ed0aa1e28390eaa046fc7 Mon Sep 17 00:00:00 2001
From: Zakariyya Mughal <zaki.mughal@gmail.com>
Date: Wed, 24 Aug 2022 23:17:14 -0400
Subject: [PATCH 25/25] Add reverse dependencies example by module

---
 .../by-module-www-mech.pl                     | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100755 scripts/reverse_dependencies/by-module-www-mech.pl

diff --git a/scripts/reverse_dependencies/by-module-www-mech.pl b/scripts/reverse_dependencies/by-module-www-mech.pl
new file mode 100755
index 0000000..c13dca1
--- /dev/null
+++ b/scripts/reverse_dependencies/by-module-www-mech.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Data::Printer;
+use JSON::MaybeXS qw( decode_json );
+use WWW::Mechanize::GZip ();
+
+my $mech = WWW::Mechanize::GZip->new;
+
+$mech->get(
+    "https://fastapi.metacpan.org/v1/reverse_dependencies/module/WWW::Mechanize"
+);
+
+my $results = decode_json( $mech->content );
+
+my @dists
+    = map { $_->{distribution} } @{ $results->{data} };
+p @dists;
