FtpURI.st
changeset 1271 ca2e206e7c7f
parent 1268 48b43aebf125
child 1275 7f2285cefdec
equal deleted inserted replaced
1270:01f4dc0293cd 1271:ca2e206e7c7f
    34 ! !
    34 ! !
    35 
    35 
    36 !FtpURI methodsFor:'ftp requests'!
    36 !FtpURI methodsFor:'ftp requests'!
    37 
    37 
    38 connectThenDo:aOneArgBlock
    38 connectThenDo:aOneArgBlock
       
    39     "setup a ftp connection and call aOneArgBlock with it"
    39 
    40 
    40     |ftp|
    41     |ftp|
    41 
    42 
    42     ftp := FTPClient new.
    43     ftp := FTPClient new.
    43 
       
    44 
       
    45     [
    44     [
    46         ftp connectTo:self host 
    45         ftp connectTo:self host 
    47             port:self port 
    46             port:self port 
    48             user:(self user ? self defaultUser)
    47             user:(self user ? self defaultUser)
    49             password:(self password ? self defaultPassword).
    48             password:(self password ? self defaultPassword).
    53             ftp close.
    52             ftp close.
    54         ].
    53         ].
    55     ]
    54     ]
    56 !
    55 !
    57 
    56 
    58 pathExists
    57 exists
    59     "establish a connection for try to get a readSteream"
    58     "does the file represented by this uri exist?
       
    59      establish a connection for try to get a readStream"
    60 
    60 
    61     |exists|
    61     |exists|
    62 
    62 
    63     self connectThenDo:[:aFtpClient|
    63     self connectThenDo:[:aFtpClient|
    64         exists := self pathExistsFtp:aFtpClient.
    64         exists := self pathExistsFtp:aFtpClient.
    96     self connectThenDo:[:ftp| |stream path attributes|
    96     self connectThenDo:[:ftp| |stream path attributes|
    97         [
    97         [
    98             path := self path.
    98             path := self path.
    99             attributes := self class attributes.
    99             attributes := self class attributes.
   100             attributes at:#fileSize put:(ftp sizeOf:path).
   100             attributes at:#fileSize put:(ftp sizeOf:path).
   101             attributes at:#baseName put:self pathSegements last.  
   101             attributes at:#baseName put:self pathSegments last.  
   102             attributes at:#uriInfo  put:self printString.  
   102             attributes at:#uriInfo  put:self printString.  
   103 
   103 
   104             stream := ftp getStreamFor:path.
   104             stream := ftp getStreamFor:path.
   105             aBlock value:stream value:attributes.
   105             aBlock value:stream value:attributes.
   106         ] ensure:[
   106         ] ensure:[
   124      - or a collection with streams on a directorie's files, but not recursive
   124      - or a collection with streams on a directorie's files, but not recursive
   125 
   125 
   126      The streams are closed after aBlock has been evaluated.
   126      The streams are closed after aBlock has been evaluated.
   127      Attributes may be the mime type (key #MIME)"
   127      Attributes may be the mime type (key #MIME)"
   128 
   128 
   129     self readStreamsDo:aBlock skipFilenamesWithSuffix:nil thenRemove:false
   129     self readStreamsDo:aBlock skipFilenamesWithSuffix:nil renameBlock:nil
   130 !
   130 !
   131 
   131 
   132 readStreamsDo:aBlock skipFilenamesWithSuffix:aSuffix thenRemove:doRemoveSource
   132 readStreamsDo:aBlock renameBlock:renameBlock
   133     "evaluate the block with a Collection of streams as first argument
   133     "evaluate the block with a Collection of streams as first argument
   134      and a dictionary containing attributes as second argument,
   134      and a dictionary containing attributes as second argument,
   135      - a collection with a stream on a single file,
   135      - a collection with a stream on a single file,
   136      - or a collection with streams on a directorie's files, but not recursive
   136      - or a collection with streams on a directorie's files, but not recursive
   137 
   137 
   138      The streams are closed after aBlock has been evaluated.
   138      The streams are closed after aBlock has been evaluated.
   139      Attributes may be the mime type (key #MIME)"
   139      Attributes may be the mime type (key #MIME)"
   140 
   140 
   141     |attributes list requestDirectory path dirPath|
   141     self readStreamsDo:aBlock skipFilenamesWithSuffix:nil renameBlock:renameBlock
       
   142 !
       
   143 
       
   144 readStreamsDo:aBlock skipFilenamesWithSuffix:skipSuffix renameBlock:renameBlock
       
   145     "evaluate the block with a Collection of streams as first argument
       
   146      and a dictionary containing attributes as second argument,
       
   147      - a collection with a stream on a single file,
       
   148      - or a collection with streams on a directorie's files, but not recursive
       
   149 
       
   150      The streams are closed after aBlock has been evaluated.
       
   151      Attributes may be the mime type (key #MIME)"
       
   152 
       
   153     |attributes list requestDirectory path dirUri dirPath|
   142 
   154 
   143     requestDirectory := false.
   155     requestDirectory := false.
   144     path := self path.
   156     path := self path.
   145     "kludge"
   157     "kludge"
   146     (path startsWith:'/~') ifTrue:[
   158     (path startsWith:'/~') ifTrue:[
   147         path := path copyFrom:2.
   159         path := path copyFrom:2.
   148     ].
   160     ].
       
   161 
   149     attributes := self class attributes.
   162     attributes := self class attributes.
   150     list := OrderedCollection new.
   163     list := OrderedCollection new.
   151 
   164 
   152     self connectThenDo:[:ftp|
   165     self connectThenDo:[:ftp| |baseName|
   153         FTPClient fileErrorSignal handle:[:ex|
   166         "try to change directory to path.
   154             list add:path.
   167          If we get a file error, we know that the directory does not exist"
   155             attributes at:#requestDirectory put:false.
   168         baseName := self baseName.
   156         ] do:[
   169         (baseName includesAny:'*?[]') ifTrue:[
   157             dirPath := path.
   170             requestDirectory := true.
       
   171             dirUri  := self directory.
       
   172             dirPath := dirUri path.
   158             ftp cd:dirPath.
   173             ftp cd:dirPath.
   159             requestDirectory := true.
   174             list addAll:
   160             attributes at:#requestDirectory put:true.
   175                 (ftp nlist select:[:filenameString| filenameString matches:baseName]).
   161             list addAll:((ftp list) collect:[:aLine| aLine asCollectionOfWords last]).
   176         ] ifFalse:[
   162         ].
   177             [
   163 
   178                 dirUri := self.
   164         requestDirectory ifFalse:[ |bName|
   179                 dirPath := path.
   165             bName := self pathSegements last.
   180                 ftp cd:dirPath.
   166             (bName startsWith:'*') ifTrue:[
       
   167                 list removeAll.
       
   168                 requestDirectory := true.
   181                 requestDirectory := true.
   169                 attributes at:#requestDirectory put:true.
   182                 list addAll:ftp nlist.
   170                 dirPath := (path asFilename directory) pathName.
   183             ] on:FTPClient fileErrorSignal do:[:ex|
   171                 ftp cd:dirPath.
   184                 "no directory, fetch path istSelf"
   172                 list addAll:((ftp list) collect:[:aLine| aLine asCollectionOfWords last]).
   185             ].
   173             ].
   186         ].
   174             (bName startsWith:'*.') ifTrue:[ |rest|
   187         requestDirectory ifFalse:[
   175                 rest := bName restAfter:$*.
   188             dirUri := self directory.
   176                 (rest includesString:'*') ifTrue:[
   189             dirPath := dirUri path.
   177                     self error:'can''t resolve path:', self printString
   190             ftp cd:dirPath.
       
   191             list add:self baseName.
       
   192         ].
       
   193 
       
   194         attributes at:#requestDirectory put:requestDirectory.
       
   195 
       
   196         "skip all files with skipSuffix aka 'file.old'"
       
   197         skipSuffix size == 0 ifFalse:[
       
   198             list := list select:[:baseName| (baseName endsWith:skipSuffix) not]
       
   199         ].
       
   200 
       
   201         list do:[:eachBaseName| |stream|
       
   202             "get a stream for the contents of the file"
       
   203             FTPClient fileErrorSignal handle:[:ex| 
       
   204                 "ignore errors -- skip subdirectories"
       
   205             ] do:[
       
   206                 stream := ftp getStreamFor:eachBaseName.
       
   207                 attributes at:#fileSize put:(ftp sizeOf:eachBaseName).
       
   208                 attributes at:#baseName put:eachBaseName.
       
   209             ].
       
   210 
       
   211             stream notNil ifTrue:[ |srcUri srcPath|
       
   212                 requestDirectory ifTrue:[
       
   213                     "accessing the contents of a directory"
       
   214                     srcUri := dirUri construct:eachBaseName.
       
   215                 ] ifFalse:[ |pathSegments|
       
   216                     "accessing a single file"
       
   217                     srcUri := self.
   178                 ].
   218                 ].
   179                 list := list select:[:str| str endsWith:rest ]
   219                 attributes at:#uriInfo put:srcUri.  
   180             ].
   220 
   181         ].
   221                 [ 
   182 
   222                     aBlock value:stream value:attributes 
   183         aSuffix size ~~ 0 ifTrue:[
   223                 ] ensure:[stream close].
   184             list := list select:[:str| (str endsWith:aSuffix) not ]
   224 
   185         ].
   225                 renameBlock notNil ifTrue:[ |renameFilenameString|
   186 
   226                     renameFilenameString := renameBlock value:eachBaseName.
   187         list do:[:aPathName| |baseName stream|
   227                     [
   188             FTPClient fileErrorSignal handle:[:ex| 
   228                         ftp rename:eachBaseName to:renameFilenameString.
   189                 "/ skip subdirectories and the summary of the list
   229                     ] on:FTPClient fileErrorSignal do:[:ex|
   190             ] do:[
   230                         "rename failed, maybe file already exists"
   191                 stream := ftp getStreamFor:aPathName.
   231                         renameFilenameString := renameFilenameString, '.', 
   192                 attributes at:#fileSize put:(ftp sizeOf:aPathName).
   232                             (AbsoluteTime now printStringFormat:'%(year)%(mon)%(day)%h%m%s').
   193                 requestDirectory 
   233                         ftp rename:eachBaseName to:renameFilenameString.
   194                     ifTrue:[  baseName := aPathName ] 
   234                     ]
   195                     ifFalse:[ baseName := self pathSegements last ].
       
   196                 attributes at:#baseName put:baseName
       
   197             ].
       
   198 
       
   199             stream notNil ifTrue:[ |src srcPath|
       
   200                 (self pathSegements includes:baseName) ifTrue:[ 
       
   201                     srcPath := (dirPath asFilename) pathName.
       
   202                     attributes at:#uriInfo put:self.  
       
   203                 ] ifFalse:[ |pathSegements|
       
   204                     src := self copy.
       
   205                     pathSegements := (dirPath asFilename construct:baseName) components.
       
   206                     pathSegements removeFirst.
       
   207                     src pathSegements:pathSegements.
       
   208                     srcPath := src path.
       
   209                     attributes at:#uriInfo put:src.  
       
   210                 ].
   235                 ].
   211 
       
   212                 [ aBlock value:stream value:attributes ] 
       
   213                     ensure:[ stream close ].
       
   214                 doRemoveSource == true ifTrue:[ 
       
   215                     (srcPath startsWith:'/') ifFalse:[ srcPath := '/', srcPath ].
       
   216                     ftp delete:srcPath.
       
   217                 ].
       
   218             ].
   236             ].
   219         ].
   237         ].
   220     ].
   238     ].
   221 
   239 
   222 
   240 
   223     "
   241     "
   224         |pwd|
   242         |pwd|
   225 
   243 
   226         pwd := Dialog requestPassword:''. 
   244         pwd := Dialog requestPassword:''. 
   227         (URI fromString:('ftp://tm:%1@exept/home/tm/tmp' bindWith:pwd) ) 
   245         (URI fromString:('ftp://tm:%1@exept/~/tmp' bindWith:pwd) ) 
   228             readStreamsDo:[:stream :attributes | 
   246             readStreamsDo:[:stream :attributes | 
   229                 Transcript showCR:(attributes at:#baseName).
   247                 Transcript showCR:(attributes at:#baseName).
   230                 Transcript showCR:(attributes at:#fileSize).
   248                 Transcript showCR:(attributes at:#fileSize).
   231                 Transcript showCR:(attributes at:#requestDirectory).
   249                 Transcript showCR:(attributes at:#requestDirectory).
   232                 Transcript showCR:(attributes at:#uriInfo).
   250                 Transcript showCR:(attributes at:#uriInfo).
   233             ].
   251             ].
   234     "
   252     "
   235 !
   253 !
   236 
   254 
   237 readStreamsDo:aBlock thenRemove:doRemoveSource
       
   238     "evaluate the block with a Collection of streams as first argument
       
   239      and a dictionary containing attributes as second argument,
       
   240      - a collection with a stream on a single file,
       
   241      - or a collection with streams on a directorie's files, but not recursive
       
   242 
       
   243      The streams are closed after aBlock has been evaluated.
       
   244      Attributes may be the mime type (key #MIME)"
       
   245 
       
   246     self readStreamsDo:aBlock skipFilenamesWithSuffix:nil thenRemove:doRemoveSource
       
   247 !
       
   248 
       
   249 writeStreamDo:aBlock
   255 writeStreamDo:aBlock
   250     "use FTPClient for now"
   256     "use FTPClient for now"
   251 
   257 
   252     self connectThenDo:[:ftp| |stream|
   258     self connectThenDo:[:ftp| |stream|
   253         [
   259         [
   254             ftp connectTo:self host 
       
   255                 port:self port 
       
   256                 user:(self user ? self defaultUser)
       
   257                 password:(self password ? self defaultPassword).
       
   258             stream := ftp putStreamFor:self path.
   260             stream := ftp putStreamFor:self path.
   259             aBlock value:stream value:self class attributes.
   261             aBlock value:stream value:self class attributes.
   260         ] ensure:[
   262         ] ensure:[
   261             stream notNil ifTrue:[
   263             stream notNil ifTrue:[
   262                 stream close.
   264                 stream close.
   284         an intermediate file theat will be renamed"
   286         an intermediate file theat will be renamed"
   285 
   287 
   286     |path toPath directory|
   288     |path toPath directory|
   287 
   289 
   288     path := self path.
   290     path := self path.
       
   291     "kludge"
       
   292     (path startsWith:'/~') ifTrue:[
       
   293         path := path copyFrom:2.
       
   294     ].
       
   295 
   289     doAtomic ifTrue:[
   296     doAtomic ifTrue:[
   290         toPath := self directoryPath, '/.transferFile'.
   297         toPath := self directoryPath, '/.transferFile'.
       
   298         "kludge"
       
   299         (toPath startsWith:'/~') ifTrue:[
       
   300             toPath := toPath copyFrom:2.
       
   301         ].
   291     ] ifFalse:[
   302     ] ifFalse:[
   292         toPath := path.
   303         toPath := path.
   293     ].
   304     ].
   294         
   305         
   295     self connectThenDo:[:ftp| |stream|
   306     self connectThenDo:[:ftp| |stream|
   296         [
   307         [
   297             ftp connectTo:self host 
       
   298                 port:self port 
       
   299                 user:(self user ? self defaultUser)
       
   300                 password:(self password ? self defaultPassword).
       
   301 
       
   302             [
   308             [
   303                 stream := ftp putStreamFor:toPath.
   309                 stream := ftp putStreamFor:toPath.
   304             ] on:FTPClient filePutErrorSignal do:[:ex|
   310             ] on:FTPClient filePutErrorSignal do:[:ex|
   305                 doCreate ifFalse:[
   311                 doCreate ifFalse:[
   306                     ex reject
   312                     ex reject
   312                 ].
   318                 ].
   313                 ftp cd:directory.
   319                 ftp cd:directory.
   314                 stream := ftp putStreamFor:toPath.
   320                 stream := ftp putStreamFor:toPath.
   315             ].
   321             ].
   316             aBlock value:stream value:self class attributes.
   322             aBlock value:stream value:self class attributes.
       
   323             stream close.
   317             doAtomic ifTrue:[
   324             doAtomic ifTrue:[
   318                 ftp rename:toPath to:path
   325                 ftp rename:toPath to:path
   319             ].
   326             ].
   320         ] ensure:[
   327         ] ifCurtailed:[
   321             stream notNil ifTrue:[
   328             stream notNil ifTrue:[
   322                 stream close.
   329                 stream close.
   323             ].
   330             ].
   324         ].
   331         ].
   325     ]
   332     ]
   334 ! !
   341 ! !
   335 
   342 
   336 !FtpURI class methodsFor:'documentation'!
   343 !FtpURI class methodsFor:'documentation'!
   337 
   344 
   338 version
   345 version
   339     ^ '$Header: /cvs/stx/stx/libbasic2/FtpURI.st,v 1.8 2003-07-11 12:48:15 stefan Exp $'
   346     ^ '$Header: /cvs/stx/stx/libbasic2/FtpURI.st,v 1.9 2003-07-13 22:49:52 stefan Exp $'
   340 ! !
   347 ! !