#!/usr/bin/perl # # ============== # riotjournal.pl # ============== # # Based on ljer.pl by amoe (http://perlmonks.thepen.com/120236.html) # # Description : Perl LiveJournal client # Version : 0.2 # Author : Dan Hetrick # Website : http://www.riotmod.com/lj # use strict; use warnings; use Tk; use LWP::UserAgent; use HTTP::Request::Common; #==========[ Settings ]========= my $APP_NAME = "RiotJournal"; my $APP_VERSION = "0.2"; my $APP_CONFIG = "$ENV{HOME}/.riotjournal.rc"; my $APP_AGENT = "$APP_NAME/$APP_VERSION"; my $APP_CGI = 'http://www.livejournal.com/cgi-bin/log.cgi'; my %global_params; my $mw; my $GUI_LOGO_WIDTH = 597; my $GUI_LOGO_HEIGHT = 86; #==========[ Post Settings ]==== my $LJ_SUBJECT; my $LJ_ENTRY; my $LJ_MUSIC; my $LJ_MOOD; my $LJ_POST_TYPE = 1; # 1 = Public, 2 = Private, 3 = Friends my $LJ_USERNAME; my $LJ_PASSWORD; my $GUI_POST_TEXT; #==========[ Main Code ]======== if ( -e "$APP_CONFIG" ) { } else { GUI_EnterUserInfo(); } $LJ_USERNAME = GetSetting( "user", $APP_CONFIG ); $LJ_PASSWORD = GetSetting( "password", $APP_CONFIG ); $APP_CGI = GetSetting( "cgi", $APP_CONFIG ); $APP_AGENT = GetSetting( "agent", $APP_CONFIG ); GUI_EnterPost(); #==========[ Support Code ]===== # ============= # GetSetting() # ============= # Arguments : Setting, Config file # Returns : Setting value # Description : Retrieves user settings from riotjournal.rc # sub GetSetting { my ( $myset, $myfile ) = @_; my $retval = ""; open( CFGFILE, "<$myfile" ) or die "Error opening $myfile."; my @cfgfile = ; close CFGFILE; foreach my $sln (@cfgfile) { if ( index( $sln, "#" ) == 0 ) { next; } if ( $sln eq "" ) { next; } my @ln = split( "=", $sln ); if ( lc( $ln[0] ) =~ /$myset/i ) { chomp $ln[1]; $retval = $ln[1]; last; } } return $retval; } # =============== # GUI_EnterPost() # =============== # Arguments : None # Returns : None # Description : Displays a Tk interface to the PostToLiveJournal() sub. # sub GUI_EnterPost { $mw = MainWindow->new(); $mw->title("$APP_NAME $APP_VERSION"); my $icon = $mw->Photo( 'image', -data => rj_icon(), format => 'gif' ); $mw->iconimage($icon); my $canvas = $mw->Canvas( '-width' => $GUI_LOGO_WIDTH, '-height' => $GUI_LOGO_HEIGHT ); $mw->Photo( 'logo', -data => rj_logo(), -format => 'gif' ); $canvas->createImage( 0, 0, '-anchor' => 'nw', '-image' => 'logo' ); $canvas->pack; $mw->Label( -text => "Subject" )->pack( -anchor => 'nw' ); $mw->Entry( -width => 75, -textvariable, \$LJ_SUBJECT ) ->pack( -anchor => 'ne', -fill => 'x' ); $mw->Label( -text => "Music" )->pack( -anchor => 'nw' ); $mw->Entry( -width => 75, -textvariable, \$LJ_MUSIC ) ->pack( -anchor => 'ne', -fill => 'x' ); $mw->Label( -text => "Mood" )->pack( -anchor => 'nw' ); $mw->Entry( -width => 75, -textvariable, \$LJ_MOOD ) ->pack( -anchor => 'ne', -fill => 'x' ); $GUI_POST_TEXT = $mw->Scrolled( 'Text', -scrollbars => 'e', -width => 80, -height => 10 ) ->pack( -anchor => 'nw', -fill => 'x' ); $mw->Radiobutton( -text => "Public", -command => sub { $LJ_POST_TYPE = 1; } )->pack( -anchor => 'nw' ); $mw->Radiobutton( -text => "Private", -value => '0', -command => sub { $LJ_POST_TYPE = 2; } )->pack( -anchor => 'nw' ); $mw->Radiobutton( -text => "Friends Only", -value => '1', -command => sub { $LJ_POST_TYPE = 3; } )->pack( -anchor => 'nw' ); $mw->Button( -text => "Post to LiveJournal", -command => sub { $LJ_ENTRY = $GUI_POST_TEXT->get( '1.0', 'end' ); PostToLiveJournal(); } )->pack( -side => 'left', -anchor => 'nw', -fill => 'x' ); $mw->Button( -text => "Exit", -command => sub { exit } )->pack( -side => 'right', -anchor => 'nw', -fill => 'x' ); MainLoop; } # =================== # GUI_EnterUserInfo() # =================== # Arguments : None # Returns : None # Description : Displays a Tk dialog to get the LiveJournal user # and password, and calls CreateUserInfoFile() # sub GUI_EnterUserInfo { my $username; my $password; $mw = MainWindow->new(); $mw->title("$APP_NAME $APP_VERSION"); my $icon = $mw->Photo( 'image', -data => rj_icon(), format => 'gif' ); $mw->iconimage($icon); my $canvas = $mw->Canvas( '-width' => 317, '-height' => $GUI_LOGO_HEIGHT ); $mw->Photo( 'logo', -data => rj_logo_small(), -format => 'gif' ); $canvas->createImage( 0, 0, '-anchor' => 'nw', '-image' => 'logo' ); $canvas->pack; $mw->Label( -text => "Enter your LiveJournal Username/Password." ) ->pack( -anchor => 'nw' ); $mw->Label( -text => "Restart $APP_NAME for changes to take effect." ) ->pack( -anchor => 'nw' ); $mw->Label( -text => "Username:" )->pack( -anchor => 'nw' ); $mw->Entry( -width => 20, -textvariable, \$username ) ->pack( -anchor => 'nw', -fill => 'x' ); $mw->Label( -text => "Password:" )->pack( -anchor => 'nw' ); $mw->Entry( -width => 20, -textvariable, \$password ) ->pack( -anchor => 'nw', -fill => 'x' ); $mw->Button( -text => "OK", -command => sub { CreateUserInfoFile( $username, $password ); exit; } )->pack( -side => 'top', -anchor => 'nw', -fill => 'x' ); $mw->Button( -text => "Exit", -command => sub { exit } )->pack( -side => 'top', -anchor => 'nw', -fill => 'x' ); MainLoop; } # ==================== # CreateUserInfoFile() # ==================== # Arguments : Username, password # Returns : None # Description : Saves username/password to /home//.riotjournal.rc # sub CreateUserInfoFile { my ( $username, $password ) = @_; open( CONFIGFILE, ">$APP_CONFIG" ) or die "Can't write configuration file."; print CONFIGFILE "# riotjournal configuration file\n"; print CONFIGFILE "user=$username\n"; print CONFIGFILE "password=$password\n"; print CONFIGFILE "cgi=http://www.livejournal.com/cgi-bin/log.cgi\n"; print CONFIGFILE "agent=$APP_NAME/$APP_VERSION\n"; close CONFIGFILE; } # =================== # PostToLiveJournal() # =================== # Arguments : None # Returns : None # Description : Posts entered data to LiveJournal # sub PostToLiveJournal { my $journaller = LWP::UserAgent->new(); $journaller->agent($APP_AGENT); $global_params{user} = $LJ_USERNAME; $global_params{password} = $LJ_PASSWORD; my %login = &login; my $http_res = $journaller->request( POST $APP_CGI, \%login ); die "Failed to login!" unless ( $http_res->is_success ); my %lj_res = split( "\n", $http_res->content ); $lj_res{success} eq 'OK' ? print "Logged in as $lj_res{name}!\n" : die "Failed to log in: $lj_res{errmsg}\n"; print "Server: $lj_res{message}\n" unless ( !$lj_res{message} ); my %postevent = &postevent; $http_res = $journaller->request( POST $APP_CGI, \%postevent ); die "Failed to update journal!" unless ( $http_res->is_success ); %lj_res = split( "\n", $http_res->content ); $lj_res{success} eq 'OK' ? print "Updated journal successfully with entry $lj_res{itemid}\n" : print "Failed to update journal: $lj_res{errmsg}\n"; exit; } # ======= # login() # ======= # Arguments : None # Returns : Parameter hash # Description : Sets LiveJournal login parameters # sub login { my %params = %global_params; $params{mode} = 'login'; $params{clientversion} = $APP_AGENT; return %params; } # =========== # postevent() # =========== # Arguments : None # Returns : Parameter hash # Description : Sets LiveJournal post parameters # sub postevent { my %params = %global_params; $params{mode} = 'postevent'; $params{lineendings} = 'unix'; if ( $LJ_POST_TYPE == 1 ) { $params{security} = 'public'; } elsif ( $LJ_POST_TYPE == 2 ) { $params{security} = 'private'; } elsif ( $LJ_POST_TYPE == 3 ) { $params{security} = 'usemask'; $params{allowmask} = 1; } @params{ 'subject', 'event', 'prop_current_music', 'prop_current_mood' } = ( $LJ_SUBJECT, $LJ_ENTRY, $LJ_MUSIC, $LJ_MOOD ); @params{ 'min', 'hour', 'day', 'mon', 'year' } = ( localtime(time) )[ 1 .. 5 ]; $params{year} += 1900; $params{mon} += 1; return %params; } # =================== # rj_logo() # =================== # Arguments : None # Returns : Base64 encoded GIF image # Description : The RiotJournal logo # sub rj_logo { my $binary_data = <