Monday 30 April 2012

Deleting file using file extension

To delete files or directory there is the delete command:

>> delete %test.txt


If you want to delete only some files on file extension basis, you can use the following script:
REBOL [
    Title: "Delete Files by Suffix"
    Date: 7-Jul-2000
    File: %delete-suffix.r
    Author: "Reburu"
    Purpose: {
        Delete files based on their suffixes.   Can also delete
        deeply through all subdirectories.
    }
    Note: "Press ESCAPE to break out at the prompt."
]
delete-suffix: func [
    "Delete files deeply by suffix."
    dir-name "Starting directory"
    suffixes "Block of suffixes or none"
    /deep "Delete into subdirectories"
    /sure "Do not verify the deletion"
][
    if dir? dir-name [
        dir-name: dirize dir-name
        ;print ["Inspecting:" dir-name]
        foreach file read dir-name [
            either dir? dir-name/:file [
                if deep [
                    either sure [
                        delete-suffix/deep/sure dir-name/:file suffixes
                    ][delete-suffix/deep dir-name/:file suffixes ]
                ]
            ][
                if any [not suffixes find suffixes find/last file "."] [
                    if any [
                        sure
                        confirm   rejoin ["Delete " dir-name   file " ?"]
                    ][
                        print ["Deleting:" dir-name/:file]
                        delete dir-name/:file
]   ]   ]   ]   ]   ]


It creates the delete-suffix function, you have to choose the directory and the file extension(s):

>> write %test.temp "example"
>> delete-suffix %. %.temp
Deleting: ./test.temp


The option /deep continue to delete in subdirectories, the option /sure doesn't ask you to confirm before deleting:

>> delete-suffix %. none ; delete all files
>> delete-suffix/deep %. [%.jpg %.gif %.bmp] ; delete image files
>> delete-suffix/deep %msvc [%.sbr %.obj %.pdb %.ilk %.pch %.bsc %.idb]
>> delete-suffix/deep/sure %. [%.err ] ; delete all error files for sure

Friday 27 April 2012

Going back from a charset

Charset are useful for parse a many other things, for example:

>> temp: charset "abc"
== make bitset! #{
0000000000000000000000000E00000000000000000000000000000000000000
}
>> type? temp
== bitset!

What characters contains temp?
The following code give you a solution:
REBOL [
    Title: "Decode Charset Function"
    Date: 23-Aug-2001
    Version: 1.0.0
    File: %decode-charset.r
    Author: "Nenad Rakocevic"
    Purpose: "Converts 'charset values to something readable"
    Email: dockimbel@free.fr
    Example: {decode-charset net-utils/url-parser/alpha-num}
]
decode-charset: func [data [bitset!] /local out byte][
    out: make string! 100
    data: to-binary data
    forall data [
        byte: to-integer data/1
        repeat i 8 [
            if 1 = (1 and byte) [
                append out to-char (i - 1) + (8 * ((index? data) - 1))
            ]
            byte: to-integer (byte / 2)
        ]
    ]
    out
]


Example:

>> decode-charset temp
== "abc"
>> decode-charset net-utils/url-parser/alpha-num
== {0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz}

Thursday 26 April 2012

Christmas countdown

Are you seriously addicted to Christmas like my girlfriend?
Here there is the Christmas countdown:

Rebol [Author: ["Izkata" "Massimiliano Vessi"] ]
xdate: "25-Dec-"
append xdate now/year
xdate: to-date xdate
toxmas: to-string (xdate - now/date )
view layout [
    across
    h1 "Time to Christmas:"
    return
    h1   toxmas rate 00:01 feel [
        engage: func [face a e] [
            face/text: to-string (xdate - now/date )
            show face
            ]
        ]
    h1 "days and"      
    h1 "xx:xx:xx"   rate 00:00:01 feel [
        engage: func [face a e] [
            face/text: to-string (24:00 - now/time )
            show face
            ]
        ]
    ]

I used the standard function engage with [face action event] arguments.

Friday 20 April 2012

System object exposed

System object is the core of Rebol configuration, but it's difficult to understand so this post will clarify a little about it.
Since it's an object, you can't call its element with the numbers (system/1),  but you need to know its composition:

>> system/version
== 2.7.8.3.1


How it is composed (click on a name to jump to the relative section):
Lets analyze one by one:


Version

It contains the number version, the first 3 digits are core version, the fourth the platform, the fifth is processor type.
Examples:
  • 2.7.8.3.1    version for Windows
  • 2.7.8.2.4    version for Apple with PPC cpu
  • 2.7.8.2.5    version for Apple with Intel cpu
  • 2.7.8.4.2    version for Linux
  • 2.7.8.7.2    version for FreeBSD
  • 2.7.8.9.4    version fot OpenBSD


Build


The date of building the current Rebol version:

>> system/build
== 1-Jan-2011/16:39:07-8:00



Product


It explains what Rebol product are you using:

>> system/product
== View


Core


It explains what core Rebol version are you using:

>> system/core
== 2.7.8


Components


This is a block made of 60 items, they are just 30 object with name before and none after them in the block:

>> for i 1 60 3 [ print system/components/:i ]
mezz
registry
getprefs
Install
protocols
ODBC
Library
shell
graphics
draw
view
viewtop
sound
crypt
bignum
dhdsa
rsa
sysport
crypt2
ssl

Each object is made of all descriptions of the component (title, owner, version, etc.):

>> print system/components/mezz
make object! [
Title: "REBOL Mezzanine Extensions"
Date: 1-Aug-2004/21:34:12
Name: 'mezz
Version: 1.2.0
File: none
Home: none
Author: none
Owner: none
Rights: none
Needs: none
Tabs: none
Usage: none
Purpose: none
Comment: none
History: none
Language: none
Type: none
Content: none
]


Words


It's an object, it contains all Rebol reserved words, if type is unset!, it means that is a dialect world and it works just in a Rebol dialect.
At the moment it contains 2642 reserved words. Some owrds can be a block or an object.


License


It's the Rebol license:
REBOL End User License Agreement

IMPORTANT. READ CAREFULLY.

This License Agreement (AGREEMENT) is a legal contract between
you and REBOL Technologies (REBOL) for the limited use of this
REBOL software product (SOFTWARE), which includes computer
software, and, as applicable, associated media, printed
materials, and electronic documentation.

REBOL grants you a non-exclusive license to use the SOFTWARE.
The SOFTWARE is licensed, not sold, to you. REBOL retains all
right, title, and interest in and to the SOFTWARE including,
without limitation, all intellectual property rights relating to
or embodied in the SOFTWARE.

The copyright, trademark, and other proprietary rights notices
contained in the SOFTWARE may not be removed, altered, or added
to in any way. You may not reverse engineer, decompile, or
disassemble the SOFTWARE.

You agree to use the SOFTWARE in compliance with all applicable
laws and regulations including all laws governing the export or
re-export of the SOFTWARE. You agree to indemnify REBOL from
and against your violation of any such laws or regulations.

You may redistribute the SOFTWARE provided that you include this
entire License AGREEMENT and all copyright and trademark
notices; and agree to indemnify, hold harmless, and defend
REBOL from and against any claims or lawsuits, including
attorneys' fees, that arise from use, reproduction, or
distribution of the SOFTWARE.

THE SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTY
OF ANY KIND, EXPRESS, IMPLIED OR STATUTORY INCLUDING WITHOUT
LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
NONINFRINGEMENT OR FITNESS FOR PARTICULAR USE OR PURPOSE.

IN NO EVENT SHALL REBOL OR ITS SUPPLIERS OR RESELLERS BE LIABLE
TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY KIND INCLUDING,
WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS OR DATA, ARISING
OUT OF THIS AGREEMENT OR USE OF THE SOFTWARE. IN NO EVENT WILL
REBOL BE LIABLE FOR (a) ANY DAMAGES IN EXCESS OF THE AMOUNT
REBOL RECEIVED FROM YOU FOR A LICENSE TO THE SOFTWARE, EVEN IF
REBOL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY,
OR (b) FOR ANY CLAIM BY ANY THIRD PARTY.

This AGREEMENT shall be governed by the laws of the State of
California. If any provision of this AGREEMENT is held to be
unenforceable, such provision shall be reformed only to the
extent necessary to make it enforceable.

This AGREEMENT contains the entire agreement between the parties
with respect to the license of the SOFTWARE. This AGREEMENT
supersedes any prior license agreement of the SOFTWARE.

By installing or using the SOFTWARE, you are consenting to be
bound by and are becoming a party to this AGREEMENT. If you do
not agree to all of the terms of this AGREEMENT, do not use the
SOFTWARE.

REBOL can be contacted at WWW.REBOL.COM



Options


It contains Rebol options like path to executable:

[
home: %/c/programmi/rebol/view/
script: none
path: %/c/programmi/rebol/view/
boot: %/C/Programmi/rebol/view/rebol.exe
args: none
do-arg: none
link-url: none
server: none
quiet: true
trace: false
help: false
install: none
boot-flags: 16
boot-version: none
binary-base: 16
cgi: make object! [
server-software: none
server-name: none
gateway-interface: none
server-protocol: none
server-port: none
request-method: none
path-info: none
path-translated: none
script-name: none
query-string: none
remote-host: none
remote-addr: none
auth-type: none
remote-user: none
remote-ident: none
Content-Type: none
content-length: none
other-headers: []
]
browser-type: 0
]



User


It contains all user informations:

name: "MaxV"
email: maxint@tiscali.it
home: none
words: none


Script


It became the current script header, if you aren't using any script it's like this:

title: none
header: none
parent: none
path: %/c/programmi/rebol/view/
args: none
words: none


Console


It contains the console history, the symbol to use at prompt, the escape sequence, the busy symbols, the tab size and the function for automatic completion:

>> probe system/console
make object! [
history: ["probe system/console"]
keys: none
prompt: ">> "
result: "== "
escape: "(escape)"
busy: "|/-\"
tab-size: 4
break: true
lookup: func [
"Console filename completion lookup."
file /value
][
if #"/" <> last file [file: first split-path file]
attempt [read file]
]
]


So you can change the console behavior:

>> system/console/prompt: "Command> "
== "Command> "
Command> system/console/result: "Result-> "
Result-> "Result-> "
Command> print "Hello"
Hello
Command> 2 - 2
Result-> 0


Ports


It contains six ports:
  • input
  • output
  • echo
  • system
  • serial
  • wait-list
Input and output are used for CGI script, for example an HTML use a script:

<html>
<form action="testpost.r" method="POST">
<input maxlength="20" name="name" size="20" type="text" />
<input type="submit" value="OK" />
</form>
</html>


testpot.r is:
#!/path/to/rebol -c
    REBOL [Title: "Print POST Data"]
    ;- Always print this line first
    print ["Content-type: text/html" newline newline]
    post-data: copy system/ports/input
    print [<HTML><PRE> post-data </PRE></HTML>]
    quit


Network


It contains PC name and IP:

>> help system/network
SYSTEM/NETWORK is an object of value:
host string! "PC19"
host-address tuple! 192.1.1.1


Schemes


It contains some standard network schemes used:
  • default
  • finger
  • whois
  • daytime
  • smtp
  • esmtp
  • pop
  • imap
  • http
  • ftp
  • nntp
  • https
You can change  or create your connections. For example if you need to connect to an FTP site, always with the same user name and password, just edit the FTP scheme, and every time you use the FTP port, rebol will use your user name and password:

>> system/schemes/ftp/user: 741856@aruba.it
>> system/schemes/ftp/pass: "secretxxxyyyy"
>> foreach item ( read ftp://ftp.rebol2.it/main/) [ print item]
1-9stylesheet.css
16-11-07stylesheet.css
16-2stylesheet.css
30-1stylesheet.css
Policarpa.jpg
Technip3.zip
_index.html
c4i/
cgi-bin/
chat-test.html
english/
gpEasy/
gpEasy_en/
htaccess.txt
immagini/
index.html
indirizzo.gif
info.php
infophp.php
it/
italiano/
postinfo.html
prototype.js
recaptchalib.php
robots.txt
sessioni.php
sfondo.jpg
stile.css
stylesheet.css
temp/
uploads/



In order to obtain more information about a scheme, use help:


>> help system/schemes/http
SYSTEM/SCHEMES/HTTP is an object of value:
   scheme          word!     HTTP
   host            none!     none
   port-id         integer!  80
   user            none!     none
   pass            none!     none
   target          none!     none
   path            none!     none
   proxy           object!   [host port-id user pass type bypass]
   access          none!     none
   allow           none!     none
   buffer-size     none!     none
   limit           none!     none
   handler         object!   [port-flags open-check close-check write-check ini...
   status          none!     none
   size            none!     none
   date            none!     none
   url             none!     none
   sub-port        none!     none
   locals          none!     none
   state           none!     none
   timeout         none!     none
   local-ip        none!     none
   local-service   none!     none
   remote-service  none!     none
   last-remote-service none! none
   direction       none!     none
   key             none!     none
   strength        none!     none
   algorithm       none!     none
   block-chaining  none!     none
   init-vector     none!     none
   padding         none!     none
   async-modes     none!     none
   remote-ip       none!     none
   local-port      none!     none
   remote-port     none!     none
   backlog         none!     none
   device          none!     none
   speed           none!     none
   data-bits       none!     none
   parity          none!     none
   stop-bits       none!     none
   rts-cts         logic!    true
   user-data       none!     none
   awake           none!     none
   passive         none!     none
   cache-size      integer!  5
   user-agent      string!   "REBOL View 2.7.8.3.1"





Error


It contains all error messages, please read http://www.rebol.com/docs/core23/rebolcore-17.html. Errors are divided in:
  • throw     
  • note
  • syntax
  • script
  • math
  • access
  • command
  • resv700
  • user
  • internal
For example:

>> system/error/syntax/type
== "Syntax Error"
>> system/error/syntax/invalid
== ["Invalid" :arg1 "--" :arg2]



Standard


It contains all standard objects, so you can copy them to obtain a complete object. It contains:
  • script
  • port
  • port-flags
  • email
  • face
  • sound
  • error
  • port-state
  • compress
  • checksum
  • net-interface
  • license
  • shell
  • crypt
  • crypt-dh
  • crypt-dsa
  • crypt-dsa-sig
  • crypt-rsa
You can use them this way:

>> temp: make system/standard/email []
>> ? temp
TEMP is an object of value:
To none! none
CC none! none
BCC none! none
From none! none
Reply-To none! none
Date none! none
Subject none! none
Return-Path none! none
Organization none! none
Message-Id none! none
Comment none! none
X-REBOL string! "View 2.7.8.3.1 http://WWW.REBOL.COM"
MIME-Version none! none
Content-Type none! none
Content none! none


View


It contains all words and object (also images) of the View or VID systems. It's huge!


Stats


Is the memory used in bit:

>> system/stats
== 545527840

Locale

Locale contains the names of day and months:

>> probe system/locale
make object! [
months: [
"January" "February" "March" "April" "May" "June"
"July" "August" "September" "October" "November" "December"
]
days: [
"Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"
]
]


User-license


Here there are the data to unlock all the advanced feature of Rebol/Command:
  • MySQL and Oracle database interfaces
  • ODBC (SQLServer, Access, Excel) database interface
  • Access to external libraries (DLLs)
  • SSL secure sockets (HTTPS client)
  • Built-in RSA, AES, Blowfish, DSA, DH encryption
  • Shell commands, launch external apps
  • Windows Registry access functions
  • Fast CGI server interface (quicker than standard CGI)


>> help system/user-license
SYSTEM/USER-LICENSE is an object of value:
name none! none
email none! none
id none! none
message none! none

Wednesday 18 April 2012

Suspend PC

If you need to suspend (hibernate) your PC, you can with Rebol on Windows use the os-sleep function of the following script:
REBOL [
    Title: "LibPowrProf"
    Date: 13-Apr-2012/21:51:25+2:00
    Author: "Oldes"
]
libPowrProf: context [
libPowrProf.dll: load/library %PowrProf.dll
SetSuspendState: make routine! [
Hibernate [integer!]
ForceCritical [integer!]
DisableWakeEvent [integer!]
return: [integer!]
] libPowrProf.dll "SetSuspendState"
set 'os-sleep func[
"Suspends the system by shutting power down"
/hybernate "Use deep (slow) hibernation"
][
SetSuspendState either hybernate [1][0] 1 0
]
]


The library PowrProf.dll is usualy in C:\Windows\System32\, but it will be load automatically.
Than you can use the os-suspend function to suspend your PC.

Monday 16 April 2012

A Rebol VID example video

Here it is a video about Rebol VID, made at Red & REBOL DevCon Winter 2012:

Wednesday 11 April 2012

How to use Rebdb

RebDB is a simple database script, you can access to all the most common database function using it. You can downland RebDB from: http://www.dobeash.com/RebDB/RebDB-203.zip

To access it you can use rebol commands or SQL commands, this guide will cover both solution.
First of all you have to load all the script this way:

>> do %db.r


Table of contents:

Using just rebol commands


In order to create a table, you have to use the command db-create, this way:

>> db-create my-table [ID Date Note]
== true

Ok, we create a table named my-table with the columns name: ID, Date and Note.
I didn't specify a type of value for each column, so if I want a description of the table using the db-desc command I obtain:

>> db-desc my-table
== [ID none! Date none! Note none!]


To insert values the command is: db-insert


db-insert my-table [next 1-Jan-2000 "Note"]


Note the use of the special word next to set a new value to the ID, this way we have a unique key (but it isn't necessary).

>> db-insert my-table [next 1-Jan-2000 "Note"]
== [1 1-Jan-2000 "Note"]


Remember that you have to insert always the correct numbers of items of the row:

>> db-insert my-table [next 1-Jan-2000 ]
** User Error: Invalid number of values
** Near: to error! :value


The command db-rows show you the numbers of row:

>> db-rows my-table
== 1


The command db-show shows the current statistics:

>> db-show
== [
"Host" "PC19"
"Address" 192.1.1.1
"Memory" 8023323
"Tables" 1
]

The command db-tables shows the current open tables:

>> db-tables
== [my-table 3 1 true 10-Apr-2012/17:54:47 10-Apr-2012/18:14:42 7 true]

It describes table name, columns, rows, sorted flag, first modify time, last modify time, hits, dirty flag.

Until you don't use db-commit, your changes aren't saved on the disks! So let's use it:

>> db-commit *
== true

Using the asterisk, we save all tables open, I could use also:

>> db-commit my-table
== true


To delete a table there is the db-drop command.

To make a query there is the db-select command:


>> db-select/where * my-table [id = 1]
== [1 1-Jan-2000 "Note"]


Examples:

>> db-insert my-table reduce ['next now to-string now]
== [2 10-Apr-2012/18:43:32+2:00 "10-Apr-2012/18:43:32+2:00"]
>> db-insert my-table reduce ['next now/time to-string now/date ]
== [3 18:43:52 "10-Apr-2012"]
>> db-select * my-table
== [1 1-Jan-2000 "Note" 2 10-Apr-2012/18:43:32+2:00 "10-Apr-2012/18:43:32+2:00" 3 18:43:52 "10-Apr
-2012"]
>> db-select/header * my-table
== [1 1-Jan-2000 "Note" 2 10-Apr-2012/18:43:32+2:00 "10-Apr-2012/18:43:32+2:00" 3 18:43:52 "10-Apr
-2012" [my-table ID Date Note]]


Using the refinement header you always know table name and columns.

The reserved functions of db.r are:

  • db-desc 
  • db-describe 
  • db-rows 
  • db-show 
  • db-table? 
  • db-tables 
  • db-close 
  • db-commit 
  • db-create 
  • db-drop 
  • db-rollback 
  • db-lookup 
  • db-select 
  • db-delete 
  • db-insert 
  • db-truncate 
  • db-update 
  • db-replay
Use the question mark for more information:

>> ? db-desc
USAGE:
DB-DESC 'table /header

DESCRIPTION:
Information about the columns of a table.
DB-DESC is a function value.

ARGUMENTS:
table -- (Type: word)

REFINEMENTS:
/header -- Append header block


Using SQL commands

The first thing to do is to load the db.r script and the SQL.r client:

>> do %db.r
== true
>> do %SQL.r
RebDB v2.0.3

RUN> commit *
true

login.sql ran in 0:00 second(s)
SQL>


Every time you launch SQL.r, it always run the SQL script login.sql. You can use it to do automatic tasks.

Now you are in the SQL cliet, so it accept the SQL grammar.

In order to create a table there is the command create:

SQL> create my-table2 [ID Date Note ]
true

The command describe show you how is made a table:

SQL> describe my-table2
Column Type
-------- ----
ID none
Date none
Note none

3 row(s) selected in 0:00 seconds


The type is just the first row types.

Let's try to insert some values:

SQL> insert into my-table2 values reduce ['next now/date "Note1" ]
ID Date Note
-- ----------- -----
1 11-Apr-2012 Note1

1 row(s) selected in 0:00 seconds


Remember that you are always in a rebol console, so you can mix rebol and SQL.

If we check the table now, here it is the result:

SQL> desc my-table2
Column Type
------ -------
ID integer
Date date
Note string

3 row(s) selected in 0:00 seconds


Here the reserved word list of the SQL client:
  • avg
  • by
  • count
  • desc
  • distinct
  • explain
  • from
  • group
  • header
  • having
  • into
  • joins
  • max
  • min
  • on
  • order
  • replaces
  • rowid
  • set
  • std
  • sum
  • table
  • to
  • values
  • where
  • with

Let's insert more data:

SQL> insert into my-table2 values reduce ['next now/date + 1 "Note2" ]
ID Date Note
-- ----------- -----
2 12-Apr-2012 Note2

1 row(s) selected in 0:00 seconds
SQL> insert into my-table2 values reduce ['next now/date + 3 "Note3" ]
ID Date Note
-- ----------- -----
3 14-Apr-2012 Note3

1 row(s) selected in 0:00 seconds

You can change one or more values with the update command:

SQL> update my-table2 set Date 14-Apr-2014 where [Note = "Note3" ]
1 row(s) updated in 0:00 seconds


With select you can retrieve the data:

SQL> select * my-table2
ID Date Note
-- ----------- -----
1 11-Apr-2012 Note1
2 12-Apr-2012 Note2
3 14-Apr-2014 Note3

3 row(s) selected in 0:00 seconds

SQL> select * my-table2 where [date > 1-1-2013]
ID Date Note
-- ----------- -----
3 14-Apr-2014 Note3

1 row(s) selected in 0:00 seconds


Remember: nothing is written on the disk, until you use commit:

SQL> commit *
true


The command rows show you the numbers of row of a table:

SQL> rows my-table2
3 row(s)

The command tables show you the open tables:

SQL> tables
Table Cols Rows Sorted? Loaded Accessed Hits Dirty?
--------- ---- ---- ------- -------------------- -------------------- ---- ------
my-table2 3 3 true 11-Apr-2012/13:04:37 11-Apr-2012/13:42:55 9 false

1 row(s) selected in 0:00 seconds


The command table? say to you if a table exits:

SQL> table? my-tabe2
false
SQL> table? my-table2
true



See also

For more information see also:

Tuesday 3 April 2012

Scrolling text example

A simple example of scrolling text with Rebol, with just 5 lines of code!

Here the source code: REBOL [
    Title: "Scrolling Movie Credits"
    Date: 16-May-2001
    Version: 1.0.1
    File: %credits.r
    Author: "Carl Sassenrath"
    Purpose: {Displays scrolling credits over an image. (Most of this example is the text for the credits.)
} ]
pic: load-thru/binary http://www.rebol.com/view/bay.jpg
roller: layout [
    backdrop pic effect [multiply 60.20.30 fit]
    text center bold 240x30 "REBOL, The Movie" yellow font [size: 16]
    credits: text white bold center 240x180 rate 30 para [origin: 0x+100]
        feel [engage: func [f a e] [
            if a = 'time [f/para/origin: f/para/origin - 0x1 show f]
        ]
    ] ]
credits/text: { Edit This File To Add Your Own Credits It is very simple to do. Only takes a minute. Only REBOL Makes It Possible... }
view roller