1#!/usr/bin/perl -w
2######################################################################
3# approve_friends
4# Sccsid:  %Z%  %M%  %I%  Delta: %G%
5# $Id: approve_friends,v 1.5 2006/03/15 01:49:48 grant Exp $
6######################################################################
7# Copyright (c) 2004 Grant Grueninger, Commercial Systems Corp.
8#
9# Description:
10#
11
12=head1 NAME
13
14approve_friends - Approve new friends and post a comment to them
15
16=head1 VERSION
17
18Version 0.09
19
20=cut
21
22our $VERSION='0.09';
23
24=head1 SYNOPSIS
25
26approve_friends [-m message] [-y] [-u username -p password] [-nc]
27    [-f filename] [-c cache_file] [-gc message ]
28
29approve_friends [-f filename.yaml]
30
31The first form of the command specifies arguments on the command line. If
32the -f flag is used, the username, password, and message will be read from
33the file. The username on the first line, password on the second, and
34message on the remaining lines.
35
36 -nc: no comment. Just approve friend requests, don't leave comments.
37 -c cache_file: Use "cache_file" as the file to store info about who
38 	we've commented.
39 -gc message: If we approve less than 50 friends, post "message" as a
40 	comment to any friends we have that don't already have a comment on
41 	their page. See the example below for how this is useful.
42
43The second form of the command takes a YAML configuration file. Any other
44command-line arguments will be ignored.
45
46Note that the ability to specify the cache file lets you set a
47different file if you have multiple accounts. If you use the same
48cache_file as you do for the "comment" script (and you should),
49both scripts will avoid posting to users you've already commented
50with either script. This allows you to run them concurrently.
51
52EXAMPLES
53
54 # Approve and leave a comment for new friends. Since we can comment 50
55 # people a day, if we've approved/commented less than 50, go through the
56 # rest of our friends list and leave a comment for as many as we can.
57 # This will leave "Thanks for adding me!" as a comment for new friends,
58 # and "Just stopping by to say hello!" as a comment for existing friends.
59 # Remember, Comment.pm will automatically skip profiles you've already
60 # commented or are on the top 8 of.
61 # Stops at 50 total posts.
62 approve_friends -m "Thanks for adding me\!" \
63     -gc "Just stopping by to say hello\!"
64
65 Sample YAML config file:
66
67 ---
68 username: myaccount@myspace.com
69 password: ILikePasswords
70 message: |
71   This is a message.
72
73   It is a few lines long
74
75   - Me
76 silent: 1  # Or 0 (default)
77 no_comment: 1  # Or 0 (default)
78 cache_file: /home/joe/approve_cache
79
80=cut
81
82#---------------------------------------------------------------------
83# Setup Variables
84
85use warnings;
86use strict;
87
88# Debugging?
89our $DEBUG=0;
90
91our $DEFAULT_MESSAGE = 'Thanks for adding me!';
92
93#---------------------------------------------------------------------
94# Libraries
95
96use WWW::Myspace 0.21;
97use WWW::Myspace::Comment;
98
99use YAML 'LoadFile';
100#use IO::All;
101
102######################################################################
103# Main Program
104
105# Get passed arguments
106my $args = &parse_args(@ARGV);
107my $result;
108
109# Log in
110my $date = `date`; chop $date;
111print "Logging in to myspace at ${date}...\n";
112my $myspace = "";
113if ( $args->{'username'} ) {
114	$myspace = WWW::Myspace->new( $args->{'username'}, $args->{'password'} );
115} else {
116	$myspace = new WWW::Myspace;
117}
118die "Login failed\n" unless ( $myspace->logged_in );
119
120# Approve friends
121print "Checking for friends to approve...\n";
122my @friends = $myspace->approve_friend_requests;
123
124# If we approved any, comment them
125my $comment = WWW::Myspace::Comment->new( $myspace );
126$comment->set_noisy(1);
127
128# Set the comment counter
129my $max_count;
130if ( defined $args->{'bypass'} ) {
131	$max_count = 400;
132	$comment->{send_message_on_captcha} = 1;
133} else {
134	$max_count = 50;
135}
136
137# Set the cache file if necessary
138$comment->cache_file( $args->{'cache_file'} )
139	if ( defined $args->{'cache_file'} );
140
141if ( @friends ) {
142	print "Approved " . @friends . " new friends: @friends\n";
143
144	unless ( defined $args->{'no_comment'} ) {
145
146		print "Leaving comments...\n";
147
148		# If we're posting less than $max_count friends, comment them all.
149		$comment->ignore_duplicates(1) if ( ( ! $args->{'general_comment'} ) &&
150			( @friends < $max_count ) );
151		$result = $comment->post_comments( $args->{'message'}, @friends );
152		print "New add comments finished with status: $result\n";
153	}
154
155}
156
157if ( $args->{'general_comment'} && ( @friends < $max_count ) ) {
158	print "Leaving comments for other friends...\n";
159
160	# Leave $max_count total comments, including those we left above
161	$comment->max_count( $max_count - @friends );
162	print "Sending to " . $comment->max_count . " friends\n";
163	( $DEBUG ) && print "I'd be sending this to ". $comment->max_count .
164		" friends if I weren't in debug mode:\n" . $args->{'general_comment'} .
165		"\n";
166	$result = $comment->post_comments( $args->{'general_comment'},
167		$myspace->get_friends );
168	print "General comments finished with status: $result\n";
169}
170
171print "Done.\n";
172
173######################################################################
174# Subroutines
175
176#----------------------------------------------------------------------
177# parse_args( @ARGS )
178# Parse command-line arguments and return a has of values
179
180sub parse_args {
181
182	my ( @passed_args ) = @_;
183
184	# Initialize
185	my $args = {};
186	my @friend_ids = ();
187	my ( $arg, $line, $data );
188
189	while ( $arg = shift( @passed_args ) ) {
190		if ( $arg eq "-m" ) {
191			$args->{'message'} = shift( @passed_args )
192		} elsif ( $arg eq "-y" ) {
193			$args->{'silent'}=1;
194		} elsif ( $arg eq "-u" ) {
195			$args->{'username'}=shift( @passed_args );
196		} elsif ( $arg eq "-p" ) {
197			$args->{'password'}=shift( @passed_args );
198		} elsif ( $arg eq "-f" ) {
199			$args->{'filename'}=shift( @passed_args );
200		} elsif ( $arg eq "-nc" ) {
201			$args->{'no_comment'} = 1;
202		} elsif ( $arg eq "-c" ) {
203			$args->{'cache_file'} = shift( @passed_args );
204		} elsif ( $arg eq "-gc" ) {
205			$args->{'general_comment'} = shift( @passed_args );
206		} elsif ( $arg eq "-b" ) {
207			$args->{'bypass'} = 1;
208		} else {
209			die "Invalid argument: $arg\n";
210		}
211
212	}
213
214	# Verify data
215	if ( ( $args->{'username'} ) && ( ! $args->{'password'} ) ) {
216		print "You must specify a password if you provide a username\n";
217		&fail();
218	}
219
220	# Check for -f flag - means we read username, password, and message
221	# from a file
222	if ( defined $args->{'filename'} ) {
223		open FILE, "<", $args->{'filename'} or die "Invalid filename: ".$args->{'filename'};
224
225		# New YAML support
226		if ( $args->{'filename'} =~ /\.ya?ml$/i ) {
227			( $DEBUG ) && print "Reading YAML config file " . $args->{'filename'} . "\n";
228#			$data < io( $args->{'filename'} );
229#			$args = LoadFile( $data );
230			$args = LoadFile( $args->{'filename'} );
231		} else {
232			( $DEBUG ) && print "Reading standard config file ". $args->{'filename'} . "\n";
233			$args->{'username'} = <FILE>;
234			$args->{'password'} = <FILE>;
235			undef $args->{'message'}; # Just in case...
236			foreach $line ( <FILE> ) {
237				$args->{'message'} .= $line;
238			}
239		}
240
241		close FILE;
242	}
243
244	# Check the comment
245	unless ( $args->{'message'} ) {
246		$args->{'message'} = $DEFAULT_MESSAGE;
247	}
248
249	# Debugging output
250	if ( $DEBUG ) {
251		print "Got arguments:\n";
252		foreach $arg (sort( keys( %{$args} ) ) ) {
253			print "$arg:" . $args->{"$arg"} . "\n";
254		}
255	}
256
257	# Return our arguments
258	return $args;
259}
260