code:
<?php

if (php_sapi_name() != 'cli') {
    die('not for web');
}

define('HTTP_TIMEOUT', 60); // ssslllloowwwww salmon if queues are off

define('INSTALLDIR', dirname(dirname(dirname(dirname(__FILE__)))));
set_include_path(INSTALLDIR . '/extlib' . PATH_SEPARATOR . get_include_path());

require_once 'PEAR.php';
require_once 'Net/URL2.php';
require_once 'HTTP/Request2.php';

// ostatus test script, client-side :)

class TestBase
{
    function log($str)
    {
        $args = func_get_args();
        array_shift($args);

        $msg = vsprintf($str, $args);
        print $msg . "\n";
    }

    function assertEqual($a, $b)
    {
        if ($a != $b) {
            throw new Exception("Failed to assert equality: expected $a, got $b");
        }
        return true;
    }

    function assertNotEqual($a, $b)
    {
        if ($a == $b) {
            throw new Exception("Failed to assert inequality: expected not $a, got $b");
        }
        return true;
    }

    function assertTrue($a)
    {
        if (!$a) {
            throw new Exception("Failed to assert true: got false");
        }
    }

    function assertFalse($a)
    {
        if ($a) {
            throw new Exception("Failed to assert false: got true");
        }
    }
}

class OStatusTester extends TestBase
{
    /**
     * @param string $a base URL of test site A (eg http://localhost/mublog)
     * @param string $b base URL of test site B (eg http://localhost/mublog2)
     * @param int $timeout HTTP timeout value (needs to be long if Salmon is slow)
     */
    function __construct($a, $b, $timeout=60) {
        $this->a = $a;
        $this->b = $b;

        $base = 'test' . mt_rand(1, 1000000);
        $this->pub = new SNTestClient($this->a, 'pub' . $base, 'pw-' . mt_rand(1, 1000000), $timeout);
        $this->sub = new SNTestClient($this->b, 'sub' . $base, 'pw-' . mt_rand(1, 1000000), $timeout);

        $this->group = 'group' . $base;
    }

    function run()
    {
        $this->setup();

        $methods = get_class_methods($this);
        foreach ($methods as $method) {
            if (strtolower(substr($method, 0, 4)) == 'test') {
                print "\n";
                print "== $method ==\n";
                call_user_func(array($this, $method));
            }
        }

        print "\n";
        $this->log("DONE!");
    }

    function setup()
    {
        $this->pub->register();
        $this->pub->assertRegistered();

        $this->sub->register();
        $this->sub->assertRegistered();
    }

    function testLocalPost()
    {
        $post = $this->pub->post("Local post, no subscribers yet.");
        $this->assertNotEqual('', $post);

        $post = $this->sub->post("Local post, no subscriptions yet.");
        $this->assertNotEqual('', $post);
    }

    /**
     * pub posts: @b/sub
     */
    function testMentionUrl()
    {
        $bits = parse_url($this->b);
        $base = $bits['host'];
        if (isset($bits['path'])) {
            $base .= $bits['path'];
        }
        $name = $this->sub->username;

        $post = $this->pub->post("@$base/$name should have this in home and replies");
        $this->sub->assertReceived($post);
    }

    function testSubscribe()
    {
        $this->assertFalse($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertFalse($this->pub->hasSubscriber($this->sub->getProfileUri()));
        $this->sub->subscribe($this->pub->getProfileLink());
        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertTrue($this->pub->hasSubscriber($this->sub->getProfileUri()));
    }

    function testPush()
    {
        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertTrue($this->pub->hasSubscriber($this->sub->getProfileUri()));

        $name = $this->sub->username;
        $post = $this->pub->post("Regular post, which $name should get via PuSH");
        $this->sub->assertReceived($post);
    }

    function testMentionSubscribee()
    {
        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertFalse($this->pub->hasSubscription($this->sub->getProfileUri()));

        $name = $this->pub->username;
        $post = $this->sub->post("Just a quick note back to my remote subscribee @$name");
        $this->pub->assertReceived($post);
    }

    function testUnsubscribe()
    {
        $this->assertTrue($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertTrue($this->pub->hasSubscriber($this->sub->getProfileUri()));
        $this->sub->unsubscribe($this->pub->getProfileLink());
        $this->assertFalse($this->sub->hasSubscription($this->pub->getProfileUri()));
        $this->assertFalse($this->pub->hasSubscriber($this->sub->getProfileUri()));
    }

    function testCreateGroup()
    {
        $this->groupUrl = $this->pub->createGroup($this->group);
        $this->assertTrue(!empty($this->groupUrl));
    }

    function testJoinGroup()
    {
        #$this->assertFalse($this->sub->inGroup($this->groupUrl));
        $this->sub->joinGroup($this->groupUrl);
        #$this->assertTrue($this->sub->inGroup($this->groupUrl));
    }

    function testLocalGroupPost()
    {
        $post = $this->pub->post("Group post from local to !{$this->group}, should go out over push.");
        $this->assertNotEqual('', $post);
        $this->sub->assertReceived($post);
    }

    function testRemoteGroupPost()
    {
        $post = $this->sub->post("Group post from remote to !{$this->group}, should come in over salmon.");
        $this->assertNotEqual('', $post);
        $this->pub->assertReceived($post);
    }

    function testLeaveGroup()
    {
        #$this->assertTrue($this->sub->inGroup($this->groupUrl));
        $this->sub->leaveGroup($this->groupUrl);
        #$this->assertFalse($this->sub->inGroup($this->groupUrl));
    }
}

class SNTestClient extends TestBase
{
    function __construct($base, $username, $password, $timeout=60)
    {
        $this->basepath = $base;
        $this->username = $username;
        $this->password = $password;
        $this->timeout = $timeout;

        $this->fullname = ucfirst($username) . ' Smith';
        $this->homepage = 'http://example.org/' . $username;
        $this->bio = 'Stub account for OStatus tests.';
        $this->location = 'Montreal, QC';
    }

    /**
     * Make a low-level web hit to this site, with authentication.
     * @param string $path URL fragment for something under the base path
     * @param array $params POST parameters to send
     * @param boolean $auth whether to include auth data
     * @return string
     * @throws Exception on low-level error conditions
     */
    protected function hit($path, $params=array(), $auth=false, $cookies=array())
    {
        $url = $this->basepath . '/' . $path;

        $http = new HTTP_Request2($url, 'POST', array('timeout' => $this->timeout));
        if ($auth) {
            $http->setAuth($this->username, $this->password, HTTP_Request2::AUTH_BASIC);
        }
        foreach ($cookies as $name => $val) {
            $http->addCookie($name, $val);
        }
        $http->addPostParameter($params);
        $response = $http->send();

        $code = $response->getStatus();
        if ($code < '200' || $code >= '400') {
            throw new Exception("Failed API hit to $url: $code\n" . $response->getBody());
        }

        return $response;
    }

    /**
     * Make a hit to a web form, without authentication but with a session.
     * @param string $path URL fragment relative to site base
     * @param string $form id of web form to pull initial parameters from
     * @param array $params POST parameters, will be merged with defaults in form
     */
    protected function web($path, $form, $params=array())
    {
        $url = $this->basepath . '/' . $path;
        $http = new HTTP_Request2($url, 'GET', array('timeout' => $this->timeout));
        $response = $http->send();

        $dom = $this->checkWeb($url, 'GET', $response);
        $cookies = array();
        foreach ($response->getCookies() as $cookie) {
            // @fixme check for expirations etc
            $cookies[$cookie['name']] = $cookie['value'];
        }

        $form = $dom->getElementById($form);
        if (!$form) {
            throw new Exception("Form $form not found on $url");
        }
        $inputs = $form->getElementsByTagName('input');
        foreach ($inputs as $item) {
            $type = $item->getAttribute('type');
            if ($type != 'check') {
                $name = $item->getAttribute('name');
                $val = $item->getAttribute('value');
                if ($name && $val && !isset($params[$name])) {
                    $params[$name] = $val;
                }
            }
        }

        $response = $this->hit($path, $params, false, $cookies);
        $dom = $this->checkWeb($url, 'POST', $response);

        return $dom;
    }

    protected function checkWeb($url, $method, $response)
    {
        $dom = new DOMDocument();
        if (!$dom->loadHTML($response->getBody())) {
            throw new Exception("Invalid HTML from $method to $url");
        }

        $xpath = new DOMXPath($dom);
        $error = $xpath->query('//p[@class="error"]');
        if ($error && $error->length) {
            throw new Exception("Error on $method to $url: " .
                                $error->item(0)->textContent);
        }

        return $dom;
    }

    protected function parseXml($path, $body)
    {
        $dom = new DOMDocument();
        if ($dom->loadXML($body)) {
            return $dom;
        } else {
            throw new Exception("Bogus XML data from $path:\n$body");
        }
    }

    /**
     * Make a hit to a REST-y XML page on the site, without authentication.
     * @param string $path URL fragment for something relative to base
     * @param array $params POST parameters to send
     * @return DOMDocument
     * @throws Exception on low-level error conditions
     */
    protected function xml($path, $params=array())
    {
        $response = $this->hit($path, $params, true);
        $body = $response->getBody();
        return $this->parseXml($path, $body);
    }

    protected function parseJson($path, $body)
    {
        $data = json_decode($body, true);
        if ($data !== null) {
            if (!empty($data['error'])) {
                throw new Exception("JSON API returned error: " . $data['error']);
            }
            return $data;
        } else {
            throw new Exception("Bogus JSON data from $path:\n$body");
        }
    }

    /**
     * Make an API hit to this site, with authentication.
     * @param string $path URL fragment for something under 'api' folder
     * @param string $style one of 'json', 'xml', or 'atom'
     * @param array $params POST parameters to send
     * @return mixed associative array for JSON, DOMDocument for XML/Atom
     * @throws Exception on low-level error conditions
     */
    protected function api($path, $style, $params=array())
    {
        $response = $this->hit("api/$path.$style", $params, true);
        $body = $response->getBody();
        if ($style == 'json') {
            return $this->parseJson($path, $body);
        } else if ($style == 'xml' || $style == 'atom') {
            return $this->parseXml($path, $body);
        } else {
            throw new Exception("API needs to be JSON, XML, or Atom");
        }
    }

    /**
     * Register the account.
     *
     * Unfortunately there's not an API method for registering, so we fake it.
     */
    function register()
    {
        $this->log("Registering user %s on %s",
                   $this->username,
                   $this->basepath);
        $ret = $this->web('main/register', 'form_register',
            array('nickname' => $this->username,
                  'password' => $this->password,
                  'confirm' => $this->password,
                  'fullname' => $this->fullname,
                  'homepage' => $this->homepage,
                  'bio' => $this->bio,
                  'license' => 1,
                  'submit' => 'Register'));
    }

    /**
     * @return string canonical URI/URL to profile page
     */
    function getProfileUri()
    {
        $data = $this->api('account/verify_credentials', 'json');
        $id = $data['id'];
        return $this->basepath . '/user/' . $id;
    }

    /**
     * @return string human-friendly URL to profile page
     */
    function getProfileLink()
    {
        return $this->basepath . '/' . $this->username;
    }

    /**
     * Check that the account has been registered and can be used.
     * On failure, throws a test failure exception.
     */
    function assertRegistered()
    {
        $this->log("Confirming %s is registered on %s",
                   $this->username,
                   $this->basepath);
        $data = $this->api('account/verify_credentials', 'json');
        $this->assertEqual($this->username, $data['screen_name']);
        $this->assertEqual($this->fullname, $data['name']);
        $this->assertEqual($this->homepage, $data['url']);
        $this->assertEqual($this->bio, $data['description']);
        $this->log("  looks good!");
    }

    /**
     * Post a given message from this account
     * @param string $message
     * @return string URL/URI of notice
     * @todo reply, location options
     */
    function post($message)
    {
        $this->log("Posting notice as %s on %s: %s",
                   $this->username,
                   $this->basepath,
                   $message);
        $data = $this->api('statuses/update', 'json',
            array('status' => $message));

        $url = $this->basepath . '/notice/' . $data['id'];
        return $url;
    }

    /**
     * Check that this account has received the notice.
     * @param string $notice_uri URI for the notice to check for
     */
    function assertReceived($notice_uri)
    {
        $timeout = 5;
        $tries = 6;
        while ($tries) {
            $ok = $this->checkReceived($notice_uri);
            if ($ok) {
                return true;
            }
            $tries--;
            if ($tries) {
                $this->log("  didn't see it yet, waiting $timeout seconds");
                sleep($timeout);
            }
        }
        throw new Exception("  message $notice_uri not received by $this->username");
    }

    /**
     * Pull the user's home timeline to check if a notice with the given
     * source URL has been received recently.
     * If we don't see it, we'll try a couple more times up to 10 seconds.
     *
     * @param string $notice_uri
     */
    function checkReceived($notice_uri)
    {
        $this->log("Checking if %s on %s received notice %s",
                   $this->username,
                   $this->basepath,
                   $notice_uri);
        $params = array();
        $dom = $this->api('statuses/home_timeline', 'atom', $params);

        $xml = simplexml_import_dom($dom);
        if (!$xml->entry) {
            return false;
        }
        if (is_array($xml->entry)) {
            $entries = $xml->entry;
        } else {
            $entries = array($xml->entry);
        }
        foreach ($entries as $entry) {
            if ($entry->id == $notice_uri) {
                $this->log("  found it $notice_uri");
                return true;
            }
        }
        return false;
    }

    /**
     * @param string $profile user page link or webfinger
     */
    function subscribe($profile)
    {
        // This uses the command interface, since there's not currently
        // a friendly Twit-API way to do a fresh remote subscription and
        // the web form's a pain to use.
        $this->post('follow ' . $profile);
    }

    /**
     * @param string $profile user page link or webfinger
     */
    function unsubscribe($profile)
    {
        // This uses the command interface, since there's not currently
        // a friendly Twit-API way to do a fresh remote subscription and
        // the web form's a pain to use.
        $this->post('leave ' . $profile);
    }

    /**
     * Check that this account is subscribed to the given profile.
     * @param string $profile_uri URI for the profile to check for
     * @return boolean
     */
    function hasSubscription($profile_uri)
    {
        $this->log("Checking if $this->username has a subscription to $profile_uri");

        $me = $this->getProfileUri();
        return $this->checkSubscription($me, $profile_uri);
    }

    /**
     * Check that this account is subscribed to by the given profile.
     * @param string $profile_uri URI for the profile to check for
     * @return boolean
     */
    function hasSubscriber($profile_uri)
    {
        $this->log("Checking if $this->username is subscribed to by $profile_uri");

        $me = $this->getProfileUri();
        return $this->checkSubscription($profile_uri, $me);
    }

    protected function checkSubscription($subscriber, $subscribed)
    {
        // Using FOAF as the API methods for checking the social graph
        // currently are unfriendly to remote profiles
        $ns_foaf = 'http://xmlns.com/foaf/0.1/';
        $ns_sioc = 'http://rdfs.org/sioc/ns#';
        $ns_rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';

        $dom = $this->xml($this->username . '/foaf');
        $agents = $dom->getElementsByTagNameNS($ns_foaf, 'Agent');
        foreach ($agents as $agent) {
            $agent_uri = $agent->getAttributeNS($ns_rdf, 'about');
            if ($agent_uri == $subscriber) {
                $follows = $agent->getElementsByTagNameNS($ns_sioc, 'follows');
                foreach ($follows as $follow) {
                    $target = $follow->getAttributeNS($ns_rdf, 'resource');
                    if ($target == ($subscribed . '#acct')) {
                        $this->log("  confirmed $subscriber subscribed to $subscribed");
                        return true;
                    }
                }
                $this->log("  we found $subscriber but they don't follow $subscribed");
                return false;
            }
        }
        $this->log("  can't find $subscriber in {$this->username}'s social graph.");
        return false;
    }

    /**
     * Create a group on this site.
     *
     * @param string $nickname
     * @param array $options
     * @return string: profile URL for the group
     */
    function createGroup($nickname, $options=array()) {
        $this->log("Creating group as %s on %s: %s",
                   $this->username,
                   $this->basepath,
                   $nickname);

        $data = $this->api('statusnet/groups/create', 'json',
            array_merge(array('nickname' => $nickname), $options));
        $url = $data['url'];

        if ($url) {
            $this->log('  created as %s', $url);
        } else {
            $this->log('  failed? %s', var_export($data, true));
        }
        return $url;
    }

    function groupInfo($nickname) {
        $data = $this->api('statusnet/groups/show', 'json', array(
            'id' => $nickname
        ));
    }

    /**
     * Join a group.
     *
     * @param string $group nickname or URL
     */
    function joinGroup($group) {
        $this->post('join ' . $group);
    }

    /**
     * Leave a group.
     *
     * @param string $group nickname or URL
     */
    function leaveGroup($group) {
        $this->post('drop ' . $group);
    }

    /**
     *
     * @param string $nickname
     * @return
     */
    function inGroup($nickname) {
        // @todo
    }
}

// @fixme switch to commandline.inc?
$timeout = HTTP_TIMEOUT;

$args = array();
$options = array();
foreach (array_slice($_SERVER['argv'], 1) as $arg) {
    if (substr($arg, 0, 2) == '--') {
        $bits = explode('=', substr($arg, 2), 2);
        if (count($bits == 2)) {
            list($key, $val) = $bits;
            $options[$key] = $val;
        } else {
            list($key) = $bits;
            $options[$key] = true;
        }
    } else {
        $args[] = $arg;
    }
}
if (count($args) < 2) {
    print <<<END_HELP
remote-tests.php [options] <url1> <url2>
  --timeout=## change HTTP timeout from default {$timeout}s
  url1: base URL of a StatusNet instance
  url2: base URL of another StatusNet instance

This will register user accounts on the two given StatusNet instances
and run some tests to confirm that OStatus subscription and posting
between the two sites works correctly.

END_HELP;
exit(1);
}

$a = $args[0];
$b = $args[1];
if (isset($options['timeout'])) {
    $timeout = intval($options['timeout']);
}

$tester = new OStatusTester($a, $b, $timeout);
$tester->run();


code:
#!/usr/bin/env php
<?php
/*
 * StatusNet - a distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));

$longoptions = array('verify', 'slap=', 'notice=');

$helptext = <<<END_OF_HELP
slap.php [options]

Test generation and sending of magic envelopes for Salmon slaps.

     --notice=N   generate entry for this notice number
     --verify     send signed magic envelope to Tuomas Koski's test service
     --slap=<url> send signed Salmon slap to the destination endpoint

END_OF_HELP;

require_once INSTALLDIR.'/scripts/commandline.inc';

if (!have_option('--notice')) {
    print "$helptext";
    exit(1);
}

$notice_id = get_option_value('--notice');

$notice = Notice::getKV('id', $notice_id);
$profile = $notice->getProfile();
$entry = $notice->asAtomEntry(true);

echo "== Original entry ==\n\n";
print $entry;
print "\n\n";

$magic_env = MagicEnvelope::signAsUser($entry, $profile->getUser());
$envxml = $magic_env->toXML();

echo "== Signed envelope ==\n\n";
print $envxml;
print "\n\n";

echo "== Testing local verification ==\n\n";
$magic_env = new MagicEnvelope($envxml);
$activity = new Activity($magic_env->getPayload()->documentElement);
$actprofile = Profile::fromUri($activity->actor->id);
$ok = $magic_env->verify($actprofile);
if ($ok) {
    print "OK\n\n";
} else {
    print "FAIL\n\n";
}

if (have_option('--verify')) {
    $url = 'http://www.madebymonsieur.com/ostatus_discovery/magic_env/validate/';
    echo "== Testing remote verification ==\n\n";
    print "Sending for verification to $url ...\n";

    $client = new HTTPClient();
    $response = $client->post($url, array(), array('magic_env' => $envxml));

    print $response->getStatus() . "\n\n";
    print $response->getBody() . "\n\n";
}

if (have_option('--slap')) {
    $url = get_option_value('--slap');
    echo "== Remote salmon slap ==\n\n";
    print "Sending signed Salmon slap to $url ...\n";

    $ok = Salmon::post($url, $entry, $profile->getUser());
    if ($ok) {
        print "OK\n\n";
    } else {
        print "FAIL\n\n";
    }
}

repo_name: piratas/tortuga

license: mit


code:
#form_ostatus_connect.dialogbox .form_data label,
#form_ostatus_sub.dialogbox .form_data label {
    display: block;
    width: 100%;
    text-align: left;
}

#form_ostatus_connect.dialogbox .form_data input,
#form_ostatus_sub.dialogbox .form_data input {
    width: 90%;
    padding: 4px;
    margin: 0;
    background-color: #fff !important;
    border: 1px solid #888;
}

#form_ostatus_connect.dialogbox .form_data .form_guide,
#form_ostatus_sub.dialogbox .form_data .form_guide {
    margin-left: 0;
    background-color: #fff !important;
}

#form_ostatus_connect.dialogbox #ostatus_nickname,
#form_ostatus_sub.dialogbox #ostatus_nickname {
    display: none;
}

#form_ostatus_connect.dialogbox input.submit_dialogbox,
#form_ostatus_sub.dialogbox input.submit_dialogbox {
    padding: 4px;
}

.entity_remote_tag {
    background-position: 5px -257px;
}

.section .entity_remote_tag {
    background-position: 5px -257px;
}


code:
So far this is still in $config['site']['oembed'].

oembed
--------

oEmbed endpoint for multimedia attachments (links in posts). Will also
work as 'oohembed' for backwards compatibility.

endpoint: oohembed endpoint using http://oohembed.com/ software. Defaults to
	  'http://oohembed.com/oohembed/'.
order: Array of methods to check for OEmbed data. Methods include 'built-in'
       (use a built-in function to simulate oEmbed for some sites),
       'well-known' (use well-known public oEmbed endpoints),
       'discovery' (discover using <link> headers in HTML), 'service' (use
       a third-party service, like oohembed or embed.ly. Default is
       array('built-in', 'well-known', 'service', 'discovery'). Note that very
       few sites implement oEmbed; 'discovery' is going to fail 99% of the
       time.

path: plugins/Oembed/CONFIGURE


code:
<?php

if (!defined('GNUSOCIAL')) { exit(1); }

class OembedPlugin extends Plugin
{
    // settings which can be set in config.php with addPlugin('Oembed', array('param'=>'value', ...));
    // WARNING, these are _regexps_ (slashes added later). Always escape your dots and end your strings
    public $domain_whitelist = array(       // hostname => service provider
                                    '^i\d*\.ytimg\.com$' => 'YouTube',
                                    '^i\d*\.vimeocdn\.com$' => 'Vimeo',
                                    );
    public $append_whitelist = array(); // fill this array as domain_whitelist to add more trusted sources
    public $check_whitelist  = false;    // security/abuse precaution

    protected $imgData = array();

    // these should be declared protected everywhere
    public function initialize()
    {
        parent::initialize();

        $this->domain_whitelist = array_merge($this->domain_whitelist, $this->append_whitelist);
    }

    public function onCheckSchema()
    {
        $schema = Schema::get();
        $schema->ensureTable('file_oembed', File_oembed::schemaDef());
        return true;
    }

    public function onRouterInitialized(URLMapper $m)
    {
        $m->connect('main/oembed', array('action' => 'oembed'));
    }

    public function onEndShowHeadElements(Action $action)
    {
        switch ($action->getActionName()) {
        case 'attachment':
            $action->element('link',array('rel'=>'alternate',
                'type'=>'application/json+oembed',
                'href'=>common_local_url(
                    'oembed',
                    array(),
                    array('format'=>'json', 'url'=>
                        common_local_url('attachment',
                            array('attachment' => $action->attachment->id)))),
                'title'=>'oEmbed'),null);
            $action->element('link',array('rel'=>'alternate',
                'type'=>'text/xml+oembed',
                'href'=>common_local_url(
                    'oembed',
                    array(),
                    array('format'=>'xml','url'=>
                        common_local_url('attachment',
                            array('attachment' => $action->attachment->id)))),
                'title'=>'oEmbed'),null);
            break;
        case 'shownotice':
            try {
                $action->element('link',array('rel'=>'alternate',
                    'type'=>'application/json+oembed',
                    'href'=>common_local_url(
                        'oembed',
                        array(),
                        array('format'=>'json','url'=>$action->notice->getUrl())),
                    'title'=>'oEmbed'),null);
                $action->element('link',array('rel'=>'alternate',
                    'type'=>'text/xml+oembed',
                    'href'=>common_local_url(
                        'oembed',
                        array(),
                        array('format'=>'xml','url'=>$action->notice->getUrl())),
                    'title'=>'oEmbed'),null);
            } catch (InvalidUrlException $e) {
                // The notice is probably a share or similar, which don't
                // have a representational URL of their own.
            }
            break;
        }

        return true;
    }

    /**
     * Save embedding information for a File, if applicable.
     *
     * Normally this event is called through File::saveNew()
     *
     * @param File   $file       The newly inserted File object.
     * @param array  $redir_data lookup data eg from File_redirection::where()
     * @param string $given_url
     *
     * @return boolean success
     */
    public function onEndFileSaveNew(File $file, array $redir_data, $given_url)
    {
        $fo = File_oembed::getKV('file_id', $file->id);
        if ($fo instanceof File_oembed) {
            common_log(LOG_WARNING, "Strangely, a File_oembed object exists for new file $file_id", __FILE__);
             return true;
        }

        if (isset($redir_data['oembed']['json'])
                && !empty($redir_data['oembed']['json'])) {
            File_oembed::saveNew($redir_data['oembed']['json'], $file->id);
        } elseif (isset($redir_data['type'])
                && (('text/html' === substr($redir_data['type'], 0, 9)
                || 'application/xhtml+xml' === substr($redir_data['type'], 0, 21)))) {

            try {
                $oembed_data = File_oembed::_getOembed($given_url);
                if ($oembed_data === false) {
                    throw new Exception('Did not get oEmbed data from URL');
                }
            } catch (Exception $e) {
                return true;
            }

            File_oembed::saveNew($oembed_data, $file->id);
        }
        return true;
    }

    public function onEndShowAttachmentLink(HTMLOutputter $out, File $file)
    {
        $oembed = File_oembed::getKV('file_id', $file->id);
        if (empty($oembed->author_name) && empty($oembed->provider)) {
            return true;
        }
        $out->elementStart('div', array('id'=>'oembed_info', 'class'=>'e-content'));
        if (!empty($oembed->author_name)) {
            $out->elementStart('div', 'fn vcard author');
            if (empty($oembed->author_url)) {
                $out->text($oembed->author_name);
            } else {
                $out->element('a', array('href' => $oembed->author_url,
                                         'class' => 'url'),
                                $oembed->author_name);
            }
        }
        if (!empty($oembed->provider)) {
            $out->elementStart('div', 'fn vcard');
            if (empty($oembed->provider_url)) {
                $out->text($oembed->provider);
            } else {
                $out->element('a', array('href' => $oembed->provider_url,
                                         'class' => 'url'),
                                $oembed->provider);
            }
        }
        $out->elementEnd('div');
    }

    public function onFileEnclosureMetadata(File $file, &$enclosure)
    {
        // Never treat generic HTML links as an enclosure type!
        // But if we have oEmbed info, we'll consider it golden.
        $oembed = File_oembed::getKV('file_id', $file->id);
        if (!$oembed instanceof File_oembed || !in_array($oembed->type, array('photo', 'video'))) {
            return true;
        }

        foreach (array('mimetype', 'url', 'title', 'modified') as $key) {
            if (!empty($oembed->{$key})) {
                $enclosure->{$key} = $oembed->{$key};
            }
        }
        return true;
    }

    public function onStartShowAttachmentRepresentation(HTMLOutputter $out, File $file)
    {
        $oembed = File_oembed::getKV('file_id', $file->id);
        if (empty($oembed->type)) {
            return true;
        }
        switch ($oembed->type) {
        case 'rich':
        case 'video':
        case 'link':
            if (!empty($oembed->html)
                    && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) {
                require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
                $config = array(
                    'safe'=>1,
                    'elements'=>'*+object+embed');
                $out->raw(htmLawed($oembed->html,$config));
            }
            break;

        case 'photo':
            $out->element('img', array('src' => $oembed->url, 'width' => $oembed->width, 'height' => $oembed->height, 'alt' => 'alt'));
            break;

        default:
            Event::handle('ShowUnsupportedAttachmentRepresentation', array($out, $file));
        }
    }

    public function onCreateFileImageThumbnailSource(File $file, &$imgPath, $media=null)
    {
        // If we are on a private node, we won't do any remote calls (just as a precaution until
        // we can configure this from config.php for the private nodes)
        if (common_config('site', 'private')) {
            return true;
        }

        // All our remote Oembed images lack a local filename property in the File object
        if ($file->filename !== null) {
            return true;
        }

        try {
            // If we have proper oEmbed data, there should be an entry in the File_oembed
            // and File_thumbnail tables respectively. If not, we're not going to do anything.
            $file_oembed = File_oembed::byFile($file);
            $thumbnail   = File_thumbnail::byFile($file);
        } catch (Exception $e) {
            // Not Oembed data, or at least nothing we either can or want to use.
            return true;
        }

        try {
            $this->storeRemoteFileThumbnail($thumbnail);
        } catch (AlreadyFulfilledException $e) {
            // aw yiss!
        }

        $imgPath = $thumbnail->getPath();

        return false;
    }

    /**
     * @return boolean          false on no check made, provider name on success
     * @throws ServerException  if check is made but fails
     */
    protected function checkWhitelist($url)
    {
        if (!$this->check_whitelist) {
            return false;   // indicates "no check made"
        }

        $host = parse_url($url, PHP_URL_HOST);
        foreach ($this->domain_whitelist as $regex => $provider) {
            if (preg_match("/$regex/", $host)) {
                return $provider;    // we trust this source, return provider name
            }
        }

        throw new ServerException(sprintf(_('Domain not in remote thumbnail source whitelist: %s'), $host));
    }

    protected function storeRemoteFileThumbnail(File_thumbnail $thumbnail)
    {
        if (!empty($thumbnail->filename) && file_exists($thumbnail->getPath())) {
            throw new AlreadyFulfilledException(sprintf('A thumbnail seems to already exist for remote file with id==%u', $thumbnail->file_id));
        }

        $url = $thumbnail->getUrl();
        $this->checkWhitelist($url);

        // First we download the file to memory and test whether it's actually an image file
        // FIXME: To support remote video/whatever files, this needs reworking.
        common_debug(sprintf('Downloading remote thumbnail for file id==%u with thumbnail URL: %s', $thumbnail->file_id, $url));
        $imgData = HTTPClient::quickGet($url);
        $info = @getimagesizefromstring($imgData);
        if ($info === false) {
            throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url);
        } elseif (!$info[0] || !$info[1]) {
            throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)'));
        }

        // We'll trust sha256 not to have collision issues any time soon :)
        $filename = hash('sha256', $imgData) . '.' . common_supported_mime_to_ext($info['mime']);
        $fullpath = File_thumbnail::path($filename);
        // Write the file to disk. Throw Exception on failure
        if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) {
            throw new ServerException(_('Could not write downloaded file to disk.'));
        }
        // Get rid of the file from memory
        unset($imgData);

        // Updated our database for the file record
        $orig = clone($thumbnail);
        $thumbnail->filename = $filename;
        $thumbnail->width = $info[0];    // array indexes documented on php.net:
        $thumbnail->height = $info[1];   // https://php.net/manual/en/function.getimagesize.php
        // Throws exception on failure.
        $thumbnail->updateWithKeys($orig, 'file_id');
    }

    public function onPluginVersion(array &$versions)
    {
        $versions[] = array('name' => 'Oembed',
                            'version' => GNUSOCIAL_VERSION,
                            'author' => 'Mikael Nordfeldth',
                            'homepage' => 'http://gnu.io/',
                            'description' =>
                            // TRANS: Plugin description.
                            _m('Plugin for using and representing Oembed data.'));
        return true;
    }
}


code: It's really called oEmbed.

path: plugins/Oembed/README


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * oEmbed data action for /main/oembed(.xml|.json) requests
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

if (!defined('GNUSOCIAL')) { exit(1); }

/**
 * Oembed provider implementation
 *
 * This class handles all /main/oembed(.xml|.json)/ requests.
 *
 * @category  oEmbed
 * @package   GNUsocial
 * @author    Craig Andrews <candrews@integralblue.com>
 * @author    Mikael Nordfeldth <mmn@hethane.se>
 * @copyright 2008 StatusNet, Inc.
 * @copyright 2014 Free Software Foundation, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

class OembedAction extends Action
{
    protected function handle()
    {
        parent::handle();

        $url = $this->trimmed('url');
        if (substr(strtolower($url),0,strlen(common_root_url())) !== strtolower(common_root_url())) {
            // TRANS: Error message displaying attachments. %s is the site's base URL.
            $this->clientError(sprintf(_('oEmbed data will only be provided for %s URLs.'), common_root_url()), 400);
        }

        $path = substr($url,strlen(common_root_url()));

        $r = Router::get();

        $proxy_args = $r->map($path);
        if (!$proxy_args) {
            // TRANS: Client error displayed in oEmbed action when path not found.
            // TRANS: %s is a path.
            $this->clientError(sprintf(_('"%s" not found.'),$path), 404);
        }

        $oembed=array();
        $oembed['version']='1.0';
        $oembed['provider_name']=common_config('site', 'name');
        $oembed['provider_url']=common_root_url();

        switch ($proxy_args['action']) {
        case 'shownotice':
            $oembed['type']='link';
            $id = $proxy_args['notice'];
            $notice = Notice::getKV($id);
            if(empty($notice)){
                // TRANS: Client error displayed in oEmbed action when notice not found.
                // TRANS: %s is a notice.
                $this->clientError(sprintf(_("Notice %s not found."),$id), 404);
            }
            $profile = $notice->getProfile();
            if (empty($profile)) {
                // TRANS: Server error displayed in oEmbed action when notice has not profile.
                $this->serverError(_('Notice has no profile.'), 500);
            }
            $authorname = $profile->getFancyName();
            // TRANS: oEmbed title. %1$s is the author name, %2$s is the creation date.
            $oembed['title'] = sprintf(_('%1$s\'s status on %2$s'),
                $authorname,
                common_exact_date($notice->created));
            $oembed['author_name']=$authorname;
            $oembed['author_url']=$profile->profileurl;
            $oembed['url']=$notice->getUrl();
            $oembed['html']=$notice->rendered;
            break;

        case 'attachment':
            $id = $proxy_args['attachment'];
            $attachment = File::getKV($id);
            if(empty($attachment)){
                // TRANS: Client error displayed in oEmbed action when attachment not found.
                // TRANS: %d is an attachment ID.
                $this->clientError(sprintf(_('Attachment %s not found.'),$id), 404);
            }
            if (empty($attachment->filename) && $file_oembed = File_oembed::getKV('file_id', $attachment->id)) {
                // Proxy the existing oembed information
                $oembed['type']=$file_oembed->type;
                $oembed['provider']=$file_oembed->provider;
                $oembed['provider_url']=$file_oembed->provider_url;
                $oembed['width']=$file_oembed->width;
                $oembed['height']=$file_oembed->height;
                $oembed['html']=$file_oembed->html;
                $oembed['title']=$file_oembed->title;
                $oembed['author_name']=$file_oembed->author_name;
                $oembed['author_url']=$file_oembed->author_url;
                $oembed['url']=$file_oembed->getUrl();
            } elseif (substr($attachment->mimetype,0,strlen('image/'))==='image/') {
                $oembed['type']='photo';
                if ($attachment->filename) {
                    $filepath = File::path($attachment->filename);
                    $gis = @getimagesize($filepath);
                    if ($gis) {
                        $oembed['width'] = $gis[0];
                        $oembed['height'] = $gis[1];
                    } else {
                        // TODO Either throw an error or find a fallback?
                    }
                }
                $oembed['url']=$attachment->getUrl();
                try {
                    $thumb = $attachment->getThumbnail();
                    $oembed['thumbnail_url'] = $thumb->getUrl();
                    $oembed['thumbnail_width'] = $thumb->width;
                    $oembed['thumbnail_height'] = $thumb->height;
                    unset($thumb);
                } catch (UnsupportedMediaException $e) {
                    // No thumbnail data available
                }
            } else {
                $oembed['type']='link';
                $oembed['url']=common_local_url('attachment',
                    array('attachment' => $attachment->id));
            }
            if ($attachment->title) {
                $oembed['title']=$attachment->title;
            }
            break;
        default:
            // TRANS: Server error displayed in oEmbed request when a path is not supported.
            // TRANS: %s is a path.
            $this->serverError(sprintf(_('"%s" not supported for oembed requests.'),$path), 501);
        }

        switch ($this->trimmed('format')) {
        case 'xml':
            $this->init_document('xml');
            $this->elementStart('oembed');
            foreach(array(
                        'version', 'type', 'provider_name',
                        'provider_url', 'title', 'author_name',
                        'author_url', 'url', 'html', 'width',
                        'height', 'cache_age', 'thumbnail_url',
                        'thumbnail_width', 'thumbnail_height',
                    ) as $key) {
                if (isset($oembed[$key]) && $oembed[$key]!='') {
                    $this->element($key, null, $oembed[$key]);
                }
            }
            $this->elementEnd('oembed');
            $this->end_document('xml');
            break;

        case 'json':
        case null:
            $this->init_document('json');
            $this->raw(json_encode($oembed));
            $this->end_document('json');
            break;
        default:
            // TRANS: Error message displaying attachments. %s is a raw MIME type (eg 'image/png')
            $this->serverError(sprintf(_('Content type %s not supported.'), $apidata['content-type']), 501);
        }
    }

    public function init_document($type)
    {
        switch ($type) {
        case 'xml':
            header('Content-Type: application/xml; charset=utf-8');
            $this->startXML();
            break;
        case 'json':
            header('Content-Type: application/json; charset=utf-8');

            // Check for JSONP callback
            $callback = $this->arg('callback');
            if ($callback) {
                print $callback . '(';
            }
            break;
        default:
            // TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
            $this->serverError(_('Not a supported data format.'), 501);
            break;
        }
    }

    public function end_document($type)
    {
        switch ($type) {
        case 'xml':
            $this->endXML();
            break;
        case 'json':
            // Check for JSONP callback
            $callback = $this->arg('callback');
            if ($callback) {
                print ')';
            }
            break;
        default:
            // TRANS: Server error displayed in oEmbed action when request specifies an unsupported data format.
            $this->serverError(_('Not a supported data format.'), 501);
            break;
        }
        return;
    }

    /**
     * Is this action read-only?
     *
     * @param array $args other arguments
     *
     * @return boolean is read only action?
     */
    function isReadOnly($args)
    {
        return true;
    }
}


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.     If not, see <http://www.gnu.org/licenses/>.
 */

if (!defined('GNUSOCIAL')) { exit(1); }

/**
 * Table Definition for file_oembed
 */

class File_oembed extends Managed_DataObject
{
    public $__table = 'file_oembed';                     // table name
    public $file_id;                         // int(4)  primary_key not_null
    public $version;                         // varchar(20)
    public $type;                            // varchar(20)
    public $mimetype;                        // varchar(50)
    public $provider;                        // varchar(50)
    public $provider_url;                    // varchar(191)   not 255 because utf8mb4 takes more space
    public $width;                           // int(4)
    public $height;                          // int(4)
    public $html;                            // text()
    public $title;                           // varchar(191)   not 255 because utf8mb4 takes more space
    public $author_name;                     // varchar(50)
    public $author_url;                      // varchar(191)   not 255 because utf8mb4 takes more space
    public $url;                             // varchar(191)   not 255 because utf8mb4 takes more space
    public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP

    public static function schemaDef()
    {
        return array(
            'fields' => array(
                'file_id' => array('type' => 'int', 'not null' => true, 'description' => 'oEmbed for that URL/file'),
                'version' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed spec. version'),
                'type' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed type: photo, video, link, rich'),
                'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'),
                'provider' => array('type' => 'varchar', 'length' => 50, 'description' => 'name of this oEmbed provider'),
                'provider_url' => array('type' => 'varchar', 'length' => 191, 'description' => 'URL of this oEmbed provider'),
                'width' => array('type' => 'int', 'description' => 'width of oEmbed resource when available'),
                'height' => array('type' => 'int', 'description' => 'height of oEmbed resource when available'),
                'html' => array('type' => 'text', 'description' => 'html representation of this oEmbed resource when applicable'),
                'title' => array('type' => 'varchar', 'length' => 191, 'description' => 'title of oEmbed resource when available'),
                'author_name' => array('type' => 'varchar', 'length' => 50, 'description' => 'author name for this oEmbed resource'),
                'author_url' => array('type' => 'varchar', 'length' => 191, 'description' => 'author URL for this oEmbed resource'),
                'url' => array('type' => 'varchar', 'length' => 191, 'description' => 'URL for this oEmbed resource when applicable (photo, link)'),
                'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
            ),
            'primary key' => array('file_id'),
            'foreign keys' => array(
                'file_oembed_file_id_fkey' => array('file', array('file_id' => 'id')),
            ),
        );
    }

    function _getOembed($url) {
        $parameters = array(
            'maxwidth' => common_config('thumbnail', 'width'),
            'maxheight' => common_config('thumbnail', 'height'),
        );
        try {
            return oEmbedHelper::getObject($url, $parameters);
        } catch (Exception $e) {
            common_log(LOG_INFO, "Error during oembed lookup for $url - " . $e->getMessage());
            return false;
        }
    }

    /**
     * Fetch an entry by using a File's id
     */
    static function byFile(File $file) {
        $file_oembed = self::getKV('file_id', $file->id);
        if (!$file_oembed instanceof File_oembed) {
            throw new ServerException(sprintf('No File_oembed entry for File id==%u', $file->id));
        }
        return $file_oembed;
    }

    public function getUrl()
    {
        return $this->url;
    }

    /**
     * Save embedding info for a new file.
     *
     * @param object $data Services_oEmbed_Object_*
     * @param int $file_id
     */
    public static function saveNew($data, $file_id) {
        $file_oembed = new File_oembed;
        $file_oembed->file_id = $file_id;
        if (!isset($data->version)) {
            common_debug('DEBUGGING oEmbed: data->version undefined in variable $data: '.var_export($data, true));
        }
        $file_oembed->version = $data->version;
        $file_oembed->type = $data->type;
        if (!empty($data->provider_name)) $file_oembed->provider = $data->provider_name;
        if (!empty($data->provider)) $file_oembed->provider = $data->provider;
        if (!empty($data->provider_url)) $file_oembed->provider_url = $data->provider_url;
        if (!empty($data->width)) $file_oembed->width = intval($data->width);
        if (!empty($data->height)) $file_oembed->height = intval($data->height);
        if (!empty($data->html)) $file_oembed->html = $data->html;
        if (!empty($data->title)) $file_oembed->title = $data->title;
        if (!empty($data->author_name)) $file_oembed->author_name = $data->author_name;
        if (!empty($data->author_url)) $file_oembed->author_url = $data->author_url;
        if (!empty($data->url)){
            $file_oembed->url = $data->url;
            $given_url = File_redirection::_canonUrl($file_oembed->url);
            if (! empty($given_url)){
                $file = File::getKV('url', $given_url);
                if ($file instanceof File) {
                    $file_oembed->mimetype = $file->mimetype;
                } else {
                    $file_redir = File_redirection::getKV('url', $given_url);
                    if (empty($file_redir)) {
                        $redir_data = File_redirection::where($given_url);
                        $file_oembed->mimetype = $redir_data['type'];
                    } else {
                        $file_id = $file_redir->file_id;
                    }
                }
            }
        }
        $file_oembed->insert();
        if (!empty($data->thumbnail_url) || ($data->type == 'photo')) {
            $ft = File_thumbnail::getKV('file_id', $file_id);
            if ($ft instanceof File_thumbnail) {
                common_log(LOG_WARNING, "Strangely, a File_thumbnail object exists for new file $file_id",
                           __FILE__);
            } else {
                File_thumbnail::saveNew($data, $file_id);
            }
        }
    }
}


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008-2010, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.     If not, see <http://www.gnu.org/licenses/>.
 */

if (!defined('STATUSNET')) {
    exit(1);
}

/**
 * Utility class to wrap basic oEmbed lookups.
 *
 * Blacklisted hosts will use an alternate lookup method:
 *  - Twitpic
 *
 * Whitelisted hosts will use known oEmbed API endpoints:
 *  - Flickr, YFrog
 *
 * Sites that provide discovery links will use them directly; a bug
 * in use of discovery links with query strings is worked around.
 *
 * Others will fall back to oohembed (unless disabled).
 * The API endpoint can be configured or disabled through config
 * as 'oohembed'/'endpoint'.
 */
class oEmbedHelper
{
    protected static $apiMap = array(
        'flickr.com' => 'https://www.flickr.com/services/oembed/',
        'youtube.com' => 'https://www.youtube.com/oembed',
        'viddler.com' => 'http://lab.viddler.com/services/oembed/',
        'revision3.com' => 'https://revision3.com/api/oembed/',
        'vimeo.com' => 'https://vimeo.com/api/oembed.json',
    );
    protected static $functionMap = array(
    );

    /**
     * Perform or fake an oEmbed lookup for the given resource.
     *
     * Some known hosts are whitelisted with API endpoints where we
     * know they exist but autodiscovery data isn't available.
     * If autodiscovery links are missing and we don't recognize the
     * host, we'll pass it to noembed.com's public service which
     * will either proxy or fake info on a lot of sites.
     *
     * A few hosts are blacklisted due to known problems with oohembed,
     * in which case we'll look up the info another way and return
     * equivalent data.
     *
     * Throws exceptions on failure.
     *
     * @param string $url
     * @param array $params
     * @return object
     */
    public static function getObject($url, $params=array())
    {
        $host = parse_url($url, PHP_URL_HOST);
        if (substr($host, 0, 4) == 'www.') {
            $host = substr($host, 4);
        }

        common_log(LOG_INFO, 'Checking for oEmbed data for ' . $url);

        // You can fiddle with the order of discovery -- either skipping
        // some types or re-ordering them.

        $order = common_config('oembed', 'order');

        foreach ($order as $method) {

            switch ($method) {
            case 'built-in':
                common_log(LOG_INFO, 'Considering built-in oEmbed methods...');
                // Blacklist: systems with no oEmbed API of their own, which are
                // either missing from or broken on noembed.com's proxy.
                // we know how to look data up in another way...
                if (array_key_exists($host, self::$functionMap)) {
                    common_log(LOG_INFO, 'We have a built-in method for ' . $host);
                    $func = self::$functionMap[$host];
                    return call_user_func($func, $url, $params);
                }
                break;
            case 'well-known':
                common_log(LOG_INFO, 'Considering well-known oEmbed endpoints...');
                // Whitelist: known API endpoints for sites that don't provide discovery...
                if (array_key_exists($host, self::$apiMap)) {
                    $api = self::$apiMap[$host];
                    common_log(LOG_INFO, 'Using well-known endpoint "' . $api . '" for "' . $host . '"');
                    break 2;
                }
                break;
            case 'discovery':
                try {
                    common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.');
                    $api = self::discover($url);
                    common_log(LOG_INFO, 'Found API endpoint ' . $api . ' for URL ' . $url);
                    break 2;
                } catch (Exception $e) {
                    common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers.');
                    // Just ignore it!
                }
                break;
            case 'service':
                $api = common_config('oembed', 'endpoint');
                common_log(LOG_INFO, 'Using service API endpoint ' . $api);
                break;
            }
        }

        if (empty($api)) {
            // TRANS: Server exception thrown in oEmbed action if no API endpoint is available.
            throw new ServerException(_('No oEmbed API endpoint available.'));
        }

        return self::getObjectFrom($api, $url, $params);
    }

    /**
     * Perform basic discovery.
     * @return string
     */
    static function discover($url)
    {
        // @fixme ideally skip this for non-HTML stuff!
        $body = self::http($url);
        return self::discoverFromHTML($url, $body);
    }

    /**
     * Partially ripped from OStatus' FeedDiscovery class.
     *
     * @param string $url source URL, used to resolve relative links
     * @param string $body HTML body text
     * @return mixed string with URL or false if no target found
     */
    static function discoverFromHTML($url, $body)
    {
        // DOMDocument::loadHTML may throw warnings on unrecognized elements,
        // and notices on unrecognized namespaces.
        $old = error_reporting(error_reporting() & ~(E_WARNING | E_NOTICE));
        $dom = new DOMDocument();
        $ok = $dom->loadHTML($body);
        error_reporting($old);

        if (!$ok) {
            throw new oEmbedHelper_BadHtmlException();
        }

        // Ok... now on to the links!
        $feeds = array(
            'application/json+oembed' => false,
        );

        $nodes = $dom->getElementsByTagName('link');
        for ($i = 0; $i < $nodes->length; $i++) {
            $node = $nodes->item($i);
            if ($node->hasAttributes()) {
                $rel = $node->attributes->getNamedItem('rel');
                $type = $node->attributes->getNamedItem('type');
                $href = $node->attributes->getNamedItem('href');
                if ($rel && $type && $href) {
                    $rel = array_filter(explode(" ", $rel->value));
                    $type = trim($type->value);
                    $href = trim($href->value);

                    if (in_array('alternate', $rel) && array_key_exists($type, $feeds) && empty($feeds[$type])) {
                        // Save the first feed found of each type...
                        $feeds[$type] = $href;
                    }
                }
            }
        }

        // Return the highest-priority feed found
        foreach ($feeds as $type => $url) {
            if ($url) {
                return $url;
            }
        }

        throw new oEmbedHelper_DiscoveryException();
    }

    /**
     * Actually do an oEmbed lookup to a particular API endpoint.
     *
     * @param string $api oEmbed API endpoint URL
     * @param string $url target URL to look up info about
     * @param array $params
     * @return object
     */
    static function getObjectFrom($api, $url, $params=array())
    {
        $params['url'] = $url;
        $params['format'] = 'json';
        $key=common_config('oembed','apikey');
        if(isset($key)) {
            $params['key'] = common_config('oembed','apikey');
        }
        $data = self::json($api, $params);
        return self::normalize($data);
    }

    /**
     * Normalize oEmbed format.
     *
     * @param object $orig
     * @return object
     */
    static function normalize($orig)
    {
        $data = clone($orig);

        if (empty($data->type)) {
            throw new Exception('Invalid oEmbed data: no type field.');
        }

        if ($data->type == 'image') {
            // YFrog does this.
            $data->type = 'photo';
        }

        if (isset($data->thumbnail_url)) {
            if (!isset($data->thumbnail_width)) {
                // !?!?!
                $data->thumbnail_width = common_config('thumbnail', 'width');
                $data->thumbnail_height = common_config('thumbnail', 'height');
            }
        }

        return $data;
    }

    /**
     * Fetch some URL and return JSON data.
     *
     * @param string $url
     * @param array $params query-string params
     * @return object
     */
    static protected function json($url, $params=array())
    {
        $data = self::http($url, $params);
        return json_decode($data);
    }

    /**
     * Hit some web API and return data on success.
     * @param string $url
     * @param array $params
     * @return string
     */
    static protected function http($url, $params=array())
    {
        $client = HTTPClient::start();
        if ($params) {
            $query = http_build_query($params, null, '&');
            if (strpos($url, '?') === false) {
                $url .= '?' . $query;
            } else {
                $url .= '&' . $query;
            }
        }
        $response = $client->get($url);
        if ($response->isOk()) {
            return $response->getBody();
        } else {
            throw new Exception('Bad HTTP response code: ' . $response->getStatus());
        }
    }
}

class oEmbedHelper_Exception extends Exception
{
    public function __construct($message = "", $code = 0, $previous = null)
    {
        parent::__construct($message, $code);
    }
}

class oEmbedHelper_BadHtmlException extends oEmbedHelper_Exception
{
    function __construct($previous=null)
    {
        return parent::__construct('Bad HTML in discovery data.', 0, $previous);
    }
}

class oEmbedHelper_DiscoveryException extends oEmbedHelper_Exception
{
    function __construct($previous=null)
    {
        return parent::__construct('No oEmbed discovery data.', 0, $previous);
    }
}


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-27 16:31+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:304
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Afrikaans (http://www.transifex.com/projects/p/gnu-social/language/af/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: af\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic (http://www.transifex.com/projects/p/gnu-social/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic (Egypt) (http://www.transifex.com/projects/p/gnu-social/language/ar_EG/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar_EG\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Asturian (http://www.transifex.com/projects/p/gnu-social/language/ast/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ast\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Belarusian (Tarask) (http://www.transifex.com/projects/p/gnu-social/language/be@tarask/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: be@tarask\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://www.transifex.com/projects/p/gnu-social/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Breton (http://www.transifex.com/projects/p/gnu-social/language/br/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: br\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Catalan (http://www.transifex.com/projects/p/gnu-social/language/ca/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Czech (http://www.transifex.com/projects/p/gnu-social/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Danish (http://www.transifex.com/projects/p/gnu-social/language/da/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: da\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: German (http://www.transifex.com/projects/p/gnu-social/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Greek (http://www.transifex.com/projects/p/gnu-social/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: el\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English (United Kingdom) (http://www.transifex.com/projects/p/gnu-social/language/en_GB/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://www.transifex.com/projects/p/gnu-social/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Juan Riquelme González <soulchainer@gmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-11 23:30+0000\n"
"Last-Translator: Juan Riquelme González <soulchainer@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/gnu-social/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr "Complemento para el uso y representación de datos en formato Oembed."


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Basque (http://www.transifex.com/projects/p/gnu-social/language/eu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Persian (http://www.transifex.com/projects/p/gnu-social/language/fa/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fa\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Finnish (http://www.transifex.com/projects/p/gnu-social/language/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fi\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: French (http://www.transifex.com/projects/p/gnu-social/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Friulian (http://www.transifex.com/projects/p/gnu-social/language/fur/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fur\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Galician (http://www.transifex.com/projects/p/gnu-social/language/gl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hebrew (http://www.transifex.com/projects/p/gnu-social/language/he/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: he\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Upper Sorbian (http://www.transifex.com/projects/p/gnu-social/language/hsb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: hsb\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hungarian (http://www.transifex.com/projects/p/gnu-social/language/hu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: hu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Interlingua (http://www.transifex.com/projects/p/gnu-social/language/ia/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ia\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Indonesian (http://www.transifex.com/projects/p/gnu-social/language/id/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://www.transifex.com/projects/p/gnu-social/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/gnu-social/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Japanese (http://www.transifex.com/projects/p/gnu-social/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Georgian (http://www.transifex.com/projects/p/gnu-social/language/ka/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ka\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Korean (http://www.transifex.com/projects/p/gnu-social/language/ko/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Colognian (http://www.transifex.com/projects/p/gnu-social/language/ksh/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ksh\n"
"Plural-Forms: nplurals=3; plural=(n==0) ? 0 : (n==1) ? 1 : 2;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Luxembourgish (http://www.transifex.com/projects/p/gnu-social/language/lb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lb\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Lithuanian (http://www.transifex.com/projects/p/gnu-social/language/lt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lt\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:39+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Latvian (http://www.transifex.com/projects/p/gnu-social/language/lv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lv\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Malagasy (http://www.transifex.com/projects/p/gnu-social/language/mg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: mg\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Macedonian (http://www.transifex.com/projects/p/gnu-social/language/mk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: mk\n"
"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Malayalam (http://www.transifex.com/projects/p/gnu-social/language/ml/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ml\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Malay (http://www.transifex.com/projects/p/gnu-social/language/ms/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ms\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Burmese (http://www.transifex.com/projects/p/gnu-social/language/my/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: my\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Norwegian Bokmål (http://www.transifex.com/projects/p/gnu-social/language/nb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nb\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:30+0000\n"
"Last-Translator: digitaldreamer <digitaldreamer@email.cz>\n"
"Language-Team: Nepali (http://www.transifex.com/projects/p/gnu-social/language/ne/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ne\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: GNU social\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-02 17:47+0100\n"
"PO-Revision-Date: 2015-02-07 09:29+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Dutch (http://www.transifex.com/projects/p/gnu-social/language/nl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nl\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#. TRANS: Plugin description.
#: OembedPlugin.php:190
msgid "Plugin for using and representing Oembed data."
msgstr ""