I modified the FeedsTwitterParser.inc to add support for twitter .xml feeds as well as .atom
The reason for this is that I wanted to have the username separate from the content of the tweet and the .xml feed is better suited for this. I tested this with a twitter favorites timeline. http://twitter.com/favorites/16720088.xml

I'm new to module contribution and I'm not sure how to create a patch so I'll just paste the code here.

<?php
// $Id: FeedsTwitterParser.inc,v 1.1 2010/08/02 17:38:14 serbanghita Exp $

/**
* Parses the Twitter search feed eg. http://search.twitter.com/search.atom?q=world cup
* and maps it the fields of the feed_item_twitter node type.
*/
class FeedsTwitterParser extends FeedsParser {

  private $batch_title ='';

  /**
  * Parses a raw string and populates FeedsImportBatch object from it.
  */
  public function parse(FeedsImportBatch $batch, FeedsSource $source) {
    // Get the file's content.
    $string = $batch->getRaw();

    //find the file format for the feed
    $config = $source->getConfig();
    $feed_url_parts = pathinfo($config['FeedsHTTPFetcher']['source']);
    $format = $feed_url_parts['extension'];


    // Parse it...
    // The parsed result should be an array of arrays of field name => value.
    $xml = simplexml_load_string($string);

    //pick parsing function based on feed type.
    switch ($format) {
        case 'atom':
            $items = $this->parseAtomFeed($xml);
            break;
        case 'xml':
            $items = $this->parseXMLFeed($xml);
            break;

        default:
            drupal_set_message('Invalid Feed Format. Please use either .xml or .atom', 'error');
            break;
    }
    
    if ($items) {
       // Populate the FeedsImportBatch object with the parsed results.
       $batch->setTitle($this->batch_title);
       $batch->setItems($items);
    }
    
  }

  public function getMappingSources() {
    return array(
      'guid' => array(
        'name' => t('GUID'),
        'description' => t('Unique ID.'),
      ),
      'published' => array(
        'name' => t('Date published'),
        'description' => t('Date when the tweet was published.'),
      ),
      'tweet_link' => array(
        'name' => t('Tweet link'),
        'description' => t('Link to the original tweet.'),
      ),
      'author_pic' => array(
        'name' => t('Author\'s pic'),
        'description' => t('Tweet author\'s pic.'),
      ),
      'tweet_text' => array(
        'name' => t('Tweet (txt)'),
        'description' => t('Text version of the tweet.'),
      ),
      'tweet_html' => array(
        'name' => t('Tweet (html)'),
        'description' => t('HTML version of the tweet.'),
      ),
      'updated' => array(
        'name' => t('Date updated'),
        'description' => t('Date when the tweet was updated.'),
      ), 
      'author_name' => array(
        'name' => t('Author\'s Name'),
        'description' => t('Tweet\'s author\'s name.'),
      ),
      'author_uri' => array(
        'name' => t('Authors\' URL'),
        'description' => t('Tweet\'s author\'s URL.'),
      ),                                         
    );
  }

    /**
    */
    private function parseAtomFeed($xml)
    {
        foreach($xml->entry as $id => $obj_entry){

            $tmp_link[0] = (array)$obj_entry->link[0]['href'];
            $tmp_link[1] = (array)$obj_entry->link[1]['href'];

            $items[] = array(
                    'guid' 		=> $obj_entry->id,
                    'published' 	=> strtotime($obj_entry->published),
                    'tweet_link' 	=> $tmp_link[0],
                    'author_pic' 	=> $tmp_link[1],
                    'tweet_text' 	=> $obj_entry->title,
                    'tweet_html' 	=> $obj_entry->content,
                    'updated'	=> strtotime($obj_entry->updated),
                    'author_name'	=> $obj_entry->author->name,
                    'author_uri'	=> $obj_entry->author->uri
            );

            //print_r($items);
            //exit;
            unset($tmp_link);
        }

        $this->batch_title = $obj_entry->title;
        return $items;
    }

    private function parseXMLFeed($xml)
    {
        foreach($xml->status as $id => $obj_entry){

            $tmp_link[1] = (array)$obj_entry->link[1]['href'];

            $items[] = array(
                    'guid' 		=> $obj_entry->id,
                    'published' 	=> strtotime($obj_entry->created_at),
                    'tweet_link' 	=> 'http://twitter.com/'.$obj_entry->user->screen_name.'/statuses/'.$obj_entry->id,
                    'author_pic' 	=> $obj_entry->user->profile_image_url,
                    'tweet_text' 	=> $obj_entry->text,
                    'tweet_html'	=> $obj_entry->text,
                    'updated'	=> strtotime($obj_entry->created_at),
                    'author_name'	=> $obj_entry->user->name,
                    'author_uri'	=> $obj_entry->user->url
            );

            //print_r($items);
            //exit;
            unset($tmp_link);
        }
        $this->batch_title = $obj_entry->text;
        return $items;
    }

}


Comments

serbanghita’s picture

Assigned: Unassigned » serbanghita

@cschlens excellent work, i'll include this right away. This paves the way for the twitter user timeline feed. Thanks!

alunyov’s picture

Hi,
excellent work!
only one remark:
instead of
...
$tmp_link[0] = (array)$obj_entry->link[0]['href'];
$tmp_link[1] = (array)$obj_entry->link[1]['href'];
...
there should be:
...
$tmp_link[0] = (string)$obj_entry->link[0]['href'];
$tmp_link[1] = (string)$obj_entry->link[1]['href'];
...
At least that works for me