s3_website 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24289cabdc9ada72b1c10f123788231a7b5f6879
4
- data.tar.gz: 1e457defca86674d0696d2fd6e69cf811d8d323f
3
+ metadata.gz: e9175154b8b9b1982291616351c8540b0dee659c
4
+ data.tar.gz: cf87ecd7a6f989c21c98699d9ce6b43fdf025e6a
5
5
  SHA512:
6
- metadata.gz: 43fb218cd322b2fbf5eb47ffd161eeeba2c712b8eb86776842e7a47cc19e6ba5c5635c0d5afdb9c59068a7b3b00bc38cea37d0faf879fa8715dfdbc8415a2733
7
- data.tar.gz: 69d47fe090b0a591a8bbb9f37a9ea50ecf8bdf02ab150f4dbce672f513ea6faa1cc8f507abfc2de4987e0333992bc6e336173bc1d27273f572c7d4e2a2e868e3
6
+ metadata.gz: 5fce5e66cd6fe88902ec1d01441387e8d4bf725420face8c6e2ac8aaeaa226613b19fae7d476b3afa95807e611cb45492e565d385742599f4399cea8e9c8497f
7
+ data.tar.gz: 105be5233f7d9dc11f704f07e3e0878059751e3e1af3162fe86e51e5fa34a26d5b94437264ff55ddbc9147a0713ae11e990ae6e7f637a8965f222e6e16f90b70
data/README.md CHANGED
@@ -25,7 +25,7 @@ and [Java](http://java.com) to run.
25
25
  Here's how you can get started:
26
26
 
27
27
  * Create API credentials that have sufficient permissions to S3. More info
28
- [here](https://github.com/laurilehmijoki/s3_website/blob/master/additional-docs/setting-up-aws-credentials.md).
28
+ [here](additional-docs/setting-up-aws-credentials.md).
29
29
  * Go to your website directory
30
30
  * Run `s3_website cfg create`. This generates a configuration file called `s3_website.yml`.
31
31
  * Put your AWS credentials and the S3 bucket name into the file
@@ -85,7 +85,6 @@ syntax information.
85
85
  * Let the power users benefit from advanced S3 website features such as
86
86
  redirects, Cache-Control headers and gzip support
87
87
  * Be as fast as possible. Do in parallel all that can be done in parallel.
88
- * Maintain 90% backward compatibility with the jekyll-s3 gem
89
88
 
90
89
  `s3_website` attempts to be a command-line interface tool that is easy to
91
90
  understand and use. For example, `s3_website --help` should print you all the
@@ -343,10 +342,13 @@ operation would cause to your live website.
343
342
  Please read the [release note](/changelog.md#200) on version 2. It contains
344
343
  information on backward incompatible changes.
345
344
 
345
+ You can find the v1 branch
346
+ [here](https://github.com/laurilehmijoki/s3_website/tree/1.x). It's in
347
+ maintenance mode. This means that v1 will see only critical bugfix releases.
348
+
346
349
  ## Example configurations
347
350
 
348
- See
349
- <https://github.com/laurilehmijoki/s3_website/blob/master/additional-docs/example-configurations.md>.
351
+ See [example-configurations](additional-docs/example-configurations.md).
350
352
 
351
353
  ## On security
352
354
 
data/changelog.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  This project uses [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## 2.1.0
6
+
7
+ * Show the upload reason when calling `push --verbose`
8
+
9
+ ## 2.0.1
10
+
11
+ * Rename binary s3_website_monadic to s3_website
12
+
5
13
  ## 2.0.0
6
14
 
7
15
  ### New features
@@ -1,3 +1,3 @@
1
1
  module S3Website
2
- VERSION = '2.0.1'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -19,7 +19,7 @@ case class Diff(
19
19
 
20
20
  object Diff {
21
21
 
22
- type UploadBatch = Future[Either[ErrorReport, Seq[LocalFile]]]
22
+ type UploadBatch = Future[Either[ErrorReport, Seq[Upload]]]
23
23
 
24
24
  def resolveDiff(s3FilesFuture: Future[Either[ErrorReport, Seq[S3File]]])
25
25
  (implicit site: Site, logger: Logger, executor: ExecutionContextExecutor): Either[ErrorReport, Diff] =
@@ -35,31 +35,31 @@ object Diff {
35
35
  val s3Md5Index = s3Files.map(_.md5).toSet
36
36
  val siteFiles = Files.listSiteFiles
37
37
  val existsOnS3 = (f: File) => s3KeyIndex contains site.resolveS3Key(f)
38
- val isChangedOnS3 = (localFile: LocalFile) => !(s3Md5Index contains localFile.md5.get)
39
- val newFiles = siteFiles collect {
40
- case file if !existsOnS3(file) => LocalFile(file, NewFile)
38
+ val isChangedOnS3 = (upload: Upload) => !(s3Md5Index contains upload.md5.get)
39
+ val newUploads = siteFiles collect {
40
+ case file if !existsOnS3(file) => Upload(file, NewFile, reasonForUpload = "the file is missing from S3")
41
41
  }
42
- val changedFiles = siteFiles collect {
43
- case file if existsOnS3(file) => LocalFile(file, FileUpdate)
42
+ val changedUploads = siteFiles collect {
43
+ case file if existsOnS3(file) => Upload(file, FileUpdate, reasonForUpload = "the S3 bucket has different contents for this file")
44
44
  } filter isChangedOnS3
45
45
  val unchangedFiles = {
46
- val newOrChangedFiles = (changedFiles ++ newFiles).map(_.originalFile).toSet
46
+ val newOrChangedFiles = (changedUploads ++ newUploads).map(_.originalFile).toSet
47
47
  siteFiles.filterNot(f => newOrChangedFiles contains f)
48
48
  }
49
- val allFiles: Seq[Either[DbRecord, LocalFile]] = unchangedFiles.map {
49
+ val recordsAndUploads: Seq[Either[DbRecord, Upload]] = unchangedFiles.map {
50
50
  f => Left(DbRecord(f))
51
- } ++ (changedFiles ++ newFiles).map {
51
+ } ++ (changedUploads ++ newUploads).map {
52
52
  Right(_)
53
53
  }
54
- LocalFileDatabase persist allFiles
55
- allFiles
54
+ LocalFileDatabase persist recordsAndUploads
55
+ recordsAndUploads
56
56
  } match {
57
57
  case Success(ok) => Right(ok)
58
58
  case Failure(err) => Left(ErrorReport(err))
59
59
  }
60
60
  }
61
61
  }
62
- def collectResult[B](pf: PartialFunction[Either[DbRecord, LocalFile],B]) =
62
+ def collectResult[B](pf: PartialFunction[Either[DbRecord, Upload],B]) =
63
63
  diffAgainstS3.map { errorOrDiffSource =>
64
64
  errorOrDiffSource.right map (_ collect pf)
65
65
  }
@@ -67,7 +67,7 @@ object Diff {
67
67
  case Left(dbRecord) => dbRecord.s3Key
68
68
  }
69
69
  val uploads: UploadBatch = collectResult {
70
- case Right(localFile) => localFile
70
+ case Right(upload) => upload
71
71
  }
72
72
  Right(Diff(unchanged, uploads :: Nil, persistenceError = Future(None)))
73
73
  }
@@ -112,26 +112,28 @@ object Diff {
112
112
 
113
113
  def resolveDiffAgainstLocalDb(s3FilesFuture: Future[Either[ErrorReport, Seq[S3File]]])
114
114
  (implicit site: Site, logger: Logger, executor: ExecutionContextExecutor): Either[ErrorReport, Diff] = {
115
- val localDiff: Either[ErrorReport, Seq[Either[DbRecord, LocalFile]]] =
115
+ val localDiff: Either[ErrorReport, Seq[Either[DbRecord, Upload]]] =
116
116
  (for {
117
117
  dbFile <- getOrCreateDbFile
118
118
  databaseIndices <- loadDbFromFile(dbFile)
119
119
  } yield {
120
120
  val siteFiles = Files.listSiteFiles
121
- val recordsOrChangedFiles = siteFiles.foldLeft(Seq(): Seq[Either[DbRecord, LocalFile]]) { (localFiles, file) =>
121
+ val recordsOrUploads = siteFiles.foldLeft(Seq(): Seq[Either[DbRecord, Upload]]) { (recordsOrUps, file) =>
122
122
  val truncatedKey = TruncatedDbRecord(file)
123
123
  val fileIsUnchanged = databaseIndices.truncatedIndex contains truncatedKey
124
124
  if (fileIsUnchanged)
125
- localFiles :+ Left(databaseIndices.fullIndex find (_.truncated == truncatedKey) get)
125
+ recordsOrUps :+ Left(databaseIndices.fullIndex find (_.truncated == truncatedKey) get)
126
126
  else {
127
+ val isUpdate = databaseIndices.s3KeyIndex contains truncatedKey.s3Key
128
+
127
129
  val uploadType =
128
- if (databaseIndices.s3KeyIndex contains truncatedKey.s3Key) FileUpdate
130
+ if (isUpdate) FileUpdate
129
131
  else NewFile
130
- localFiles :+ Right(LocalFile(file, uploadType))
132
+ recordsOrUps :+ Right(Upload(file, uploadType, reasonForUpload(truncatedKey, databaseIndices, isUpdate)))
131
133
  }
132
134
  }
133
- logger.debug(s"Discovered ${siteFiles.length} files on the local site, of which ${recordsOrChangedFiles count (_.isRight)} are new or changed")
134
- recordsOrChangedFiles
135
+ logger.debug(s"Discovered ${siteFiles.length} files on the local site, of which ${recordsOrUploads count (_.isRight)} are new or changed")
136
+ recordsOrUploads
135
137
  }) match {
136
138
  case Success(ok) => Right(ok)
137
139
  case Failure(err) => Left(ErrorReport(err))
@@ -146,7 +148,7 @@ object Diff {
146
148
  case Right(f) => f
147
149
  }
148
150
 
149
- val changesMissedByLocalDiff: Future[Either[ErrorReport, Seq[LocalFile]]] = s3FilesFuture.map { errorOrS3Files =>
151
+ val changesMissedByLocalDiff: Future[Either[ErrorReport, Seq[Upload]]] = s3FilesFuture.map { errorOrS3Files =>
150
152
  for (s3Files <- errorOrS3Files.right) yield {
151
153
  val remoteS3Keys = s3Files.map(_.s3Key).toSet
152
154
  val localS3Keys = unchangedAccordingToLocalDiff.map(_.s3Key).toSet
@@ -154,11 +156,11 @@ object Diff {
154
156
  def isChangedOnS3(s3File: S3File) = (localS3Keys contains s3File.s3Key) && !(localMd5 contains s3File.md5)
155
157
  val changedOnS3 = s3Files collect {
156
158
  case s3File if isChangedOnS3(s3File) =>
157
- LocalFile(site resolveFile s3File, FileUpdate)
159
+ Upload(site resolveFile s3File, FileUpdate, reasonForUpload = "someone else has modified the file on the S3 bucket")
158
160
  }
159
161
  val missingFromS3 = localS3Keys collect {
160
162
  case localS3Key if !(remoteS3Keys contains localS3Key) =>
161
- LocalFile(site resolveFile localS3Key, NewFile)
163
+ Upload(site resolveFile localS3Key, NewFile, reasonForUpload = "someone else has removed the file from the S3 bucket")
162
164
 
163
165
  }
164
166
  changedOnS3 ++ missingFromS3
@@ -177,23 +179,23 @@ object Diff {
177
179
  val unchangedFilesFinal = errorOrDiffAgainstS3 map {
178
180
  _ fold (
179
181
  (error: ErrorReport) => Left(error),
180
- (syncResult: (Seq[DbRecord], Seq[LocalFile])) => Right(syncResult._1)
182
+ (syncResult: (Seq[DbRecord], Seq[Upload])) => Right(syncResult._1)
181
183
  )
182
184
  }
183
185
 
184
- val changedAccordingToS3Diff = errorOrDiffAgainstS3.map {
186
+ val uploadsAccordingToS3Diff = errorOrDiffAgainstS3.map {
185
187
  _ fold (
186
188
  (error: ErrorReport) => Left(error),
187
- (syncResult: (Seq[DbRecord], Seq[LocalFile])) => Right(syncResult._2)
189
+ (syncResult: (Seq[DbRecord], Seq[Upload])) => Right(syncResult._2)
188
190
  )
189
191
  }
190
192
  val persistenceError: Future[Either[ErrorReport, _]] = for {
191
193
  unchanged <- unchangedFilesFinal
192
- changedAccordingToS3 <- changedAccordingToS3Diff
194
+ uploads <- uploadsAccordingToS3Diff
193
195
  } yield
194
196
  for {
195
197
  records1 <- unchanged.right
196
- records2 <- changedAccordingToS3.right
198
+ records2 <- uploads.right
197
199
  } yield
198
200
  persist(records1.map(Left(_)) ++ records2.map(Right(_)) ++ uploadsAccordingToLocalDiff.map(Right(_))) match {
199
201
  case Success(_) => Unit
@@ -201,12 +203,28 @@ object Diff {
201
203
  }
202
204
  Diff(
203
205
  unchangedFilesFinal map (_.right.map(_ map (_.s3Key))),
204
- uploads = Future(Right(uploadsAccordingToLocalDiff)) :: changedAccordingToS3Diff :: Nil,
206
+ uploads = Future(Right(uploadsAccordingToLocalDiff)) :: uploadsAccordingToS3Diff :: Nil,
205
207
  persistenceError = persistenceError map (_.left.toOption)
206
208
  )
207
209
  }
208
210
  }
209
211
 
212
+ private def reasonForUpload(truncatedKey: TruncatedDbRecord, databaseIndices: DbIndices, isUpdate: Boolean) = {
213
+ if (isUpdate) {
214
+ val lengthChanged = !(databaseIndices.fileLenghtIndex contains truncatedKey.fileLength)
215
+ val mtimeChanged = !(databaseIndices.lastModifiedIndex contains truncatedKey.fileModified)
216
+ if (lengthChanged)
217
+ "file length has changed according to the local database"
218
+ else if (mtimeChanged)
219
+ "file mtime has changed according to the local database"
220
+ else if (mtimeChanged && lengthChanged)
221
+ "file mtime and length have changed according to the local database"
222
+ else
223
+ "programmer error: faulty logic in inferring the reason for upload"
224
+ }
225
+ else "file is new according to the local database"
226
+ }
227
+
210
228
  private def getOrCreateDbFile(implicit site: Site, logger: Logger) =
211
229
  Try {
212
230
  val dbFile = new File(getTempDirectory, "s3_website_local_db_" + sha256Hex(site.rootDirectory))
@@ -216,9 +234,11 @@ object Diff {
216
234
  }
217
235
 
218
236
  case class DbIndices(
219
- s3KeyIndex: Set[S3Key],
220
- truncatedIndex: Set[TruncatedDbRecord],
221
- fullIndex: Set[DbRecord]
237
+ s3KeyIndex: Set[S3Key],
238
+ fileLenghtIndex: Set[Long],
239
+ lastModifiedIndex: Set[Long],
240
+ truncatedIndex: Set[TruncatedDbRecord],
241
+ fullIndex: Set[DbRecord]
222
242
  )
223
243
 
224
244
  private def loadDbFromFile(databaseFile: File)(implicit site: Site, logger: Logger): Try[DbIndices] =
@@ -237,23 +257,25 @@ object Diff {
237
257
  DbIndices(
238
258
  s3KeyIndex = fullIndex map (_.s3Key),
239
259
  truncatedIndex = fullIndex map (TruncatedDbRecord(_)),
240
- fullIndex
260
+ fileLenghtIndex = fullIndex map (_.fileLength),
261
+ lastModifiedIndex = fullIndex map (_.fileModified),
262
+ fullIndex = fullIndex
241
263
  )
242
264
  }
243
265
 
244
- def persist(recordsOrChangedFiles: Seq[Either[DbRecord, LocalFile]])(implicit site: Site, logger: Logger): Try[Seq[Either[DbRecord, LocalFile]]] =
266
+ def persist(recordsOrUploads: Seq[Either[DbRecord, Upload]])(implicit site: Site, logger: Logger): Try[Seq[Either[DbRecord, Upload]]] =
245
267
  getOrCreateDbFile flatMap { dbFile =>
246
268
  Try {
247
- val dbFileContents = recordsOrChangedFiles.map { recordOrChangedFile =>
248
- val record: DbRecord = recordOrChangedFile fold(
269
+ val dbFileContents = recordsOrUploads.map { recordOrUpload =>
270
+ val record: DbRecord = recordOrUpload fold(
249
271
  record => record,
250
- changedFile => DbRecord(changedFile.s3Key, changedFile.originalFile.length, changedFile.originalFile.lastModified, changedFile.md5.get)
272
+ upload => DbRecord(upload.s3Key, upload.originalFile.length, upload.originalFile.lastModified, upload.md5.get)
251
273
  )
252
274
  record.s3Key :: record.fileLength :: record.fileModified :: record.uploadFileMd5 :: Nil mkString "|"
253
275
  } mkString "\n"
254
276
 
255
277
  write(dbFile, dbFileContents)
256
- recordsOrChangedFiles
278
+ recordsOrUploads
257
279
  }
258
280
  }
259
281
  }
@@ -275,6 +297,6 @@ object Diff {
275
297
 
276
298
  object DbRecord {
277
299
  def apply(original: File)(implicit site: Site): DbRecord =
278
- DbRecord(site resolveS3Key original, original.length, original.lastModified, LocalFile.md5(original).get)
300
+ DbRecord(site resolveS3Key original, original.length, original.lastModified, Upload.md5(original).get)
279
301
  }
280
302
  }
@@ -18,13 +18,13 @@ object S3 {
18
18
 
19
19
  def uploadRedirect(redirect: Redirect, a: Attempt = 1)
20
20
  (implicit config: Config, s3Settings: S3Setting, pushMode: PushMode, executor: ExecutionContextExecutor, logger: Logger) =
21
- upload(Right(redirect))
21
+ uploadToS3(Right(redirect))
22
22
 
23
- def uploadFile(localFile: LocalFile, a: Attempt = 1)
23
+ def uploadFile(up: Upload, a: Attempt = 1)
24
24
  (implicit config: Config, s3Settings: S3Setting, pushMode: PushMode, executor: ExecutionContextExecutor, logger: Logger) =
25
- upload(Left(localFile))
25
+ uploadToS3(Left(up))
26
26
 
27
- def upload(source: Either[LocalFile, Redirect], a: Attempt = 1)
27
+ def uploadToS3(source: Either[Upload, Redirect], a: Attempt = 1)
28
28
  (implicit config: Config, s3Settings: S3Setting, pushMode: PushMode, executor: ExecutionContextExecutor, logger: Logger):
29
29
  Future[Either[FailedUpload, SuccessfulUpload]] =
30
30
  Future {
@@ -35,7 +35,7 @@ object S3 {
35
35
  val report = SuccessfulUpload(
36
36
  source.fold(_.s3Key, _.s3Key),
37
37
  source.fold(
38
- localFile => Left(SuccessfulNewOrCreatedDetails(localFile.uploadType, localFile.uploadFile.get.length(), uploadDuration)),
38
+ upload => Left(SuccessfulNewOrCreatedDetails(upload.uploadType, upload.uploadFile.get.length(), uploadDuration, upload.reasonForUpload)),
39
39
  redirect => Right(SuccessfulRedirectDetails(redirect.uploadType, redirect.redirectTarget))
40
40
  ),
41
41
  putObjectRequest
@@ -44,7 +44,7 @@ object S3 {
44
44
  Right(report)
45
45
  } recoverWith retry(a)(
46
46
  createFailureReport = error => FailedUpload(source.fold(_.s3Key, _.s3Key), error),
47
- retryAction = newAttempt => this.upload(source, newAttempt)
47
+ retryAction = newAttempt => this.uploadToS3(source, newAttempt)
48
48
  )
49
49
 
50
50
  def delete(s3Key: S3Key, a: Attempt = 1)
@@ -60,18 +60,18 @@ object S3 {
60
60
  retryAction = newAttempt => this.delete(s3Key, newAttempt)
61
61
  )
62
62
 
63
- def toPutObjectRequest(source: Either[LocalFile, Redirect])(implicit config: Config): Try[PutObjectRequest] =
63
+ def toPutObjectRequest(source: Either[Upload, Redirect])(implicit config: Config): Try[PutObjectRequest] =
64
64
  source.fold(
65
- localFile =>
65
+ upload =>
66
66
  for {
67
- uploadFile <- localFile.uploadFile
68
- contentType <- localFile.contentType
67
+ uploadFile <- upload.uploadFile
68
+ contentType <- upload.contentType
69
69
  } yield {
70
70
  val md = new ObjectMetadata()
71
71
  md setContentLength uploadFile.length
72
72
  md setContentType contentType
73
- localFile.encodingOnS3.map(_ => "gzip") foreach md.setContentEncoding
74
- localFile.maxAge foreach { seconds =>
73
+ upload.encodingOnS3.map(_ => "gzip") foreach md.setContentEncoding
74
+ upload.maxAge foreach { seconds =>
75
75
  md.setCacheControl(
76
76
  if (seconds == 0)
77
77
  s"no-cache; max-age=$seconds"
@@ -79,7 +79,7 @@ object S3 {
79
79
  s"max-age=$seconds"
80
80
  )
81
81
  }
82
- val req = new PutObjectRequest(config.s3_bucket, localFile.s3Key, new FileInputStream(uploadFile), md)
82
+ val req = new PutObjectRequest(config.s3_bucket, upload.s3Key, new FileInputStream(uploadFile), md)
83
83
  config.s3_reduced_redundancy.filter(_ == true) foreach (_ => req setStorageClass ReducedRedundancy)
84
84
  req
85
85
  }
@@ -146,7 +146,7 @@ object S3 {
146
146
  }
147
147
 
148
148
  case class SuccessfulRedirectDetails(uploadType: UploadType, redirectTarget: String)
149
- case class SuccessfulNewOrCreatedDetails(uploadType: UploadType, uploadSize: Long, uploadDuration: Option[Long])
149
+ case class SuccessfulNewOrCreatedDetails(uploadType: UploadType, uploadSize: Long, uploadDuration: Option[Long], reasonForUpload: String)
150
150
 
151
151
  case class SuccessfulUpload(s3Key: S3Key,
152
152
  details: Either[SuccessfulNewOrCreatedDetails, SuccessfulRedirectDetails],
@@ -167,12 +167,20 @@ object S3 {
167
167
  md.getContentEncoding ::
168
168
  putObjectRequest.getStorageClass ::
169
169
  Nil map (Option(_)) // AWS SDK may return nulls
170
- ) :+ uploadSizeForHumans :+ uploadSpeedForHumans
170
+ ) :+ uploadSizeForHumans :+ uploadSpeedForHumans :+ uploadReason
171
171
  detailFragments.collect {
172
172
  case Some(detailFragment) => detailFragment
173
173
  }.mkString(" | ")
174
174
  }
175
175
 
176
+ lazy val uploadReason =
177
+ details
178
+ .fold(uploadDetails => Some(uploadDetails.reasonForUpload), _ => None)
179
+ .collect {
180
+ case reasonForUpload if logger.verboseOutput =>
181
+ s"upload reason: $reasonForUpload"
182
+ }
183
+
176
184
  lazy val uploadSize = details.fold(
177
185
  newOrCreatedDetails => Some(newOrCreatedDetails.uploadSize),
178
186
  redirectDetails => None
@@ -7,7 +7,7 @@ import java.util.zip.GZIPOutputStream
7
7
  import org.apache.tika.Tika
8
8
  import s3.website.Ruby._
9
9
  import s3.website._
10
- import s3.website.model.LocalFile.tika
10
+ import s3.website.model.Upload.tika
11
11
  import s3.website.model.Encoding.encodingOnS3
12
12
  import java.io.File.createTempFile
13
13
  import org.apache.commons.io.IOUtils.copy
@@ -50,7 +50,7 @@ case object RedirectFile extends UploadType {
50
50
  val pushAction = Redirected
51
51
  }
52
52
 
53
- case class LocalFile(originalFile: File, uploadType: UploadType)(implicit site: Site) {
53
+ case class Upload(originalFile: File, uploadType: UploadType, reasonForUpload: String)(implicit site: Site) {
54
54
  lazy val s3Key = site.resolveS3Key(originalFile)
55
55
 
56
56
  lazy val encodingOnS3 = Encoding.encodingOnS3(s3Key)
@@ -60,7 +60,7 @@ case class LocalFile(originalFile: File, uploadType: UploadType)(implicit site:
60
60
  *
61
61
  * May throw an exception, so remember to call this in a Try or Future monad
62
62
  */
63
- lazy val uploadFile: Try[File] = LocalFile uploadFile originalFile
63
+ lazy val uploadFile: Try[File] = Upload uploadFile originalFile
64
64
 
65
65
  lazy val contentType: Try[String] = tika map { tika =>
66
66
  val mimeType = tika.detect(originalFile)
@@ -92,10 +92,10 @@ case class LocalFile(originalFile: File, uploadType: UploadType)(implicit site:
92
92
  /**
93
93
  * May throw an exception, so remember to call this in a Try or Future monad
94
94
  */
95
- lazy val md5 = LocalFile md5 originalFile
95
+ lazy val md5 = Upload md5 originalFile
96
96
  }
97
97
 
98
- object LocalFile {
98
+ object Upload {
99
99
  lazy val tika = Try(new Tika())
100
100
 
101
101
  def md5(originalFile: File)(implicit site: Site): Try[MD5] =
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_website
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lauri Lehmijoki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-03 00:00:00.000000000 Z
11
+ date: 2014-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor