Fill out Message class, get streaming from stdin working.
FossilOrigin-Name: 8f3589d9d53f730c498e99104318e0ac41f3ef3c59945eab57986fbd386e6f61
This commit is contained in:
parent
33a5553e31
commit
312de83456
2 changed files with 90 additions and 20 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
# vim: set et nosta sw=4 ts=4 :
|
# vim: set et nosta sw=4 ts=4 :
|
||||||
#
|
#
|
||||||
# A class that represents an individual Maildir.
|
# A class that represents an individual Maildir, and a Nessage class to nanage
|
||||||
|
# files underneath them.
|
||||||
#
|
#
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
@ -9,6 +10,8 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/os,
|
std/os,
|
||||||
|
std/osproc,
|
||||||
|
std/posix,
|
||||||
std/streams,
|
std/streams,
|
||||||
std/strformat,
|
std/strformat,
|
||||||
std/times
|
std/times
|
||||||
|
|
@ -17,6 +20,16 @@ import
|
||||||
util
|
util
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# C O N S T A N T S
|
||||||
|
#############################################################
|
||||||
|
|
||||||
|
const
|
||||||
|
OWNERDIRPERMS = { fpUserExec, fpUserWrite, fpUserRead }
|
||||||
|
OWNERFILEPERMS = { fpUserWrite, fpUserRead }
|
||||||
|
BUFSIZE = 8192 # reading and writing buffer size
|
||||||
|
|
||||||
|
|
||||||
#############################################################
|
#############################################################
|
||||||
# T Y P E S
|
# T Y P E S
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
@ -32,7 +45,9 @@ type Maildir* = ref object
|
||||||
# An email message, under a specific Maildir.
|
# An email message, under a specific Maildir.
|
||||||
#
|
#
|
||||||
type Message* = ref object
|
type Message* = ref object
|
||||||
|
basename: string
|
||||||
dir: Maildir
|
dir: Maildir
|
||||||
|
headers: seq[ tuple[ header: string, value: seq[string] ] ]
|
||||||
path: string
|
path: string
|
||||||
stream: FileStream
|
stream: FileStream
|
||||||
|
|
||||||
|
|
@ -50,28 +65,88 @@ proc newMaildir*( path: string ): Maildir =
|
||||||
result.tmp = path & "/tmp"
|
result.tmp = path & "/tmp"
|
||||||
|
|
||||||
if not dirExists( path ):
|
if not dirExists( path ):
|
||||||
let perms = { fpUserExec, fpUserWrite, fpUserRead }
|
|
||||||
debug "Creating new maildir at {path}.".fmt
|
debug "Creating new maildir at {path}.".fmt
|
||||||
try:
|
try:
|
||||||
for p in [ result.path, result.cur, result.new, result.tmp ]:
|
for p in [ result.path, result.cur, result.new, result.tmp ]:
|
||||||
p.createDir
|
p.createDir
|
||||||
p.setFilePermissions( perms )
|
p.setFilePermissions( OWNERDIRPERMS )
|
||||||
|
|
||||||
except CatchableError as err:
|
except CatchableError as err:
|
||||||
deferral "Unable to create Maildir: ({err.msg}), deferring delivery.".fmt
|
deferral "Unable to create Maildir: ({err.msg}), deferring delivery.".fmt
|
||||||
|
|
||||||
|
|
||||||
|
proc subDir*( dir: Maildir, path: string ): Maildir =
|
||||||
|
## Creates a new Maildir relative to an existing one.
|
||||||
|
result = newMaildir( dir.path & "/" & path )
|
||||||
|
|
||||||
|
|
||||||
proc newMessage*( dir: Maildir ): Message =
|
proc newMessage*( dir: Maildir ): Message =
|
||||||
## Create and return a Message - an open FileStream under a specific Maildir
|
## Create and return a Message - an open FileStream under a specific Maildir
|
||||||
## (in tmp)
|
## (in tmp)
|
||||||
result = new Message
|
result = new Message
|
||||||
|
|
||||||
let now = getTime()
|
let now = getTime()
|
||||||
|
var hostname = newString(256)
|
||||||
|
discard getHostname( cstring(hostname), cint(256) )
|
||||||
|
|
||||||
result.dir = dir
|
result.dir = dir
|
||||||
result.path = dir.path & dir.tmp & '/' & $now.toUnixFloat()
|
result.basename = $now.toUnixFloat() & '.' & $getCurrentProcessID() & '.' & $hostname
|
||||||
|
result.path = result.dir.tmp & "/" & result.basename
|
||||||
|
result.headers = @[]
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug "Opening new message at {result.path}.".fmt
|
||||||
|
result.stream = openFileStream( result.path, fmWrite )
|
||||||
|
result.path.setFilePermissions( OWNERFILEPERMS )
|
||||||
|
except CatchableError as err:
|
||||||
|
deferral "Unable to write file {result.path}: {err.msg}".fmt
|
||||||
|
|
||||||
|
|
||||||
|
proc save*( msg: Message, dir=msg.dir ) =
|
||||||
|
## Move the message from tmp to new. Defaults to its current
|
||||||
|
## maildir, but can be provided a different one.
|
||||||
|
msg.stream.close()
|
||||||
|
let newpath = dir.new & "/" & msg.basename
|
||||||
|
debug "Moving message to {newpath}.".fmt
|
||||||
|
msg.path.moveFile( newpath )
|
||||||
|
msg.dir = dir
|
||||||
|
msg.path = newpath
|
||||||
|
|
||||||
# make new message (tmp)
|
|
||||||
# save message (move from tmp to new)
|
proc delete*( msg: Message ) =
|
||||||
|
## Remove a message from disk.
|
||||||
|
msg.stream.close()
|
||||||
|
debug "Removing message at {msg.path}.".fmt
|
||||||
|
msg.path.removeFile
|
||||||
|
msg.path = ""
|
||||||
|
|
||||||
|
|
||||||
|
proc writeStdin*( msg: Message ) =
|
||||||
|
## Streams stdin to the message file, returning how
|
||||||
|
## many bytes were written.
|
||||||
|
let input = stdin.newFileStream()
|
||||||
|
var buf = input.readStr( BUFSIZE )
|
||||||
|
var total = buf.len
|
||||||
|
msg.stream.write( buf )
|
||||||
|
|
||||||
|
while buf != "" and buf.len == BUFSIZE:
|
||||||
|
buf = input.readStr( BUFSIZE )
|
||||||
|
total = total + buf.len
|
||||||
|
msg.stream.write( buf )
|
||||||
|
msg.stream.flush()
|
||||||
|
msg.stream.close()
|
||||||
|
debug "Wrote {total} bytes from stdin".fmt
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: filter through external program
|
||||||
|
# - open new message
|
||||||
|
# - stream current message to new
|
||||||
|
# - remove current
|
||||||
|
# - return new
|
||||||
|
#
|
||||||
|
# FIXME: header parsing to tuples
|
||||||
|
# - open file
|
||||||
|
# - skip lines that don't match headers
|
||||||
|
# - unwrap multiline headers
|
||||||
|
# - store header, add value to seq of strings
|
||||||
|
|
||||||
|
|
|
||||||
17
src/sieb.nim
17
src/sieb.nim
|
|
@ -1,8 +1,7 @@
|
||||||
# vim: set et nosta sw=4 ts=4 :
|
# vim: set et nosta sw=4 ts=4 :
|
||||||
|
|
||||||
import
|
import
|
||||||
std/os,
|
std/os
|
||||||
std/streams
|
|
||||||
|
|
||||||
import
|
import
|
||||||
lib/config,
|
lib/config,
|
||||||
|
|
@ -19,15 +18,11 @@ let
|
||||||
conf = get_config( opts.config )
|
conf = get_config( opts.config )
|
||||||
default = newMaildir( home & "Maildir" )
|
default = newMaildir( home & "Maildir" )
|
||||||
|
|
||||||
|
let dest = default.subDir( ".wooo" )
|
||||||
|
|
||||||
echo repr default.newMessage
|
let msg = default.newMessage
|
||||||
|
msg.writeStdin()
|
||||||
|
# msg.filter()
|
||||||
|
msg.save( dest )
|
||||||
|
|
||||||
# let input = stdin.newFileStream()
|
|
||||||
# var buf = input.readStr( 8192 )
|
|
||||||
# var message = buf
|
|
||||||
# while buf != "":
|
|
||||||
# buf = input.readStr( 8192 )
|
|
||||||
# message = message & buf
|
|
||||||
|
|
||||||
# echo message
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue