REBOL [ Title: "Wiki" Date: 3-Jul-2002 Name: Wiki Version: 1.0.0 File: %Wiki.r Author: "Andrew Martin" Purpose: {Wiki. Creates a Wiki using Rebol, and the Xitami web server.} Email: Al.Bri@xtra.co.nz Web: http://valley.150m.com Category: [util net markup 5] ] Wiki_Directory: %/C/Rebol/Wiki/Files/ ; Where all the Wiki's .txt files are stored. Remote: %/c/Xitami/cgi-bin/ if Remote <> what-dir [ write join Remote Rebol/script/header/File read Rebol/script/header/File ] if not value? 'Values [ do %/C/Rebol/Values/Values.r ] if none? Rebol/options/cgi/script-name [ browse http://localhost/cgi-bin/Wiki.r quit ] Forbidden: {\/:*?"<>|} ; A Wiki name cannot contain any of these characters. Permitted: exclude Printable charset Forbidden CGI: make object! [ Post?: "POST" = Rebol/options/cgi/request-method Get?: "GET" = Rebol/options/cgi/request-method Script-File: to-file Rebol/options/cgi/script-name Script-URL: join make url! compose [ http (join Rebol/options/cgi/server-name Rebol/options/cgi/script-name) ] #"?" Query: Rebol/options/cgi/query-string ] Date_Rule: [ 1 2 digit [#"/" | #"-"] [1 2 digit | 3 12 alpha] [#"/" | #"-"] [4 digit | 2 digit] ] File_Rule: [some [some Permitted opt #"/"]] See_Other: func [URL [url!]] [ print rejoin [ Rebol/options/cgi/server-protocol " Status: 303 See Other" newline "Location: " URL newline ] ] Deplus: func [Value [string!]] [ dehex replace/all copy Value #"+" #" " ] Enspace: func [Value [file! string!]] [ replace/all copy Value #" " "%20" ] Envelope: func [Title [string!] Body [block!]] [ content-type text/html print ML compose/deep [ ?xml/version/encoding "1.0" "UTF-8" html [ head [ title (Title) link/rel/type/href "stylesheet" "text/css" %/Stylesheet.css ] body [(Body)] ] ] ] Pages: make object! [ New: make object! [ Name: File: none Rule?: does [ all [ CGI/Get? string? CGI/Query not empty? CGI/Query parse/all CGI/Query [ [ Date_Rule ( error? try [ Name: to-string load deplus CGI/Query ] ) | File_Rule ( Name: deplus CGI/Query ) ] end ( File: to-file Name any [directory? File File: Extension File %.txt] ) ] not exists? Wiki_Directory/:File ] ] Execute: has [Title] [ either directory? File [ md/deep Wiki_Directory/:File See_Other rejoin [CGI/Script-URL enspace Name] ] [ Envelope Title: join "New: " Name compose/deep [ h1 (Title) ( Save/Html Name "Change text in Name text box to rename page." rejoin [ Name newline head insert/dup copy "" #"*" length? Name newline ] ) ] ] ] ] Save: make object! [ Rule?: does [ CGI/Post? ] Execute: has [Post Length Name Text File] [ Post: make string! 2 + Length: to-integer Rebol/options/cgi/content-length read-io Rebol/ports/input Post Length parse/all Post [ "Name=" copy Name to #"&" skip "Text=" copy Text to end end ] either none? Name [ See_Other CGI/Script-URL ] [ Name: deplus Name File: extension to-file Name %.txt either none? Text [ if exists? Wiki_Directory/:File [ delete Wiki_Directory/:File ] See_Other rejoin [ CGI/Script-URL use [Dir] [ either none? Dir: directory File [ "" ] [ rejoin [ enspace directory File ] ] ] ] ] [ Text: deplus Text make-dir/deep directory Wiki_Directory/:File write/binary Wiki_Directory/:File Text See_Other rejoin [CGI/Script-URL enspace Name] ] ] ] Html: func [Name [string!] Hint [string!] Text [string!]] [ compose/deep [ form/method/action "POST" (CGI/Script-File) [ label [ "Name: " input/type/name/value "text" "Name" (Name) #" " (Hint) ] br textarea/name/rows/cols/wrap/style "Text" 25 80 "virtual" "width:100%;" ( Text ) div/align "right" [ input/type/value "submit" "Save" ] ] ] ] ] Edit: make object! [ Title: "Edit" Name: File: none Command: join #"*" Title Rule?: does [ all [ CGI/Get? string? CGI/Query not empty? CGI/Query parse/all CGI/Query [ Command #"=" copy Name File_Rule end ( Name: deplus Name File: extension to-file Name %.txt ) ] exists? Wiki_Directory/:File ] ] Execute: has [Page_Title] [ Page_Title: rejoin [Title ": " Name] Envelope Page_Title compose/deep [ h1 (Page_Title) ( Save/Html Name "Change text in Name text box to clone page." read Wiki_Directory/:File ) ] ] Html: func [Title [string!]] [ compose/deep [ form/method/action "GET" (CGI/Script-File) [ input/type/value "submit" "Edit" input/type/name/value "hidden" (Command) (Title) ] ] ] ] Random_Page: make object! [ random/seed now Title: "Random" Command: join #"*" Title Rule?: does [ all [ CGI/Get? string? CGI/Query not empty? CGI/Query parse/all CGI/Query [ Command #"=" Title end ] ] ] Execute: has [File] [ until [ File: first random recursive-read Wiki_Directory %.txt = extension? File ] See_Other rejoin [CGI/Script-URL enspace copy/part File find File %.txt] ] Html: does [ compose/deep [ form/method/action "GET" (CGI/Script-File) [ input/type/value "submit" (Title) input/type/name/value "hidden" (Command) (Title) ] ] ] ] Search: make object! [ Query: none Title: "Search" Command: join #"*" Title Rule?: has [Rule Index] [ Rule: join Command #"=" all [ CGI/Get? string? CGI/Query not empty? CGI/Query any [ all [ #"?" = last CGI/Query any [ Query: dehex copy/part CGI/Query find CGI/Query #"?" ] ] all [ found? Index: find CGI/Query Rule 1 = Index: index? Index found? Index: find/tail CGI/Query Rule Query: deplus Index ] ] ] ] Execute: has [Results Index Title] [ if empty? Query [ See_Other CGI/Script-URL exit ] Results: make block! 100 append Results [ tr [ th "Results" th "Document" ] ] foreach File recursive-read Wiki_Directory [ if %.txt = Extension? File [ Text: read Wiki_Directory/:File if found? Index: find Text Query [ File: head clear extension? File append Results compose/deep [ tr [ td [ (rejoin ["..." copy/part Index -35]) span/class "Hilight" (copy/part Index length? Query) (append copy/part at Index 1 + length? Query 35 "...") ] td [ a/href (rejoin [CGI/Script-File #"?" File]) (File) ] ] ] ] ] ] Envelope Title: rejoin ["Search: " Query] compose/deep [ h1 (Title) table/width "100%" [(Results)] hr table/width "100%" [ tr [ td/align "left" [(Contents/Html)] td/align "left" [(Random_Page/Html)] td/align "center" [(Search/Html Query)] td/align "right" #" " ] ] ] ] Html: func [Default [string!]] [ compose/deep [ form/method/action "GET" (CGI/Script-File) [ label [ (rejoin [Title SP Rebol/script/header/title ": "]) input/type/name/value "text" (Command) (Default) ] input/type/value "submit" (Title) ] ] ] ] View: make object! [ File: Name: none Rule?: does [ all [ CGI/Get? string? CGI/Query not empty? CGI/Query parse/all dehex CGI/Query [ [ copy Name Date_Rule ( error? try [ Name: to-string load Name ] ) | copy Name File_Rule ] end ( File: join to-file Name %.txt ) ] exists? Wiki_Directory/:File ] ] Execute: has [Title] [ Envelope Title: to-string filename File compose/deep [ ( eText/Wiki/Base read Wiki_Directory/:File rejoin [ CGI/Script-File #"?" any [directory File ""] ] ) hr table/width "100%" [ tr [ td/align "left" [(Contents/Html)] td/align "left" [(Random_Page/Html)] td/align "center" [(Search/Html Title)] td/align "right" [(Edit/Html Name)] ] ] ] ] ] Delete_Subdirectory: make object! [ Title: "Delete" Command: join #"*" Title Subdirectory: none Rule?: does [ all [ CGI/Get? string? CGI/Query not empty? CGI/Query parse/all CGI/Query [ Command #"=" copy Subdirectory File_Rule end ( Subdirectory: to-file deplus Subdirectory ) ] ] ] Execute: has [Url] [ Url: CGI/Script-URL if all [ exists? Wiki_Directory/:Subdirectory empty? read Wiki_Directory/:Subdirectory delete Wiki_Directory/:Subdirectory not none? Subdirectory: directory Subdirectory ] [ Url: rejoin [CGI/Script-URL Subdirectory] ] See_Other Url ] Html: func [Subdirectory [file!]] [ compose/deep [ form/method/action "GET" (CGI/Script-File) [ input/type/value "submit" (Title) input/type/name/value "hidden" (Command) (to-string Subdirectory) ] ] ] ] Contents: make object! [ Title: "Contents" Subdirectory: none Rule?: does [ all [ CGI/Get? any [ none? CGI/Query empty? CGI/Query all [ #"/" = last Subdirectory: dehex CGI/Query exists? Wiki_Directory/:Subdirectory Subdirectory: to-file Subdirectory ] ] ] ] Execute: has [Links] [ Envelope Title compose/deep [ h1 (Title) (all [Subdirectory compose [h2 (to-string Subdirectory)]]) ( Links: make block! 100 foreach File read either Subdirectory [ Wiki_Directory/:Subdirectory ] [ Wiki_Directory ] [ if any [ Directory? File all [ %.txt = Extension? File File: filename File ] ] [ append Links compose/deep [ li [ a/href ( rejoin [ CGI/Script-File #"?" either Subdirectory [ Subdirectory/:File ] [ File ] ] ) (File) ] ] ] ] either empty? Links [ Delete_Subdirectory/Html Subdirectory ] [ compose/deep [ ul [(Links)] ] ] ) hr table/width "100%" [ tr [ td/align "left" [ ( either Subdirectory [Contents/Html] [""] ) ] td/align "left" [(Random_Page/Html)] td/align "right" [(Search/Html Title)] ] ] ] ] Html: does [ compose/deep [ form/method/action "GET" (CGI/Script-File) [ input/type/value "submit" (Title) ] ] ] ] ] foreach Page next first Pages [ Page: get in Pages Page if Page/Rule? [ Page/Execute quit ] ] Envelope Rebol/script/header/Title compose/deep [ h1 (Rebol/script/header/Title) p/class "Initial" (reform ["Now: " now]) pre [ "Rebol/options/cgi: " (mold Rebol/options/cgi) ] ]