2016-05-07 3 views
1

Ich habe Probleme mit dem Download media from the media uri auf den MMS-Nachrichten zur Verfügung gestellt.Laden Sie Mediendatei von Twilio, mit der Medien-URI

val url = https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx 

die bereitgestellten Medien-URL in der obigen Struktur ist,

new URL(url) #> new File("file.png") !! //this fails, due to multiple redirects 

Wenn ich den URI in Browser öffnen endet die Umleitung

http://media.twiliocdn.com.s3-external-1.amazonaws.com/xx/xx 

1. url in

up -> 2. url -> über url; so, insgesamt 2 Weiterleitungen

Und wenn ich den Ausschnitt oben mit der neuen URL versuche, funktioniert es. Ich bin mir sicher, dass es aufgrund der vielen Weiterleitungen das Snippet überhaupt nicht funktioniert hat.

benutze play Rahmen mit scala, kann ich jede beliebige Quelle Beispiel bekommen die Datei zum Download bereit. Jede Hilfe oder Hinweise wird geschätzt. Versuchte verschiedene Beispiele, konnte das Problem jedoch nicht lösen.

Einige Befunde => Accessing Twilio MMS images

etwas ähnliches für scala?

Update: @millhouse

def fileDownloader(urls: String, location: String) = { 

    import play.api.Play.current 
    import scala.concurrent.ExecutionContext.Implicits.global 

    // Make the request 
    val futureResponse: Future[(WSResponseHeaders, Enumerator[Array[Byte]])] = 
     WS.url(urls).withFollowRedirects(true).getStream() 

    futureResponse.flatMap { 
     case (headers, body) => 
     val file = new File(location) 
     val outputStream = new FileOutputStream(file) 

     // The iteratee that writes to the output stream 
     val iteratee = Iteratee.foreach[Array[Byte]] { bytes => 
      outputStream.write(bytes) 
     } 

     // Feed the body into the iteratee 
     (body |>>> iteratee).andThen { 
      case result => 
      // Close the output stream whether there was an error or not 
      outputStream.close() 
      // Get the result or rethrow the error 
      result.get 
     }.map(_ => file) 
    } 
    } 

Dies ist der Ansatz, den ich bisher verwendet hatte (Werke), wie in der Play-Dokumentation erklärt. Aber ich brauchte eine Sync-Ansatz, was bedeutet, ich würde einen weiteren Schrittauf erfolgreiche Datei herunterladen müssen. Entschuldigung, dass ich nicht klargestellt habe.

Update 2: auf diese Weise gelöst,

 def fileDownloader(urls: String, location: String) = { 

        import play.api.Play.current 
        import scala.concurrent.ExecutionContext.Implicits.global 

        // Make the request 
        val futureResponse: Future[(WSResponseHeaders, Enumerator[Array[Byte]])] = 
         WS.url(urls).withFollowRedirects(true).getStream() 

        val downloadedFile: Future[File] = futureResponse.flatMap { 
         case (headers, body) => 
         val file = new File(location) 
         val outputStream = new FileOutputStream(file) 

         // The iteratee that writes to the output stream 
         val iteratee = Iteratee.foreach[Array[Byte]] { bytes => 
          outputStream.write(bytes) 
         } 

         // Feed the body into the iteratee 
         (body |>>> iteratee).andThen { 
          case result => 
          // Close the output stream whether there was an error or not 
          outputStream.close() 
          // Get the result or rethrow the error 
          result.get 
         }.map(_ => file) 
        } 
    downloadedFile.map{ fileIn => 
       //things needed to do 
} 
        } 

Danke,

Antwort

2

Ich habe nicht den Twilio MMS-API, aber es sollte sehr einfach zu bekommen, das Play-Framework-HTTP-Client folgen Umleitungen verwendet , die documented option an den Client mit:

val url = "https://api.twilio.com/2010-04-01/Accounts/xx/Messages/xx/Media/xx" 

ws.url(url).withFollowRedirects(true).get().map { response => 
    val theBytes:Array[Byte] = response.bodyAsBytes // Play 2.4 and lower 
    // ... save it 
} 

Beachten Sie, dass der obige Code für Play 2.4.x funktioniert und niedriger; the bodyAsBytes method of WSResponse returns an Array[Byte]. Wenn Sie auf dem aktuellen topaktuelle und Play 2.5.x, bodyAsBytes Verwendung gibt Ihnen ein Akka ByteString mit vielen netten funktionellen Methoden, aber Sie wollen wahrscheinlich nur toArray auf sie nennen, wenn alles, was Sie wollen, ist es, die Daten zu speichern:

ws.url(url).withFollowRedirects(true).get().map { response => 
    val theBytes:Array[Byte] = response.bodyAsBytes.toArray // Play 2.5 
    // ... save it 
} 
+0

Danke für die Antwort. Aber ich kann nicht finden, dass "bodyAsBytes" Methode in Bezug auf die WS-Antwort. Vermisse ich irgendwelche Importe oder .... mit 2.3.8 btw – mane

+0

Könntest du mein Update, Millhouse überprüfen. Danke, – mane

+1

Danke für deine Hilfe @millhouse! Wenn Sie ein Dankeschön-T-Shirt von Twilio möchten, senden Sie eine E-Mail an [email protected] –