Skip to content

Instantly share code, notes, and snippets.

@LizardLeliel
Last active February 5, 2016 02:23
Show Gist options
  • Save LizardLeliel/bb2cc230a30b3405f850 to your computer and use it in GitHub Desktop.
Save LizardLeliel/bb2cc230a30b3405f850 to your computer and use it in GitHub Desktop.
muf code, for implementing a very functional @mail command to handle reading, sending, and deleting mail. Some parts aren't mine, but are used with permission. Other then that, most of this is my work.
(newmailsend.muf)
$include #3 (ansilib.muf)
$include #6 (Useful.muf)
( words appearing in this program in order:
greenline - pushes a greenline onto the stack.
usage - notifies the caller the basic commands.
usage2 - notifies the caller some more advanced commands.
sendusage - If a string is on the stack, it'll notify it to
the user (its assumed the string is an error message).
it will then say how to use the @mail/send command.
intarraytostring - Converts an array of integers or an array of strings
representign integers into a string with those integers
seperated by spaces. delete/deleteall/clean uses
this function.
printmail - Prints a message to the user, whether its for a preview
of a message s/he's about to send or s/he is reading
his/her inbox.
printinbox - Prints the caller's inbox.
sendmail - Sends a message to one or more users. Takes three arguments.
its arguments are prepared by preparemail.
preparemail - Takes the command line argument from the user, parses them,
and places appriopriate data on the stack to be used by
sendmail. It will also notify if the user is using the
command wrong if it finds an error while intrepreting
the command line arguement.
readmail - Takes a string of integers, prints the corresponding
inbox mail to the caller's screen. Will also make sure
each integer is appriopriate and tell the user if not,
and if the string is empty will tell the user how to use
@mail/read breifly.
getinbox - Pushes an array of timestamps to the stack.
unreadmessages - Pushes an array of strings representing numbers. The
numbers represent what numbers the user would need to
type in read/delete/etc. to use the command on all
messages which are marked as read. They are as a string
representing a number instead of a number themselves
to work with array_diff and the fact that using explode_array
on user input splits the input into strings instead of
integers.
deletemessages - Takes a string of mail indices seperated by space, and deletes
each. It will tell if a number is invalid as well as say
how many mails are unread before it asks the user if s/he's
sure. It will also say which numbers are invalid as its
deleting. Also: it will delete the mail from newest to oldest,
regardless of the order the user inputted the numbers.
This is so the correct mail will be deleted.
unreadmail - Similar to deletemessages, but does not ask the user if s/he's
sure, does not say which mail he's going to unread are
already unread, and lastly it marks mail as unread instead
of delete.
generateallmailindices - Like unreadmessages, but instead the array contains
every mail index represented as a string-integer.
it is used in deleteall/deleteunread.
clean - Pushes a string representing what a user would input if
they wanted to apply read/delete etc. to every /read/
message, then calls delete with that string as its
argument.
deleteall - Similar above, except the string pushed for delete representes
every message except for the ones the users wanted to exclude.
Most of these words also tell how many messages were sent/read/etc.
succesfully.
)
: greenline ( -- s)
"^[o^[g-------------------------------------------------------------------------------"
;
: usage ( -- )
greenline tellme
"^[o^[yTo send a mail:" tellme
"^[o^[c@mail recipient(s)=Title of Mail/Message" tellme
"^[o^[rOR" tellme
"^[o^[c@mail/send recipient(s)=Title of Mail/Message" tellme
"\n" tellme
"^[o^[yTo view your inbox:" tellme
{ "^[o^[c@mail/read ^[o^[rOR ^[o^[c@mail/delete ^[o^[rOR"
" ^[o^[c@mail ^[o^[g(without anything after either command)" }cat tellme
"\n" tellme
"^[o^[yTo read a message:" tellme
"^[o^[c@mail/read message_number(s)" tellme
"\n" tellme
"^[o^[yTo delete a message:" tellme
"^[o^[c@mail/delete message_number(s)" tellme
"\n" tellme
{
"^[o^[gTo send the same message to multiple people, separate the"
" recipient names with spaces in the recipient(s) field of @mail."
}cat tellme
"\n" tellme
{
"^[o^[gTo read or delete one more message at a time, separate the"
" message numbers with spaces in @mail/read or @mail/delete."
}cat tellme
"\n" tellme
{
"^[o^[gYou can use %r for new lines or %t for tabs when writing"
" a message to send."
}cat tellme
"\n" tellme
"^[o^[gFor more info, type: ^[o^[c@mail/help2" tellme
greenline tellme
;
: usage2 ( -- )
greenline tellme
"^[o^[yTo mark mark any mail as \"new\"/unread:" tellme
"^[o^[c@mail/unread message_number(s)" tellme
"\n" tellme
"^[o^[yTo delete every message that is not \"new\":" tellme
"^[o^[c@mail/clean" tellme
"\n" tellme
"^[o^[yTo delete every message in your inbox:" tellme
"^[o^[c@mail/deleteall message_number(s)_to_exclude" tellme
"\n" tellme
{
"^[o^[gTo unread one more message at a time, separate the"
" message numbers with spaces in @mail/unread."
}cat tellme
"\n" tellme
{
"^[o^[gWhen using @mail/deleteall, you can type numbers which are"
" separated by space to"
" the right of the command before pressing enter to save those"
" messages from being deleted. For example:"
" ^[o^[c@mail/deleteall 1 3"
" ^[o^[gWill delete every message but the first and"
" third oldest message in your inbox."
}cat tellme
greenline tellme
;
: sendusage
dup string? if tellme then
{
"^[o^[yUsage:\n"
"^[o^[c@mail recipient(s)=Title/Message\n"
"^[o^[yIn the message, you may use %r for new lines, %t for"
" tabs.\n"
"^[o^[yYou can send the same message to multiple people by"
" separating their names with spaces in the recipient(s)"
" field."
}cat tellme
;
( EXAMPLE: { 1 3 5 }array -> "1 4 5" )
: intarraytostring (array-of-ints -- string-of-ints)
var returnstring
"" returnstring !
foreach swap pop
intostr " " strcat
returnstring @
swap strcat returnstring !
repeat
returnstring @ strip
;
: printmail (time sender recipients title message -- )
var receivers
var sender
var title
var message
var paragraph
var decision
var time
message ! title ! receivers ! sender ! time !
"^[o^[g-------------------------------------------------------------------------------" tellme
{ "^[o^[yTitle:^[w " title @ }cat tellme
{ "^[o^[yFrom:^[w " sender @ }cat tellme
{ "^[o^[yTo:^[w " receivers @ }cat tellme
{ "^[o^[yDate:^[w %a %b %e, %Y, %T %Z" time @ timefmt }cat tellme
message @ foreach swap pop paragraph !
paragraph @ tellme
repeat
"^[o^[g-------------------------------------------------------------------------------" tellme
;
: printinbox
var mail
var count
var maillist (move to global?)
me @ "~page/newmail/" array_get_propdirs 0 array_sort maillist !
"^[o^[g-------------------------------------------------------------------------------" tellme
"^[o^[g| ### | ^[cFrom: ^[g| ^[cTitle ^[g| ^[cNew ^[g|" tellme
"^[o^[g-------------------------------------------------------------------------------" tellme
maillist @ foreach mail ! 1 + count !
{ "^[o^[g| ^[c"
count @ intostr 3 " " padl " ^[g| ^[w"
me @ { "~page/newmail/" mail @ "/from" }cat getprop 1 16 midstr 16 " " padr " ^[g| ^[w"
me @ { "~page/newmail/" mail @ "/title" }cat getprop 1 41 midstr 41 " " padr " ^[g| ^[y"
me @ { "~page/newmail/" mail @ "/read" }cat getprop dup not if pop " ^[yNEW" else pop " " then " ^[g|"
}cat tellme
repeat
"^[o^[g-------------------------------------------------------------------------------" tellme
;
( arrayofnames title arrayofparagraphs --
Sends the mail
)
: sendmail
var message
var title
var recipients
var tempname
var tempref
var failcount
var paragraph
var paranum
var curtime
message ! title ! recipients !
0 failcount !
systime curtime !
recipients @ foreach swap pop tempname !
tempname @ pmatch tempref !
tempref @ player? (0 if not a player)
if
tempref @ { "~page/ignore" me @ intostr }cat getprop
me @ "W" flag? not
and ( Evaluates to 1 if sender isn't a wizard and receiver is ignoring )
else
1
then
if
{
"^[o^[rCould not find " tempname @ "."
}cat tellme
failcount @ 1 + failcount !
else
tempref @ { "~page/newmail/" curtime @ "/title" }cat title @ setprop
tempref @ { "~page/newmail/" curtime @ "/to" }cat tempname @ setprop
tempref @ { "~page/newmail/" curtime @ "/from" }cat me @ name setprop
message @ foreach paragraph ! paranum !
tempref @
{
"~page/newmail/" curtime @ "/message/"
paranum @ 1 + intostr
}cat paragraph @ setprop
repeat
(Notify receiver)
tempref @ "You have new mail." "Hey!" pretty notify
then
repeat
failcount @ 0 = if
"All messages sent successfully" tellme
else
{
"^[o^[yFailed to send ^[o^[r" failcount @ " ^[o^[ymessage(s)."
}cat tellme
then
;
(argstring -- array of recipients,
title,
array of paragraphs,
1/0 [sucess/fail]
This simply prepares the input for sendmail. A 1 will
be on the stack on sucess, 0 otherwise.
)
: preparemail
var recipients
var title
var message
(No parameters passed)
dup not if
printinbox
"^[o^[yFor more information on @mail, type ^[o^[c@mail/help" tellme
0 exit
then
strip
(Split the names from the title/message)
"=" split
dup not if
"^[o^[rMissing title and message" sendusage 0 exit
then
(Split the title from the message)
"/" split
dup not if
"^[o^[rMissing message" sendusage 0 exit
then
(Replace %t and %r, explode arrays, and assign to variables)
9 itoc "%t" subst
"%r" explode_array
message !
title !
dup not if
"^[o^[rNo recipients!" sendusage 0 exit
then
recipients !
title @ not if
"No Title" title !
then
(Show Preview)
systime me @ name recipients @
title @ message @ printmail
"^[o^[gIs this correct?" tellme
read "[yY]*" smatch not if
"^[o^[rAborted." tellme 0 exit
then
recipients @ " " explode_array recipients !
recipients @ title @ message @ 1
;
: readmail (string-of-ints -- )
dup if (Person did input arguements)
var mailindices
var mailindexstr
var mailindex
var maillist
var lastmessageindex
var mail
var message
strip " " explode_array mailindices !
me @ "~page/newmail/" array_get_propdirs 0 array_sort maillist !
maillist @ array_count lastmessageindex !
mailindices @ foreach mailindexstr ! pop
mailindexstr @ atoi mailindex !
mailindex @ not
mailindex @ lastmessageindex @ >
mailindex @ 0 <
or or if
{
"^[o^[r"
mailindexstr @
" is not a valid number."
}cat tellme
else
maillist @ mailindex @ 1 - array_getitem mail !
{ }array message !
me @ { "~page/newmail/" mail @ "/message/" }cat array_get_propvals foreach swap pop
message @ array_appenditem message !
repeat
mail @ atoi
me @ { "~page/newmail/" mail @ "/from"}cat getprop
me @ { "~page/newmail/" mail @ "/to"}cat getprop
me @ { "~page/newmail/" mail @ "/title"}cat getprop
message @
printmail
me @ { "~page/newmail/" mail @ "/read" }cat 1 setprop
then
repeat
else pop (Person didn't input arguments - therefore show inbox)
printinbox
"^[o^[yTo read a message:" tellme
"^[o^[c@mail/read message_number(s)" tellme
"^[o^[yTo read multiple messages, separate the numbers with spaces." tellme
then
;
: getinbox ( -- array-of-timestamps)
me @ "~page/newmail/" array_get_propdirs
;
: unreadmessages (-- array-of-indices NOT TIMESTAMPS)
var unreadindices
var mailtimestamp
var index
{ }array unreadindices !
getinbox foreach mailtimestamp ! index !
me @ {
"~page/newmail/" mailtimestamp @ "/read"
}cat getprop not if
index @ 1 + intostr unreadindices @ 0
array_insertitem unreadindices !
then
repeat
unreadindices @
;
(me @ { "~page/newmail/" mail @ "/read" }cat remove_prop)
: deletemessage (string-of-ints -- )
dup if
var mailindices
var maillist
var lastmessageindex
var mailindex
var mailindexstr
var mail
var deleteattempts
var success
var unread
(initialize various variables)
strip " " explode_array 2 array_sort mailindices !
me @ "~page/newmail/" array_get_propdirs 0 array_sort maillist !
maillist @ array_count lastmessageindex !
0 success !
mailindices @ array_count deleteattempts !
(Tell the user how many messages he's going to delete)
{
"^[o^[c" mailindices @ array_count "^[o^[g"
" message(s) will be attempted to be deleted."
" ^[o^[gIs this ok?"
}cat tellme
(Tell if there are any unread messages)
unreadmessages
mailindices @
array_intersect unread !
unread @ if
{ "^[o^[r(WARNING: There are ^[o^[c"
unread @ array_count " ^[o^[runread message(s) that you"
" are going to delete!)"
}cat tellme
then
read "[Yy]*" smatch not if
"^[o^[rAborted." tellme exit
then
(Begin deleting)
mailindices @ foreach mailindexstr ! pop
mailindexstr @ atoi mailindex !
mailindex @ not
mailindex @ lastmessageindex @ >
mailindex @ 0 <
or or if
{
"^[o^[r"
mailindexstr @
" is not a valid number."
}cat tellme
else
maillist @ mailindex @ 1 - array_getitem mail !
me @ { "~page/newmail/" mail @ }cat remove_prop
success @ 1 + success !
then
repeat
success @ deleteattempts @ = if
{
"All " deleteattempts @
" message(s) deleted successfully."
}cat tellme
else
{
"^[o^[r" success @ " ^[o^[yof ^[o^[r"
deleteattempts @ " ^[o^[ydeleted successfully."
}cat tellme
then
"^[o^[yDone." tellme
else
printinbox
"^[o^[yTo delete a message:" tellme
"^[o^[c@mail/delete message_number(s)" tellme
"^[o^[yTo delete multiple messages, separate the numbers with spaces." tellme
then
;
: unreadmail (string-of-ints -- )
dup if
var mailindices
var maillist
var lastmessageindex
var mailindex
var mailindexstr
var mail
var deleteattempts
var success
strip " " explode_array 2 array_sort mailindices !
me @ "~page/newmail/" array_get_propdirs 0 array_sort maillist !
maillist @ array_count lastmessageindex !
0 success !
mailindices @ array_count deleteattempts !
mailindices @ foreach mailindexstr ! pop
mailindexstr @ atoi mailindex !
mailindex @ not
mailindex @ lastmessageindex @ >
mailindex @ 0 <
or or if
{
"^[o^[r"
mailindexstr @
" is not a valid number."
}cat tellme
else
maillist @ mailindex @ 1 - array_getitem mail !
me @ { "~page/newmail/" mail @ "/read" }cat remove_prop
success @ 1 + success !
then
repeat
success @ deleteattempts @ = if
{
"All " deleteattempts @
" messages unread successfully."
}cat tellme
else
{
"^[o^[r" success @ " ^[o^[yof ^[o^[r"
deleteattempts @ " ^[o^[yunread successfully."
}cat tellme
then
else
printinbox
"^[o^[yTo undread a message:" tellme
"^[o^[c@mail/unread message_number(s)" tellme
"^[o^[yTo unread multiple messages, separate the numbers with spaces." tellme
then
;
: generateallmailindices ( -- array_of_int_strings)
var returnarray
{ }array returnarray !
1 me @ "~page/newmail/" array_get_propdirs array_count 1 for
intostr returnarray @ 0 array_insertitem returnarray !
repeat
returnarray @
;
: clean
unreadmessages generateallmailindices array_diff
dup not if
"^[o^[yNo mail to delete." tellme
pop exit
then
intarraytostring deletemessage
;
: deleteall
strip " " explode_array
generateallmailindices
array_diff
dup not if
"^[o^[yNo mail to delete." tellme
pop exit
then
intarraytostring deletemessage
;
: main
command @ "@mail" smatch
command @ "@mail/send" smatch
or if
preparemail if sendmail then
then
command @ "@mail/read" smatch if
readmail
then
command @ "@mail/delete" smatch if
deletemessage
then
command @ "@mail/help" smatch if
usage
then
command @ "@mail/help2" smatch if
usage2
then
command @ "@mail/unread" smatch if
unreadmail
then
command @ "@mail/clean" smatch if
clean
then
command @ "@mail/deleteall" smatch if
deleteall
then
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment