summaryrefslogtreecommitdiffstats
path: root/scripts/centericq.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/centericq.pl')
-rw-r--r--scripts/centericq.pl342
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.");
+
+#######################################################################