List all of your Basecamp Classic files & attachments

Less of a blog, and more of a utility post - if you have PHP and want to find out what's eating up your Basecamp file-space allocation, this little script might help you.

Insert your API token in the right spot, insert your email in the user agent, and execute from the command line.



function fetch( $uri )
{
    /* Adjust these three variables */

    //  1 - your Basecamp URL
    $basecamp_url   = 'https://yourbasecamp.basecamphq.com/';

    // 2 - get this from your "Account" section
    $username       = 'YOURAPITOKEN';

    // 3 - enter your main account email, or face potential throttling
    $youremail      = 'youremail@youremail.com';


    $password       = 'notused';
    $session        = curl_init();

    curl_setopt($session, CURLOPT_URL, $basecamp_url . $uri );
    curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($session, CURLOPT_HTTPGET, 1);
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($session, CURLOPT_USERPWD, $username . ":" . $password);
    curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($session, CURLOPT_USERAGENT, "Circlical Account Maintenance ($youremail)" );

    $response = curl_exec($session);
    curl_close($session);

    return $response;
}

function fffsize( $size )
{
    $base   = @log($size) / log(1024);
    $suffix = array("", "k", "M", "G", "T")[@floor($base)];
    return @round( pow(1024, $base - @floor($base)), 2 ) . $suffix;
}

function info( $str )
{
    echo "\033[01;36m" . $str  . " \033[0m\n";
}

$attachment_list    = [];
$projects           = simplexml_load_string( fetch( 'projects.xml' ) );

foreach( $projects as $p )
{

    $project_name   = $p->name;
    $project_id     = $p->id;
    $ncount         = 0;

    info( "Scanning project $project_name..." );

    do{
        $attachments = simplexml_load_string( fetch( "projects/{$project_id}/attachments.xml?n={$ncount}" ) );
        if( count( $attachments->attachment ) )
        {
            foreach( $attachments as $a )
            {
                $attachment_list[] = array(
                    'project'   => (string)$project_name,
                    'file'      => (string)$a->name,
                    'size'      => (string)$a->{'byte-size'},
                );

                $ncount++;
            }
        }
    }
    while( count( $attachments->attachment ) >= 100 );
}

// now sort the darned attachments
usort( $attachment_list, function( $a, $b ){
    return $b['size'] - $a['size'];
});

$mask = "| %-20.20s | %-30.30s | %15.15s |\n";


echo printf( $mask, "Project", "File", "Size" );

foreach( $attachment_list as $a )
{
    echo printf( $mask, $a['project'], $a['file'], fffsize( $a['size'] ) );
}



Pretty print your ZF2 JsonModel the easy way

Looking for a quick cut and paste, I found crazy composer modules and overcomplicated blog articles.  Thought I'd help Occam out a bit with this very simple blog entry!  BTW I lied, we're going to skip JsonModel.

 

Sorry for the crappy indentation, trying to make it fit in Squarespace.  JSON_PRETTY_PRINT came along with PHP 5.4

 


        public function prettyJsonAction()
        {
            $contacts = array( 'foo' => 'bar' );
            $response = $this->getResponse();

            $response
                ->getHeaders()
                ->addHeaderLine( 'Content-Type', 'application/json' );

            $response
                ->setContent( 
                    json_encode( $contacts, JSON_PRETTY_PRINT )
                );

            return $response;
        }