parent $mail_root parent $mail_list parent $user_interfaces object $mail_ui var $root child_index 0 var $root owners [$mail_ui] var $root owned [$mail_ui] var $root fertile 0 var $has_commands commands [["@m?ail * on *", 'mail_on_cmd], ["@mail-sub?scribe|@msub?scribe *", 'subscribe_cmd], ["@mail-unsub?scribe|@munsub?scribe *", 'unsubscribe_cmd], ["@mail-subscribed|@msubscribed", 'subscribed_cmd], ["@mail-r?ead|@mr?ead * on *", 'mail_read_cmd], ["@mail-rem?ove|@mrem?ove|@mrm * from|on *", 'mail_remove_cmd], ["@msend|@mmail * to *", 'send_note_cmd], ["@mail-lists", 'mail_lists_cmd]] var $has_commands shortcuts [["@m?ail", 'mail_on_cmd, ["@mail", "", "on", "me"]]] var $root inited 1 var $mail_ui subscribed #[] var $mail_list letters #[] var $mail_list letters_index #[] var $mail_list senders 1 var $mail_list readers [$core] var $mail_list notify [$mail_ui] var $mail_list last_letter 0 var $gendered gender $gender_neuter var $described prose #[] var $root manager $mail_ui var $root writable [$mail_ui] var $root readable ['parameters, 'methods, 'code] var $root dbref 'mail_ui var $old_command_environment verb_cache #[] var $old_command_environment command_cache [] var $old_command_environment shortcuts_cache [] var $named name ['prop, "Mail User Interface"] var $mail_list mail [] var $mail_ui current 0 method send_note_cmd arg cmd, note, prep, line; var subj, lists, list, x, mail; (> .perms(sender(), 'this) <); note = .match_env_nice(note); line = line.explode_english_list(); lists = []; for x in (line) { catch ~listnf { list = $mail_utils.match_mail_recipient(x); lists = [@lists, list]; } with handler { .tell(("The list \"" + x) + "\" is invalid."); } } if (!lists) { .tell("No valid lists are specified!"); return; } subj = .prompt("Subject: "); if (subj == "@abort") { .tell("Aborted."); return; } mail = $mail.new_mail(); mail.set_subject(subj); mail.set_text(note.text()); catch any { mail.send(@lists); } with handler { .tell((traceback()[1])[2]); } .tell("Mail sent."); . method mail_read_cmd arg cmd, rng, on, list; var mail, x, lname; (> .perms(sender(), 'this) <); list = $mail_utils.match_mail_recipient(list || "me"); .new_list(list); if (rng) { if (rng == "next") { if (!(current['location])) .tell("No next message."); else .read_mail(list.next(current['location])); return; } catch ~range { rng = $mail_utils.range_to_actual($parse.range(rng), current); } with handler { .tell((traceback()[1])[2]); return; } } mail = list.mail(); lname = list.mail_name(); if (rng) { for x in [rng[1] .. rng[2]] { if (x > listlen(mail)) break; .read_mail(mail[x], lname); } } else if (current['location]) { .read_mail(current['location], lname); } else { .tell(("List " + lname) + " has no mail on it."); } . method mail_remove_cmd arg cmd, rng, from, list; var mail, all_mail, x, name; (> .perms(sender(), 'this) <); list = $mail_utils.match_mail_recipient(list || "me"); .new_list(list); if (rng) { catch ~range { mail = (| $object.to_dbref(rng) |); if (!mail) { rng = $mail_utils.range_to_actual($parse.range(rng), current); all_mail = list.mail(); mail = []; for x in [rng[1] .. rng[2]] { if (x > listlen(all_mail)) break; mail = [@mail, all_mail[x]]; } } else { mail = [mail]; } } with handler { .tell((traceback()[1])[2]); return; } } for x in (mail) { catch ~perm { name = x.name(); list.del_mail(x); .tell(("Removed mail message " + name) + " from list."); } with handler { .tell((traceback()[1])[2]); } } . method read_mail arg mail, list_name; (> .perms(sender(), 'this) <); .tell(((("Message " + (mail.name())) + " on ") + list_name) + ":"); .tell(mail.format()); mail.did_read(); . method subscribed (> .perms(sender(), 'this) <); return subscribed; . method subscribed_cmd arg cmd; var l, line; (> .perms(sender(), 'this) <); for l in (subscribed.keys()) { if (l == this()) continue; line = (" " + (l.mail_name())) + " "; if ((l.last_received_on()) > (subscribed[l])) line = line + " (new mail)"; else line = line + " (no new mail)"; .tell(line); } . method unsubscribe_cmd arg com, str; var list, line, mname; (> .perms(sender(), 'this) <); list = .match_mail_recipient(str); if (list == this()) return .tell("You cannot unsubscribe yourself."); mname = .mail_name(listr); if (!(list in (subscribed.keys()))) return .tell("You are not subscribed to " + mname); .unsubscribe(list); .tell(("Successfully unsubscribed from" + mname) + "."); . method subscribe_cmd arg cmd, str; var list, mname; (> .perms(sender(), 'this) <); list = $mail_utils.match_mail_recipient(str); mname = $mail_utils.mail_name(list); if (list in (subscribed.keys())) return .tell(("You are already subscribed to " + mname) + "."); if (!(list.list_is_readable_by(this()))) return .tell(mname + " is not subscribeable by you."); .subscribe(list); .tell(("Successfully subscribed to " + mname) + "."); . method subscribe arg list; (> .perms(sender(), 'this) <); subscribed = subscribed.add(list, time()); . method unsubscribe arg list; (> .perms(sender(), 'this) <); subscribed = subscribed.del(list); . method mail_lists_cmd arg cmd; var l, line; (> .perms(sender(), 'this) <); for l in (($mail_db.database()).values()) { line = ""; if (l.list_is_readable_by(this())) line = "[Readable]"; if (l.list_is_sendable_by(this())) line = ("[Sendable]" + (line ? " " | "")) + line; .tell((pad(l.mail_name(), ((.linelen()) - strlen(line)) - 1) + " ") + line); } . method new_list arg list; (> .perms(sender(), 'this) <); if (list in (subscribed.keys())) subscribed = subscribed.add(list, time()); current = #[['location, list.start()], ['list, list]]; . method init_mail_ui (> .perms(caller(), $root) <); subscribed = #[[this(), time()]]; .new_list(this()); . method mail_on_cmd arg cmd, rng, on, list; var syn, r, all_mail, mail, x, line; (> .perms(sender(), 'this) <); syn = cmd + " [<range> on <mail list>]"; catch any { list = $mail_utils.match_mail_recipient(list); if (list != (current['list])) .new_list(list); all_mail = (current['list]).mail(); if (!all_mail) { .tell(("No mail on " + ($mail_utils.mail_name(list))) + "."); return; } if (!rng) { r = [1, listlen(all_mail)]; rng = r; } else { rng = $parse.range(rng); r = $mail_utils.range_to_actual(rng, current); } } with handler { switch (error()) { case ~listnf, ~range: .tell((traceback()[1])[2]); default: rethrow(error()); } return; } line = "Mail"; if ((r[1]) != (r[2])) line = (((line + " from ") + tostr(rng[1])) + " to ") + tostr(rng[2]); line = ((line + " on ") + ($mail_utils.mail_name(current['list]))) + ":"; .tell(line); for x in [r[1] .. r[2]] { mail = all_mail[x]; line = (mail == (current['location])) ? "=>" | " "; line = (line + pad(tostr(x), -3)) + ":"; line = (line + ((mail.has_read(this())) ? " " | "!")) + " "; line = (line + pad(mail.subject(), (.linelen()) - 38)) + " "; line = (line + pad((mail.from()).name(), 19)) + " "; line = line + pad($time.ldate(mail.time(), 'date), 9); .tell(line); } .tell("------"); .