photo album tool

topic posted Wed, October 20, 2004 - 5:43 PM by  Eli
So for a mass posting of photos to my album I recently hacked together a small tool. First I used a browser debugger to capture the POST action of putting an image in my album. This was my lazy way of (1) figuring out the form elements used and (2) grabbing my current credentials (cookies). I then whipped up a little perl script that took a simple config file and posted all the images listed there, with optional captions. Result: more than 100 images added quickly and without tedious find the image, 'submit', wait, repeat.

Based on that I created another tool that would parse the individual photo pages for photo URL and caption and build an imput file to rebuild my album. I used a download tool to grab all 420 pages of my album, ran the parse tool over it, fetched all of the photos (as tribe has them), and now I can rebuild my album from scratch.

Next tool to write would be one to delete everything from my album, so that I can use the recreation tool for caption changes, resorting, updating in the middle, etc.
posted by:
Eli
offline Eli
  • The post tool. Beware possible cut&paste errors. The two here documents (HEADS and BODY) have lines that begin with tab, for instance.

    #!/usr/bin/perl -w
    # Post images to a personal album.
    #
    # Reads from STDIN file information of the form:
    #
    # /fullpath/to/file [ TAB caption to be used ]
    #
    # The caption is optional and may contain spaces or tabs. Filenames can
    # contain spaces but not tabs.
    #
    # Cookies and personid will need to be adjusted.
    # 19 Oct 2004
    use strict;
    use vars qw ( $fn $caption $file $heads $body $name $size $post $tmpout $persid );

    #sanfrancisco.tribe.net/templa.../person

    # My person id
    $persid = '19038ed6-a828-4986-a1f1-6d0723a3eec3';
    $tmpout = "/tmp/tribe-album.out";

    $heads = <<'HEADS';
    POST /template/profile%2CPhotos.vm/context/person?parentid=<<PERSONID>>&r=10535 HTTP/1.1
    Host: sanfrancisco.tribe.net
    User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7b) Gecko/20040323 Firefox/0.8.0+
    Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
    Accept-Language: en,en-us;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Connection: keep-alive
    Referer: sanfrancisco.tribe.net/tribe/.../person
    Cookie: backtrack=closed; TRIBE_NET=3; TRIBE_STATE=state-cookie-here; JSESSIONID=session-cookie-here; remember=true; TRIBE_TOKEN=token-cookie-here
    Content-Type: multipart/form-data; boundary=---------------------------2067952646757102194432804585
    Content-Length: <<SIZE>>

    HEADS


    $body = <<'BODY';
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="action"

    UploadPhoto
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="commitTemplate"

    profile,Photos.vm
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="dispatcher_callstack"


    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="renderctx"

    person
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="pers_mode"

    modify
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="pers_path"

    Application[tribe].Person[<<PERSONID>>]
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="photo_mode"

    create
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="photo_path"

    Application[tribe].Person[<<PERSONID>>].Photo
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="photo_upload"; filename="<<NAME>>"
    Content-Type: image/jpeg

    <<FILE>>
    -----------------------------2067952646757102194432804585
    Content-Disposition: form-data; name="photo_description"

    <<CAPTION>>
    -----------------------------2067952646757102194432804585--
    BODY

    $heads =~ s/^\t//gm;
    $body =~ s/^\t//gm;
    $heads =~ s/\cM?\cJ/\cM\cJ/g;
    $body =~ s/\cM?\cJ/\cM\cJ/g;
    $heads =~ s/<<PERSONID>>/$persid/g;
    $body =~ s/<<PERSONID>>/$persid/g;

    while(<>) {
    if(/(.+)\t(.+)/) {
    $fn = $1;
    $caption = $2;
    } else {
    chomp $_;
    $fn = $_;
    $caption = '';
    }

    if(!open(FILE, $fn)) {
    warn "Cannot open $fn: $!\n";
    next;
    }
    $/ = undef;
    $file = <FILE>;
    close FILE;
    $/ = "\n";

    $post = $body;
    $post =~ s/<<NAME>>/$fn/;
    $post =~ s/<<CAPTION>>/$caption/;
    $post =~ s/<<FILE>>/$file/; # this s/// should be last for body

    $size = length($post);
    $post = $heads . $post;
    $post =~ s/<<SIZE>>/$size/; # after attaching heads

    print STDERR "$fn\n";
    if ($caption) { print STDERR "$caption\n"; }

    unlink($tmpout);
    if(!open(NC, "| nc sanfrancisco.tribe.net 80 > $tmpout")) {
    warn "Cannot open pipe to netcat: $!\n";
    next;
    }
    print NC $post;
    close NC;
    print STDERR "\$! = " . (0 + $!) . "; \$? = $?\n";

    if(!-f $tmpout) { die "No output file\n"; }
    if(!open(STATUS, $tmpout)) { die "Cannot check status: $tmpout: $!\n"; }

    $/ = undef;
    $_ = <STATUS>;
    close STATUS;
    $/ = "\n";

    if(/\sLocation: http:/) {
    print STDERR "posted\n";
    unlink($tmpout);
    } else {
    print STDERR "problem, check $tmpout\n";
    }
    }

  • The album extractor tool. Again watch out for cut&paste issues.

    #!/usr/bin/perl -w
    # From individual photo pages (offset=N) extract the image URL
    # and save it to a fetch.URLs file and the caption and save that
    # with the image name to a post.control.in file. From this we
    # can use a mirrored copy of an album to create a bget fetch list
    # and a post list to recreate the album.
    # 20 Oct 2004
    use strict;
    use vars qw( $albfile $state $imageurl $imagename $caption
    $outfetch $outpost
    );

    $outfetch = "fetch.URLs";
    $outpost = "post.control.in";

    if (-f $outfetch) { die "File $outfetch exists, won't clobber\n"; }
    if (-f $outpost ) { die "File $outpost exists, won't clobber\n"; }

    if(!open(URLS, "> $outfetch")) {
    die "Cannot open $outfetch: $!\n";
    }

    if(!open(POST, "> $outpost")) {
    die "Cannot open $outpost: $!\n";
    }

    for $albfile (@ARGV) {
    if(!open(IN, $albfile)) {
    warn "Cannot open $albfile: $!\n";
    next;
    }

    $/ = undef;
    $_ = <IN>;
    close IN;

    s/.*(<!-- FULL-SIZE PHOTO WIDGET START -->)//s;
    if(!defined($1)) {
    warn "$albfile: did not find widget start\n";
    next;
    }

    s/(<!-- FULL-SIZE PHOTO WIDGET END -->).*//s;
    if(!defined($1)) {
    warn "$albfile: did not find widget end\n";
    next;
    }

    if (m, <img [^>]*\b src=['"]?
    ([^'"\s>]+)
    ,xi) {
    $imageurl = $1;
    } else {
    warn "$albfile: did not find image url\n";
    next;
    }

    if($imageurl =~ m%/([\da-f-]{10,})$%) {
    $imagename = $1;
    } else {
    warn "$albfile: did not find image name\n";
    next;
    }

    s/.*(<!-- NOTE: LINK GOES BACK TO ALBUM PAGE. HANDY! -->\s*<a\b[^>]*>)//s;
    if(!defined($1)) {
    warn "$albfile: did not find link note\n";
    next;
    }

    s%(</a>).*%%s;
    if(!defined($1)) {
    warn "$albfile: did not find close anchor\n";
    next;
    }

    # $_ should now be either only white space or a caption without
    # html tags.
    if(y:<>:<>:) {
    warn "$albfile: caption still has tags: $_\n";
    next;
    }

    s/^\s*//;
    s/\s*$//;


    if(/\S/) {
    $caption = "\t$_";
    } else {
    $caption = '';
    }

    print URLS "$imageurl\t$imagename\n";
    print POST "$imagename$caption\n";
    }

    close URLS;
    close POST;

    __END__

    Note that bget is a tool of mine for web testing/page downloading. The release
    version is at CPAN in the scripts section or my directory.

    cpan.org/scripts/Web/index.html
    cpan.org/authors/id/E/EL/ELIJAH/

    1.1 is the latest released version.

Recent topics in "tribe.hacks"

Topic Author Replies Last Post
New Tribe Skins Diana 0 June 5, 2007
Mark all read Ashton 1 August 9, 2005
hiding albums with user stylesheets Tom 5 July 7, 2005
(main) image trick Eli 5 June 14, 2005