r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Rebol School] Rebol School

Claude
1-Jun-2010
[3233x4]
REBOL[]


send: func [
	"Send a message to an address (or block of addresses)"
	;Note - will also be used with REBOL protocol later.
	address [email! block!] "An address or block of addresses"
	message "Text of message. First line is subject."
	/only   "Send only one message to multiple addresses"
	/header "Supply your own custom header"
	header-obj [object!] "The header to use"
	/attach "Attach file, files, or [.. [filename data]]"
	files [file! block!] "The files to attach to the message"
	/subject "Set the subject of the message"
	subj "The subject line"
	/show "Show all recipients in the TO field"
	/local smtp-port boundary make-boundary tmp from
][
	make-boundary: does []

	if file? files [files: reduce [files]] ; make it a block
	if email? address [address: reduce [address]] ; make it a block
	message: either string? message [copy message] [mold message]

	if not header [                 ; Clone system default header
		header-obj: make system/standard/email [

   subject: any [subj copy/part message any [find message newline 50]]
		]
	]
	if subject [header-obj/subject: subj]
	either none? header-obj/from [

  if none? header-obj/from: from: system/user/email [net-error "Email 
  header not set: no from address"]
		if all [string? system/user/name not empty? system/user/name][
			header-obj/from: rejoin [system/user/name " <" from ">"]
		]
	][
		from: header-obj/from
	]
	if none? header-obj/to [
		header-obj/to: tmp: make string! 20
		if show [
			foreach email address [repend tmp [email ", "]]
			clear back back tail tmp
		]
	]
	if none? header-obj/date [header-obj/date: to-idate now]

	if attach [

  boundary: rejoin ["--__REBOL--" system/product "--" system/version 
  "--" checksum form now/precise "__"]
		header-obj/MIME-Version: "1.0"

  header-obj/content-type: join "multipart/mixed; boundary=" [{"} skip 
  boundary 2 {"}]
		message: build-attach-body message files boundary
	]

	;-- Send as an SMTP batch or individually addressed:
	smtp-port: open [scheme: 'esmtp]
	either only [ ; Only one message to multiple addrs
		address: copy address
		; remove non-email values
		remove-each value address [not email? :value]

  message: head insert insert tail net-utils/export header-obj newline 
  message
		insert smtp-port reduce [from address message]
	] [
		foreach addr address [
			if email? addr [
				if not show [insert clear header-obj/to addr]

    tmp: head insert insert tail net-utils/export header-obj newline 
    message
				insert smtp-port reduce [from reduce [addr] tmp]
			]
		]
	]
	close smtp-port
]

resend: func [
	"Relay a message"
	to from message /local smtp-port
][
	smtp-port: open [scheme: 'esmtp]
	insert smtp-port reduce [from reduce [to] message]
	close smtp-port
]

build-attach-body: function [
	{Return an email body with attached files.}
	body [string!] {The message body}

 files [block!] {List of files to send [%file1.r [%file2.r "data"]]}
	boundary [string!] {The boundary divider}
][
	make-mime-header
	break-lines
	file
	val
][
	make-mime-header: func [file] [
		net-utils/export context [

   Content-Type: join {application/octet-stream; name="} [file {"}]
			Content-Transfer-Encoding: "base64"

   Content-Disposition: join {attachment; filename="} [file {"^/}]
		]
	]
	break-lines: func [mesg data /at num] [
		num: any [num 72]
		while [not tail? data] [
			append mesg join copy/part data num #"^/"
			data: skip data num
		]
		mesg
	]
	if not empty? files [
		insert body reduce [boundary "^/Content-type: text/html^/^/"]
		append body "^/^/"
		if not parse files [
			some [
				(file: none)
				[
					set file file! (val: read/binary file)
					| into [
						set file file!
						set val skip ;anything allowed
						to end
					]
				] (
					if file [
						repend body [
							boundary "^/"
							make-mime-header any [find/last/tail file #"/" file]
						]
						val: either any-string? val [val] [mold :val]
						break-lines body enbase val
					]
				)
			]
		] [net-error "Cannot parse file list."]
		append body join boundary "--^/"
	]
	body
]
i find it on http://www.rebol.org/
do %./send.r

header: make system/standard/email [
        Subject:  rejoin ["example REBOL "]
        Organization: ""
        Content-Type: "multipart/html"
]


msg: rejoin [
{<img src = "test.jpg" /> </html>}



]

send/header/attach [[cr-:-fideurambank-:-lu]] msg header [%test.jpg]
with this you can send mail with images in html
amacleod
1-Jun-2010
[3237]
Nice Claude! I'll check it out. Thanks.
GiuseppeC
1-Jun-2010
[3238]
Thanks Claude, I'll try to use this too.
Davide
1-Jun-2010
[3239]
To display the image inline the header "Content-ID" is mandatory. 
So add something like:

Content-ID: rejoin ["<" file ">"]


And use that id to reference the image in html, prefixed with string 
"cid:" 

<img src="cid:test.jpg" />
PatrickP61
23-Sep-2010
[3240]
I want to capture only  the function names in a block and write it 
to a file.

The WHAT function does this by printing a list of function names 
and then a short description.
I tried this:

data: to-block what


** Script error: to-block does not allow unset! for its value argument

How can I just capture the Function names in a block using WHAT?
Graham
23-Sep-2010
[3241]
have a look at the source of 'what and modify it?
PatrickP61
23-Sep-2010
[3242]
that is a possibility of course, but I thought there would be a faster 
way of just capturing the printed output into a blcok
Gregg
23-Sep-2010
[3243]
Unfortunately some functions, like WHAT, weren't designed with that 
in mind.
Chris
23-Sep-2010
[3244]
You can use 'echo to capture the result in a temporary file, then 
delete the file after:

	echo %tmp.txt
	what
	echo none
	parse read %tmp.txt [...]
	delete %tmp.txt

Shame you can't echo to a string or binary...
PatrickP61
23-Sep-2010
[3245]
Chris, That is a good idea, for the quick and dirty, but I am having 
an issue with WHAT

WHAT has what is supposed to be an optional field for module name 
that follows it.  But if I do this:

	echo %tmp.txt
	what
	echo none

This is processed as if it was this:

	echo %tmp.txt

 what echo               <--- echo becomes the passed parameter into 
 WHAT
	none


How do I get around that other than specifying a dummy field?  Try 
this:

	echo %tmp.txt
	what

 halt		<--- halt will NOT be executed since it is pulled into the 
 WHAT function!!
	echo none
BrianH
23-Sep-2010
[3246x2]
It's only optional from the command line, not within a script.
In a script, try what ().
PatrickP61
23-Sep-2010
[3248]
Will do
BrianH
23-Sep-2010
[3249]
or (what)
PatrickP61
23-Sep-2010
[3250x2]
That works just fine!  Thanks
What is the easiest way to capture the first literal in a string?

LIST: {??                    Debug print a word, path, or blo...}

I tried  FIRST  TO-BLOCK  LIST but got this:
>> first to-block list
** Syntax error: invalid "word" -- "word,"
** Where: to to-block

** Near: (line 1) ??                    Debug print a word, pat...

It works when I have a valid word (not ?? or other)
Steeve
23-Sep-2010
[3252]
first load/next list
BrianH
23-Sep-2010
[3253x2]
>> a: {??                    Debug print a word, path, or blo...}
== {??                    Debug print a word, path, or blo...}
>> parse a [return to " "]
== "??"
That's R3 though.
PatrickP61
23-Sep-2010
[3255x2]
Yeah, I'm in R3
They both work!  Thanks
BrianH
23-Sep-2010
[3257]
>> to-word parse a [return to " "]
== ??

It will be faster than LOAD/next, trust me. Might be slower than 
TRANSCODE/next though.
PatrickP61
23-Sep-2010
[3258]
Parse is very fast I guess??
BrianH
23-Sep-2010
[3259x2]
Yes, but TRANSCODE is faster. However, TRANSCODE only works on UTF8 
binary, so when you add the binary conversion the PARSE method ends 
up being marginally faster.
>> dp [first transcode/next to-binary a]
== make object! [
    timer: 0:00:00.000013
    evals: 15
    eval-natives: 6
    eval-functions: 2
    series-made: 4
    series-freed: 1
    series-expanded: 1
    series-bytes: 570
    series-recycled: 0
    made-blocks: 2
    made-objects: 0
    recycles: 0
]

>> dp [to-word parse a [return to " "]]
== make object! [
    timer: 0:00:00.000012
    evals: 17
    eval-natives: 5
    eval-functions: 2
    series-made: 2
    series-freed: 0
    series-expanded: 0
    series-bytes: 435
    series-recycled: 0
    made-blocks: 1
    made-objects: 0
    recycles: 0
]

>> b: to-binary a
== #{
3F3F20202020202020202020202020202020202020204465627567207072696E
74206120776F72642C20706174682C206F7220626C6F2E2E2E
}

>> dp [first transcode/next b]
== make object! [
    timer: 0:00:00.00001
    evals: 11
    eval-natives: 5
    eval-functions: 1
    series-made: 3
    series-freed: 1
    series-expanded: 1
    series-bytes: 512
    series-recycled: 0
    made-blocks: 2
    made-objects: 0
    recycles: 0
]
PatrickP61
23-Sep-2010
[3261x2]
Will ECHO write a file in UTF-8 and so allow me to use TRANSCODE?
I guess I could just try it out
BrianH
23-Sep-2010
[3263]
But remember, READ/lines and all line-oriented stuff works with strings, 
not binary. You might be better off working with PARSE.
PatrickP61
23-Sep-2010
[3264x2]
Hey, this worked!

first transcode/next read %tmp.txt


!        <-- which is the first function name in my temporary file

Now, how do I get the first literal for each line???  Parse??
Here is what I have so far in my attempt to capture ONLY the function 
names in Rebol:

echo %tmp.txt 
what () 
echo none 
funct-list: first transcode/next read %tmp.txt


Not exactly sure how to go through all the records in %tmp.txt yet
BrianH
23-Sep-2010
[3266]
map-each x read/lines %tmp.txt [to-word parse x [return to " "]]
PatrickP61
23-Sep-2010
[3267x2]
Thank you very much BrianH and Steeve.  I appreciate it
Here is the completed script to get only Function names (nothing 
else) in a file:

echo %tmp.txt 
what () 
echo none 
funct-block: read/lines %tmp.txt

funct-names: map-each x funct-block [to-word parse x [return to " 
"]]
write/lines %Funct.txt funct-names
BrianH
23-Sep-2010
[3269x2]
funct-names: sort map-each [w v] to-block system/contexts/exports 
[either any-function? :v [to-word w] [()]]
WHAT gets its words from the system/contexts/exports object. MAP-EACH 
takes a block, so the object is converted to a block. The :v is equivalent 
to GET/any 'v in R3. The () in the second EITHER block is to generate 
an unset! value, which will cause MAP-EACH to not add a value to 
the block for that round. And SORT sorts words in R3.
PatrickP61
23-Sep-2010
[3271x2]
The ECHO was quick and dirty.  Your solution is, of course, better 
since it is getting the values directly as opposed to using ECHO. 
 Thanks BrianH
Hi everyone,


 I would really like to be able to capture some text from an html 
 webpage into a block.  Looking at Carl's cookbook at www.rebol.net/cookbook/recipes/0041.html 
 , he has a tiny script called "Tiny HTML to Text converter".


So I thought I could try it in R3, but alas, the /markup refinement 
doesn't seem to be defined.  


What would you suggest I use instead to capture a webpage text using 
R3?
BrianH
23-Sep-2010
[3273x2]
Are you using a107? If so, try this:
>> decode 'markup to-binary "<html>blah</html>"
== [<html> "blah" </html>]
Note that it works on binaries, not strings, so just use plain READ. 
We haven't made a nice mezzanine wrapper for it yet. Bringing back 
the LOAD/markup option is unlikely (LOAD is too complex already) 
but a simple LOAD-MARKUP function is likely.
PatrickP61
23-Sep-2010
[3275x2]
Hi Brian,  Man, do you ever sleep -- you were up late last night, 
or are you somewhere around the globe?  Yes the Decode did work when 
I did this:


html-blk: decode 'markup to-binary read http://www.rebol.com/docs/reference.html


Is there an easy way to parse out the html stuff and get ONLY the 
text parts?
I am guessing I could use "remove-each item html-blk [tag? item] 
 .. I'll give it a try.
Maxim
23-Sep-2010
[3277x2]
remove-each item html-blk [tag? item]
hehe
PatrickP61
23-Sep-2010
[3279]
lol
Maxim
23-Sep-2010
[3280]
confirmed... you are now an official reboler  (why are you using 
Rebol School ;-)
BrianH
23-Sep-2010
[3281]
You could even remove the TO-BINARY from your code - READ returns 
a binary.
PatrickP61
23-Sep-2010
[3282]
I am soooo intimidated by all you expert rebolers -- I'm just playing 
around getting the hang of it!