diff --git a/importers/keyring-importer-jetpack.php b/importers/keyring-importer-jetpack.php
new file mode 100644
index 0000000..4ea191b
--- /dev/null
+++ b/importers/keyring-importer-jetpack.php
@@ -0,0 +1,280 @@
+';
+ }
+ }
+
+ function custom_options() {
+ ?>
+
+
+ |
+
+
+ |
+
error( __( "You must select a site from which to import posts." ) );
+ }
+
+ if ( empty( $_POST['category'] ) || ! ctype_digit( $_POST['category'] ) ) {
+ $this->error( __( "Make sure you select a valid category to import your links into." ) );
+ }
+
+ if ( empty( $_POST['author'] ) || ! ctype_digit( $_POST['author'] ) ) {
+ $this->error( __( "You must select an author to assign to all imported links." ) );
+ }
+
+ if ( isset( $_POST['auto_import'] ) ) {
+ $_POST['auto_import'] = true;
+ } else {
+ $_POST['auto_import'] = false;
+ }
+
+ // If there were errors, output them, otherwise store options and start importing
+ if ( count( $this->errors ) ) {
+ $this->step = 'options';
+ } else {
+ $this->set_option( array(
+ 'site' => (int) $_POST['site'],
+ 'category' => (int) $_POST['category'],
+ 'tags' => explode( ',', $_POST['tags'] ),
+ 'author' => (int) $_POST['author'],
+ 'auto_import' => $_POST['auto_import'],
+ ) );
+
+ $this->step = 'import';
+ }
+ }
+
+ function build_request_url() {
+ // Get posts for the site we're importing from
+ $url = sprintf( "https://public-api.wordpress.com/rest/v1.1/sites/%s/posts/", $this->get_option( 'site' ) );
+ $url = add_query_arg(
+ array(
+ 'number' => self::POSTS_PER_REQUEST,
+ ),
+ $url
+ );
+
+ if ( $this->auto_import ) {
+ // Get most recent post we've imported (if any), and its date so that we can get new ones since then
+ $latest = get_posts( array(
+ 'numberposts' => 1,
+ 'orderby' => 'date',
+ 'order' => 'DESC',
+ 'tax_query' => array( array(
+ 'taxonomy' => 'keyring_services',
+ 'field' => 'slug',
+ 'terms' => array( $this->taxonomy->slug ),
+ 'operator' => 'IN',
+ ) ),
+ ) );
+
+ // If we have already imported some, then start since the most recent
+ if ( $latest ) {
+ $url = add_query_arg(
+ array(
+ 'after' => urlencode( date( 'Y-m-d H:i:s', strtotime( $latest[0]->post_date_gmt ) + 1 ) ),
+ 'order_by' => 'date',
+ 'order' => 'ASC',
+ ),
+ $url
+ );
+ }
+ } else {
+ // Handle page offsets (only for non-auto-import requests)
+ $url = add_query_arg(
+ array(
+ 'page' => $this->get_option( 'page', 1 ),
+ 'order_by' => 'date',
+ 'order' => 'DESC',
+ ),
+ $url
+ );
+ }
+
+ return $url;
+ }
+
+ function extract_posts_from_data( $raw ) {
+ $importdata = $raw;
+
+ if ( null === $importdata ) {
+ $this->finished = true;
+ return new Keyring_Error( 'keyring-jetpack-importer-failed-download', __( 'Failed to download or parse posts from WordPress.com. Please wait a few minutes and try again.' ) );
+ }
+
+ // .found should be there
+ if ( ! property_exists( $importdata, 'found' ) || ! property_exists( $importdata, 'posts' ) ) {
+ $this->finished = true;
+ return new Keyring_Error( 'keyring-jetpack-importer-no-posts', __( 'No posts were found for the site.' ) );
+ }
+
+ // if .found is 0, then we have no posts, we're done
+ if ( 0 == $importdata->found || empty( $importdata->posts ) ) {
+ $this->finished = true;
+ return;
+ }
+
+ // Parse/convert everything to WP post structs
+ foreach ( $importdata->posts as $post ) {
+
+ $post_title = $post->title;
+
+ // Parse/adjust dates
+ $post_date_gmt = date( 'Y-m-d H:i:s', strtotime( $post->date ) );
+ $post_date = get_date_from_gmt( $post_date_gmt );
+
+ // Apply selected category (ignores the categories from the original post)
+ $post_category = array( $this->get_option( 'category' ) );
+
+ // Get the default/forced ones, and merge with tags from the post
+ $tags = array_merge( $this->get_option( 'tags' ), array_keys( (array) $post->tags ) );
+
+ $href = $post->URL;
+ $post_content = $post->content;
+ $post_excerpt = $post->excerpt;
+
+ // Other bits
+ $post_author = $this->get_option( 'author' );
+ $post_status = 'publish';
+ $post_format = $post->format;
+ $jetpack_id = $post->global_ID;
+ $jetpack_raw = $post;
+
+ // Build the post array, and hang onto it along with the others
+ $this->posts[] = compact(
+ 'post_author',
+ 'post_date',
+ 'post_date_gmt',
+ 'post_content',
+ 'post_excerpt',
+ 'post_title',
+ 'post_status',
+ 'post_format',
+ 'post_category',
+ 'tags',
+ 'href',
+ 'jetpack_id',
+ 'jetpack_raw'
+ );
+ }
+ }
+
+ function insert_posts() {
+ global $wpdb;
+ $imported = 0;
+ $skipped = 0;
+ foreach ( $this->posts as $post ) {
+ extract( $post );
+ if (
+ ! $jetpack_id
+ ||
+ $wpdb->get_var( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = 'jetpack_id' AND meta_value = %s", $jetpack_id ) )
+ ||
+ $post_id = post_exists( $post_title, $post_content, $post_date )
+ ) {
+ // Looks like a duplicate, which means we've already processed it
+ $skipped++;
+ } else {
+ $post_id = wp_insert_post( $post );
+
+ if ( is_wp_error( $post_id ) ) {
+ return $post_id;
+ }
+
+ if ( ! $post_id ) {
+ continue;
+ }
+
+ // Track which Keyring service was used
+ wp_set_object_terms( $post_id, self::LABEL, 'keyring_services' );
+
+ // Assign post format based on what it was originally
+ set_post_format( $post_id, $post_format );
+
+ // Update Category
+ wp_set_post_categories( $post_id, $post_category );
+
+ add_post_meta( $post_id, 'jetpack_id', $jetpack_id );
+ add_post_meta( $post_id, 'href', $href );
+
+ if ( count( $tags ) ) {
+ wp_set_post_terms( $post_id, implode( ',', $tags ) );
+ }
+
+ add_post_meta( $post_id, 'raw_import_data', wp_slash( json_encode( $jetpack_raw ) ) );
+
+ $imported++;
+
+ do_action( 'keyring_post_imported', $post_id, static::SLUG, $post );
+ }
+ }
+ $this->posts = array();
+
+ // Return, so that the handler can output info (or update DB, or whatever)
+ return array( 'imported' => $imported, 'skipped' => $skipped );
+ }
+}
+
+} // end function Keyring_Jetpack_Importer
+
+
+add_action( 'init', function() {
+ Keyring_Jetpack_Importer(); // Load the class code from above
+ keyring_register_importer(
+ 'jetpack',
+ 'Keyring_Jetpack_Importer',
+ plugin_basename( __FILE__ ),
+ __( 'Import posts from a Jetpack-powered WordPress site (WordPress.com or self-hosted), using the Jetpack REST API.', 'keyring' )
+ );
+} );