rgb has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I'm novice to perl. I have log from a device like this.

jan 15 20:08:05 Played: abc news URL: abc.com
jan 15 20:09:10 Stopped: abc news
jan 15 20:11:11 Played: Discovery URL: discovery.com
jan 15 20:15:33 Stopped: Discover
jan 15 20:15:28 Played: CNN URL:cnn.com
jan 15 20:20:12 Stopped: CNN
jan 15 20:21:54 Played: Discovery URL: discovery.com
jan 15 20:31:54 Stopped: Discovery

My requirement is to match for any played lines and extract time i.e.jan 15 20:08:05 and video title, i could easily do this by taking entire file in array and searching 'Played' string. But it doesn't end there, i also need to look for next immediate stopped time of that title and calculate the total duration of the playback.
e.g: playback time of "abc news 1m 05 sec"
Please help experts.

Replies are listed 'Best First'.
Re: report generation
by roboticus (Chancellor) on Jan 23, 2009 at 03:04 UTC
    rgb:

    We're not a code-writing service, so I'll assume you're asking for a general approach you can use to start building a program. So here goes:

    I'd suggest you create a hash, and when you see a movie start time, add it to the hash using the video title as the hash key. Then when you see a stopped tag, you can look up the start time from the hash and print the video title and duration and remove it from the hash.

    There would be two special cases you'll want to handle: (1) You may receive a Stopped message without a Played record. Just print a warning when this occurs. (You'll be able to detect it because the video isn't in the hash.) The other special case is when you reach the end of your file, and there are some videos that haven't received their Stopped message yet. Just scan through the hash and print appropriate messages as req'd.

    ...roboticus
      Special case 3: Receiving two "played" messages for the same video without a corresponding "stopped" message in between. (i.e., The inverse of special case 1.)

      If this is a legitimate case, then you may need to use a hash of arrays or other means of supporting multiple start times for a video, as well as a means of deciding which of the multiple start times a stop time should correspond to. If it is not legitimate, emitting a warning message should suffice.

Re: report generation
by monarch (Priest) on Jan 23, 2009 at 03:09 UTC
    Well you know one thing: a stopped time always comes after a start time.

    So create a hash, keyed by URL. As you scan each line add an entry to your hash with a key of URL and value of time. When you encounter a stopped line merely subtract the time from the current line from the time stored in the hash with the same key as the url of the current line.

    e.g. meta code:

    my %seen = (); # keyed by URL, contains times while ( <line> ) { if ( line =~ m/(date)(action)(URL)/ ) { if ( action == "played" ) { seen{URL} = date; } elsif ( action == "stopped" ) { duration = date - seen{URL}; print( "URL: duration" ); } } }

    I'll leave it as an exercise for the student to turn this meta-code into real Perl. You'll probably want to introduce more error checking too.

Re: report generation
by ELISHEVA (Prior) on Jan 23, 2009 at 05:55 UTC