Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
It's like we need to hold workshops on how to write well-formatted Perl... Less is more. You need less parenthesis, shorter synonyms, and more strategic use of whitespace. Also, a two-space tab indent.

Did you know you're popping off the first line of the filehandle before the while loop?

Adbot
ADBOT LOVES YOU

LightI3ulb
Oct 28, 2006

Standard pleasure model.
syntax error at ipcsv.pl line 27, near "$csvfile ("
syntax error at ipcsv.pl line 30, near ""$csv_dir$csvfile";"
syntax error at ipcsv.pl line 35, near "$logfile ("
syntax error at ipcsv.pl line 38, near "<$log>;"
syntax error at ipcsv.pl line 51, near "}"
syntax error at ipcsv.pl line 54, near "}"
Execution of ipcsv.pl aborted due to compilation errors.

LightI3ulb
Oct 28, 2006

Standard pleasure model.

Triple Tech posted:

It's like we need to hold workshops on how to write well-formatted Perl... Less is more. You need less parenthesis, shorter synonyms, and more strategic use of whitespace. Also, a two-space tab indent.

Did you know you're popping off the first line of the filehandle before the while loop?

Yes, the first line of the file is the headers, which I don't want.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Among a bunch of other things, you should concatenate with a period (.) not a comma (,) so the first I'm going to say is to replace:

open $out, ">", "$log_dir$csvfile";

with: open $out, ">" . "$log_dir$csvfile";

if not: open $out, ">$log_dir$csvfile";

or even better: open($out, '>' . $log_dir . $csvfile);

Couple of suggestions:

1. As has been said use strict; though I generally use #!/usr/bin/perl -w instead of use warnings; thought that's all a matter of taste.

2. If you're declaring variables as the same value (in this case, undefined), you can declare them like my ($foo, $bar, $baz) = 'whatever'; or just my ($foo, $bar, $baz);

3. Also, another useful thing to use for getting a file list is glob() so instead of
code:
opendir $csvdir, $csv_dir;
my @csvfiles = grep {!/^\./} readdir $csvdir;
closedir $csvdir;

opendir $logdir, $log_dir;
my @logfiles = grep {!/^\./} readdir $logdir;
closedir $logdir;
you could have
code:
my @csvfiles = glob("$csv_dir/*");
my @logfiles = glob("$log_dir/*");
It doesn't scale too well once you get into several hundred files, but it is very useful.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!

Fenderbender posted:

Among a bunch of other things, you should concatenate with a period (.) not a comma (,) so the first I'm going to say is to replace:

open $out, ">", "$log_dir$csvfile";

with: open $out, ">" . "$log_dir$csvfile";

if not: open $out, ">$log_dir$csvfile";

or even better: open($out, '>' . $log_dir . $csvfile);

I'd suggest the very opposite! The way he already has it is perfect. Separating the mode from the filename is a really good idea. What if his filename started with a >? Or any other character the mode parser looks for. Concatenation versus interpolation is really a preference thing - Perl transforms interpolation to concatenation in the compile phase.



The error is here:

foreach (my $csvfile (@csvfiles)){

The correct syntax is:

foreach my $csvfile (@csvfiles) {

LightI3ulb
Oct 28, 2006

Standard pleasure model.
Wow.

:suicide:

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

LightI3ulb posted:

Yes, the first line of the file is the headers, which I don't want.

It should be annotated as such for clarity and great justice.

code:
my $line;

# discarding the header line
$line = <$fh>;

while ($line = <$fh> ) {
...

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Just because I get some sick joy out of reformatting and condensing code, I took a swing (not that I've tested it, just really reformatted and changed a few things). Do not take this as a lesson in how to write code, this is more for me than it is for you, but it can give you some idea of how it can be done differently. Perl has a lot of stylistic measures that are purely preferential so don't think you're doing something wrong because I'm doing something slightly different. I agree with Triple Tech that we need to write a style guide.

code:
#!/usr/bin/perl -w

use strict;

use Data::Dumper;

my (@csva, @loga);
my ($csvdir, $logdir);
my ($csv_fh, $log_fh);
my ($csvline, $logline);
my ($csv, $log);
my $out

my $csv_dir = "/home/jnooraga/csvdir/";
my $log_dir = "/home/jnooraga/csvdir/logs/";

my @csvfiles = glob("$csv_dir*");
my @logfiles = glob("$log_dir*");

foreach my $csvfile (@csvfiles) {
    next if (-d "$csv_dir$csvfile");

    open($out, '>' . $log_dir . $csvfile);
    open($csv, '<' . $csv_dir . $csvfile);

    $csvline = <$csv>;

    while ($csvline = <$csv>) {
        chomp($csvline);

        @csva = split(',', $csvline);

        foreach my $logfile (@logfiles) {
            next if (-d "$log_dir$logfile");

            open($log, '<' . $log_dir . $logfile);
            my $logline = <$log>;

            while ($logline = <$log>) {
                @loga = split(',', $logline);

                if ($loga[0] eq $csva[2]){
                    for (my $j=0;$j<scalar(@csva);$j++){
                        print $out $csva[$j] . ',';
                    }
                    print $out '"' . $loga[13] . "\"\n";
                }
            }

            close $log;
        }
    }

    close $csv;
    close $out;
}
Just remember that there are a lot of little things you can do to make your code more readable, and in some cases can help clarify for the compiler.

Fenderbender fucked around with this message at 15:16 on May 14, 2008

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

Fenderbender posted:

Just because I get some sick joy out of reformatting and condensing code...

I see you and I raise you. Untested. Main problems (with the original code) include not knowing interpolation/parsing tricks and excessive scope.

code:
#!/usr/bin/perl -w
use strict;

use Data::[b][/b]Dumper;

my $csv_dir = "/home/jnooraga/csvdir/";
my $log_dir = "/home/jnooraga/csvdir/logs/";

my @csvfiles = glob("$csv_dir*");
my @logfiles = glob("$log_dir*");

for my $csvfile (@csvfiles) {
    next if -d "$csv_dir$csvfile";

    open my($out), ">$log_dir$csvfile";
    open my($csv), "<$csv_dir$csvfile";

    my $line = <$csv>; # shift off the first line containing headers
    while ($line = <$csv>) {
        chomp $line;

        my @csva = split ',', $line;

        for my $logfile (@logfiles) {
            next if -d "$log_dir$logfile";

            open my($log), "<$log_dir$logfile";

            my $logline = <$log>; # shift off the first line containing headers
            while ($logline = <$log>) {
                my @loga = split ',', $logline;

                my $concept1 = $loga[0];
		my $concept2 = $csva[2];
		my $concept3 = $loga[13];

                if ($concept1 eq $concept2){
		    print $out "$_," for @csva;
                    print $out qq!"$concept3"\n!;
                }
            }
        }
    }
}

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

I see you and I raise you. Untested. Main problems (with the original code) include not knowing interpolation/parsing tricks and excessive scope.

Though you condense the code, there is an amount of readability lost. If you're going for less lines, I think this would save you a few.

code:
            my $logline = <$log>; # shift off the first line containing headers
            while ($logline = <$log>) {
                my @loga = split ',', $logline;

                if ($log[0] eq $csva[2]){
		    print $out "$_," for @csva;
                    print $out qq~"$loga[13]"\n~;
                }
            }

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

Fenderbender posted:

Though you condense the code, there is an amount of readability lost. If you're going for less lines, I think this would save you a few.

code:
            my $logline = <$log>; # shift off the first line containing headers
            while ($logline = <$log>) {
                my @loga = split ',', $logline;

                if ($log[0] eq $csva[2]){
		    print $out "$_," for @csva;
                    print $out qq~"$loga[13]"\n~;
                }
            }

I disagree, actually. I find that as a seasoned Perl guy (and not someone who just uses Perl on the side), less is more. I'm not saying it's a golfing contest. Clearly, I would have lost some strokes (and performance) by introducing those concept scalars. But the way the OP wrote it, those scalars tell you nothing of what business logic is going on. And poo poo like this always bubbles up and turns into maintenance nightmares.

My heuristic is as follows
* Write code the way it speaks to you in your head, with maximum inclusion of business concepts
* When possible, take away excessive punctuation/parenthesis
** If this rule introduces ANY sort of confusion or disambiguity, introduce punctuation and parenthesis tastefully

Obviously that last part will depend on the programmer, but I think shorter code is much more powerful and easier to understand than long code. Long code doesn't automatically mean good code.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

I disagree, actually. I find that as a seasoned Perl guy (and not someone who just uses Perl on the side), less is more. I'm not saying it's a golfing contest. Clearly, I would have lost some strokes (and performance) by introducing those concept scalars. But the way the OP wrote it, those scalars tell you nothing of what business logic is going on. And poo poo like this always bubbles up and turns into maintenance nightmares.

My heuristic is as follows
* Write code the way it speaks to you in your head, with maximum inclusion of business concepts
* When possible, take away excessive punctuation/parenthesis
** If this rule introduces ANY sort of confusion or disambiguity, introduce punctuation and parenthesis tastefully

Obviously that last part will depend on the programmer, but I think shorter code is much more powerful and easier to understand than long code. Long code doesn't automatically mean good code.

Oh, I agree. That is pretty much what goes on in my head as I'm coding. I just see far too often people that have tried to do too much on one line that can be handled more concisely. I completely agree that your way is more concise, I guess I misunderstood what you were attempting to go for.

For example, just a few minutes ago I was able to bring 7 lines of someone else's code down to just 3 with a simple

open($fh_conf, $conf_file) or die "Couldn't open file $conf_file: $!\n";
my $conf_vars = { map { chomp;split('|') } <$fh_conf> };
close($fh_conf);


and lost little readability. I think we're mostly agreeing in different ways.

Erasmus Darwin
Mar 6, 2001

Triple Tech posted:


code:
my $csv_dir = "/home/jnooraga/csvdir/";
my $log_dir = "/home/jnooraga/csvdir/logs/";

my @csvfiles = glob("$csv_dir*");
my @logfiles = glob("$log_dir*");

I've got one minor quibble with this. I personally prefer moving the last / to when $csv_dir and $log_dir are used rather than sticking it in the config string:

code:
my $csv_dir = "/home/jnooraga/csvdir";
my $log_dir = "/home/jnooraga/csvdir/logs";

my @csvfiles = glob("$csv_dir/*");
my @logfiles = glob("$log_dir/*");
1) Invocations have a more natural looking "$dir/$file" style to them which mimics what they really are.
2) If someone changes the directories (especially if you were to move their definition to a config file or something), they won't shoot themselves in the foot regardless of whether or not they include a final slash (since an extra slash gets ignored but a missing slash causes everything to break).

Yes, I've put way, way too much thought into this.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Erasmus Darwin posted:

I've got one minor quibble with this. I personally prefer moving the last / to when $csv_dir and $log_dir are used rather than sticking it in the config string:

code:
my $csv_dir = "/home/jnooraga/csvdir";
my $log_dir = "/home/jnooraga/csvdir/logs";

my @csvfiles = glob("$csv_dir/*");
my @logfiles = glob("$log_dir/*");
1) Invocations have a more natural looking "$dir/$file" style to them which mimics what they really are.
2) If someone changes the directories (especially if you were to move their definition to a config file or something), they won't shoot themselves in the foot regardless of whether or not they include a final slash (since an extra slash gets ignored but a missing slash causes everything to break).

Yes, I've put way, way too much thought into this.

Once again, I completely agree, I was more trying to reformat and clean than change values. I think I might start a Perl style guide thread in the next couple of days based on some of the stuff I've seen in this thread, if anybody would like that.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
YAPC::Asia is streaming their talks at http://live.yapcasia.org/. Right now I'm listening to Ingy talk about pQuery. The schedule of talks will also be useful.

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled
I have a question regarding basic IO::Socket usage. We use these card printers at my work and I'd like to automate some of our repetitive card-printing tasks with perl. From perl, I'm able to connect to the card printer and send commands, and they work. I have not been able to receive the responses from the printer, which I'd like to figure out. Here is my code currently:
code:
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $command = "!CC"; # get number of cards printed
my $printer_ip = "10.1.245.25";

# connect to card printer
my $socket = IO::Socket::INET->new(
   PeerAddr => $printer_ip,
   PeerPort => 9100,
) || die "Could not connect to $printer_ip\:9100 : $!\n";

# send command
print $socket "\e$command\r\n";

# read and echo the response
my $resp = <$socket>;
print $resp;
If I change $command to the "print a test card" command, the test card will indeed print. But regardless of the command I never get a response. Any ideas?

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Cock Democracy posted:

If I change $command to the "print a test card" command, the test card will indeed print. But regardless of the command I never get a response. Any ideas?

Do the responses have a terminating newline? Can you run something like wireshark and see what's actually going over the wire?

ANAmal.net
Mar 2, 2002


100% digital native web developer
EDIT: gently caress, never mind, I just noticed that this question was answered at the top of the page.

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled

ShoulderDaemon posted:

Do the responses have a terminating newline? Can you run something like wireshark and see what's actually going over the wire?

Not quite sure what's going on here... after I make the initial connection, it looks like the printer is trying to open a new connection with me every second or so.

Only registered members can see post attachments!

Cock Democracy fucked around with this message at 02:02 on May 20, 2008

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
The angle brackets read until they find $/, which is usually set to \n. Your best bet is to keep calling getc and passing it to ord() so you can see what the printer is returning (untested):
code:
# disable output buffering on STDOUT
use IO::Handle;
*STDOUT->autoflush;

while (1) {
  my $char = $socket->getc();
  printf '%s (%d) ', $char, ord($char);
}
That'll give you a better idea of how the printer answers queries and should point you in the right direction...

more falafel please
Feb 26, 2005

forums poster

Cock Democracy posted:

Not quite sure what's going on here... after I make the initial connection, it looks like the printer is trying to open a new connection with me every second or so.

Maybe the printer isn't trying to use your socket, but instead connect back? This may require you to keep a listening socket open to accept connections from the printer after the command has been sent.

edit: ok, I'll be honest, I didn't actually look at the screenshot, so ignore that.

more falafel please fucked around with this message at 16:43 on May 20, 2008

npe
Oct 15, 2004
I don't think you're reading that right, it's not trying to create new connections, those are just ACK's on the existing connection.

[Edit: forget this, it's just the window update and dupe acks...]

What's happening is, you're initiating the connection, sending a segment with 6 bytes of data, which the printer responds to with 7 empty segments before you finally terminate the connection from the client end (the FIN).

In short, it's just not sending you anything back. The next step for you would be to look at the contents of the segment with the 6 bytes and see if you're actually transmitting what you should be. Having all of those duplicate ACK segments makes me wonder if there's something sketchy on the printer end of things, but first find out if you're sending the right data.

npe fucked around with this message at 16:15 on May 20, 2008

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled

yaoi prophet posted:

In short, it's just not sending you anything back. The next step for you would be to look at the contents of the segment with the 6 bytes and see if you're actually transmitting what you should be. Having all of those duplicate ACK segments makes me wonder if there's something sketchy on the printer end of things, but first find out if you're sending the right data.
This was the problem.

Once I found the "Follow TCP stream" feature in Wireshark and viewed the stream in hex, I quickly realized I was not sending commands in the proper format. Weird that it would perform the commands and just not respond in that situation, but whatever, it's working now.

Thanks for the help.

Stabby McDamage
Dec 11, 2005

Doctor Rope
I have a large file (>4GB), and when I do a tell() on it, I get negative values since I'm on a 32-bit Linux. Is there a way to use 64-bit file offsets in Perl without installing a 64-bit OS or recompiling the binary?

Stabby McDamage fucked around with this message at 15:40 on May 22, 2008

ashgromnies
Jun 19, 2004
Okay, I've been pounding my head against this for like an hour and I don't know what I'm doing wrong.

I'm trying to use SOAP::Lite to create a SOAP formatted response, that needs to contain a relatively simple series of elements.

Basically, there needs to be a status and then an element named history, which is an array of elements named pointHistory that are of type PointHistory. Yeah, making the names and types so similar is confusing.

Here's an example of what it should look like:

XML for example, not SOAP but you get the point...
code:
<getPointHistoryResponse>
	<status>1</status>
	<history>
		<pointHistory>
			<description>description 1</description>
			<date>2008-01-02 23:45:00</date>
			<points>200</points>
		</pointHistory>
		<pointHistory>
			<description>description 2</description>
			<date>2008-01-03 23:44:01</date>
			<points>250</points>
		</pointHistory>
	</history>
</getPointHistoryResponse>
(element names don't need to be EXACT since the client side hasn't been finalized yet)

Here's what I'm getting back right now:

code:
		<namesp1:pointHistoryResponse xmlns:namesp1="http://myns.com">
			<status xsi:type="xsd:int">1</status>
			<history xsi:type="tns1:ArrayOfPointHistory">
				<description xsi:type="xsd:string">description 1</description>
				<date xsi:type="xsd:string">10-03-06</date>
				<points xsi:type="xsd:int">100</points>
				<description xsi:type="xsd:string">description 2</description>
				<date xsi:type="xsd:string">10-03-06</date>
				<points xsi:type="xsd:int">100</points>
			</history>
		</namesp1:pointHistoryResponse>
As you can see, the histories aren't getting wrapped up in a container element correctly.

Here is the pertinent part of my WSDL:

code:
            <element name="pointHistory">
                <complexType>
                    <sequence>
                        <element name="swid" type="xsd:string"/>
                    </sequence>
                </complexType>
            </element>

            <complexType name="PointHistory">
                <sequence>
                    <element name="description" type="xsd:string"/>
                    <element name="date" type="xsd:string"/>
                    <element name="points" type="xsd:int"/>
                </sequence>
            </complexType>

            <complexType name="ArrayOfPointHistory">
                <complexContent>
                    <restriction base="soapenc:Array">
                        <attribute ref="soapenc:arrayType"
                        wsdl:arrayType="tns1:PointHistory[]"/>
                    </restriction>
                </complexContent>
            </complexType>


            <element name="pointHistoryResponse">
                <complexType>
                    <sequence>
                        <element name="history" type="tns1:ArrayOfPointHistory"/>
                        <element name="status" type="xsd:int"/>
                    </sequence>
                </complexType>
            </element>
And here's the perl code used to generate it:

code:
        my @credit_arr;
        foreach my $credit(@$history){
            my $elem = SOAP::Data->value(
                SOAP::Data->name('pointHistory' =>
                    SOAP::Data->name('description' => $credit->{description})->type('xsd:string'),
                    SOAP::Data->name('date' => $credit->{credit_date})->type('xsd:string'),
                    SOAP::Data->name('points' => $credit->{point_value})->type('xsd:int')
                )
            )->type('tns1:PointHistory');
            push @credit_arr,$elem;
        }

        $soap_return = SOAP::Data->value(
                            SOAP::Data->name('status' => 1)->type('xsd:int'),
                            SOAP::Data->name("history" => \SOAP::Data->value(
                                              SOAP::Data->name("pointHistory" => @credit_arr)
                                                        ->type("tns1:PointHistory"))
                                                   )->type("tns1:ArrayOfPointHistory"),
                      )->attr({xmlns => 'http://myns.com'})->uri('myns.com')->type('pointHistoryResponse');
I honestly have no idea where to go with this now :( I figured that wrapping the description, date, and points with the SOAP::Data->name('pointHistory') object would do it but apparently not. I also have a poor grasp of how SOAP::Data works since this is my first try at using it... what a pain.

<deleted user>

ashgromnies posted:

code:
SOAP::Data->name("pointHistory" => @credit_arr)

I'm in a rush and not familiar with SOAP or this module, so sorry for posting, but two things to check....

1) $elem may not be getting what you think (list of individual nodes), and you're dumping that here via list context. How about using the SOAP::Data->name('thing')->value(); form instead?

2) I think you are wanting to supply SOAP::Data->name("history") with a list of "pointHistory" nodes, but it looks like you are supplying just one with @credit_arr as its value/children.

Either way, bust out Data::Dumper, check out what is going into $elem & @credit_arr and have a look at the SOAP::Lite source and make sure those methods expect/return what you expect. I only glanced, but the docs seem to suck.

ashgromnies
Jun 19, 2004

genericadmin posted:

1) $elem may not be getting what you think (list of individual nodes), and you're dumping that here via list context. How about using the SOAP::Data->name('thing')->value(); form instead?


It does seem to be getting what I want, it even shows it being enclosed in an element named pointHistory. Making that change didn't affect the results.


genericadmin posted:

2) I think you are wanting to supply SOAP::Data->name("history") with a list of "pointHistory" nodes, but it looks like you are supplying just one with @credit_arr as its value/children.


@credit_arr is an array of PointHistory nodes when I Data::Dumper it.

genericadmin posted:

Either way, bust out Data::Dumper, check out what is going into $elem & @credit_arr and have a look at the SOAP::Lite source and make sure those methods expect/return what you expect. I only glanced, but the docs seem to suck.

Yep, the docs are pretty bad. I have access to the O'Reilly bookshelf and all the books there that reference SOAP::Lite have like two pages where they make a Hello World example and then say, "Have fun!"


EDIT: Ah, fixed it! I needed to replace $elem with:

code:
        my @credit_arr;
        foreach my $credit(@$history){
            my $elem = SOAP::Data->name('pointHistory')->type('tns1:PointHistory')->value(
                    \SOAP::Data->value(
                        SOAP::Data->name('description' => $credit->{description})->type('xsd:string'),
                        SOAP::Data->name('date' => $credit->{credit_date})->type('xsd:string'),
                        SOAP::Data->name('points' => $credit->{point_value})->type('xsd:int')
                    )
            );
            push @credit_arr,$elem;
Surprisingly, I found the answer in "Amazon Hacks" that had a section labeled "Program AWS with SOAP::Lite and Perl". It didn't work after I followed what you said in your first solution because I put the type('tns1:PointHistory') AFTER the value, and I guess it didn't like that.

ashgromnies fucked around with this message at 15:31 on May 23, 2008

LightI3ulb
Oct 28, 2006

Standard pleasure model.
Does anyone know of any modules that would allow me to receive mail and work with the attachments? The ones I've found on google are typically just for sending.

LightI3ulb
Oct 28, 2006

Standard pleasure model.
Does anyone know of any modules that would allow me to receive mail and work with the attachments? The ones I've found on google are typically just for sending.

heeen
May 14, 2005

CAT NEVER STOPS
code:
SOAP::Data->name("pointHistory" => @credit_arr)
Even without knowing the package, this looks highly suspicious. sub parameters get coerced into flat arrays, which would lead to the following parameters passed to the sub:
code:
@_=("pointHistory", $credit_arr[0],  $credit_arr[1],  $credit_arr[2], ...)
which I'm quite certain the sub can't handle correctly. How does the sub know how many parameter elements belong to pointHistory and where the next hash key begins?
What the sub probably expects is:
code:
SOAP::Data->name("pointHistory" => \@credit_arr)
which it then can turn into a hash again.

heeen
May 14, 2005

CAT NEVER STOPS

LightI3ulb posted:

Does anyone know of any modules that would allow me to receive mail and work with the attachments? The ones I've found on google are typically just for sending.

How do you define "receiving"? opening a port and listening to it? You're better off with letting a proper mail demon handling the receiving and a perl module reading a mbox file or Maildir frequently.

<deleted user>

LightI3ulb posted:

Does anyone know of any modules that would allow me to receive mail and work with the attachments? The ones I've found on google are typically just for sending.

Are you talking about a module to interface POP3 or IMAP protocol to access mail attachments? Sending mail is SMTP, storage and access of mail are other animals in a different part of the zoo.

LightI3ulb
Oct 28, 2006

Standard pleasure model.
I want to be able to access my mailbox, download the email message with the attachment (which I think will be CSV), and then use the CSV like a normal file.

Ninja Rope
Oct 22, 2005

Wee.

LightI3ulb posted:

Does anyone know of any modules that would allow me to receive mail and work with the attachments? The ones I've found on google are typically just for sending.

search.cpan.org is a much better resource for finding modules than any other search engine.

If you search there for "pop3", there are a bunch of modules returned. I've used Mail::POP3 client before and it worked alright. I ended up using one of the MIME modules to decode and process attachments, but I don't remember what or how I did it. I'm sure there are similar modules for IMAP.

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Net::IMAP::Simple makes IMAP access really easy, if your mail server speaks it. To parse the emails once you've gotten them, install MIME::Tools, and then:

code:
use MIME::Parser;
my $parser = MIME::Parser->new;
my $email = $parser->parse_data($email_text);

for my $part ($email->parts) {
  my $filename = $part->head->recommended_filename;
  my $mime_type = $part->head->mime_type;

  do_something($filename, $mime_type, $part->bodyhandle->as_string)
  if wanted($filename) or interesting($mime_type);
}

Mario Incandenza fucked around with this message at 08:24 on May 24, 2008

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Is anyone else going to be at YAPC::NA in Chicago next month?

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

Sartak posted:

Is anyone else going to be at YAPC::NA in Chicago next month?

The plan is to ask my boss^2 for clearance... Worst case scenario, I take those days off as vacation.

For some reason I'm feeling a little ehh about it... Is YAPC really that fun/worth it?

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!

Triple Tech posted:

For some reason I'm feeling a little ehh about it... Is YAPC really that fun/worth it?

It'll be my first YAPC, so I can't say for sure. But I am very excited about it. There are so many talks I want to see and people I want to meet. You should definitely come by. It's only $100. I think you'll get your money's worth.

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Wow, that looks awesome. Make sure you go see Adam Kennedy, his talks at YAPC::AU are entertaining and informative.

Adbot
ADBOT LOVES YOU

leedo
Nov 28, 2000

I'm going to be there on and off throughout. My work isn't paying for it so I am taking a few half days to see the talks I am interested in.

  • Locked thread