Version Description
- Update to use new Tumblr API, many fixes and improvements.
Download this release
Release Info
Developer | Otto42 |
Plugin | Tumblr Importer |
Version | 0.7 |
Comparing to | |
See all releases |
Code changes from version 0.6 to 0.7
- readme.txt +7 -1
- tumblr-importer.php +299 -154
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: wordpressdotorg, Otto42, dd32, westi, dllh
|
|
3 |
Tags: tumblr, import
|
4 |
Requires at least: 3.2
|
5 |
Tested up to: 3.4
|
6 |
-
Stable tag: 0.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -25,7 +25,13 @@ Imports a Tumblr blog into a WordPress blog.
|
|
25 |
|
26 |
== Upgrade Notice ==
|
27 |
|
|
|
|
|
28 |
== Changelog ==
|
|
|
|
|
|
|
|
|
29 |
= 0.6 =
|
30 |
* Significant improvements in the performance of the importer
|
31 |
* Improves import of images from Tumblr - better choice of images sizes for theme display
|
3 |
Tags: tumblr, import
|
4 |
Requires at least: 3.2
|
5 |
Tested up to: 3.4
|
6 |
+
Stable tag: 0.7
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
25 |
|
26 |
== Upgrade Notice ==
|
27 |
|
28 |
+
Version 0.7 fixes problems caused by Tumblr's removal of the old API, and now uses their new API.
|
29 |
+
|
30 |
== Changelog ==
|
31 |
+
|
32 |
+
= 0.7 =
|
33 |
+
* Update to use new Tumblr API, many fixes and improvements.
|
34 |
+
|
35 |
= 0.6 =
|
36 |
* Significant improvements in the performance of the importer
|
37 |
* Improves import of images from Tumblr - better choice of images sizes for theme display
|
tumblr-importer.php
CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://wordpress.org/extend/plugins/tumblr-importer/
|
|
5 |
Description: Import posts from a Tumblr blog.
|
6 |
Author: wordpressdotorg
|
7 |
Author URI: http://wordpress.org/
|
8 |
-
Version: 0.
|
9 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
10 |
*/
|
11 |
|
@@ -49,6 +49,7 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
49 |
function __construct() {
|
50 |
add_action( 'tumblr_importer_metadata', array( $this, 'tumblr_importer_metadata' ) );
|
51 |
add_filter( 'tumblr_importer_format_post', array( $this, 'filter_format_post' ) );
|
|
|
52 |
add_filter( 'wp_insert_post_empty_content', array( $this, 'filter_allow_empty_content' ), 10, 2 );
|
53 |
parent::__construct();
|
54 |
}
|
@@ -60,9 +61,17 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
60 |
|
61 |
if ( !isset($this->error) ) $this->error = null;
|
62 |
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
$this->check_credentials();
|
65 |
-
}
|
66 |
if ( isset( $_POST['blogurl'] ) ) {
|
67 |
$this->start_blog_import();
|
68 |
}
|
@@ -97,18 +106,29 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
97 |
|
98 |
<div class='wrap'><?php echo screen_icon(); ?>
|
99 |
<h2><?php _e('Import Tumblr', 'tumblr-importer'); ?></h2>
|
|
|
100 |
<p><?php _e('Howdy! This importer allows you to import posts from your Tumblr account into your WordPress site.', 'tumblr-importer'); ?></p>
|
101 |
-
<p><?php _e(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
<form action='?import=tumblr' method='post'>
|
103 |
-
<?php wp_nonce_field( 'tumblr-import' ) ?>
|
104 |
<table class="form-table">
|
105 |
<tr>
|
106 |
-
<th scope="row"><label for='
|
107 |
-
<td><input type='text' class="regular-text" name='
|
108 |
</tr>
|
109 |
<tr>
|
110 |
-
<th scope="row"><label for='
|
111 |
-
<td><input type='
|
112 |
</tr>
|
113 |
</table>
|
114 |
<p class='submit'>
|
@@ -116,26 +136,73 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
116 |
</p>
|
117 |
</form>
|
118 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
<?php
|
|
|
120 |
}
|
121 |
|
122 |
-
function check_credentials() {
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
$
|
127 |
-
|
128 |
-
|
129 |
-
$error = __("This doesn't appear to be a valid email address. Please check it and try again.",'tumblr-importer');
|
130 |
-
$this->error = $error;
|
131 |
}
|
132 |
-
|
133 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
if ( is_wp_error ($blogs) ) {
|
135 |
$this->error = $blogs->get_error_message();
|
136 |
} else {
|
137 |
$this->blogs = $blogs;
|
138 |
}
|
|
|
139 |
}
|
140 |
|
141 |
function show_blogs($error=null) {
|
@@ -270,7 +337,6 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
270 |
$done = true;
|
271 |
|
272 |
$this->error=null;
|
273 |
-
|
274 |
if ( !empty( $this->blog[$url]['progress'] ) ) {
|
275 |
$done = false;
|
276 |
do {
|
@@ -288,7 +354,9 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
288 |
//$this->do_queued_import($url);
|
289 |
break;
|
290 |
case 'pages':
|
291 |
-
|
|
|
|
|
292 |
break;
|
293 |
case 'finish':
|
294 |
default:
|
@@ -343,7 +411,7 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
343 |
|
344 |
do_action( 'tumblr_importing_post', $post );
|
345 |
$id = wp_insert_post( $post );
|
346 |
-
|
347 |
if ( !is_wp_error( $id ) ) {
|
348 |
$post['ID'] = $id; // Allows for the media importing to wp_update_post()
|
349 |
if ( isset( $post['format'] ) ) set_post_format($id, $post['format']);
|
@@ -368,7 +436,11 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
368 |
} while ( false != ($post = next($imported_posts) ) && $this->have_time() );
|
369 |
}
|
370 |
}
|
371 |
-
|
|
|
|
|
|
|
|
|
372 |
function do_drafts_import($url) {
|
373 |
$start = $this->blog[$url]['drafts_complete'];
|
374 |
$total = $this->blog[$url]['total_drafts'];
|
@@ -385,6 +457,7 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
385 |
if ($this->blog[$url]['posts_complete'] + TUMBLR_MAX_IMPORT > $total) $count = $total - $start;
|
386 |
else $count = TUMBLR_MAX_IMPORT;
|
387 |
|
|
|
388 |
$imported_posts = $this->fetch_posts($url, $start, $count, $this->email, $this->password, 'draft' );
|
389 |
|
390 |
if ( empty($imported_posts) ) {
|
@@ -423,7 +496,7 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
423 |
} while ( false != ($post = next($imported_posts) ) && $this->have_time() );
|
424 |
}
|
425 |
}
|
426 |
-
|
427 |
function do_pages_import($url) {
|
428 |
$start = $this->blog[$url]['pages_complete'];
|
429 |
|
@@ -479,7 +552,6 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
479 |
$path = parse_url($source,PHP_URL_PATH);
|
480 |
$filename = basename($path);
|
481 |
}
|
482 |
-
|
483 |
// Download file to temp location
|
484 |
$tmp = download_url( $source );
|
485 |
if ( is_wp_error($tmp) )
|
@@ -546,7 +618,7 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
546 |
|
547 |
break;
|
548 |
|
549 |
-
|
550 |
// Handle Tumblr Hosted Audio
|
551 |
if ( isset( $post['media']['audio'] ) ) {
|
552 |
$id = $this->handle_sideload_import( $post, (string)$post['media']['audio'], $post['post_title'], (string)$post['media']['filename'] );
|
@@ -596,6 +668,32 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
596 |
return true; // all processed
|
597 |
}
|
598 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
599 |
/**
|
600 |
* Fetch a list of blogs for a user
|
601 |
*
|
@@ -603,61 +701,41 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
603 |
* @param $password
|
604 |
* @returns array of blog info or a WP_Error
|
605 |
*/
|
606 |
-
function get_blogs(
|
607 |
-
$url = 'http://
|
608 |
-
|
609 |
-
$params = array(
|
610 |
-
'email'=>$email,
|
611 |
-
'password'=>$password,
|
612 |
-
);
|
613 |
-
$options = array( 'body' => $params );
|
614 |
-
|
615 |
-
// fetch the list
|
616 |
-
$out = wp_remote_post($url,$options);
|
617 |
|
618 |
-
switch (
|
619 |
case 403: // Bad Username / Password
|
620 |
do_action( 'tumblr_importer_handle_error', 'get_blogs_403' );
|
621 |
-
return new WP_Error('tumblr_error', __('Tumblr says that the
|
622 |
-
break;
|
623 |
case 200: // OK
|
624 |
break;
|
625 |
default:
|
626 |
-
$_error = sprintf( __( 'Tumblr replied with an error: %s', 'tumblr-importer' ),
|
627 |
-
do_action( 'tumblr_importer_handle_error', 'response_' .
|
628 |
return new WP_Error('tumblr_error', $_error );
|
629 |
-
|
630 |
}
|
631 |
-
$body = wp_remote_retrieve_body($out);
|
632 |
-
|
633 |
-
// parse the XML into something useful
|
634 |
-
$xml = simplexml_load_string($body);
|
635 |
|
636 |
$blogs = array();
|
637 |
-
|
638 |
-
if (!isset($xml->tumblelog)) {
|
639 |
-
new WP_Error('tumblr_error', __('No blog information found for this account. ', 'tumblr-importer' ));
|
640 |
-
do_action( 'tumblr_importer_handle_error', 'no_blog_found' );
|
641 |
-
}
|
642 |
-
|
643 |
-
$tblogs = $xml->tumblelog;
|
644 |
-
foreach ($tblogs as $tblog) {
|
645 |
$blog = array();
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
$blog['
|
650 |
-
$blog['
|
651 |
-
$blog['
|
652 |
-
$blog['
|
653 |
-
$blog['avatar'] = (string) $tblog['avatar-url'];
|
654 |
-
$blog['url'] = (string) $tblog['url'];
|
655 |
-
$blog['name'] = (string) $tblog['name'];
|
656 |
|
657 |
$blogs[] = $blog;
|
658 |
}
|
|
|
|
|
|
|
659 |
|
660 |
-
|
|
|
661 |
}
|
662 |
|
663 |
/**
|
@@ -668,141 +746,144 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
668 |
* @param $state can be empty for normal posts, or "draft", "queue", or "submission" to get those posts
|
669 |
* @returns false on error, array of posts on success
|
670 |
*/
|
671 |
-
function fetch_posts($url, $start=0, $count = 50, $email = null, $password = null, $state = null) {
|
672 |
-
$url =
|
673 |
-
$
|
674 |
-
|
675 |
-
|
676 |
-
);
|
677 |
-
|
678 |
-
|
679 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
680 |
}
|
681 |
|
682 |
-
|
683 |
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
$xml = simplexml_load_string($body);
|
693 |
-
|
694 |
-
if (!isset($xml->posts->post)) return false;
|
695 |
|
696 |
-
$tposts = $xml->posts;
|
697 |
$posts = array();
|
698 |
-
|
|
|
699 |
$post = array();
|
700 |
-
$post['tumblr_id'] = (string) $tpost
|
701 |
-
$post['tumblr_url'] = (string) $tpost
|
702 |
-
$post['post_date'] = date( 'Y-m-d H:i:s', strtotime ( (string) $tpost
|
703 |
-
$post['post_date_gmt'] = date( 'Y-m-d H:i:s', strtotime ( (string) $tpost
|
704 |
-
$post['post_name'] = (string) $tpost
|
705 |
-
if (
|
706 |
-
|
|
|
707 |
$post['tags_input'] = array();
|
708 |
-
foreach ( $tpost->
|
709 |
$post['tags_input'][] = rtrim( (string) $tag, ','); // Strip trailing Commas off it too.
|
710 |
}
|
711 |
|
712 |
-
|
713 |
-
// TODO reorg this as needed
|
714 |
-
switch ((string) $tpost['type']) {
|
715 |
case 'photo':
|
716 |
$post['format'] = 'image';
|
717 |
-
$post['media']['src'] = (string) $tpost->
|
718 |
-
$post['media']['link'] =(string) $tpost->{'photo-link-url'};
|
719 |
-
$post['media']['width'] = (string) $tpost[
|
720 |
-
$post['media']['height'] = (string) $tpost[
|
721 |
-
$post['post_content'] = (string) $tpost->
|
722 |
-
if ( !empty( $tpost->
|
723 |
$post['format'] = 'gallery';
|
724 |
-
foreach ( $tpost->
|
725 |
$post['gallery'][] = array (
|
726 |
-
'src'
|
727 |
-
'width'
|
728 |
-
'height'
|
729 |
-
'caption'
|
730 |
);
|
731 |
}
|
732 |
}
|
733 |
break;
|
734 |
case 'quote':
|
735 |
$post['format'] = 'quote';
|
736 |
-
$post['post_content'] = (string) $tpost->
|
737 |
-
$post['post_content'] .= "\n\n" . (string) $tpost->
|
738 |
break;
|
739 |
case 'link':
|
740 |
$post['format'] = 'link';
|
741 |
-
$linkurl = (string) $tpost->
|
742 |
-
$linktext = (string) $tpost->
|
743 |
-
$post['post_content'] = "<a href='
|
744 |
-
|
|
|
|
|
745 |
break;
|
746 |
-
case '
|
747 |
$post['format'] = 'chat';
|
748 |
-
$post['post_title'] = (string) $tpost->
|
749 |
-
$post['post_content'] = (string) $tpost->
|
750 |
break;
|
751 |
case 'audio':
|
752 |
$post['format'] = 'audio';
|
753 |
-
$post['media']['filename'] = basename( (string) $tpost->
|
754 |
-
|
755 |
-
$post['
|
756 |
-
|
757 |
-
|
|
|
758 |
break;
|
759 |
case 'video':
|
760 |
$post['format'] = 'video';
|
761 |
$post['post_content'] = '';
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
$post['media']['filename'] = basename($post['media']['video']) . '.' . $vidmeta['extension'];
|
768 |
-
$post['media']['width'] = $vidmeta['width'];
|
769 |
-
$post['media']['height'] = $vidmeta['height'];
|
770 |
-
}
|
771 |
-
} else if ( false !== strpos( (string) $tpost->{'video-source'}, 'embed' ) ) {
|
772 |
-
if ( preg_match_all('/<embed (.+?)>/', (string) $tpost->{'video-source'}, $matches) ) {
|
773 |
foreach ($matches[1] as $match) {
|
774 |
-
foreach ( wp_kses_hair($match, array('http')) as $attr)
|
775 |
-
$embed[$attr['name']] = $attr['value'];
|
776 |
}
|
777 |
-
|
778 |
// special case for weird youtube vids
|
779 |
-
$embed['src'] = preg_replace('|http://www.youtube.com/v/([a-zA-Z0-9_]+).*|i', 'http://www.youtube.com/watch?v=$1', $embed['src']);
|
780 |
-
|
781 |
// TODO find other special cases, since tumblr is full of them
|
782 |
-
|
783 |
$post['post_content'] = $embed['src'];
|
784 |
}
|
|
|
785 |
// Sometimes, video-source contains iframe markup.
|
786 |
-
if ( preg_match( '/<iframe/', $
|
787 |
-
$embed['src'] = preg_replace( '|<iframe.*src="http://www.youtube.com/embed/([a-zA-Z0-9_\-]+)\??.*".*</iframe>|', 'http://www.youtube.com/watch
|
788 |
$post['post_content'] = $embed['src'];
|
789 |
}
|
790 |
-
|
|
|
|
|
791 |
} else {
|
792 |
-
// @todo: See if the video
|
793 |
-
|
794 |
-
$post['post_content'] .= isset($tpost->{'video-player'}[1]) ? $tpost->{'video-player'}[1] : (string) $tpost->{'video-player'}[0];
|
795 |
}
|
796 |
-
|
|
|
797 |
break;
|
798 |
case 'answer':
|
799 |
-
|
800 |
-
$post['
|
|
|
801 |
break;
|
802 |
case 'regular':
|
|
|
803 |
default:
|
804 |
-
$post['post_title'] = (string) $tpost->
|
805 |
-
$post['post_content'] = (string) $tpost->
|
806 |
break;
|
807 |
}
|
808 |
$posts[] = $post;
|
@@ -883,5 +964,69 @@ class Tumblr_Import extends WP_Importer_Cron {
|
|
883 |
return $maybe_empty;
|
884 |
}
|
885 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
886 |
}
|
887 |
}
|
5 |
Description: Import posts from a Tumblr blog.
|
6 |
Author: wordpressdotorg
|
7 |
Author URI: http://wordpress.org/
|
8 |
+
Version: 0.7
|
9 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
10 |
*/
|
11 |
|
49 |
function __construct() {
|
50 |
add_action( 'tumblr_importer_metadata', array( $this, 'tumblr_importer_metadata' ) );
|
51 |
add_filter( 'tumblr_importer_format_post', array( $this, 'filter_format_post' ) );
|
52 |
+
add_filter( 'tumblr_importer_get_consumer_key', array( $this, 'get_consumer_key' ) );
|
53 |
add_filter( 'wp_insert_post_empty_content', array( $this, 'filter_allow_empty_content' ), 10, 2 );
|
54 |
parent::__construct();
|
55 |
}
|
61 |
|
62 |
if ( !isset($this->error) ) $this->error = null;
|
63 |
|
64 |
+
$this->consumerkey = defined ('TUMBLR_CONSUMER_KEY') ? TUMBLR_CONSUMER_KEY : ( !empty($_POST['consumerkey']) ? $_POST['consumerkey'] : $this->consumerkey );
|
65 |
+
$this->secretkey = defined ('TUMBLR_SECRET_KEY') ? TUMBLR_SECRET_KEY : ( !empty($_POST['secretkey']) ? $_POST['secretkey'] : $this->secretkey );
|
66 |
+
|
67 |
+
// if we have access tokens, verify that they work
|
68 |
+
if ( !empty( $this->access_tokens ) ) {
|
69 |
+
// TODO
|
70 |
+
} else if ( isset( $_GET['oauth_verifier'] ) ) {
|
71 |
+
$this->check_permissions();
|
72 |
+
} else if ( !empty( $this->consumerkey ) && !empty( $this->secretkey ) ) {
|
73 |
$this->check_credentials();
|
74 |
+
}
|
75 |
if ( isset( $_POST['blogurl'] ) ) {
|
76 |
$this->start_blog_import();
|
77 |
}
|
106 |
|
107 |
<div class='wrap'><?php echo screen_icon(); ?>
|
108 |
<h2><?php _e('Import Tumblr', 'tumblr-importer'); ?></h2>
|
109 |
+
<?php if ( empty($this->request_tokens) ) { ?>
|
110 |
<p><?php _e('Howdy! This importer allows you to import posts from your Tumblr account into your WordPress site.', 'tumblr-importer'); ?></p>
|
111 |
+
<p><?php _e("First, you will need to create an 'app' on Tumblr. The app provides a connection point between your blog and Tumblr's servers.", 'tumblr-importer'); ?></p>
|
112 |
+
|
113 |
+
<p><?php _e('To create an app, visit this page:', 'tumblr-importer'); ?><a href="http://www.tumblr.com/oauth/apps">http://www.tumblr.com/oauth/apps</a></p>
|
114 |
+
<ol>
|
115 |
+
<li><?php _e('Click the large green "Register Application" button.','tumblr-importer'); ?></li>
|
116 |
+
<li><?php _e('You need to fill in the "Application Name", "Application Website", and "Default Callback URL" fields. All the rest can be left blank.','tumblr-importer'); ?></li>
|
117 |
+
<li><?php _e('For the "Application Website" and "Default Callback URL" fields, please put in this URL: ','tumblr-importer'); echo '<strong>'.home_url().'</strong>'; ?></li>
|
118 |
+
<li><?php _e('Note: It is important that you put in that URL <em>exactly as given</em>.','tumblr-importer'); ?></li>
|
119 |
+
</ol>
|
120 |
+
|
121 |
+
<p><?php _e('After creating the application, copy and paste the "OAuth Consumer Key" and "Secret Key" into the given fields below.', 'tumblr-importer'); ?></p>
|
122 |
+
|
123 |
<form action='?import=tumblr' method='post'>
|
|
|
124 |
<table class="form-table">
|
125 |
<tr>
|
126 |
+
<th scope="row"><label for='consumerkey'><?php _e('OAuth Consumer Key:','tumblr-importer'); ?></label></label></th>
|
127 |
+
<td><input type='text' class="regular-text" name='consumerkey' value='<?php if (isset($this->consumerkey)) echo esc_attr($this->consumerkey); ?>' /></td>
|
128 |
</tr>
|
129 |
<tr>
|
130 |
+
<th scope="row"><label for='secretkey'><?php _e('Secret Key:','tumblr-importer'); ?></label></label></th>
|
131 |
+
<td><input type='text' class="regular-text" name='secretkey' value='<?php if (isset($this->secretkey)) echo esc_attr($this->secretkey); ?>' /></td>
|
132 |
</tr>
|
133 |
</table>
|
134 |
<p class='submit'>
|
136 |
</p>
|
137 |
</form>
|
138 |
</div>
|
139 |
+
<?php } else {
|
140 |
+
?>
|
141 |
+
<p><?php _e("Everything seems to be in order, so now you need to tell Tumblr to allow the plugin to access your account.", 'tumblr-importer'); ?></p>
|
142 |
+
<p><?php _e("To do this, click the Authorize link below. You will be redirected back to this page when you've granted the permission.", 'tumblr-importer'); ?></p>
|
143 |
+
|
144 |
+
<p><a href="<?php echo $this->authorize_url; ?>"><?php _e('Authorize the Application','tumblr-importer'); ?></a></p>
|
145 |
<?php
|
146 |
+
}
|
147 |
}
|
148 |
|
149 |
+
function check_credentials() {
|
150 |
+
if ( !( $response = $this->oauth_get_request_token() ) )
|
151 |
+
return;
|
152 |
+
|
153 |
+
if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
|
154 |
+
$this->error = __('Tumblr returned an error: ', 'tumblr-importer') . wp_remote_retrieve_response_code( $response ) .' '. wp_remote_retrieve_body( $response );
|
155 |
+
return;
|
|
|
|
|
156 |
}
|
157 |
+
// parse the body
|
158 |
+
$this->request_tokens = array();
|
159 |
+
wp_parse_str( wp_remote_retrieve_body( $response ), $this->request_tokens);
|
160 |
+
$this->authorize_url = add_query_arg(array(
|
161 |
+
'oauth_token' => $this->request_tokens ['oauth_token'],
|
162 |
+
'oauth_callback' => urlencode( self_admin_url('admin.php?import=tumblr') ),
|
163 |
+
), 'http://www.tumblr.com/oauth/authorize');
|
164 |
+
|
165 |
+
return;
|
166 |
+
}
|
167 |
+
|
168 |
+
function check_permissions() {
|
169 |
+
$verifier = $_GET['oauth_verifier'];
|
170 |
+
$token = $_GET['oauth_token'];
|
171 |
+
|
172 |
+
// get the access_tokens
|
173 |
+
$url = 'http://www.tumblr.com/oauth/access_token';
|
174 |
+
|
175 |
+
$params = array('oauth_consumer_key' => $this->consumerkey,
|
176 |
+
"oauth_nonce" => time().rand(),
|
177 |
+
"oauth_timestamp" => time(),
|
178 |
+
"oauth_token" => $this->request_tokens['oauth_token'],
|
179 |
+
"oauth_signature_method" => "HMAC-SHA1",
|
180 |
+
"oauth_verifier" => $verifier,
|
181 |
+
"oauth_version" => "1.0",
|
182 |
+
);
|
183 |
+
|
184 |
+
$params['oauth_signature'] = $this->oauth_signature(array($this->secretkey,$this->request_tokens['oauth_token_secret']), 'GET', $url, $params);
|
185 |
+
|
186 |
+
$url = add_query_arg( array_map('urlencode', $params), $url);
|
187 |
+
$response = wp_remote_get( $url );
|
188 |
+
unset($this->request_tokens);
|
189 |
+
if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
|
190 |
+
$this->error = __('Tumblr returned an error: ', 'tumblr-importer') . wp_remote_retrieve_response_code( $response ) .' '. wp_remote_retrieve_body( $response );
|
191 |
+
return;
|
192 |
+
} else {
|
193 |
+
$this->access_tokens = array();
|
194 |
+
wp_parse_str( wp_remote_retrieve_body( $response ), $this->access_tokens);
|
195 |
+
}
|
196 |
+
|
197 |
+
// try to get the list of blogs on the account
|
198 |
+
|
199 |
+
$blogs = $this->get_blogs();
|
200 |
if ( is_wp_error ($blogs) ) {
|
201 |
$this->error = $blogs->get_error_message();
|
202 |
} else {
|
203 |
$this->blogs = $blogs;
|
204 |
}
|
205 |
+
return;
|
206 |
}
|
207 |
|
208 |
function show_blogs($error=null) {
|
337 |
$done = true;
|
338 |
|
339 |
$this->error=null;
|
|
|
340 |
if ( !empty( $this->blog[$url]['progress'] ) ) {
|
341 |
$done = false;
|
342 |
do {
|
354 |
//$this->do_queued_import($url);
|
355 |
break;
|
356 |
case 'pages':
|
357 |
+
// TODO Tumblr's new API has no way to retrieve pages that I can find
|
358 |
+
$this->blog[$url]['progress'] = 'finish';
|
359 |
+
//$this->do_pages_import($url);
|
360 |
break;
|
361 |
case 'finish':
|
362 |
default:
|
411 |
|
412 |
do_action( 'tumblr_importing_post', $post );
|
413 |
$id = wp_insert_post( $post );
|
414 |
+
|
415 |
if ( !is_wp_error( $id ) ) {
|
416 |
$post['ID'] = $id; // Allows for the media importing to wp_update_post()
|
417 |
if ( isset( $post['format'] ) ) set_post_format($id, $post['format']);
|
436 |
} while ( false != ($post = next($imported_posts) ) && $this->have_time() );
|
437 |
}
|
438 |
}
|
439 |
+
|
440 |
+
function get_draft_post_type( $post_type ) {
|
441 |
+
return 'draft';
|
442 |
+
}
|
443 |
+
|
444 |
function do_drafts_import($url) {
|
445 |
$start = $this->blog[$url]['drafts_complete'];
|
446 |
$total = $this->blog[$url]['total_drafts'];
|
457 |
if ($this->blog[$url]['posts_complete'] + TUMBLR_MAX_IMPORT > $total) $count = $total - $start;
|
458 |
else $count = TUMBLR_MAX_IMPORT;
|
459 |
|
460 |
+
add_filter( 'tumblr_post_type', array( $this, 'get_draft_post_type' ) );
|
461 |
$imported_posts = $this->fetch_posts($url, $start, $count, $this->email, $this->password, 'draft' );
|
462 |
|
463 |
if ( empty($imported_posts) ) {
|
496 |
} while ( false != ($post = next($imported_posts) ) && $this->have_time() );
|
497 |
}
|
498 |
}
|
499 |
+
|
500 |
function do_pages_import($url) {
|
501 |
$start = $this->blog[$url]['pages_complete'];
|
502 |
|
552 |
$path = parse_url($source,PHP_URL_PATH);
|
553 |
$filename = basename($path);
|
554 |
}
|
|
|
555 |
// Download file to temp location
|
556 |
$tmp = download_url( $source );
|
557 |
if ( is_wp_error($tmp) )
|
618 |
|
619 |
break;
|
620 |
|
621 |
+
case 'audio':
|
622 |
// Handle Tumblr Hosted Audio
|
623 |
if ( isset( $post['media']['audio'] ) ) {
|
624 |
$id = $this->handle_sideload_import( $post, (string)$post['media']['audio'], $post['post_title'], (string)$post['media']['filename'] );
|
668 |
return true; // all processed
|
669 |
}
|
670 |
|
671 |
+
|
672 |
+
/**
|
673 |
+
* Get a request token from the OAuth endpoint (also serves as a test)
|
674 |
+
*
|
675 |
+
*/
|
676 |
+
function oauth_get_request_token() {
|
677 |
+
if ( empty($this->consumerkey) || empty ($this->secretkey) )
|
678 |
+
return false;
|
679 |
+
|
680 |
+
$url = 'http://www.tumblr.com/oauth/request_token';
|
681 |
+
|
682 |
+
$params = array('oauth_callback' => urlencode( self_admin_url('admin.php?import=tumblr') ),
|
683 |
+
'oauth_consumer_key' => $this->consumerkey,
|
684 |
+
"oauth_version" => "1.0",
|
685 |
+
"oauth_nonce" => time(),
|
686 |
+
"oauth_timestamp" => time(),
|
687 |
+
"oauth_signature_method" => "HMAC-SHA1",
|
688 |
+
);
|
689 |
+
|
690 |
+
$params['oauth_signature'] = $this->oauth_signature(array($this->secretkey,''), 'POST', $url, $params);
|
691 |
+
|
692 |
+
$response = wp_remote_post( $url, array('body' => $params));
|
693 |
+
|
694 |
+
return $response;
|
695 |
+
}
|
696 |
+
|
697 |
/**
|
698 |
* Fetch a list of blogs for a user
|
699 |
*
|
701 |
* @param $password
|
702 |
* @returns array of blog info or a WP_Error
|
703 |
*/
|
704 |
+
function get_blogs() {
|
705 |
+
$url = 'http://api.tumblr.com/v2/user/info';
|
706 |
+
$response = $this->oauth_get_request($url);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
707 |
|
708 |
+
switch ( $response->meta->status ) {
|
709 |
case 403: // Bad Username / Password
|
710 |
do_action( 'tumblr_importer_handle_error', 'get_blogs_403' );
|
711 |
+
return new WP_Error('tumblr_error', __('Tumblr says that the the app is not authorized. Please check the settings and try to connect again.', 'tumblr-importer' ) );
|
|
|
712 |
case 200: // OK
|
713 |
break;
|
714 |
default:
|
715 |
+
$_error = sprintf( __( 'Tumblr replied with an error: %s', 'tumblr-importer' ), $response->meta->msg );
|
716 |
+
do_action( 'tumblr_importer_handle_error', 'response_' . $response->meta->status );
|
717 |
return new WP_Error('tumblr_error', $_error );
|
|
|
718 |
}
|
|
|
|
|
|
|
|
|
719 |
|
720 |
$blogs = array();
|
721 |
+
foreach ( $response->response->user->blogs as $tblog ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
$blog = array();
|
723 |
+
$blog['title'] = (string) $tblog->title;
|
724 |
+
$blog['posts'] = (int) $tblog->posts;
|
725 |
+
$blog['drafts'] = (int) $tblog->drafts;
|
726 |
+
$blog['queued'] = (int) $tblog->queue;
|
727 |
+
$blog['avatar'] = '';
|
728 |
+
$blog['url'] = (string) $tblog->url;
|
729 |
+
$blog['name'] = (string) $tblog->name;
|
|
|
|
|
|
|
730 |
|
731 |
$blogs[] = $blog;
|
732 |
}
|
733 |
+
$this->blogs = $blogs;
|
734 |
+
return $this->blogs;
|
735 |
+
}
|
736 |
|
737 |
+
function get_consumer_key() {
|
738 |
+
return $this->consumerkey;
|
739 |
}
|
740 |
|
741 |
/**
|
746 |
* @param $state can be empty for normal posts, or "draft", "queue", or "submission" to get those posts
|
747 |
* @returns false on error, array of posts on success
|
748 |
*/
|
749 |
+
function fetch_posts($url, $start=0, $count = 50, $email = null, $password = null, $state = null ) {
|
750 |
+
$url = parse_url( $url, PHP_URL_HOST );
|
751 |
+
$post_type = apply_filters( 'tumblr_post_type', '' );
|
752 |
+
$url = trailingslashit( "http://api.tumblr.com/v2/blog/$url/posts/$post_type" );
|
753 |
+
|
754 |
+
do_action( 'tumblr_importer_pre_fetch_posts' );
|
755 |
+
|
756 |
+
// These extra params hose up the auth if passed for oauth requests e.g. for drafts, so use them only for normal posts.
|
757 |
+
if ( '' == $post_type ) {
|
758 |
+
$params = array(
|
759 |
+
'offset' => $start,
|
760 |
+
'limit' => $count,
|
761 |
+
'api_key' => apply_filters( 'tumblr_importer_get_consumer_key', '' ),
|
762 |
+
);
|
763 |
+
$url = add_query_arg( $params, $url );
|
764 |
}
|
765 |
|
766 |
+
$response = $this->oauth_get_request($url);
|
767 |
|
768 |
+
switch ( $response->meta->status ) {
|
769 |
+
case 200: // OK
|
770 |
+
break;
|
771 |
+
default:
|
772 |
+
$_error = sprintf( __( 'Tumblr replied with an error: %s', 'tumblr-importer' ), $response->meta->msg );
|
773 |
+
do_action( 'tumblr_importer_handle_error', 'response_' . $response->meta->status );
|
774 |
+
return new WP_Error('tumblr_error', $_error );
|
775 |
+
}
|
|
|
|
|
|
|
776 |
|
|
|
777 |
$posts = array();
|
778 |
+
$tposts = $response->response->posts;
|
779 |
+
foreach( $tposts as $tpost ) {
|
780 |
$post = array();
|
781 |
+
$post['tumblr_id'] = (string) $tpost->id;
|
782 |
+
$post['tumblr_url'] = (string) $tpost->post_url;
|
783 |
+
$post['post_date'] = date( 'Y-m-d H:i:s', strtotime ( (string) $tpost->date ) );
|
784 |
+
$post['post_date_gmt'] = date( 'Y-m-d H:i:s', strtotime ( (string) $tpost->date ) );
|
785 |
+
$post['post_name'] = (string) $tpost->slug;
|
786 |
+
if ( 'private' == $tpost->state )
|
787 |
+
$post['private'] = (string) $tpost->state;
|
788 |
+
if ( isset( $tpost->tags ) ) {
|
789 |
$post['tags_input'] = array();
|
790 |
+
foreach ( $tpost->tags as $tag )
|
791 |
$post['tags_input'][] = rtrim( (string) $tag, ','); // Strip trailing Commas off it too.
|
792 |
}
|
793 |
|
794 |
+
switch ( (string) $tpost->type ) {
|
|
|
|
|
795 |
case 'photo':
|
796 |
$post['format'] = 'image';
|
797 |
+
$post['media']['src'] = (string) $tpost->photos[0]->original_size->url;
|
798 |
+
$post['media']['link'] = '';//TODO: Find out what to use here.(string) $tpost->{'photo-link-url'};
|
799 |
+
$post['media']['width'] = (string) $tpost->photos[0]->original_size->width;
|
800 |
+
$post['media']['height'] = (string) $tpost->photos[0]->original_size->height;
|
801 |
+
$post['post_content'] = (string) $tpost->caption;
|
802 |
+
if ( ! empty( $tpost->photos ) ) {
|
803 |
$post['format'] = 'gallery';
|
804 |
+
foreach ( $tpost->photos as $photo ) {
|
805 |
$post['gallery'][] = array (
|
806 |
+
'src' => $photo->original_size->url,
|
807 |
+
'width' => $photo->original_size->width,
|
808 |
+
'height' => $photo->original_size->height,
|
809 |
+
'caption' => $photo->caption,
|
810 |
);
|
811 |
}
|
812 |
}
|
813 |
break;
|
814 |
case 'quote':
|
815 |
$post['format'] = 'quote';
|
816 |
+
$post['post_content'] = '<blockquote>' . (string) $tpost->text . '</blockquote>';
|
817 |
+
$post['post_content'] .= "\n\n<div class='attribution'>" . (string) $tpost->source . '</div>';
|
818 |
break;
|
819 |
case 'link':
|
820 |
$post['format'] = 'link';
|
821 |
+
$linkurl = (string) $tpost->url;
|
822 |
+
$linktext = (string) $tpost->title;
|
823 |
+
$post['post_content'] = "<a href='$linkurl'>$linktext</a>";
|
824 |
+
if ( ! empty( $tpost->description ) )
|
825 |
+
$post['post_content'] .= '<div class="link_description">' . (string) $tpost->description . '</div>';
|
826 |
+
$post['post_title'] = (string) $tpost->title;
|
827 |
break;
|
828 |
+
case 'chat':
|
829 |
$post['format'] = 'chat';
|
830 |
+
$post['post_title'] = (string) $tpost->title;
|
831 |
+
$post['post_content'] = (string) $tpost->body;
|
832 |
break;
|
833 |
case 'audio':
|
834 |
$post['format'] = 'audio';
|
835 |
+
$post['media']['filename'] = basename( (string) $tpost->audio_url );
|
836 |
+
// If no .mp3 extension, add one so that sideloading works.
|
837 |
+
if ( ! preg_match( '/\.mp3$/', $post['media']['filename'] ) )
|
838 |
+
$post['media']['filename'] .= '.mp3';
|
839 |
+
$post['media']['audio'] = (string) $tpost->audio_url .'?plead=please-dont-download-this-or-our-lawyers-wont-let-us-host-audio';
|
840 |
+
$post['post_content'] = (string) $tpost->player . "\n" . (string) $tpost->caption;
|
841 |
break;
|
842 |
case 'video':
|
843 |
$post['format'] = 'video';
|
844 |
$post['post_content'] = '';
|
845 |
+
|
846 |
+
$video = array_shift( $tpost->player );
|
847 |
+
|
848 |
+
if ( false !== strpos( (string) $video->embed_code, 'embed' ) ) {
|
849 |
+
if ( preg_match_all('/<embed (.+?)>/', (string) $video->embed_code, $matches) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
850 |
foreach ($matches[1] as $match) {
|
851 |
+
foreach ( wp_kses_hair( $match, array( 'http' ) ) as $attr )
|
852 |
+
$embed[ $attr['name'] ] = $attr['value'];
|
853 |
}
|
854 |
+
|
855 |
// special case for weird youtube vids
|
856 |
+
$embed['src'] = preg_replace( '|http://www.youtube.com/v/([a-zA-Z0-9_]+).*|i', 'http://www.youtube.com/watch?v=$1', $embed['src'] );
|
857 |
+
|
858 |
// TODO find other special cases, since tumblr is full of them
|
|
|
859 |
$post['post_content'] = $embed['src'];
|
860 |
}
|
861 |
+
|
862 |
// Sometimes, video-source contains iframe markup.
|
863 |
+
if ( preg_match( '/<iframe/', $video->embed_code ) ) {
|
864 |
+
$embed['src'] = preg_replace( '|<iframe.*src="http://www.youtube.com/embed/([a-zA-Z0-9_\-]+)\??.*".*</iframe>|', 'http://www.youtube.com/watch?v=$1', $video->embed_code );
|
865 |
$post['post_content'] = $embed['src'];
|
866 |
}
|
867 |
+
} elseif ( preg_match( '/<iframe.*vimeo/', $video->embed_code ) ) {
|
868 |
+
$embed['src'] = preg_replace( '|<iframe.*src="(http://player.vimeo.com/video/([a-zA-Z0-9_\-]+))\??.*".*</iframe>.*|', 'http://vimeo.com/$2', $video->embed_code );
|
869 |
+
$post['post_content'] = $embed['src'];
|
870 |
} else {
|
871 |
+
// @todo: See if the video source is going to be oEmbed'able before adding the flash player
|
872 |
+
$post['post_content'] .= $video->embed_code;
|
|
|
873 |
}
|
874 |
+
|
875 |
+
$post['post_content'] .= "\n" . (string) $tpost->caption;
|
876 |
break;
|
877 |
case 'answer':
|
878 |
+
// TODO: Include asking_name and asking_url values?
|
879 |
+
$post['post_title'] = (string) $tpost->question;
|
880 |
+
$post['post_content'] = (string) $tpost->answer;
|
881 |
break;
|
882 |
case 'regular':
|
883 |
+
case 'text':
|
884 |
default:
|
885 |
+
$post['post_title'] = (string) $tpost->title;
|
886 |
+
$post['post_content'] = (string) $tpost->body;
|
887 |
break;
|
888 |
}
|
889 |
$posts[] = $post;
|
964 |
return $maybe_empty;
|
965 |
}
|
966 |
|
967 |
+
|
968 |
+
/**
|
969 |
+
* OAuth Signature creation
|
970 |
+
*/
|
971 |
+
function oauth_signature($secret, $method, $url, $params = array()) {
|
972 |
+
uksort($params, 'strcmp');
|
973 |
+
foreach ($params as $k => $v) {
|
974 |
+
$pairs[] = $this->_urlencode_rfc3986($k).'='.$this->_urlencode_rfc3986($v);
|
975 |
+
}
|
976 |
+
$concatenatedParams = implode('&', $pairs);
|
977 |
+
$baseString= $method."&". $this->_urlencode_rfc3986($url)."&".$this->_urlencode_rfc3986($concatenatedParams);
|
978 |
+
if (!is_array($secret)) {
|
979 |
+
$secret[0] = $secret;
|
980 |
+
$secret[1] = '';
|
981 |
+
}
|
982 |
+
$secret = $this->_urlencode_rfc3986($secret[0])."&".$this->_urlencode_rfc3986($secret[1]);
|
983 |
+
$oauth_signature = base64_encode(hash_hmac('sha1', $baseString, $secret, TRUE));
|
984 |
+
return $oauth_signature;
|
985 |
+
}
|
986 |
+
|
987 |
+
/**
|
988 |
+
* Helper function for OAuth Signature creation
|
989 |
+
*/
|
990 |
+
function _urlencode_rfc3986($input)
|
991 |
+
{
|
992 |
+
if (is_array($input)) {
|
993 |
+
return array_map(array($this, '_urlencode_rfc3986'), $input);
|
994 |
+
} else if (is_scalar($input)) {
|
995 |
+
return str_replace(array('+', '%7E'), array(' ', '~'), rawurlencode($input));
|
996 |
+
} else {
|
997 |
+
return '';
|
998 |
+
}
|
999 |
+
}
|
1000 |
+
|
1001 |
+
/**
|
1002 |
+
* Do a GET request with the access tokens
|
1003 |
+
*/
|
1004 |
+
function oauth_get_request($url) {
|
1005 |
+
if ( empty( $this->access_tokens ) )
|
1006 |
+
return false;
|
1007 |
+
|
1008 |
+
$params = array('oauth_consumer_key' => $this->get_consumer_key(),
|
1009 |
+
"oauth_nonce" => time(),
|
1010 |
+
"oauth_timestamp" => time(),
|
1011 |
+
"oauth_token" => $this->access_tokens['oauth_token'],
|
1012 |
+
"oauth_signature_method" => "HMAC-SHA1",
|
1013 |
+
"oauth_version" => "1.0",
|
1014 |
+
);
|
1015 |
+
|
1016 |
+
$params['oauth_signature'] = $this->oauth_signature(array($this->secretkey,$this->access_tokens['oauth_token_secret']), 'GET', $url, $params);
|
1017 |
+
|
1018 |
+
$url = add_query_arg( array_map('urlencode', $params), $url);
|
1019 |
+
|
1020 |
+
$response = wp_remote_get( $url );
|
1021 |
+
|
1022 |
+
if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
|
1023 |
+
return false;
|
1024 |
+
} else {
|
1025 |
+
$body = wp_remote_retrieve_body( $response );
|
1026 |
+
return json_decode($body);
|
1027 |
+
}
|
1028 |
+
}
|
1029 |
+
|
1030 |
+
|
1031 |
}
|
1032 |
}
|