2

Hi

I have a lot of sensitive information stored on my Fogbugz Wiki. While I understand that you back it up, I need to prove to my bosses here that we take our own backups regularly (3-6 month) so that if the worst did happen We would still have our data.

I am not just thinking system failure here, but during a global recession companies go out of business all the time. My bosses rightly ask "What if fogbugz dissapears into liquidation, where is our data, how do I get it?" This I am assured is the question they will ask just before sacking me for not having the answers.

.........S

flag

2 Answers

3

I'm assuming you're on FogBugz On Demand. See this page for how we treat your data.

If you want to supplement our already strong backup practices, the best thing you can do is to periodically download a copy of your FogBugz database. If you need to do this more than every three months, let us know. You will then have the full HTML of every post, and we have a fully documented database schema. Or, you could get your hands on a copy of FogBugz for your server and bring it up that way.

As to Fog Creek disappearing into liquidation, we have no creditors, no debt, no outside investors, no VC, so there's really no one who could force us into liquidating our assets (fish tank, Aeron chairs, computers). Which means there's really no one who could prevent us from open-sourcing our entire code base as we walk out the door.

link|flag
I like your answer better... – James McLeod Mar 3 2010 at 20:39
Thanks! (15 chars) – Rich Armstrong Mar 4 2010 at 13:37
1

The easiest way to do this is to use the XML API to get a list of articles, (cmd=listArticles;ixWiki=<WikiID>) and then retrieve each article (cmd=viewArticle;ixWikiPage=<ArticleID>). You can save this somewhere locally, and then reformat using XLST if the need ever arises.

If you are PHP-inclined...

define('API_XML', 'api.xml');

# Debug flags - these may be over-ridden in client code.
# They are not members of C_FOGBUGZ because it may be more convenient to set them # just after this file has been included rather than after the C_FOGBUGZ class has been constructed
# 
$debug['DESCR'] = false;
$debug['QUERY'] = false;
$debug['RESPONSE'] = false;
$debug['LOG_API_ERROR'] = false;
$debug['DIE_ON_API_ERROR'] = false;

class C_FOGBUGZ
{
    const TARGET_API_VERSION = 7;

    var $api_url;
    var $token;
    var $http_options;

    function __construct($base_url, $http_options = array())
    {
        $this->http_options = $http_options;

        $url = "$base_url/" . API_XML;
        $xml = $this->get($url, 'Initializing connection');
        $xml_obj = simplexml_load_string($xml);
        if (self::TARGET_API_VERSION < $xml_obj->minversion)
            die("Error: incompatible version of API ($xml_obj->minversion}, expected a value less than or equal to " . self::TARGET_API_VERSION);
        $this->api_url = "$base_url/$xml_obj->url";
    }

    function __destruct()
    {
        if (isset($this->token))
            $this->logoff();
    }

    //@{
    /// \name FogBugz Commands

    function listArticles($ixWiki)
    {
        $fields = array(
            'cmd' => 'listArticles',
            'ixWiki' => "$ixWiki"
        );
        return $this->post($fields, "Retrieving list of articles in Wiki $ixWiki");
    }

    function listWikis()
    {
        $fields['cmd'] = 'listWikis';
        return $this->post($fields, 'Retrieving Wikis');
    }

    function logoff()
    {
        $fields['cmd'] = 'logoff';

        $xml = $this->post($fields, 'Logging off');
        unset ($this->token);
        return $xml;
    }

    function logon($user, $password)
    {
        $fields = array(
            'cmd' => 'logon',
            'email' => $user,
            'password' => $password
        );

        $xml = $this->post($fields, 'Logging on');
        $xml_obj = simplexml_load_string($xml);

        if (!property_exists($xml_obj, 'error')){
            $this->token = "$xml_obj->token";
            return true;
        }

        return $this->commonErrorHandler($xml_obj);
    }

    function viewArticle($ixWikiPage)
    {
        $fields = array(
            'cmd' => 'viewArticle',
            'ixWikiPage' => "$ixWikiPage"
        );
        return $this->post($fields, "Retrieving Wiki article $ixWikiPage");
    }

    //@}

    //@{
    /// \name Communication Utilities
    function get($url, $descr)
    {
        global $debug;

        if ($debug['DESCR']) echo "$descr\n";
        if ($debug['QUERY']) echo "$url\n";

        $response = http_get($url, $this->http_options, $info);
        return $this->process_http_response($response, $info);
    }

    function post($fields, $descr)
    {
        global $debug;

        if (isset($this->token))
            $fields['token'] = $this->token;

        if ($debug['DESCR']) echo "$descr\n";
        if ($debug['QUERY']) var_dump($fields);

        $response = http_post_fields($this->api_url, $fields, NULL, NULL, $info);
        return $this->process_http_response($response, $info);
    }

    function process_http_response($response, $info)
    {
        global $debug;

        $error = $info['error'];
        if (!is_null($error) && strlen($error))
            die("HTTP POST error: $error");

        $parsed = http_parse_message($response);
        if ($debug['RESPONSE']) echo "$parsed->body\n";
        return $parsed->body;
    }
    //@}
};

define('BASE_URL', 'http://fogbugz.ondemand.com');
define('ADMIN', 'Administrator');
define('PASSWORD', 'PASSWORD');
$http_options = array();

$fb_api = new C_FOGBUGZ(BASE_URL, $http_options);
$fb_api->logon(ADMIN, PASSWORD);

$xml = $fb_api->listWikis();
$wikis_obj = simplexml_load_string($xml);
foreach ($wikis_obj->wikis as $wiki) {
    echo "{$wiki->wiki->ixWiki} {$wiki->wiki->sWiki}\n";
    $xml = $fb_api->listArticles($wiki->wiki->ixWiki);
    $articles_obj = simplexml_load_string($xml);

    foreach ($articles_obj->articles->article as $article) {
        # In real life, you would want to write a file here for each page instead of displaying the data
        echo "{$article->ixWikiPage} {$article->sHeadline}\n";
        echo $fb_api->viewArticle($article->ixWikiPage);
    }
}
link|flag
Unfortunately, you can't get attachments from the wiki over the API. Thanks for the script, though! – Rich Armstrong Mar 3 2010 at 19:13
Too bad. I'm new to FogBugz Wiki use. – James McLeod Mar 3 2010 at 20:04

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.