-------------------------------------------------------------------------------- -- Title: LWDirectoryService.lua -- Description: Like a square peg in a round hole -- Author: Raphaël Szwarc http://alt.textdrive.com/lua/ -- Creation Date: February 1, 2005 -- Legal: Copyright (C) 2005 Raphaël Szwarc -------------------------------------------------------------------------------- -- import dependencies local LWService = require( "LWService" ) local LWFileService = require( "LWFileService" ) local LWLink = require( "LWLink" ) local LWResponse = require( "LWResponse" ) local LWString = require( "LWString" ) local LWTemplate = require( "LWTemplate" ) local MIMEType = require( "MIMEType" ) local LUBundle = require( "LUBundle" ) local LUFormat = require( "LUFormat" ) local LUTask = require( "LUTask" ) local LFSFile = require( "LFSFile" ) local LUURI = require( "LUURI" ) local os = require( "os" ) local math = require( "math" ) -- define the class local super = LWService local self = super() -- class variable(s) local _template = nil -- initialization method function self:init( aPrefix, aPath, anAuthenticator ) super.init( self, aPrefix, anAuthenticator ) self._path = aPath return self end -- method to access this service directory function self:directory() if self._directory == nil then self._directory = LFSFile( self:path() ) end return self._directory end -- method to access this file service function self:fileService() if self._fileService == nil then local aPrefix = self:prefix() local aPath = self:path() local anAuthenticator = self:authenticator() self._fileService = LWFileService( aPrefix, aPath, anAuthenticator ) end return self._fileService end -- method to access this service path function self:path() return self._path end -- method to handle a GET method function self:handleGet( aContext, hasContent ) local aPath = self:pathWithContext( aContext ) if aPath == nil then local aDirectory = self:directory() local aPath = aDirectory:path() local lastModified = aDirectory:lastModified() local aTemplate = self:template() local aCount = 0 aTemplate:put( "encoding", LWResponse:encoding() ) aTemplate:put( "name", LWString:encode( aDirectory:pathComponents():last() ) ) for aFileName in aDirectory:iterator( LWFileService:filter() ) do local aFileTemplate = aTemplate:get( "files" ) local aFile = LFSFile( aPath, aFileName ) local lastModified = aFile:lastModified() local aLink = self:prefix() .. aFileName aFileTemplate:put( "size", LUFormat:formatNumber( math.ceil( aFile:size() / 1024 ) ) ) aFileTemplate:put( "date", os.date( "%x", lastModified ) ) aFileTemplate:put( "link", LWLink:encode( aLink ) ) aFileTemplate:put( "type", MIMEType:typeWithExtension( aFile:extension() ) ) aFileTemplate:put( "name", LWString:encode( aFileName ) ) aTemplate:put( "files", aFileTemplate ) aCount = aCount + 1 LUTask:yield() end aTemplate:put( "size", LUFormat:formatNumber( aCount ) ) aContext:response():headers():put( "etag", aDirectory:id() ) aContext:response():headers():put( "last-modified", LWResponse:stringWithTime( lastModified ) ) aContext:response():writeContent( aTemplate:toString(), hasContent ) else self:fileService():handleGet( aContext, hasContent ) end return self end -- method to access the directory template function self:template() if _template == nil then local aBundle = LUBundle:bundleWithName( "LWDirectoryService" ) local aFile = aBundle:fileWithName( "LWDirectoryService", "txt" ) _template = LWTemplate( aFile:content() ) end return _template:copy() end return self