Paste: start of multipart [ first try ] (erg plz take a look)

Author: randy7
Mode: factor
Date: Sun, 8 Feb 2009 09:21:12
Plain Text |
IN: multipart-upload

USING: io.pathnames io.files sequences arrays math.parser kernel combinators accessors 
       io.encodings.binary io.encodings.string ;

! This is just re-creating a captured example, so it's a specific use case, and should be generalized, according to the spec.

! Things I'm not sure about: 1) if length should be part of it.
!                            2) how to combine text with binary. 
! right now I convert the text to binary and append the file to it.
! I prefer to have data passed until the last moment, but will use write if the file gets corrupted otherwise.

! EXAMPLE:
! { } "HI I'm the content" "here's the field name!" <text-part> suffix
! "C:/video/2009/01-January-2009/01/SINGLE NEWS wmv and PHOTOS gif/20090101-01-China_Stocks_Biggest_Loser_in_2008.wmv"
! "file name field" <file-part> suffix
! "----------l3PMNll8CXjZ5BC7GGnaMo" build-multi-part
! "E:/mimetest2.txt" utf8 set-file-contents




TUPLE: text-part { content-disposition initial: "form-data" } field-name content ;
TUPLE: file-part file { content-disposition initial: "form-data" } field-name filename mimetype raw ;



: content-type-from-ext ( filename -- type )
    file-extension
    {
        {        [ "wmv" = ] [ "video/x-ms-wmv" ] }
        [ "sorry I don't know this type, please add the correct mimetype" throw  ]
    } cond ;

: content-type-by-data ( file -- type )
    ! a 'magic number' guesser. binding to 'file' or tap into its magic file. 
    "UNIMPLEMENTED. FUTURE WORK" throw ;

: content-type ( file -- type )
    content-type-from-ext ;
    

: <text-part> ( content field-name -- tuple )
    text-part new
    swap >>field-name
    swap >>content ;
    
: <file-part> ( file field-name -- tuple )
    file-part new
    swap >>field-name
    swap [ >>file ] [    
        [ file-name >>filename ] [ content-type >>mimetype ] [ binary file-contents >>raw ] tri 
                    ] bi ;
    
: nl+ ( str -- str ) "\r\n" prepend ;
: +nl ( str -- str ) "\r\n" append ;
: +2nl ( str -- str ) +nl +nl ;

: quote-me ( str -- str ) "\"" dup surround ;
: crlf-me ( str -- str ) "\r\n" dup surround ;

: dispo+name ( tuple -- dispo name )
    [ content-disposition>> "Content-Disposition: " prepend ]
    [ field-name>> quote-me "name=" prepend ] bi  ;


: build-file-part ( tuple -- str ) 
    [
        [ 
            [ dispo+name ] 
            [ filename>> quote-me "filename=" prepend ] bi 3array "; " join +nl 
        ]
        [ mimetype>> "Content-Type: " prepend +nl ] bi append 
        +nl binary decode
    ]    
    [ raw>> ] bi  append ; 
    

: build-text-part ( tuple -- str )
    [ dispo+name 2array "; " join +nl ] [ content>> nl+ ] bi append ;

: build-one-part ( tuple -- str )
    {
        { [ dup file-part? ] [ build-file-part ] }
        { [ dup text-part? ] [ build-text-part ] }
        [ "ERROR: expected a text-part or a file-part tuple" throw ]
    } cond ;

: content-length-txt ( str -- length-str )
    length number>string
    "Content-Length: " prepend +nl ;
    
: content-type-txt ( boundary -- str )
    "Content-Type: multipart/form-data; boundary=" prepend +nl ;

: -over ( x y -- y x y )
    dup -rot ;    
    
: join+before ( seq chars -- str )
    [ join ] keep prepend ;
    
    
: build-multi-part ( parts-seq boundary -- string ) ! seq of tuples and a boundary.
    swap
    [ text-part? ] partition append
    [ build-one-part ] map  
    over "--" prepend crlf-me join+before         ! boundary seq -> boundary seq boundary' -> boundary str
    -over [ content-length-txt ] [ content-type-txt ] [ ] tri*
    3append ;
    

Annotation: example's output

Author: randy
Mode: factor
Date: Sun, 8 Feb 2009 09:29:34
Plain Text |
Content-Length: 5242904
Content-Type: multipart/form-data; boundary=----------l3PMNll8CXjZ5BC7GGnaMo

------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="here's the field name!"

HI I'm the content
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="file name field"; filename="20090101-01-China_Stocks_Biggest_Loser_in_2008.wmv"
Content-Type: video/x-ms-wmv

0&ֲ²uֲŽfֳֲ¦ֳ™
! ...much more

Annotation: my reference was this

Author: randy7
Mode: factor
Date: Sun, 8 Feb 2009 09:31:13
Plain Text |
POST /my_videos_post HTTP/1.0
User-Agent: Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0
Host: sjc-v62.sjc.youtube.com
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: he-IL,he;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Referer: http://www.youtube.com/my_videos_upload
Cookie: VISITOR_INFO1_LIVE=RyMHgSrLn4o; __utmz=27069237.1233390205.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); GEO=568206017824927ddc9c8498480268e7cwwAAAAySUzUlnBiAPn1i0k=; use_hitbox=72c46ff6cbcdb7c5585c36411b6b334edAEAAAAw; LOGIN_INFO=72c7771eb065b1adf2809b9e6739cd2ce3QgAAAAbV91c2VyX2lkX0FORF9zZXNzaW9uX251bWJlcl9tZDVzIAAAADZjMGE2ZDhjMDg4M2ExOWEyODdmNWJiMGM5NzJjM2Y4dAkAAABtX3VzZXJfaWRsAgAAAIsWdAJ0FQAAAG1fYXV0aGVudGljYXRpb25fdHlwZXQIAAAAUEFTU1dPUkQw; dkv=dfc5f3aee8a93e4f7424c49b41a295cae3QJAAAAYWdlX3JhbmdlaQQAAAB0BwAAAG9wdF9vdXRpAQAAAHQDAAAAYWdlaRoAAAB0AgAAAGtscwwAAABPX01fSF9tal9WX1N0BAAAAGNhbnZUdAcAAAB2ZXJzaW9uaQcAAAB0DAAAAGVuY3J5cHRlZF9pZHMWAAAAOElvaDRhdE5ETzVhMFZ5MnFGbWF1UXQCAAAAa3V0AQAAAEJ0CgAAAHVzZXJfZ3JvdXB0AQAAAEow; PREF=f2=3&gl=US&uvdm=1; __utma=27069237.4483187181175769600.1233390205.1233909287.1233910413.4; __utmc=27069237; __utmb=27069237.4.10.1233910413
Cookie2: $Version=1
Connection: Keep-Alive
Content-Length: 5246827
Content-Type: multipart/form-data; boundary=----------l3PMNll8CXjZ5BC7GGnaMo

------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="upload_key"

4F9242EA83CED317-75903989AD07E7E0
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="addresser"

w7HZgXwNz6UKYUVASL8EXLliEGLcAbymNbYg55YPCRr5GhrkYD-1C-8sUO6Z1575IzSI3QLq_Al9blPDCvOnVg==
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_command"

myvideo_submit
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_myvideo_keywords"

news ntdtv ntd
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_myvideo_title"

Japanese Man Arrested, Scams Investors of Over a Billion
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_myvideo_descr"

CHANG: 
The head of a Japanese bedding firm has been arrested on suspicion of a scam that media say defrauded tens of thousands of investors. He’d promised them sky-high returns and "yen from heaven."

STORY: 
Television stations in Japan are broadcasting images of police plowing through a tight media scrum to get to 75 year old L&G Chairman Kazutsugi Nami. He had been awaiting his arrest at a restaurant near his home.

Police say Nami is one of 22 people suspected of committing fraud.

Japanese media say the executives, including Nami, who had earlier denied wrongdoing, are suspected of collecting close to 1 and a half billion U.S. dollars from about 37,000 people. They’d promised a 36 percent annual return on investment. The firm is now in the midst of bankruptcy procedures.

Nami and the others also collected funds in exchange for the firm's currency called "Enten.” Enten was written with Japanese characters for "yen" and "heaven." They said it could be used at company-sponsored bazaars and Internet markets.
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_myvideo_categories"

25
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="language"

EN
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_privacy"

private
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_private_share_entities"


------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="contact"


------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_date_day"

0
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_date_yr"

0
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_date_mon"

0
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="location"


------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_comments"

Yes
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_comment_ratings"

Yes
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_responses"

Kinda
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_embedding"

Yes
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_offweb"


------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_ratings"

Yes
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="allow_syndication"

Yes
------------l3PMNll8CXjZ5BC7GGnaMo
Content-Disposition: form-data; name="field_uploadfile"; filename="20090205-08-Japanese_Man_Arrested__Scams_Investors_of_Over_a_Billion_.wmv"
Content-Type: video/x-ms-wmv

<start of binary file>
0&?u?f???

New Annotation

Summary:
Author:
Mode:
Body: