root/HTTP/WikiContentFileService.lua

Revision 1452 (checked in by rsz, 2 weeks ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               WikiContentFileService.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       January 30, 2007
6 -- Legal:               Copyright (C) 2007 Raphaël Szwarc
7 --                      Under the terms of the MIT License
8 --                      http://www.opensource.org/licenses/mit-license.html
9 --------------------------------------------------------------------------------
10
11 -- import dependencies
12 local HTTP = require( 'HTTP' )
13
14 local os = require( 'os' )
15
16 local getmetatable = getmetatable
17 local require = require
18 local setmetatable = setmetatable
19 local tostring = tostring
20
21 --------------------------------------------------------------------------------
22 -- WikiContentFileService
23 --------------------------------------------------------------------------------
24
25 module( 'WikiContentFileService' )
26 _VERSION = '1.0'
27
28 local self = setmetatable( _M, {} )
29 local meta = getmetatable( self )
30
31 --------------------------------------------------------------------------------
32 -- Utilities
33 --------------------------------------------------------------------------------
34
35 local function ValidContent( aContent, aName )
36     if aContent
37     and aContent.exists
38     and ( '%s.txt' ):format( aContent.data.title ):lower() == aName:lower() then
39         return true
40     end
41 end
42
43 local function FindFile( aContent, aName )
44     aName = aName:lower()
45    
46     for aFile in aContent.file do
47         if aFile.name == aName then
48             return aFile
49         end
50     end
51 end
52
53 local function ValidFile( aContent, aName )
54     local aName = aName:lower();
55     local aReference = ( '%s/file/%s' ):format( aContent.name, aName )
56     local aFile = FindFile( aContent, aName )
57
58     if not aFile then
59         return false
60     end
61    
62     if not aContent.text:find( aReference, 1, true ) then
63         local aTime = os.time()
64         local anInterval = aTime - aFile.modification
65
66         if anInterval < 3600 then
67             return true
68         else
69             aFile.delete = true
70             return false
71         end
72     end
73    
74     return true
75 end
76
77 local function DAVContentResource( aContent )
78     local aName = ( '%s.txt' ):format( aContent.data.title )
79     local aCreation = aContent.creation
80     local aModification = aContent.modification
81     local aSize = aContent.text:len()
82     local aResource = { mode = 'file', creation = aCreation, modification = aModification, name = aName, size = aSize }
83    
84     return aResource
85 end
86
87 local function DAVFileResource( aContent, aName )
88     local aFile = FindFile( aContent, aName )
89     local aResource = { mode = aFile.mode, modification = aFile.modification, name = aFile.name, size = aFile.size }
90
91     return aResource   
92 end
93
94 local function DAVListIterator( aContent )
95     local anIterator = aContent.file
96    
97     return function()
98         local aFile = anIterator()
99        
100         if aFile then
101             local aResource = { mode = aFile.mode, modification = aFile.modification, name = aFile.name, size = aFile.size }
102            
103             return aResource
104         end
105     end
106 end
107
108 local function DAVListResource( aContent )
109     local anIterator = DAVListIterator( aContent )
110     local aModification = aContent.modification
111     local aResource = { iterator = anIterator, mode = 'directory', modification = aModification, size = 0 }
112    
113     return aResource
114 end
115
116 local function DAVResource( aContent, aName )
117     if not aName then
118         return DAVListResource( aContent )
119     elseif ValidContent( aContent, aName ) then
120         return DAVContentResource( aContent )
121     elseif ValidFile( aContent, aName ) then
122         return DAVFileResource( aContent, aName )
123     end
124 end
125
126 --------------------------------------------------------------------------------
127 -- Service methods
128 --------------------------------------------------------------------------------
129
130 function self:get()
131     local aContent = self.content
132     local aName = self.name
133
134     if aContent and aContent.exists and aName then   
135         local aName = aName:lower()
136        
137         if ValidContent( aContent, aName ) then
138             HTTP.response.header[ 'content-type' ] = 'text/plain; charset=utf-8'
139        
140             return aContent.text
141         elseif ValidFile( aContent, aName ) then
142             local File = require( 'File' )
143             local HTTPFile = require( 'HTTPFile' )
144             local aDirectory = File( aContent.directory.path, 'file', '' )
145             local aHandler = HTTPFile( aDirectory.path )
146            
147             return aHandler( aName )
148         end
149     end
150 end
151
152 --------------------------------------------------------------------------------
153 -- DAV service methods
154 --------------------------------------------------------------------------------
155
156 function self:options()
157     HTTP.response.header[ 'allow' ] = 'DELETE, GET, HEAD, LOCK, MOVE, OPTIONS, PROPFIND, PUT, UNLOCK'
158     HTTP.response.header[ 'content-type' ] = 'text/plain'
159    
160     return HTTP.response.header[ 'allow' ]
161 end
162
163 function self:propfind()
164     local aContent = self.content
165    
166     if aContent and aContent.exists then
167         local WikiDAV = require( 'WikiDAV' )
168         local aResource = DAVResource( aContent, self.name )
169    
170         if aResource then
171             return WikiDAV( aResource ):propfind()
172         end
173     end
174 end
175
176 --------------------------------------------------------------------------------
177 -- Metamethods
178 --------------------------------------------------------------------------------
179
180 function meta:__call( aContent, aName )
181     local aService = { content = aContent, name = aName }
182    
183     setmetatable( aService, self )
184    
185     return aService
186 end
187
188 function meta:__concat( aValue )
189     return tostring( self ) .. tostring( aValue )
190 end
191
192 function meta:__tostring()
193     return ( '%s/%s' ):format( self._NAME, self._VERSION )
194 end
195
196 function self:__index( aKey )
197     local aValue = getmetatable( self )[ aKey ]
198    
199     if not aValue and aKey:find( '^get.+' ) then
200         local aName = aKey:match( '^get(.+)$' )
201        
202         self.name = aName
203        
204         return function( self, anExtension )
205
206             self.name = ( '%s.%s' ):format( aName, anExtension or '' )
207
208             return self
209         end
210     elseif not aValue and aKey:find( '^propfind.+' ) then
211         local aName = aKey:match( '^propfind(.+)$' )
212        
213         self.name = aName
214
215         return function( self, anExtension )
216            
217             self.name = ( '%s.%s' ):format( aName, anExtension or '' )
218
219             return self
220         end
221     end
222    
223     self[ aKey ] = aValue
224    
225     return aValue
226 end
227
228 function self:__concat( aValue )
229     return tostring( self ) .. tostring( aValue )
230 end
231
232 function self:__tostring()
233     return tostring( self.name )
234 end
Note: See TracBrowser for help on using the browser.