function api_getJourno_invoke($params)
{
    /* input can be a journo or list of journos */
    $j = $params['journo'];
    if (is_null($j)) {
        api_error("missing required parameter: 'journo'");
        return;
    }
    $idents = preg_split('/\\s*,\\s*/', $j);
    $journo_ids = resolve_ids($idents);
    // TODO: impose a max number of journos here...
    // fetch cached versions
    $cache_ids = array();
    $qs = array();
    foreach ($journo_ids as $id) {
        $cache_ids[] = "json_{$id}";
        $qs[] = '?';
    }
    $q = db_query("SELECT content FROM htmlcache WHERE name in (" . implode(',', $qs) . ")", $cache_ids);
    // cook up the results!
    $temp_results = array();
    foreach ($journo_ids as $id) {
        $temp_results[$id] = null;
    }
    $basic_fields = array('id', 'ref', 'prettyname', 'firstname', 'lastname', 'oneliner');
    while ($row = db_fetch_array($q)) {
        $cached_json = $row['content'];
        $raw = json_decode($cached_json, true);
        if ($raw['status'] != 'a') {
            //continue;
        }
        // the basics:
        $journo = array_cherrypick($raw, $basic_fields);
        // pick out contact details
        $known_emails = array();
        if ($raw['known_email']) {
            $known_emails[] = $raw['known_email']['email'];
        }
        $guessed_emails = array();
        if ($raw['guessed']) {
            $guessed_emails = $raw['guessed']['emails'];
        }
        $contact = array('known_emails' => $known_emails, 'guessed_emails' => $guessed_emails, 'twitter_id' => $raw['twitter_id'], 'phone_number' => $raw['phone_number']);
        $journo['contact'] = $contact;
        // tags
        if (!$raw['quick_n_nasty']) {
            $journo['tags'] = $raw['tags'];
        } else {
            $journo['tags'] = array();
        }
        $id = intval($journo['id']);
        $temp_results[$id] =& $journo;
    }
    // reorder the results to match input params
    $results = array();
    foreach ($journo_ids as $id) {
        $results[] = $temp_results[$id];
    }
    $output = array('results' => $results);
    api_output($output);
}
function api_getArticles_invoke($params)
{
    $article_ids = array();
    if ($params['id36']) {
        $id36s = preg_split("/[\\s,]+/", $params['id36']);
        foreach ($id36s as $id36) {
            $article_ids[] = article_id36_to_id($id36);
        }
    }
    if ($params['url']) {
        // look up article by its original url
        $url = $params['url'];
        $art_id = article_find($url);
        if (is_null($art_id)) {
            api_error("couldn't find article with url: '" . $url . "'");
            return;
        }
        $article_ids[] = $art_id;
    }
    if (!$article_ids) {
        api_error("No articles specified - use 'id36' and/or 'url'");
        return;
    }
    #$brief = $params['brief'] ? TRUE : FALSE;
    $fields = array('title', 'id36', 'srcorgname', 'iso_pubdate', 'permalink', 'journos', 'description');
    $results = array();
    foreach ($article_ids as $id) {
        $raw = article_collect($id);
        $art = array_cherrypick($raw, $fields);
        $results[] = $art;
    }
    $output = array('status' => 0, 'results' => $results);
    api_output($output);
}
        }
        $sql = <<<EOT
            SELECT a.id, a.srcid, a.title, c.content, a.pubdate, c.scraped as content_scraped, a.permalink,
                    a.srcorg, o.shortname, o.prettyname, o.home_url
                FROM ((article a INNER JOIN article_content c ON c.article_id=a.id) INNER JOIN organisation o ON o.id=a.srcorg)
                WHERE c.scraped<?
                    AND a.srcorg IN (SELECT pub_id FROM (pub_set_map m INNER JOIN pub_set s ON s.id=m.pub_set_id) WHERE name='national_uk')
                ORDER BY c.scraped DESC
                LIMIT ?;
EOT;
        $r = db_query($sql, $before_dt->format('Y-m-d\\TH:i:s.uO'), $limit);
    }
    $fields = array('id', 'srcid', 'title', 'content', 'pubdate', 'content_scraped', 'permalink');
    $time_fields = array('pubdate', 'content_scraped');
    while ($row = db_fetch_array($r)) {
        $out = array_cherrypick($row, $fields);
        // add source publication info
        $source = array('id' => $row['srcorg'], 'shortname' => $row['shortname'], 'prettyname' => $row['prettyname'], 'home_url' => $row['home_url']);
        $out['source'] = $source;
        // sanitize the timestamps
        foreach ($time_fields as $tf) {
            $dt = new DateTime($out[$tf]);
            $out[$tf] = $dt->format('Y-m-d\\TH:i:s.uO');
        }
        $results[] = $out;
    }
    // go through and add in id36 and journo data to articles
    foreach ($results as &$art) {
        $art['id36'] = article_id_to_id36($art['id']);
        $sql = <<<EOT
SELECT j.prettyname, j.ref