Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: AT&T Usenet Netnews Service Shutting Down

15 views
Skip to first unread message
Message has been deleted

Eli the Bearded

unread,
Jun 20, 2009, 9:00:39 PM6/20/09
to
In alt.hackers, Limpy <ivab...@thatswaytoomuch.infoREMOVE> wrote:
> Once upon a time, in a newsgroup called alt.hackers on Mon, 8 Jun
> 2009 23:40:00 GMT we were all amazed to see
> <news-s...@sbcglobal.net> write:
>> Please note that on or around July 15, 2009, AT&T will no longer be
>> offering access to the Usenet netnews service.
> Yeah, ok, but what I wanna know is, how the hell does one post to this
> stinkin' newsgroup?

Looks like you've figured that out on your own. But you failed to include
a hack in your message (merely being able to post here is not an
acceptable hack, but most anything else is).

ObHack:

I use flickr a lot, and I noticed some people used third parties to
organize automatic sets based on various criteria. Sets based on which
items people had commented on or favorited appealed to me. But I didn't
like the idea of trusting some random code on some random site to
access my photos. So I got a API key and learned the interface, and
now I have a script triggered by automatic email notices of activity
on my stream that can parse the activity message to get the item and
type of activity (photo or set, comment or fave) and sort the item
automatically. (Sets with comments at the set level go into a
"collection" (ie, set of sets), doing that was a whole different layer
of hack, since the collection API is not yet public.)

Elijah
------
can be found at the obvious name on flickr

Message has been deleted

Stainless Steel Rat

unread,
Dec 1, 2009, 3:33:35 PM12/1/09
to
In article <77hah5hq2gq5l67qm...@4ax.com>,
Limpy <ivab...@thatswaytoomuch.infoREMOVE> wrote:
> Oh ok, Eli the Obvious, here's my ObHack:
> Google. It's like magic!
> If you have a problem you can just google it! Like today I'm trying to
> fix an xbox 360 and I typed in the error code and, as they say in
> internets land, "walla" an answer magically appears on my screen!
> Woohoo!

That's not a hack. That's just SOP.
ObHack: Wrapping your Xbox 360 in a blanket and running it until the
thermal protection circuit shuts it down to reflow the solder on the
mainboard. No, I don't recommend doing this unless you want to risk
permanently destroying your '360.

Eli the Bearded

unread,
Dec 1, 2009, 8:11:41 PM12/1/09
to
In alt.hackers, Stainless Steel Rat <rat...@newsguy.com> wrote:
> In article <77hah5hq2gq5l67qm...@4ax.com>,
> Limpy <ivab...@thatswaytoomuch.infoREMOVE> wrote:
> > Oh ok, Eli the Obvious, here's my ObHack:
> > Google. It's like magic!
> > If you have a problem you can just google it! Like today I'm trying to
> > fix an xbox 360 and I typed in the error code and, as they say in
> > internets land, "walla" an answer magically appears on my screen!

You need a better class of problems to keep life interesting if Google
can fix them so easily. I don't know what the hell was wrong with
siege (web load tester) under Solaris that caused it to core dump
for me. Well, actually I do know that it was only doing it under
certain conditions, and I did enough forensics on the core to identify
that the *printf for the "Content-Type" header was involved. I replaced
the %s in the source with the value I wanted and it was working.

> ObHack: Wrapping your Xbox 360 in a blanket and running it until the
> thermal protection circuit shuts it down to reflow the solder on the
> mainboard. No, I don't recommend doing this unless you want to risk
> permanently destroying your '360.

Yeah, sounds like a risky way to achieve the goal.

ObSubjectLine: A long time Kirk Israel was a regular here. He's lost his
Usenet connection, but he's still around. Here's his latest, an Advent
calendar of Java apps:

http://kisrael.com/java/advent2009/

ObHack: Another flickr related item. In some circles on flickr it's
amost cliche to "Add a note" to an image showing a suggested photo
crop. So it occurred to me, why not implement that? Thus I now have
a command line script to take a photo id, the text of a note box,
and then use that to download a photo, crop it (requires scaling
note box to original image size and taking image rotation into
account), copy the Exif tags from the original to the new, and
re-upload it, optionally using the 'replace photo' method. For
good measure I delete the note if the photo was replaced.

Example usage.
Original image:
http://www.flickr.com/photos/elithebearded/4022799281/
Cropped image:
http://www.flickr.com/photos/elithebearded/4027864066/

$ flickr-cropper 4022799281 'The sign.' new

After upload, I edited the text on the 'The sign.' note to be a
hyperlink to the new image.

Next up is generalizing this to a perform some operation on this
area script. I'm thinking of adding inset images, selective blurring,
and anything else I can script by command line.

Elijah
------
:r $FR/flickr-cropper
#!/usr/bin/env perl
# Using a special note as a guide, crop and replace a photo.
# usage:
# cropper photoid "target note contents" [ newflag ]
#
# If newflag is set ("1", "y", "new", etc) then the cropped version
# will be uploaded as a new image instead of replacing the original.
#
# After a photo replacement the target note will be deleted.
#
# Jul 2009 Eli the Bearded
use strict;
use warnings;
use Flickr::API;
use Data::Dumper;
use vars qw( $flickr_api_key $flickr_api_secret $flickr_token $api $apiconf
$photoid $target $url $verbose
$flickrtool $uploadtool $replacetool
$exiftool $dltool $rottool $croptool
@notebox @sizes $sizes_cache $getinfo_cache
);

$apiconf = (defined($ENV{FLICKR_API_RC})? $ENV{FLICKR_API_RC} :
(defined($ENV{HOME})? "$ENV{HOME}/.flickrapirc" : "flickrapirc"));
do $apiconf || die "$0: can't load rc $apiconf: $!.\n";


########## external tool setup
# external tools, with %X escapes:
# %% %
# %c name of cropped file
# %d rotation to perform (clockwise degrees)
# %D rotation to perform (counterclockwise degrees)
# %h height of crop
# %i original photo id
# %l left column of crop
# %o name of original file
# %r rotate tool in pipeline (only substitues if rotation is non-zero)
# %t top row of crop
# %u url of orignal file
# %w width of crop

# flickr-upload is part of the Flickr::Upload perl package on CPAN
$uploadtool = 'flickr-upload %c';

# flickr-replace is based on flickr-upload and needs Flickr::Upload
$replacetool = 'flickr-replace --id=%i %c';

# bget is a basic HTTP fetch tool I wrote, it is on CPAN in the scripts
# section, or you can use 'lynx --dump %u > %o' or similar.
$dltool = 'bget -f %u > %o';

# rotation command, will be substituted into $croptool if needed
$rottool = 'pamflip -r%D |';

# this needs to accept a jpeg on standard in, and save a jpeg to %c
$croptool = 'djpeg %o | %r pamcut %l %t %w %h | cjpeg -q 90 > %c';

# copy Exif tags from original to new file, you can use /bin/true if
# if you don't care.
$exiftool = 'exiftool -TagsFromFile %o %c';

#
#
########## end tool setup


$api = new Flickr::API({ 'key' => $flickr_api_key,
'secret' => $flickr_api_secret });

$photoid = shift;
$target = shift;

if(!defined($target) or !defined($photoid)) {
die "$0: usage: cropper photoid 'target note contents' [ newflag ]\n";
}

if(defined($ARGV[0]) and $ARGV[0]) {
$flickrtool = $uploadtool;
print "Will upload new. \n";
} else {
$flickrtool = $replacetool;
print "Will upload replacement. \n";
}


sub getinfo($) {
my $id = shift;
my $response;
my $content;

if($id !~ /^\d+$/) {
die "$0: photoid $id is not numerical\n";
} else {

$response = $api->execute_method('flickr.photos.getInfo', {
'photo_id' => $id,
'auth_token' => $flickr_token,
});

$content = $$response{_content};
}

return $content; # might be undef
} # sub getinfo

sub getsizes($) {
my $id = shift;
my $response;
my $content;

if($id !~ /^\d+$/) {
die "$0: photoid $id is not numerical\n";
} else {

$response = $api->execute_method('flickr.photos.getSizes', {
'photo_id' => $id,
'auth_token' => $flickr_token,
});

$content = $$response{_content};
}

return $content; # might be undef
} # sub getsizes

sub geturl($$) {
my $sizes = shift; # response from flickr.photos.getSizes
my $size = shift; # name of size to find URL
my $url;

while($sizes =~ /<size ([^>]*)/g) {
my $hold = $1;

# label="Original" width="640" height="480"
# url="http://www.flickr.com/photos/stewart/567229075/sizes/o/"
# source="http://farm2.static.flickr.com/1103/567229075_6dc09dc6da_o.jpg"
if($hold =~ /label="$size"/i) {
if($hold =~ /source="([^"]+)"/) {
$url = $1
}
}
}

return $url; # may be undef
} # sub geturl

sub gettarget($$) {
my $info = shift;
my $tar = shift;
my $noteid;
my $text;
my $note_w;
my $note_h;
my $note_x;
my $note_y;

if(!defined($info)) {
die "$0: failed to get photo info\n";
} else {

while ($info =~ m: <note (.*?) </note>:gx) {
my $thisbit = $1;
if($thisbit =~ /\bid="([^"]+)"/) { $noteid = $1; }
if($thisbit =~ /\bx="(\d+)"/) { $note_x = $1; }
if($thisbit =~ /\by="(\d+)"/) { $note_y = $1; }
if($thisbit =~ /\bw="(\d+)"/) { $note_w = $1; }
if($thisbit =~ /\bh="(\d+)"/) { $note_h = $1; }
if($thisbit =~ />\s*(.+)$/) { $text = $1; }
$text =~ s/\s+$//;
if($text eq $tar) {
return ($noteid, $note_x, $note_y, $note_w, $note_h);
}
# print "Skipping text: '$text'\n";

}
}

return (undef, undef, undef, undef, undef);
} # sub gettarget


sub deletenote($){
my $noteid = shift;
my $resp;
my $cont;

$resp = $api->execute_method('flickr.photos.notes.delete', {
'note_id' => $noteid,
'auth_token' => $flickr_token,
});

$cont = $$resp{_content};

if($cont !~ /<rsp\s*stat="ok"/) {
print "Error removing $noteid:\n$cont\n";
} else {
print "removed note $noteid\n";
}
} # sub deletenote

sub calccropsize($$$) {
my $sizes = shift;
my $getinfo = shift;
my $note_r = shift;
my $orig_rot;
my $orig_wide;
my $orig_height;
my $scaled_wide;
my $scaled_height;
my $new_top;
my $new_left;
my $new_wide;
my $new_height;

while($sizes =~ /<size ([^>]*)/g) {
my $hold = $1;
my $w;
my $h;

# label="Original" width="640" height="480"
if($hold =~ /width="(\d+)"/) {
$w = $1;
}
if($hold =~ /height="(\d+)"/) {
$h = $1;
}
if($hold =~ /label="Original"/i) {
$orig_wide = $w;
$orig_height = $h;
}
if($hold =~ /label="Medium"/i) {
$scaled_wide = $w;
$scaled_height = $h;
}
}

if(!defined($orig_wide) or !defined($orig_height)) {
die "$0: cannot get original size\n";
}
if(!defined($scaled_wide) or !defined($scaled_height)) {
die "$0: cannot get scaled size\n";
}

if($getinfo =~ /rotation="(90|180|270)"/) {
$orig_rot = $1;
if($orig_rot != 180) {
# swap width / height if rotated 90 left or 90 right.
($orig_wide, $orig_height) = ($orig_height, $orig_wide)
}
} else {
$orig_rot = 0;
}

# $note_r = [$noteid, $note_x, $note_y, $note_w, $note_h]

$new_left = int( ($$note_r[1] / $scaled_wide ) * $orig_wide );
$new_top = int( ($$note_r[2] / $scaled_height) * $orig_height );
$new_wide = int( ($$note_r[3] / $scaled_wide ) * $orig_wide );
$new_height = int( ($$note_r[4] / $scaled_height) * $orig_height );

print "orignal image is ${orig_wide}x$orig_height, scaled is ${scaled_wide}x$scaled_height\n";
print "target box at ($$note_r[1],$$note_r[2]) is $$note_r[3]x$$note_r[4]\n";
print "rotate: $orig_rot, crop at $new_top,$new_left to ${new_wide}x$new_height\n";
return($orig_rot, $new_top, $new_left, $new_wide, $new_height);
} # sub calccropsize

sub dotoolsubs($$) {
my $tool = shift;
my $sub_r = shift;

$tool =~ s/%(.)/(defined($$sub_r{$1})? $$sub_r{$1} : '')/eg;

return $tool;
} # sub dotoolsubs

sub runtool($) {
my $cmd = shift;

if ($verbose) { print "system($cmd);\n" }
system($cmd);

} # sub runtool

sub docrop($$$) {
my $siz_r = shift;
my $url = shift;
my $id = shift;
my $tool;

my %subs = (
'%' => '%',

# %c name of cropped file
'c' => "$ENV{HOME}/tmp/fc-$id-c",

# %d rotation to perform (clockwise degrees)
'd' => $$siz_r[0],

# %D rotation to perform (counterclockwise degrees)
'D' => (360 - $$siz_r[0]),

# %h height of crop
'h' => $$siz_r[4],

# %i original photo id
'i' => $id,

# %l left column of crop
'l' => $$siz_r[2],

# %o name of original file
'o' => "$ENV{HOME}/tmp/fc-$id-o",

# %r rotate tool in pipeline
'r' => '', # defined later if needed

# %t top row of crop
't' => $$siz_r[1],

# %u url of orignal file
'u' => $url,

# %w width of crop
'w' => $$siz_r[3],

);

if($$siz_r[0]) {
$tool = dotoolsubs($rottool, \%subs);
$subs{r} = $tool;
}

$tool = dotoolsubs($dltool, \%subs);
runtool($tool);

$tool = dotoolsubs($croptool, \%subs);
runtool($tool);

$tool = dotoolsubs($exiftool, \%subs);
runtool($tool);

$tool = dotoolsubs($flickrtool, \%subs);
runtool($tool);

unlink($subs{o}); # original file
unlink($subs{c}); # cropped file

} # sub docrop

# This will give us note information and rotation of original image
$getinfo_cache = getinfo($photoid);
if(!defined($getinfo_cache)) {
die "$0: could not get info on $photoid\n";
}

# extract the note information
@notebox = gettarget($getinfo_cache, $target);
if(!defined($notebox[0])) {
die "$0: no target note found on $photoid\n";
}

# get urls and dimensions of available sizes
$sizes_cache = getsizes($photoid);
if(!defined($sizes_cache)) {
die "$0: can't get sizes for $photoid\n";
}

$url = geturl($sizes_cache, "Original");
if(!defined($url)) {
die "$0: can't get orignal url $photoid\n";
}

@sizes = calccropsize($sizes_cache, $getinfo_cache, \@notebox);


# docrop uses a number of global $*tool variables
docrop(\@sizes,$url,$photoid);

# only delete note if we are doing a replacement.
if(!(defined($ARGV[0]) and $ARGV[0])) {
deletenote($notebox[0]);
}

__END__

0 new messages