WordPress.org

Plugin Directory

Changeset 892402


Ignore:
Timestamp:
04/13/14 19:59:19 (11 months ago)
Author:
ozh
Message:

Version 2.0

Changelog on Github

Location:
ozh-tweet-archiver/trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • ozh-tweet-archiver/trunk/inc/import.php

    r292441 r892402  
    22// Functions related to fetching & importing tweets 
    33 
    4 // Poll Twitter API and get tweets 
     4/** 
     5 * Poll Twitter API and get tweets 
     6 * 
     7 * @param  bool $echo  True to output results and redirect page (ie called from option page) 
     8 * @return bool        false if error while polling Twitter, true otherwise 
     9 */ 
    510function ozh_ta_get_tweets( $echo = false ) { 
    611    global $ozh_ta; 
    712     
    8     ozh_ta_schedule_next( 0 ); // clear scheduling 
    9  
    10     if( !$ozh_ta['screen_name'] ) { 
    11         ozh_ta_debug( 'No screen name defined' ); 
    12         return false; 
    13     } 
    14      
    15      
     13    if( !ozh_ta_is_configured() ) { 
     14        ozh_ta_debug( 'Config incomplete, cannot import tweets' ); 
     15        return false; 
     16    } 
     17 
    1618    $api = add_query_arg( array( 
    17         'count' => OZH_TA_BATCH, 
     19        'count'       => OZH_TA_BATCH, 
     20        'page'        => $ozh_ta['api_page'], 
    1821        'screen_name' => urlencode( $ozh_ta['screen_name'] ), 
    19         'page' => $ozh_ta['api_page'], 
    20         'since_id' => $ozh_ta['last_tweet_id_inserted'] 
     22        'since_id'    => $ozh_ta['last_tweet_id_inserted'] 
    2123    ), OZH_TA_API ); 
    22      
    2324    ozh_ta_debug( "Polling $api" ); 
    2425     
    25     $response = wp_remote_get( $api, array( 'timeout' => 10 ) ); 
    26     $tweets = wp_remote_retrieve_body( $response ); 
    27     // Fix integers in the JSON response to have them handled as strings and not integers 
    28     $tweets = preg_replace( '/"\s*:\s*([\d]+)\s*([,}{])/', '": "$1"$2', $tweets ); 
    29     $ratelimit = wp_remote_retrieve_header( $response, 'x-ratelimit-limit' ); 
    30     $ratelimit_r = wp_remote_retrieve_header( $response, 'x-ratelimit-remaining' ); 
    31      
    32     ozh_ta_debug( "rate: $ratelimit_r" ); 
    33      
    34     // Fail Whale FTW 
    35     if ( !$tweets or strpos( $tweets, 'Please wait a moment and try again. For more information, check out <a href="http://status.twitter.com">Twitter Status &raquo;</a></p>' ) ) { 
    36      
     26    $headers = array( 
     27        'Authorization' => 'Bearer ' . $ozh_ta['access_token'], 
     28    ); 
     29    ozh_ta_debug( "Headers: " . json_encode( $headers ) ); 
     30     
     31    $response = wp_remote_get( $api, array( 
     32        'headers' => $headers, 
     33        'timeout' => 10 
     34    ) ); 
     35     
     36    $tweets      = wp_remote_retrieve_body( $response ); 
     37    $ratelimit   = wp_remote_retrieve_header( $response, 'x-rate-limit-limit' ); 
     38    $ratelimit_r = wp_remote_retrieve_header( $response, 'x-rate-limit-remaining' ); 
     39    $status      = wp_remote_retrieve_response_code( $response ); 
     40    ozh_ta_debug( "API status: $status" ); 
     41    ozh_ta_debug( "API rate: $ratelimit_r/$ratelimit" ); 
     42     
     43    /** 
     44     * Something to check when Twitter update their API : 
     45     * 
     46     * Currently, when you try to retrieve more tweets than available (either you already have fetched 3200, or you 
     47     * have fetched them all), the API returns no particular error: status 200, just an empty body. 
     48     * In the future, check if they change this and return a particular message or status code 
     49     */ 
     50     
     51    // Fail Whale or other error 
     52    if ( !$tweets or $status != 200 ) { 
     53         
     54        // 401 : Unauthorized 
     55        if( $status == 401 ) { 
     56            ozh_ta_debug( 'Could not fetch tweets: unauthorized access.' ); 
     57            if( $echo ) { 
     58                wp_die( '<p>Twitter returned an "Unauthorized" error. Check your consumer key and secret!</p>' ); 
     59            } else { 
     60                // TODO: what to do in such a case? Better not to silently die and do nothing. 
     61                // Email blog admin ? 
     62                return false; 
     63            } 
     64        } 
     65         
     66        // 419 : Rate limit exceeded 
     67        // 5xx : Fail whale 
    3768        ozh_ta_debug( 'Twitter fail, retry in '.OZH_TA_NEXT_FAIL ); 
    3869 
     
    4576        // Context: from cron 
    4677        } else { 
    47             // schedule same operation in 60 seconds 
     78            // schedule same operation later 
    4879            ozh_ta_schedule_next( OZH_TA_NEXT_FAIL ); 
    4980            return false; 
     
    5283     
    5384    // No Fail Whale, let's import 
     85 
     86    // Legacy note: 
     87    // We used to have to fix integers in the JSON response to have them handled as strings and not integers, 
     88    // to avoid having tweet ID 438400650846928897 interpreted as 4.34343e15 
     89    // $tweets = preg_replace( '/"\s*:\s*([\d]+)\s*([,}{])/', '": "$1"$2', $tweets ); 
     90    // This isn't needed anymore since, smartly, Twitter's API returns both an id and an id_str. Nice, Twitter :) 
     91 
    5492    $tweets = array_reverse( (array)json_decode( $tweets ) ); 
    55      
     93    $ozh_ta['_last_tweet_id_inserted'] = 0; 
     94     
    5695    // Tweets found, let's archive 
    5796    if ( $tweets ) { 
    58         $results = ozh_ta_insert_tweets( $tweets, true ); 
    59         // array( "inserted", "last_tweet_id_inserted", (array)$user ); 
    60          
     97     
     98        if( ozh_ta_is_debug() ) { 
     99            $overall = new ozh_ta_query_count();  
     100        } 
     101 
     102        $results = ozh_ta_insert_tweets( $tweets, true ); 
     103        // array( inserted, skipped, tagged, num_tags, last_tweet_id_inserted, (array)$user ); 
     104         
    61105        // Record highest temp last_tweet_id_inserted, increment api_page and update user info 
    62106        $ozh_ta['_last_tweet_id_inserted'] = max( $results['last_tweet_id_inserted'], $ozh_ta['_last_tweet_id_inserted'] ); 
     
    65109        update_option( 'ozh_ta', $ozh_ta ); 
    66110 
    67         ozh_ta_debug( "Twitter OK, imported {$results['inserted']}, next in ".OZH_TA_NEXT_SUCCESS ); 
     111        ozh_ta_debug( "Twitter OK, imported {$results['inserted']}, skipped {$results['skipped']}, tagged {$results['tagged']} with {$results['num_tags']} tags, next in ".OZH_TA_NEXT_SUCCESS ); 
     112        if( ozh_ta_is_debug() ) { 
     113            ozh_ta_debug( 'Total queries: ' . $overall->stop() );             
     114        } 
    68115 
    69116        // Context: option page 
    70117        if( $echo ) { 
    71             echo "<p>Tweets inserted:<strong>{$results[ 'inserted' ]}</strong></p>"; 
     118            echo "<p>Tweets inserted: <strong>{$results[ 'inserted' ]}</strong></p>"; 
    72119            $url = wp_nonce_url( admin_url( 'options-general.php?page=ozh_ta&action=import_all&time='.time() ), 'ozh_ta-import_all' ); 
    73120            ozh_ta_reload( $url, OZH_TA_NEXT_SUCCESS ); 
     
    75122        // Context: from cron 
    76123        } else { 
    77             // schedule next operation in 30 seconds 
     124            // schedule next operation soon 
    78125            ozh_ta_schedule_next( OZH_TA_NEXT_SUCCESS ); 
    79126        } 
     
    86133        // Schedule next operation 
    87134        ozh_ta_schedule_next( $ozh_ta['refresh_interval'] ); 
    88         ozh_ta_debug( "Twitter finished, imported {$result['inserted']}, next in {$ozh_ta['refresh_interval']}" ); 
     135        ozh_ta_debug( "Twitter finished, next in {$ozh_ta['refresh_interval']}" ); 
    89136         
    90137        // Update real last_tweet_id_inserted, stats, & reset API paging 
     
    92139        unset( $ozh_ta['_last_tweet_id_inserted'] ); 
    93140        $ozh_ta['api_page'] = 1; 
    94         $ozh_ta['twitter_stats']['link_count'] = $wpdb->get_var( "SELECT COUNT(ID) FROM `$wpdb->posts` WHERE `post_content` LIKE '%http://%'" ); 
     141        $ozh_ta['twitter_stats']['link_count'] = $wpdb->get_var( "SELECT COUNT(ID) FROM `$wpdb->posts` WHERE `post_type` = 'post' AND `post_status` = 'publish' AND `post_content` LIKE '%class=\"link%'" ); 
    95142        $ozh_ta['twitter_stats']['replies'] = $wpdb->get_row( "SELECT COUNT( DISTINCT `meta_value`) as unique_names, COUNT( `meta_value`) as total FROM `$wpdb->postmeta` WHERE `meta_key` = 'ozh_ta_reply_to_name'", ARRAY_A ); 
    96143        $ozh_ta['twitter_stats']['total_archived'] = $wpdb->get_var( "SELECT COUNT(`meta_key`) FROM `$wpdb->postmeta` WHERE `meta_key` = 'ozh_ta_id'" ); 
     
    108155} 
    109156 
    110 // Insert tweets as posts 
    111 function ozh_ta_insert_tweets( $tweets, $display = false ) { 
    112     $inserted = 0; 
     157/** 
     158 * Linkify @usernames, #hashtags and t.co links, then return text  
     159 * 
     160 * @param  object $tweet  a Tweet object (json_decoded result of https://dev.twitter.com/docs/platform-objects/tweets) 
     161 * @return string         formatted tweet 
     162 */ 
     163function ozh_ta_linkify_tweet( $tweet ) { 
     164    global $ozh_ta; 
     165     
     166    $text = $tweet->text; 
     167     
     168    // Linkify twitter names if applicable 
     169    if( isset( $tweet->entities->user_mentions ) && $mentions = $tweet->entities->user_mentions ) { 
     170        foreach( $mentions as $mention ) { 
     171            $screen_name = $mention->screen_name; 
     172            $name        = $mention->name; 
     173             
     174            $text = ozh_ta_convert_mentions( $text, $screen_name, $name ); 
     175        } 
     176    } 
     177     
     178    // un-t.co links if applicable 
     179    if( isset( $tweet->entities->urls ) && $urls = $tweet->entities->urls ) { 
     180        foreach( $urls as $url ) { 
     181            $expanded_url = $url->expanded_url; 
     182            $display_url  = $url->display_url; 
     183            $tco_url      = $url->url; 
     184             
     185            $text = ozh_ta_convert_links( $text, $expanded_url, $display_url, $tco_url ); 
     186        } 
     187    } 
     188     
     189    // hashtag links if applicable 
     190    if( isset( $tweet->entities->hashtags ) && $hashes = $tweet->entities->hashtags ) { 
     191        foreach( $hashes as $hash ) { 
     192            $hash_text = $hash->text; 
     193             
     194            $text = ozh_ta_convert_hashtags( $text, $hash_text ); 
     195        } 
     196    } 
     197     
     198    // embed images if applicable. This operation shall be the last one 
     199    if( isset( $tweet->entities->media ) && $medias = $tweet->entities->media ) { 
     200        foreach( $medias as $media ) { 
     201            $media_url    = $media->media_url_https; 
     202            $display_url  = $media->display_url; 
     203            $expanded_url = $media->expanded_url; 
     204            $tco_url      = $media->url; 
     205             
     206            // Convert links 
     207            if( $ozh_ta['un_tco'] == 'yes' ) { 
     208                $replace = sprintf( '<a href="%s" title="%s" class="link link_untco link_untco_image">%s</a>', 
     209                                $expanded_url, $expanded_url, $display_url ); 
     210            } else { 
     211                $replace = sprintf( '<a href="%s" class="link link_tco link_tco_image">%s</a>', 
     212                                    $tco_url, $tco_url ); 
     213            } 
     214 
     215            // Add image 
     216            if( $ozh_ta['embed_images'] == 'yes' ) { 
     217                $insert  = sprintf( '<span class="embed_image embed_image_yes"><a href="%s"><img src="%s" /></a></span>', 
     218                                    $expanded_url, $media_url ); 
     219            } else { 
     220                $insert  = ''; 
     221            } 
     222             
     223            $text  = preg_replace( '!' . $tco_url . '!', $replace, $text, 1 ); 
     224            $text .= $insert; 
     225        } 
     226    } 
     227     
     228     
     229    return $text; 
     230} 
     231 
     232/** 
     233 * Insert tweets as posts 
     234 * 
     235 * @param array $tweets   Array of tweet objects 
     236 * @return array          Array of stats about the insertion 
     237 */ 
     238function ozh_ta_insert_tweets( $tweets ) { 
     239 
     240    // Flag as importing : this will cut some queries in the process, regarding (ping|track)backs 
     241    if( !defined( 'WP_IMPORTING' ) ) 
     242        define( 'WP_IMPORTING', true ); 
     243 
     244    global $ozh_ta; 
     245    $inserted = $skipped = $tagged = $num_tags = 0; 
    113246    $user = array(); 
    114      
    115     global $ozh_ta; 
     247     
     248    if( ozh_ta_is_debug() ) { 
     249        $num_sql_batch = new ozh_ta_query_count();  
     250    } 
    116251         
    117252    foreach ( (array)$tweets as $tweet ) { 
    118253         
    119         // Current tweet 
    120         $tid    = (string)$tweet->id; 
    121         $text   = $tweet->text; 
    122         $date   = date( 'Y-m-d H:i:s', strtotime( $tweet->created_at ) ); 
    123         $source = $tweet->source; 
     254        if( ozh_ta_is_debug() ) { 
     255            $num_sql_post = new ozh_ta_query_count();  
     256        } 
     257 
     258        // Current tweet 
     259        $tid            = (string)$tweet->id_str; 
     260        $text           = ozh_ta_linkify_tweet( $tweet ); 
     261        $date           = date( 'Y-m-d H:i:s', strtotime( $tweet->created_at ) ); 
     262        $source         = $tweet->source; 
     263        $has_hashtags   = count( $tweet->entities->hashtags ) > 0; 
    124264        $reply_to_name  = $tweet->in_reply_to_screen_name; 
    125         $reply_to_tweet = (string)$tweet->in_reply_to_status_id; 
    126          
     265        $reply_to_tweet = (string)$tweet->in_reply_to_status_id_str; 
     266         
    127267        // Info about Twitter user 
    128268        if( !$user ) { 
    129269            $user = array( 
    130                 'tweet_counts' => $tweet->user->statuses_count, 
    131                 'followers' => $tweet->user->followers_count, 
    132                 'following' => $tweet->user->friends_count, 
    133                 'listed_count' => $tweet->user->listed_count, 
     270                'tweet_counts'      => $tweet->user->statuses_count, 
     271                'followers'         => $tweet->user->followers_count, 
     272                'following'         => $tweet->user->friends_count, 
     273                'listed_count'      => $tweet->user->listed_count, 
    134274                'profile_image_url' => $tweet->user->profile_image_url, 
    135                 'tweeting_since' => date( 'Y-m-d H:i:s', strtotime( $tweet->user->created_at ) ), 
     275                'tweeting_since'    => date( 'Y-m-d H:i:s', strtotime( $tweet->user->created_at ) ), 
    136276            ); 
    137277        } 
     
    146286            // Insert tweet as new post 
    147287            $post = array( 
    148                 'post_title'   => $text, 
    149                 'post_content' => $text, 
    150                 'post_date'    => $date, 
    151                 'post_category'=> array( $ozh_ta['post_category'] ), 
    152                 'post_status'  => 'publish', 
    153                 'post_author'  => $ozh_ta['post_author'], 
     288                'post_title'    => strip_tags( $text ), 
     289                'post_content'  => $text, 
     290                'post_date'     => $date, 
     291                'post_category' => array( $ozh_ta['post_category'] ), 
     292                'post_status'   => 'publish', 
     293                'post_author'   => $ozh_ta['post_author'], 
     294                'guid'          => home_url() . '/?tid=' . $tid,  // forcing a GUID will save one query when inserting 
    154295            ); 
    155296            // Plugins: hack here 
     
    159300 
    160301            // Insert post meta data 
    161             add_post_meta( $post_id, 'ozh_ta_id', $tid, true ); 
     302            add_post_meta( $post_id, 'ozh_ta_id', $tid ); 
    162303            if( $source ) 
    163                 add_post_meta( $post_id, 'ozh_ta_source', $source, true ); 
     304                add_post_meta( $post_id, 'ozh_ta_source', $source ); 
    164305            if( $reply_to_name ) 
    165                 add_post_meta( $post_id, 'ozh_ta_reply_to_name', $reply_to_name, true ); 
     306                add_post_meta( $post_id, 'ozh_ta_reply_to_name', $reply_to_name ); 
    166307            if( $reply_to_tweet ) 
    167                 add_post_meta( $post_id, 'ozh_ta_reply_to_tweet', $reply_to_tweet, true ); 
    168          
    169             $last_tweet_id_inserted = $tid; 
    170             ozh_ta_debug( "Inserted $post_id (tweet id: $tid, tweet: ". substr($text, 0, 45) ."...)" ); 
     308                add_post_meta( $post_id, 'ozh_ta_reply_to_tweet', $reply_to_tweet ); 
     309 
     310            ozh_ta_debug( " Inserted #$post_id (tweet id: $tid, tweet: ". ozh_ta_trim_long_string( $text, 100 ) . ')' ); 
     311         
     312            if( ozh_ta_is_debug() ) { 
     313                ozh_ta_debug( '  Import query cost: ' . $num_sql_post->stop() ); 
     314            } 
     315 
     316            // Tag post if applicable 
     317            if( $has_hashtags && $ozh_ta['add_hash_as_tags'] == 'yes' ) { 
     318                $hashtags  = ozh_ta_get_hashtags( $tweet ); 
     319                $num_tags += count( $hashtags ); 
     320                $hashtags  = implode( ', ', $hashtags ); 
     321                ozh_ta_debug( "  Tagging post $post_id with " . $hashtags ); 
     322                $tagged++; 
     323                if( ozh_ta_is_debug() ) { 
     324                    $num_sql_tag = new ozh_ta_query_count(); 
     325                } 
     326                wp_set_post_tags( $post_id, $hashtags ); 
     327                if( ozh_ta_is_debug() ) { 
     328                    ozh_ta_debug( '   Tagging query cost: ' . $num_sql_tag->stop() ); 
     329                } 
     330                 
     331            } 
     332             
     333            $last_tweet_id_inserted = $tid; 
    171334            $inserted++; 
    172335             
    173336        } else { 
    174337            // This tweet has already been imported ?! 
    175             ozh_ta_debug( "Skipping tweet $tid, already imported?!" ); 
     338            ozh_ta_debug( " Skipping tweet $tid, already imported?!" ); 
     339            $skipped++; 
    176340        } 
    177341    } 
    178342 
    179     return array( 
    180         'inserted' => $inserted, 
     343    if( ozh_ta_is_debug() ) { 
     344        ozh_ta_debug( 'Batch import query cost: ' . $num_sql_batch->stop() ); 
     345    } 
     346 
     347    return array( 
     348        'inserted'               => $inserted, 
     349        'skipped'                => $skipped, 
     350        'tagged'                 => $tagged, 
     351        'num_tags'               => $num_tags, 
    181352        'last_tweet_id_inserted' => $tid, 
    182         'user' => $user, 
     353        'user'                   => $user, 
    183354    ); 
    184355} 
    185356 
    186  
    187 // Schedule next twitter archiving 
    188 function ozh_ta_schedule_next( $delay = 30 ) { 
    189     wp_clear_scheduled_hook( 'ozh_ta_cron_import' ); 
    190     ozh_ta_debug( "Schedule cleared" ); 
    191     if( $delay ) { 
    192         wp_schedule_single_event( time()+$delay, 'ozh_ta_cron_import' ); 
    193         ozh_ta_debug( "Schedule next in $delay" ); 
    194     } 
    195 } 
    196  
    197  
     357/** 
     358 * Return list of hashtags for a given tweet 
     359 * 
     360 * @param  object $tweet  a Tweet object (json_decoded result of https://dev.twitter.com/docs/platform-objects/tweets) 
     361 * @return array          Array of hashtags 
     362 */ 
     363function ozh_ta_get_hashtags( $tweet ) { 
     364    $list = array(); 
     365    foreach( $tweet->entities->hashtags as $tag ) { 
     366        $list[] = $tag->text; 
     367    } 
     368    return $list; 
     369} 
     370 
     371 
     372/** 
     373 * Count MySQL queries between two events 
     374 * 
     375 * Usage: 
     376 * $context = new ozh_ta_query_count(); 
     377 * // ... do some stuff in that context 
     378 * var_dump( $context->stop() ); // int 4 
     379 */ 
     380class ozh_ta_query_count { 
     381     
     382    private $start; 
     383    private $stop; 
     384     
     385    public function __construct() { 
     386        $this->start(); 
     387    } 
     388     
     389    private function start() { 
     390        global $wpdb; 
     391        $this->start = $wpdb->num_queries; 
     392    } 
     393     
     394    public function stop() { 
     395        global $wpdb; 
     396        $this->stop = $wpdb->num_queries; 
     397        return ($this->stop - $this->start ); 
     398    } 
     399 
     400} 
     401 
     402/** 
     403 * Fetch a single tweet 
     404 * 
     405 * This function is not used in the plugin, it's here to be used when debugging or for custom use 
     406 * 
     407 * @param  string $id   Tweet ID ('454752497002115072' in 'https://twitter.com/ozh/statuses/454752497002115072') 
     408 * @return bool|object  false if not found, or tweet object (see https://dev.twitter.com/docs/platform-objects/tweets) 
     409 */ 
     410function ozh_ta_get_single_tweet( $id ) { 
     411    global $ozh_ta; 
     412     
     413    if( !ozh_ta_is_configured() ) { 
     414        ozh_ta_debug( 'Config incomplete, cannot import tweets' ); 
     415        return false; 
     416    } 
     417 
     418    $api = 'https://api.twitter.com/1.1/statuses/show.json?id=' . $id; 
     419    $headers = array( 
     420        'Authorization' => 'Bearer ' . $ozh_ta['access_token'], 
     421    ); 
     422 
     423    ozh_ta_debug( "Polling $api" ); 
     424     
     425    $response = wp_remote_get( $api, array( 
     426        'headers' => $headers, 
     427        'timeout' => 10 
     428    ) ); 
     429     
     430    $tweet = json_decode( wp_remote_retrieve_body( $response ) ); 
     431     
     432    // var_dump( $tweet ); 
     433    if( isset( $tweet->errors ) ) { 
     434        ozh_ta_debug( "Tweet #$id not found!" ); 
     435        return false; 
     436    } 
     437     
     438    return $tweet; 
     439} 
     440 
     441/** 
     442 * Import a single tweet as a post 
     443 * 
     444 * This function is not used in the plugin, it's here to be used when debugging or for custom use 
     445 * 
     446 * @param  string $id   Tweet ID ('454752497002115072' in 'https://twitter.com/ozh/statuses/454752497002115072') 
     447 * @return bool|array   false if not fuond, or array of stats about the insertion 
     448 */ 
     449function ozh_ta_import_single_tweet( $id ) { 
     450    if( $tweet = ozh_ta_get_single_tweet( $id ) ) { 
     451        return( ozh_ta_insert_tweets( array( $tweet ) ) ); 
     452    } 
     453     
     454    return false; 
     455} 
  • ozh-tweet-archiver/trunk/inc/option-page.php

    r292186 r892402  
    11<?php 
    22 
     3// Add the nagging message on all admin page except the plugin's one 
    34function ozh_ta_notice_config() { 
    45    global $plugin_page; 
    5     if( $plugin_page == 'ozh_ta' ) 
    6         return; 
    7  
    8     $url = menu_page_url( 'ozh_ta', false ); 
    9     $message = 'Please configure <strong>Ozh\' Tweet Archiver</strong> <a href="'.$url.'">settings</a> now'; 
    10     echo <<<NOTICE 
    11     <div class="error"><p>$message</p></div> 
    12 NOTICE; 
     6 
     7    // on the plugin page 
     8    if( $plugin_page == 'ozh_ta' ) { 
     9        global $ozh_ta; 
     10        if(    isset( $ozh_ta['cons_key'] ) 
     11            && isset( $ozh_ta['cons_secret'] ) 
     12            && ( !isset( $ozh_ta['access_token'] ) || !$ozh_ta['access_token'] ) 
     13        ) { 
     14            $message = 'Could not authenticate to Twitter. Check your consumer key and secret, then try again'; 
     15        } else { 
     16            return; 
     17        } 
     18 
     19    // on all other admin pages 
     20    } else { 
     21        $url = menu_page_url( 'ozh_ta', false ); 
     22        $message = 'Please configure <strong>Ozh\' Tweet Archiver</strong> <a href="'.$url.'">settings</a> now'; 
     23    } 
     24 
     25    echo "<div class='error'><p>$message</p></div>"; 
    1326} 
    1427 
     
    1932    if( isset( $_GET['action'] ) && $_GET['action'] == 'cancel_auto' ) { 
    2033        check_admin_referer( 'ozh_ta-cancel_auto' ); 
    21         ozh_ta_require( 'import.php' ); 
    2234        ozh_ta_schedule_next( 0 ); 
    2335        return; 
     
    6880        // Import the goodness 
    6981        ozh_ta_require( 'import.php' ); 
    70         ozh_ta_schedule_next( 0 ); 
     82        ozh_ta_schedule_next( 0 ); // clear any scheduling : it'll be rescheduled after all tweets have been imported 
    7183        ozh_ta_get_tweets( true ); 
    7284         
     
    95107    </style> 
    96108    <?php 
    97     if( OZH_TA_DEBUG ) { 
    98         echo "<pre>"; 
    99         print_r( $ozh_ta ); 
     109    if( ozh_ta_is_debug() ) { 
     110        echo "<pre style='border:1px solid;padding:5px 15px;'>"; 
     111        var_dump( $ozh_ta ); 
    100112        echo "</pre>"; 
    101113    } 
    102114     
    103     if( $ozh_ta['screen_name'] ) { 
    104         ozh_ta_do_page_manual(); 
    105     } 
    106  
    107115    if( wp_next_scheduled( 'ozh_ta_cron_import' ) && !ozh_ta_is_manually_archiving() ) { 
    108116        ozh_ta_do_page_scheduled(); 
    109117    } 
    110118     
     119    if( ozh_ta_is_configured() ) { 
     120        ozh_ta_do_page_manual(); 
     121    } 
     122 
    111123    // Option page when not doing operation 
    112124    if( !isset( $_GET['action'] ) or $_GET['action'] != 'import_all' ) { ?> 
     
    153165        })(jQuery); 
    154166        </script> 
    155         <p class="submit"><input name="Submit" type="submit" value="Save Changes" /></p> 
     167        <?php 
     168        submit_button(); 
     169        submit_button( 'Reset all settings', 'delete', 'delete_btn' ); 
     170        ?> 
     171        <script> 
     172        (function($){ 
     173        $('#delete_btn').click( function() { 
     174            if (!confirm('Really reset everything? No undo!')) { 
     175                return false; 
     176            } 
     177        }); 
     178        })(jQuery); 
     179        </script> 
    156180        </form> 
    157181    <?php } ?> 
  • ozh-tweet-archiver/trunk/inc/settings.php

    r292186 r892402  
    2424    // Twitter section: screen name field 
    2525    add_settings_field( 
    26         'ozh_ta_setting_screen_name',   // setting ID 
    27         'Enter your Twitter user name', // text on the left 
    28         'ozh_ta_setting_screen_name',   // callback function for field 
    29         'ozh_ta',                       // plugin page 
    30         'ozh_ta_section_twitter'        // section name 
     26        'ozh_ta_setting_screen_name',  // setting ID 
     27        'Twitter user name',           // text on the left 
     28        'ozh_ta_setting_screen_name',  // callback function for field 
     29        'ozh_ta',                      // plugin page 
     30        'ozh_ta_section_twitter'       // section name 
     31    ); 
     32    // Twitter section: consumer key 
     33    add_settings_field( 
     34        'ozh_ta_setting_cons_key',  // setting ID 
     35        'Consumer Key',             // text on the left 
     36        'ozh_ta_setting_cons_key',  // callback function for field 
     37        'ozh_ta',                   // plugin page 
     38        'ozh_ta_section_twitter'    // section name 
     39    ); 
     40    // Twitter section: consumer secret 
     41    add_settings_field( 
     42        'ozh_ta_setting_cons_secret', // setting ID 
     43        'Consumer Secret',            // text on the left 
     44        'ozh_ta_setting_cons_secret', // callback function for field 
     45        'ozh_ta',                     // plugin page 
     46        'ozh_ta_section_twitter'      // section name 
    3147    ); 
    3248    // Plugin section: lots of fields 
     
    3854        'link_hashtags'    => 'Link #hashtags', 
    3955        'add_hash_as_tags' => 'Add hashtags as post tags', 
     56        'un_tco'           => 'Expand <code>t.co</code> links', 
     57        'embed_images'     => 'Embed <code>pic.twitter.com</code> images', 
    4058    ); 
    4159    foreach( $fields as $field => $text ) { 
     
    5371// Plugin settings section header 
    5472function ozh_ta_section_plugin_text() { 
    55     echo '<p>Configure how the plugin will archive the tweets</p>'; 
     73    echo '<p>Configure how the plugin will archive the tweets (default settings will work just fine)</p>'; 
    5674} 
    5775 
    5876// Twitter settings section header 
    5977function ozh_ta_section_twitter_text() { 
    60     // bleh. No need. 
     78    echo '<p>Create a new application on <a href="https://apps.twitter.com/app/new">apps.twitter.com</a>, fill in the details, save, then click on the <strong>Test OAuth</strong> button to get your consumer key and consumer secret.</p>'; 
    6179} 
    6280 
     
    7088    switch( $setting ) { 
    7189    case 'screen_name': 
     90    case 'cons_key': 
     91    case 'cons_secret': 
     92        $value = esc_attr( $value ); 
     93        echo "<input id='$setting' name='ozh_ta[$setting]' type='text' value='$value' />"; 
     94        break; 
    7295        $value = esc_attr( $value ); 
    7396        echo "<input id='$setting' name='ozh_ta[$setting]' type='text' value='$value' />"; 
     
    128151        echo "</select>\n"; 
    129152 
    130         echo "<br/>Example: \"<span id='helper_link_usernames' class='tweet_sample'>Check the other 
    131         #WordPress 
    132         stuff by 
     153        echo "<br/>Example: \"<span id='helper_link_usernames' class='tweet_sample'>Thank you 
    133154        <span id='toggle_link_usernames_no' class='toggle_link_usernames' style='display:". ($value == 'no' ? 'inline' : 'none') ."'>@ozh</span> 
    134         <span id='toggle_link_usernames_yes' class='toggle_link_usernames' style='display:". ($value == 'yes' ? 'inline' : 'none') ."'>@<a href='http://twitter.com/ozh'>ozh</a></span> 
    135         <a href='http://ozh.in/projects'>http://ozh.in/projects</a></span>\""; 
    136  
     155        <span id='toggle_link_usernames_yes' class='toggle_link_usernames' style='display:". ($value == 'yes' ? 'inline' : 'none') ."'>@<a href='https://twitter.com/ozh'>ozh</a></span> 
     156        for the #WordPress plugins!</span>\""; 
     157 
     158        break; 
     159         
     160    case 'un_tco': 
     161        $options = array( 
     162            'no'  => 'No', 
     163            'yes' => 'Yes', 
     164        ); 
     165        $value = ( $value == 'yes' ? 'yes' : 'no' ); 
     166        echo "<select class='toggler' id='$setting' name='ozh_ta[$setting]'>\n"; 
     167        foreach( $options as $option => $desc ){ 
     168            echo "<option value='$option' ".selected( $option, $value, false ).">$desc</option>\n"; 
     169        } 
     170        echo "</select>\n"; 
     171         
     172        echo "<br/>Example: \"<span id='helper_un_tco' class='tweet_sample fade-303060 fade'>Wow super site  
     173        <span id='toggle_un_tco_no' class='toggle_un_tco' style='display:". ($value == 'no' ? 'inline' : 'none') ."'><a href='http://t.co/JeIYgZHB6o'>t.co/JeIYgZHB6o</a></span> 
     174        <span id='toggle_un_tco_yes' class='toggle_un_tco' style='display:". ($value == 'yes' ? 'inline' : 'none') ."'><a href='http://ozh.org/'>ozh.org</a></span> 
     175        ! Check it out!</span>\""; 
     176         
     177        break; 
     178         
     179    case 'embed_images': 
     180        $options = array( 
     181            'no'  => 'No', 
     182            'yes' => 'Yes', 
     183        ); 
     184        $value = ( $value == 'yes' ? 'yes' : 'no' ); 
     185        echo "<select class='toggler' id='$setting' name='ozh_ta[$setting]'>\n"; 
     186        foreach( $options as $option => $desc ){ 
     187            echo "<option value='$option' ".selected( $option, $value, false ).">$desc</option>\n"; 
     188        } 
     189        echo "</select>\n"; 
     190         
     191        echo "<br/><span id='helper_embed_images' class='tweet_sample fade-303060 fade'> 
     192        <span id='toggle_embed_images_no' class='toggle_embed_images' style='display:". ($value == 'no' ? 'inline' : 'none') ."'>Just display a link to the image</span> 
     193        <span id='toggle_embed_images_yes' class='toggle_embed_images' style='display:". ($value == 'yes' ? 'inline' : 'none') ."'>Display a link and an &lt;img> after the text</span> 
     194        </span>"; 
     195         
    137196        break; 
    138197         
     
    158217        echo "</select>\n"; 
    159218         
    160         echo "<br/>Example: \"<span id='helper_link_hashtags' class='tweet_sample fade-303060 fade'>Check the other 
     219        echo "<br/>Example: \"<span id='helper_link_hashtags' class='tweet_sample fade-303060 fade'>Thank you @ozh for the 
    161220        <span id='toggle_link_hashtags_no' class='toggle_link_hashtags' style='display:". ($value == 'no' ? 'inline' : 'none') ."'>#WordPress</span> 
    162221        <span id='toggle_link_hashtags_twitter' class='toggle_link_hashtags' style='display:". ($value == 'twitter' ? 'inline' : 'none') ."'><a href='http://search.twitter.com/search?q=%23WordPress'>#WordPress</a></span> 
    163222        <span id='toggle_link_hashtags_local' class='toggle_link_hashtags' style='display:". ($value == 'local' ? 'inline' : 'none') ."'><a href='".ozh_ta_get_tag_link('wordpress')."'>#WordPress</a></span> 
    164         stuff by @ozh <a href='http://ozh.in/projects'>http://ozh.in/projects</a></span>\""; 
     223        plugins!</span>\""; 
    165224         
    166225        break; 
     
    187246} 
    188247 
    189 // Field: screen_name 
     248// Field: cons_key 
     249function ozh_ta_setting_cons_key() { 
     250    ozh_ta_setting( 'cons_key' ); 
     251} 
     252 
     253// Field: cons_secret 
     254function ozh_ta_setting_cons_secret() { 
     255    ozh_ta_setting( 'cons_secret' ); 
     256} 
     257 
     258// Field: refresh_interval 
    190259function ozh_ta_setting_refresh_interval() { 
    191260    ozh_ta_setting( 'refresh_interval' ); 
    192261} 
    193262 
    194 // Field: screen_name 
     263// Field: post_category 
    195264function ozh_ta_setting_post_category() { 
    196265    ozh_ta_setting( 'post_category' ); 
    197266} 
    198267 
    199 // Field: screen_name 
     268// Field: post_author 
    200269function ozh_ta_setting_post_author() { 
    201270    ozh_ta_setting( 'post_author' ); 
    202271} 
    203272 
    204 // Field: screen_name 
     273// Field: link_usernames 
    205274function ozh_ta_setting_link_usernames() { 
    206275    ozh_ta_setting( 'link_usernames' ); 
    207276} 
    208277 
    209 // Field: screen_name 
     278// Field: link_hashtags 
    210279function ozh_ta_setting_link_hashtags() { 
    211280    ozh_ta_setting( 'link_hashtags' ); 
    212281} 
    213282 
    214 // Field: screen_name 
     283// Field: un_tco 
     284function ozh_ta_setting_un_tco() { 
     285    ozh_ta_setting( 'un_tco' ); 
     286} 
     287 
     288// Field: un_tco 
     289function ozh_ta_setting_embed_images() { 
     290    ozh_ta_setting( 'embed_images' ); 
     291} 
     292 
     293// Field: add_hash_as_tags 
    215294function ozh_ta_setting_add_hash_as_tags() { 
    216295    ozh_ta_setting( 'add_hash_as_tags' ); 
     
    230309    global $ozh_ta; 
    231310     
    232     // Screw validation. Just don't be an idiot.     
    233      
    234     // don't lose stuff that are not "settings" submitted in the plugin page 
    235     $input = array_merge( $ozh_ta, $input ); 
     311    // Screw validation. Just don't be an idiot. 
     312     
     313    // Reset if applicable 
     314    if( isset( $_POST['delete_btn'] ) ) { 
     315        $input = array(); 
     316        ozh_ta_schedule_next( 0 ); 
     317    } else { 
     318        // don't lose stuff that are not "settings" submitted in the plugin page 
     319        $input = array_merge( $ozh_ta, $input ); 
     320         
     321        // Consumer key & secret defined? Get an OAuth token 
     322        if( isset( $input['cons_key'] ) && isset( $input['cons_secret'] ) && !ozh_ta_is_manually_archiving() ) { 
     323            $input['access_token'] = ozh_ta_get_token( $input['cons_key'], $input['cons_secret'] ); 
     324        } 
     325    } 
    236326 
    237327    return $input; 
    238328} 
    239  
  • ozh-tweet-archiver/trunk/inc/template_tags.php

    r292186 r892402  
    1515add_action( 'ozh_ta_source', 'ozh_ta_source', 10, 0 ); 
    1616 
    17 // Template tag: tweet id (eg the 13456464123 part of the http://twitter.com/ozh/statuses/13456464123 ) 
     17// Template tag: tweet id (eg the 13456464123 part of the https://twitter.com/ozh/statuses/13456464123 ) 
    1818function ozh_ta_id( $echo = true ) { 
    1919    $what = ozh_ta_get_meta( 'id' ); 
     
    2424add_action( 'ozh_ta_id', 'ozh_ta_id', 10, 0 ); 
    2525 
    26 // Template tag: tweet link (http://twitter.com/ozh/statuses/13456464123) 
     26// Template tag: tweet link (https://twitter.com/ozh/statuses/13456464123) 
    2727function ozh_ta_tweet_link( $echo = true ) { 
    2828    global $ozh_ta; 
    29     $link = 'http://twitter.com/'.$ozh_ta['screen_name'].'/statuses/'.ozh_ta_get_meta( 'id' ); 
     29    $link = 'https://twitter.com/'.$ozh_ta['screen_name'].'/statuses/'.ozh_ta_get_meta( 'id' ); 
    3030    if( $echo ) 
    3131        echo $link; 
     
    5959        $nofollow = apply_filters( 'ozh_ta_reply_to_nofollow', 'rel="nofollow"' ); 
    6060        $text = str_replace( '%name%', $name, $text ); 
    61         $link = sprintf( '<a href="http://twitter.com/%s/statuses/%s" %s class="ozh_ta_in_reply">%s</a>', 
     61        $link = sprintf( '<a href="https://twitter.com/%s/statuses/%s" %s class="ozh_ta_in_reply">%s</a>', 
    6262            $name, $tweet, $nofollow, $text ); 
    6363        $link = apply_filters( 'ozh_ta_in_reply_to_tweet_link', $link ); 
     
    137137    $links = ozh_ta_get_total( 'link_count' ); 
    138138    $total = ozh_ta_get_total( 'total_archived' ); 
    139     $what = (string)( intval( 1000 * $links / $total ) / 10 ).'%'; 
    140     if( $echo ) 
    141         echo $what; 
    142     return $what; 
     139    $ratio = $total > 0 ? (string)( intval( 1000 * $links / $total ) / 10 ).'%' : '' ; 
     140    if( $echo ) 
     141        echo $ratio; 
     142    return $ratio; 
    143143} 
    144144add_action( 'ozh_ta_link_ratio', 'ozh_ta_link_ratio', 10, 0 ); 
     
    147147function ozh_ta_reply_ratio( $echo = true ) { 
    148148    $replies = ozh_ta_get_total( 'replies' ); 
    149     $total = ozh_ta_get_total( 'total_archived' ); 
    150     $what = (string)( intval( 1000 * $replies['total'] / $total ) / 10 ).'%'; 
    151     if( $echo ) 
    152         echo $what; 
    153     return $what; 
     149    $total   = ozh_ta_get_total( 'total_archived' ); 
     150    $ratio   = $total > 0 ? (string)( intval( 1000 * $replies['total'] / $total ) / 10 ).'%' : ''; 
     151    if( $echo ) 
     152        echo $ratio; 
     153    return $ratio; 
    154154} 
    155155add_action( 'ozh_ta_reply_ratio', 'ozh_ta_reply_ratio', 10, 0 ); 
     
    189189function ozh_ta_get_total( $what ) { 
    190190    global $ozh_ta; 
    191     return $ozh_ta['twitter_stats'][$what]; 
     191    return isset( $ozh_ta['twitter_stats'][$what] ) ? $ozh_ta['twitter_stats'][$what] : ''; 
    192192} 
    193193 
     
    196196    global $id; 
    197197    return get_post_meta( $id, 'ozh_ta_'.$what, true ); 
    198     echo "<pre>";var_dump( debug_backtrace() );echo "</pre>"; 
    199     return 'bleh'; 
    200198} 
    201199 
  • ozh-tweet-archiver/trunk/ozh-ta.php

    r292441 r892402  
    33Plugin Name: Ozh' Tweet Archiver 
    44Plugin URI: http://planetozh.com/blog/my-projects/ozh-tweet-archiver-backup-twitter-with-wordpress/ 
    5 Description: Archive your tweets and import them as posts. Can convert #hashtags to WordPress tags. 
    6 Version: 1.0.1 
     5Description: Archive your tweets and import them as posts 
     6Version: 2.0 
    77Author: Ozh 
    88Author URI: http://ozh.org/ 
    99*/ 
    1010 
    11 /* History 
    12    1.0     initial release 
    13    1.0.1   fix notice when no tweet found 
     11/** 
     12 * History 
     13 * 1.0     initial release 
     14 * 1.0.1   fix notice when no tweet found 
     15 * 2.0     change to Twitter API v1.1, with help from @EHER 
     16 *         allow embedding of images 
     17 *         allow unwrapping t.co links 
     18 */ 
     19 
     20/* 
     21 FIXME Known bug: 
     22 The plugin will eat backslashes. A simple fix would be to replace \ with &#92; prior to inserting, but I haven't checked 
     23 all potential unwanted side effects yet. 
    1424*/ 
    1525 
    1626// Constants that should work for everyone 
    17 define( 'OZH_TA_API', 'http://api.twitter.com/1/statuses/user_timeline.json' ); // Twitter API url (no auth needed) 
    18 define( 'OZH_TA_BATCH', 100 );  // How many tweets to import at most. 200 is the max allowed on Twitter. Take it easy on shared hosting. 
    19 define( 'OZH_TA_DEBUG', false ); // Log debug messages 
    20 define( 'OZH_TA_NEXT_SUCCESS', 10 ); // How long to wait between sucessfull batches 
    21 define( 'OZH_TA_NEXT_FAIL', 90 ); // How long to wait after a Fail Whale 
     27define( 'OZH_TA_API', 'https://api.twitter.com/1.1/statuses/user_timeline.json' ); // Twitter API url (1.1 version) 
     28define( 'OZH_TA_BATCH', 15 );       // How many tweets to import at most. Take it easy on shared hosting. 
     29define( 'OZH_TA_NEXT_SUCCESS', 5 ); // How long to wait between sucessfull batches (in seconds) 
     30define( 'OZH_TA_NEXT_FAIL', 120 );  // How long to wait after a Fail Whale (in seconds) 
    2231 
    2332global $ozh_ta; 
     
    3039add_action( 'admin_init',  'ozh_ta_load_admin' ); 
    3140add_action( 'admin_menu',  'ozh_ta_add_page'); 
    32 add_filter( 'the_content', 'ozh_ta_linkify' ); 
     41add_filter( 'the_content', 'ozh_ta_convert_old_posts' ); 
    3342 
    3443// Import tweets from cron job 
    3544function ozh_ta_cron_import() { 
    3645    ozh_ta_require( 'import.php' ); 
     46    ozh_ta_debug( 'Starting cron job' ); 
    3747    ozh_ta_get_tweets(); 
    3848} 
     
    4252    global $ozh_ta; 
    4353     
    44     if( !$ozh_ta = get_option( 'ozh_ta' ) ) 
    45         $ozh_ta = ozh_ta_defaults(); 
    46  
     54    ozh_ta_require( 'utils.php' ); 
    4755    ozh_ta_require( 'template_tags.php' ); 
     56     
     57    $ozh_ta = get_option( 'ozh_ta' ); 
     58    if( $ozh_ta == false ) { 
     59        $ozh_ta = ozh_ta_defaults(); 
     60    } else { 
     61        array_merge( ozh_ta_defaults(), $ozh_ta ); 
     62    } 
    4863     
    4964    ozh_ta_debug( 'Plugin init' ); 
    50 } 
    51  
    52 // Require files as needed 
    53 function ozh_ta_require( $file ) { 
    54     require_once( dirname(__FILE__).'/inc/'.$file ); 
    5565} 
    5666 
     
    6171    ozh_ta_require( 'option-page.php' ); 
    6272    ozh_ta_init_settings(); 
    63     if( !$ozh_ta['screen_name'] ) 
     73    if( !ozh_ta_is_configured() ) { 
    6474        add_action( 'admin_notices', 'ozh_ta_notice_config' ); 
     75    } 
    6576    add_filter( 'plugin_row_meta', 'ozh_ta_plugin_row_meta', 10, 2 ); 
    6677    add_filter( 'plugin_action_links_'.plugin_basename( __FILE__ ), 'ozh_ta_plugin_actions' ); 
     
    7283    $class = ''; 
    7384    $text = 'Configure'; 
    74     if( !isset( $ozh_ta['screen_name'] ) or empty( $ozh_ta['screen_name'] ) ) { 
     85    if( !ozh_ta_is_configured() ) { 
    7586        $class = 'delete'; 
    7687        $text .= ' now!'; 
     
    90101// Add plugin menu 
    91102function ozh_ta_add_page() { 
    92     ozh_ta_debug( 'add_page' ); 
    93103    $page = add_options_page( 'Ozh\' Tweet Archiver', 'Tweet Archiver', 'manage_options', 'ozh_ta', 'ozh_ta_do_page' ); 
    94 } 
    95  
    96 // Add links to URLs, @usernames and #hashtags. 
    97 // This is to be hooked into filter 'the_content' 
    98 function ozh_ta_linkify( $text ) { 
    99     global $ozh_ta; 
    100      
    101     // Linkify twitter names if applicable 
    102     if( $ozh_ta['link_usernames'] == 'yes' ) { 
    103         $nofollow = apply_filters( 'ozh_ta_username_nofollow', 'rel="nofollow"' ); 
    104         $text = preg_replace( 
    105             '/(\W)@(\w+)/', 
    106             '\\1@<a href="http://twitter.com/\\2" '.$nofollow.'>\\2</a>', 
    107             $text 
    108         ); 
    109     } 
    110      
    111     if( $ozh_ta['link_hashtags'] != 'no' ) { 
    112         // find hashtags 
    113         preg_match_all( '/\B#(\w*[a-zA-Z-]+\w*)/', $text, $matches ); 
    114         $hashtags = $matches[0]; // #bleh 
    115         $tags = $matches[1];     //  bleh 
    116         unset( $matches ); 
    117          
    118         if( $hashtags ) { 
    119          
    120             // Check if post has been already tagged, if not, tag it 
    121             global $id; 
    122             if( !get_post_meta( $id, 'ozh_ta_tagged', true ) ){ 
    123                 ozh_ta_debug( "Tagging post $id with ".implode( ', ', $hashtags ) ); 
    124                 wp_set_post_tags( $id, implode( ', ', $tags ) ); 
    125                 add_post_meta( $id, 'ozh_ta_tagged', '1', true ); 
    126             } 
    127              
    128             $nofollow = apply_filters( 'ozh_ta_hashtag_nofollow', 'rel="nofollow"' ); 
    129             // Replace the array $tag with an array of links 
    130             array_walk( $tags, 'ozh_ta_linkify_'.$ozh_ta['link_hashtags'], $nofollow ); 
    131             // Linkify hashtags 
    132             $text = str_replace( $hashtags, $tags, $text );  
    133         } 
    134     } 
    135      
    136     // Linkify other links. Note: nofollowed by WP and there's no filters on this 
    137     $text = make_clickable( $text ); 
    138  
    139     return apply_filters( 'ozh_ta_post_linkify', $text ); 
    140 } 
    141  
    142 // Create a Twitter search link (array_walk() callback) 
    143 function ozh_ta_linkify_twitter( &$tag, $key, $nofollow ) { 
    144     $tag = '<a href="http://search.twitter.com/search?q=%23'.$tag.'" '.$nofollow.'>#'.$tag.'</a>'; 
    145 } 
    146  
    147 // Create a local tag link (array_walk() callback) 
    148 function ozh_ta_linkify_local( &$tag, $key, $nofollow ) { 
    149     $tag = '<a href="'.ozh_ta_get_tag_link( $tag ).'">#'.$tag.'</a>'; 
    150 } 
    151  
    152 // Get link for a given tag. 
    153 // (Note: the tag may or may not actually exist) 
    154 function ozh_ta_get_tag_link( $tag ) { 
    155     global $wp_rewrite; 
    156     $link = $wp_rewrite->get_tag_permastruct(); 
    157      
    158     $tag = sanitize_title_with_dashes( $tag ); 
    159  
    160     if( empty( $link ) ) { 
    161         // site.com/?tag=bleh 
    162         $link = trailingslashit( home_url() ) . '?tag=' . $tag; 
    163     } else { 
    164         // site.com/tag/bleh/ 
    165         $link = str_replace( '%tag%', $tag, $link ); 
    166         $link = home_url( user_trailingslashit( $link, 'category' ) ); 
    167     } 
    168     return apply_filters( 'ozh_ta_get_tag_link', $link ); 
    169104} 
    170105 
     
    177112    return array( 
    178113        // plugin: 
    179         'refresh_interval' => 5*60, // 5 minutes 
    180         'post_category' => get_option('default_category'), // integer 
    181         'post_author' => $wpdb->get_var("SELECT ID FROM $wpdb->users ORDER BY ID LIMIT 1"), // first user id found 
    182         'link_hashtags' => 'twitter', // can be no/local/twitter 
    183         'add_hash_as_tags' => 'yes', // can be yes/no 
    184         'link_usernames' => 'yes', // can be yes/no 
     114        'refresh_interval'       => 60*60, // 60 minutes 
     115        'post_category'          => get_option('default_category'), // integer 
     116        'post_author'            => $wpdb->get_var("SELECT ID FROM $wpdb->users ORDER BY ID LIMIT 1"), // first user id found 
     117        'link_hashtags'          => 'local', // can be no/local/twitter 
     118        'add_hash_as_tags'       => 'yes', // can be yes/no 
     119        'link_usernames'         => 'yes', // can be yes/no 
     120        'embed_images'           => 'yes', // can be yes/no 
     121        'un_tco'                 => 'yes', // can be yes/no 
    185122        'last_tweet_id_inserted' => 1, // ID of last inserted tweet 
    186         'api_page' => 1, // current page being polled on the API 
     123        'api_page'               => 1, // current page being polled on the API 
    187124         
    188125        // twitter user: 
    189         'screen_name' => '', 
     126        'screen_name'   => '', 
     127        'cons_key'      => '', 
     128        'cons_secret'   => '', 
     129        'access_token'  => '', 
    190130        'twitter_stats' => array (), 
    191131    ); 
    192132} 
    193133 
    194 // Delay before next update 
    195 function ozh_ta_next_update_in( $human_time = true ) { 
    196     global $ozh_ta; 
    197      
    198     $next = wp_next_scheduled( 'ozh_ta_cron_import' ); 
    199     $freq = $ozh_ta['refresh_interval']; 
    200     $now = time(); 
    201     if( $next < $now ) 
    202         $next = $now + $freq - 1; 
    203      
    204     if( $human_time ) 
    205         return ozh_ta_seconds_to_words( $next - $now ); 
    206     else  
    207         return ($next - $now ); 
    208 } 
    209  
    210  
    211 // Transform 132456 seconds into x hours y minutes z seconds 
    212 function ozh_ta_seconds_to_words( $seconds ) { 
    213     $ret = ""; 
    214  
    215     $hours = intval( intval($seconds) / 3600 ); 
    216     if( $hours > 0 ) { 
    217         $ret .= "$hours hour"; 
    218         $ret .= ( $hours > 1 ? 's ' : ' ' ); 
    219     } 
    220  
    221     $minutes = intval( $seconds / 60 ) % 60; 
    222     if( $minutes > 0 ) { 
    223         $ret .= "$minutes minute"; 
    224         $ret .= ( $minutes > 1 ? 's ' : ' ' ); 
    225     } 
    226    
    227     $seconds = $seconds % 60; 
    228     if( $seconds > 0 ) { 
    229         $ret .= "$seconds second"; 
    230         $ret .= ( $seconds > 1 ? 's ' : ' ' ); 
    231     } 
    232  
    233     return trim( $ret ); 
    234 } 
    235  
    236 // Log debug message in flat file 
    237 function ozh_ta_debug( $in ) { 
    238     if( !defined( 'OZH_TA_DEBUG' ) || !OZH_TA_DEBUG ) 
    239         return; 
    240          
    241     if( is_array( $in ) or is_object( $in ) ) 
    242         $in = print_r( $in, true ); 
    243      
    244     $ts = date('r'); 
    245      
    246     error_log( "$ts: $in\n", 3, dirname(__FILE__).'/debug.log' ); 
    247 } 
     134// Require files as needed 
     135function ozh_ta_require( $file ) { 
     136    require_once( dirname(__FILE__).'/inc/'.$file ); 
     137} 
     138 
     139// Convert links, @mentions and #hashtags from older posts 
     140function ozh_ta_convert_old_posts( $text ) { 
     141 
     142    // Has this post already been converted? Assuming a span means already formatted 
     143    if( strpos( $text, '<span class="' ) !== false ) 
     144        return $text; 
     145 
     146    global $ozh_ta; 
     147     
     148    // Get unformatted title: this will be the unmodified original tweet -- pure text, no HTML 
     149    global $post; 
     150    $title = $post->post_title; 
     151    $ID    = $post->ID; 
     152     
     153    // Keep track of whether the post has been formatted 
     154    $updated = false; 
     155 
     156    // Tweet has links that have not been converted 
     157    if( ( strpos( $title, 'http://' ) !== false OR strpos( $title, 'https://' ) !== false ) && strpos( $text, 'class="link' ) === false ) { 
     158        preg_match_all( '!https?://\S*!', $title, $matches ); 
     159        foreach( $matches[0] as $url ) { 
     160             
     161            // t.co URL ? 
     162            if( $ozh_ta['un_tco'] == 'yes' && strpos( $url, 'http://t.co/' ) === 0 ) { 
     163                $expanded_url = ozh_ta_expand_tco_url( $url ); 
     164                $tco_url      = $url; 
     165            } else { 
     166                $expanded_url = $tco_url = $url; 
     167            } 
     168            $display_url  = ozh_ta_trim_long_string( preg_replace( '/https?:\/\//', '', $expanded_url ) ); 
     169             
     170            $text = ozh_ta_convert_links( $text, $expanded_url, $display_url, $tco_url ); 
     171        } 
     172        $updated = true; 
     173    } 
     174     
     175    // Tweet has @mentions that have not been converted 
     176    if( strpos( $title, '@' ) !== false && strpos( $text, 'class="username' ) === false ) { 
     177        preg_match_all( '/\B@(\w+)/', $title, $matches ); // good news, this won't match joe@site.com 
     178        if( isset( $matches[1] ) ) { 
     179            foreach( $matches[1] as $mention ) { 
     180                $text = ozh_ta_convert_mentions( $text, $mention, $mention ); 
     181            } 
     182        } 
     183        $updated = true; 
     184    } 
     185     
     186    // Tweet has #hashtags that have not been converted 
     187    if( strpos( $title, '#' ) !== false && strpos( $text, 'class="hashtag' ) === false ) { 
     188        preg_match_all( '/\B#(\w*[a-zA-Z-]+\w*)/', $text, $matches ); 
     189        if( isset( $matches[1] ) ) { 
     190            foreach( $matches[1] as $tag ) { 
     191                $text = ozh_ta_convert_hashtags( $text, $tag ); 
     192            } 
     193             
     194            if( $ozh_ta['add_hash_as_tags'] == 'yes' ) { 
     195                wp_set_post_tags( $ID, implode( ', ', $matches[1] ) ); 
     196            } 
     197        } 
     198        $updated = true; 
     199    } 
     200     
     201    // Did we alter the post? Update it, then 
     202    if( $updated ) { 
     203        $post->post_content = $text; 
     204        wp_update_post( $post ); 
     205    } 
     206     
     207    return $text; 
     208} 
     209 
     210 
  • ozh-tweet-archiver/trunk/readme.txt

    r688299 r892402  
    77Contributors: ozh 
    88 
    9 Import and archive your tweets (also convert #hashtags into post tags)  
     9Import and archive your tweets with WordPress 
    1010 
    1111== Description == 
    1212 
    13 Make a fresh WordPress install and archive all your tweets: easier to search than on Twitter, and no more 3200 tweet limit to your history. 
     13Make a fresh WordPress install and archive all your tweets: 
     14 
     15* It's easier to search than on Twitter 
     16* WordPress is not limited to the most recent 3200 tweets 
     17* It will automatically expand all those ugly `t.co` links 
     18* All your #hashtags can be converted to WordPress tags 
    1419 
    1520Plugin's page: [Ozh' Tweet Archiver](http://planetozh.com/blog/my-projects/ozh-tweet-archiver-backup-twitter-with-wordpress/ "Ozh' Tweet Archiver") 
    1621 
    1722Live example: [Ozh' Tweets](http://planetozh.com/tweets/ "Ozh' Tweets") 
     23 
     24Development: [on Github](https://github.com/ozh/ozh-tweet-archiver) 
    1825 
    1926== Screenshots == 
     
    2633 
    27341. In the plugin source itself 
    28 1. Here: http://plugins.trac.wordpress.org/log/ozh-tweet-archiver?verbose=on 
     351. Here: https://github.com/ozh/ozh-tweet-archiver 
    2936 
    3037== Installation == 
Note: See TracChangeset for help on using the changeset viewer.