diff options
Diffstat (limited to 'scripts/centericq.pl')
-rw-r--r-- | scripts/centericq.pl | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/scripts/centericq.pl b/scripts/centericq.pl new file mode 100644 index 0000000..9b80170 --- /dev/null +++ b/scripts/centericq.pl @@ -0,0 +1,342 @@ +# $Id: centericq.pl,v 1.0.0 2002/10/19 13:15:49 Garion Exp $ +use strict; +use vars qw($VERSION %IRSSI); +$VERSION = "1.0.0"; +%IRSSI = ( + authors => "Joost \"Garion\" Vunderink", + contact => "joost\@carnique.nl", + name => "centericq", + description => "Staturbar item which indicates how many new messages you have in your centericq", + sbitems => "centericq", + license => "Public Domain", + url => "http://irssi.org, http://scripts.irssi.org", +); + +# centericq new messages statusbar item +# for irssi 0.8.4 by Timo Sirainen +# +# This statusbar item checks whether you have unread messages in +# ~/.centericq/, and if so, displays a status in your statusbar. +# Example status: [ICQ: JamesOff-1,Linn-3,Paul-4] +# +# Use: +# /script load centericq +# /statusbar <name> add centericq +# +# Known bugs: +# - It only works for ICQ and MSN in centericq. +# - The refreshing is not optimal. You'll need to swap windows to make +# the statusbar item disappear if you've read the messages. +# - You have to reload the script if you add new people in centericq. +# - Works only with centericq in ~/.centericq/ +# +# TODO: +# - Use only the first N letters of the nickname instead of the full +# nickname. + +use Irssi; +use Irssi::TextUI; + +my $icqdir = $ENV{'HOME'} . "/.centericq"; +my ($last_refresh_time, $refresh_tag); +my $statusbar_item; + +# The following vars are all hashes with key the name of the dir in +# ~/.centericq/ of that person + +my %lastreads; # Timestamp of the last read message, per nick +my %numunreads; # Number of unread messages, per nick +my %historyts; # Timestamp of the history file of each nick +my %lastreadts; # Timestamp of the lastread file of each nick +my %friendnicks; # The nicknames of the friends + + +####################################################################### +# This is the function that will be called each N seconds, where +# N is given by the centericq_refresh_time setting. + +sub refresh_centericq { + check_new_friends(); + + my @friends = keys(%lastreads); + my ($friend, $changed) = ("", 0); + foreach $friend (@friends) { + if (history_changed($friend) || lastread_changed($friend)) { + $changed = 1; + update_status($friend); + } + } + + if ($changed) { + update_statusbar_item(); + } + + # Adding new timeout to make sure that this function will be called + # again + if ($refresh_tag) { + Irssi::timeout_remove($refresh_tag) + } + my $time = Irssi::settings_get_int('centericq_refresh_time'); + $refresh_tag = Irssi::timeout_add($time*1000, 'refresh_centericq', undef); +} + + +####################################################################### +# Checks if any new friends have been added. Not yet functional. + +sub check_new_friends { + #Irssi::print("Checking if there are any new friends..."); +} + +####################################################################### +# Checks if the last modified date/time of the lastread file has changed. +# A -lot- more efficient than reading and processing the whole file :) + +sub lastread_changed { + my ($friend) = @_; + + my $lr = get_lastread($friend); + if ($lr != $lastreads{$friend}) { + #Irssi::print("Lastread of $friendnick{$friend} changed from $lastreads{$friend} to $lr."); + $lastreads{$friend} = $lr; + return 1; + } + + return 0; +} + +####################################################################### +# Checks if the last modified date/time of the history file has changed. +# A -lot- more efficient than reading and processing the whole file :) + +sub history_changed { + my ($friend) = @_; + my $ts = get_historyts($friend); + if ($ts != $historyts{$friend}) { + #Irssi::print("History ts of $friendnick{$friend} changed from $historyts{$friend} to $ts."); + $historyts{$friend} = $ts; + return 1; + } + + return 0; +} + +####################################################################### +# Reads the last read message and determines the number of unread +# messages of $friend. + +sub update_status { + my ($friend) = @_; + $lastreads{$friend} = get_lastread($friend); + $numunreads{$friend} = get_numunreads($friend); +} + +####################################################################### +# Gets the number of unread messages of all nicks and puts them together +# in a nice statusbar string. +# It then requests a statusbar item redraw. + +sub update_statusbar_item { + #Irssi::print("Updating statusbaritem..."); + $statusbar_item = ""; + + my @keys = keys(%lastreads); + my ($key, $status); + + foreach $key(@keys) { + if ($numunreads{$key} > 0) { + #Irssi::print("$friendnick{$key} has $numunreads{$key} unreads."); + $status .= $friendnicks{$key} . "-" . $numunreads{$key} . ","; + } + } + $status =~ s/,$//; + if (length($status) > 0) { + $statusbar_item = "ICQ: " . $status; + Irssi::statusbar_items_redraw('centericq'); + } +} + + +####################################################################### +# This is the function called by irssi to obtain the statusbar item +# for centericq. + +sub centericq { + my ($item, $get_size_only) = @_; + + if (length($statusbar_item) == 0) { + # no icq - don't print the [ICQ] at all + if ($get_size_only) { + $item->{min_size} = $item->{max_size} = 0; + } + } else { + $item->default_handler($get_size_only, undef, $statusbar_item, 1); + } +} + +####################################################################### +# Initialization of the hashes with the useful data. + +sub init { + if (!opendir(ICQDIR, $icqdir)) { + Irssi::print("There is no directory $icqdir, which is needed for this script."); + return 0; + } + + my ($icqfriends, $msnfriends) = (0, 0); + while (my $filename = readdir(ICQDIR)) { + # ICQ friends + if ($filename =~ /^[0-9]+$/ && $filename !~ /^0$/) { + $icqfriends++; + init_friend($filename); + } + # MSN friends + if ($filename =~ /^m.+/ && $filename !~ /^modelist$/ ) { + $msnfriends++; + init_friend($filename); + } + } + Irssi::print("Watching $icqfriends ICQ friends and $msnfriends MSN friends."); + + closedir(ICQDIR); + return 1; +} + +####################################################################### +# Initialises all data of $friend + +sub init_friend { + my ($friend) = @_; + + $lastreads{$friend} = get_lastread($friend); + $numunreads{$friend} = get_numunreads($friend); + #$filesizes{$friend} = get_filesize($friend); + $friendnicks{$friend} = get_nickname($friend); + $historyts{$friend} = get_historyts($friend); + #Irssi::print("Initilialized $friendnick{$friend}."); +} + +####################################################################### +# Returns the last read message of $friend + +sub get_lastread { + my ($friend) = @_; + my $lastreadfile = $icqdir . "/" . $friend . "/lastread"; + + open(F, "<", $lastreadfile) || return 0; #die("Could not open $lastreadfile.");; + my $lastrd = <F>; + close(F); + chop($lastrd); + #Irssi::print("Found lastread $lastrd of $friend from $lastreadfile."); + + return $lastrd; +} + +####################################################################### +# Returns the number of unread messages for $friend + +sub get_numunreads { + my ($friend) = @_; + my $lr = $lastreads{$friend}; + # Unknown last read message - return 0. + if ($lr == 0) { + return 0; + } + + my $msgfile = $icqdir . "/" . $friend . "/history"; + open(F, "<", $msgfile) || return 0; #die("Could not open $msgfile."); + my @lines = <F>; + chop(@lines); + close(F); + + my $numlines = @lines; + + # read all lines up to the lastread message + my $line; + my $bla = 0; + do { + $line = shift(@lines); + $bla++; + } while ($line ne $lr); + + # now count the number of times that "MSG" is found on a line below + # a line with "IN" + my $count = 0; + my $incoming = 0; + my $verify = 0; + my $bli = 0; + + for (@lines) { + $bli++; + # Sometimes 2 messages get in at the same time. Remove this so-called + # new message if it has the same time as the last read message. + if ($verify == 1) { + if ($_ =~ /$lr/) { + $count--; + } + $verify = 0; + } + # A line with "IN" has been found; check if the next line is "MSG". + if ($incoming == 1) { + if ($_ =~ /^MSG/) { + $count++; + $verify = 1; + } + $incoming = 0; + } + # Check for "IN". + if ($_ =~ /^IN/) { + $incoming = 1; + } + } + + return $count; +} + +####################################################################### +# Returns the nickname of a friend. This is taken from the 46th line +# of the info file. Let's hope that centericq does not change its +# config file format. + +sub get_nickname { + my ($friend) = @_; + + my $infofile = $icqdir . "/" . $friend . "/info"; + open(F, "<", $infofile) || return $friend; #die("Could not open $msgfile."); + my @lines = <F>; + chop(@lines); + close(F); + + return $lines[45]; +} + +####################################################################### +# Returns the timestamp of the history file of $friend. + +sub get_historyts { + my ($friend) = @_; + my $histfile = $icqdir . "/" . $friend . "/history"; + my @stat = stat($histfile); + return $stat[9]; +} + +####################################################################### +# Adding stuff to irssi + +Irssi::settings_add_int('misc', 'centericq_refresh_time', 120); +#Irssi::settings_add_bool('misc', 'centericq_debug', 0); +Irssi::statusbar_item_register('centericq', '{sb $0-}', 'centericq'); + +####################################################################### +# Startup functions + +if (init() == 0) { + Irssi::print("You need centericq for this script."); + return 0; +} +update_statusbar_item(); +refresh_centericq(); + +Irssi::print("Centericq statusbar item loaded."); + +####################################################################### |