<commit_before>! Copyright (C) 2014 <NAME>
! See http://factorcode.org/license.txt for BSD license

USING: accessors byte-arrays colors.constants combinators
formatting fry images images.loader images.loader.private
images.viewer io io.encodings.binary io.encodings.string
io.encodings.utf8 io.sockets io.styles kernel make math
math.parser namespaces present prettyprint sequences splitting
summary urls vocabs ;

IN: gopher

<PRIVATE

CONSTANT: A_TEXT CHAR: 0
CONSTANT: A_MENU CHAR: 1
CONSTANT: A_CSO CHAR: 2
CONSTANT: A_ERROR CHAR: 3
CONSTANT: A_MACBINHEX CHAR: 4
CONSTANT: A_PCBINHEX CHAR: 5
CONSTANT: A_UUENCODED CHAR: 6
CONSTANT: A_INDEX CHAR: 7
CONSTANT: A_TELNET CHAR: 8
CONSTANT: A_BINARY CHAR: 9
CONSTANT: A_DUPLICATE CHAR: +
CONSTANT: A_SOUND CHAR: s
CONSTANT: A_EVENT CHAR: e
CONSTANT: A_CALENDAR CHAR: c
CONSTANT: A_HTML CHAR: h
CONSTANT: A_TN3270 CHAR: T
CONSTANT: A_MIME CHAR: M
CONSTANT: A_IMAGE CHAR: I
CONSTANT: A_WHOIS CHAR: w
CONSTANT: A_QUERY CHAR: q
CONSTANT: A_GIF CHAR: g
CONSTANT: A_WWW CHAR: w
CONSTANT: A_PLUS_IMAGE CHAR: :
CONSTANT: A_PLUS_MOVIE CHAR: ;
CONSTANT: A_PLUS_SOUND CHAR: <

: get-binary ( selector -- binary )
    "\r\n" append utf8 encode write flush
    input-stream get (stream-contents-by-block) ;

: get-gif ( selector -- image )
    get-binary "gif" (image-class) load-image* ;

: get-text ( selector -- lines )
    "?" split1 [ "\t" glue ] when* "\r\n" append
    utf8 encode write flush
    input-stream get (stream-contents-by-block)
    utf8 decode string-lines
    "." over index [ head ] when* ;

TUPLE: gopher-link type name selector host port ;

M: gopher-link summary >url present ;

: <gopher-link> ( item -- gopher-link )
    [ "" ] [
        unclip swap "\t" split first4 gopher-link boa
    ] if-empty ;

M: gopher-link >url
    dup type>> CHAR: h = [
        selector>> "URL:" ?head drop
    ] [
        {
            [ host>> ] [ port>> ] [ type>> ] [ selector>> ]
        } cleave "gopher://%s:%s/%s%s" sprintf
    ] if >url ;

: get-menu ( selector -- lines )
    get-text [ <gopher-link> ] map ;

: get-selector ( selector -- stuff )
    "/" split1 "" or swap
    dup length 1 > [ string>number ] [ first ] if
    {
        { A_TEXT [ get-text ] }
        { A_MENU [ get-menu ] }
        { A_INDEX [ get-menu ] }
        { A_GIF [ get-gif ] }
        [ drop get-binary ]
    } case ;

PRIVATE>

ERROR: not-a-gopher-url url ;

: gopher ( url -- object )
    dup url? [ >url ] unless
    dup protocol>> "gopher" = [ not-a-gopher-url ] unless {
        [ host>> ]
        [ port>> 70 or <inet> binary ]
        [ path>> rest ]
    } cleave '[ _ get-selector ] with-client ;

: gopher. ( url -- )
    gopher {
        { [ dup byte-array? ] [ . ] }
        { [ dup image? ] [ image. ] }
        [
            [
                dup gopher-link? [
                    dup type>> CHAR: i = [
                        name>> print
                    ] [
                        [ name>> ] keep [
                            presented ,,
                            COLOR: blue foreground ,,
                        ] H{ } make format nl
                    ] if
                ] [
                    print
                ] if
            ] each
        ]
    } cond ;

"gopher-ui" require<commit_msg>gopher: don't require UI by default.<commit_after>! Copyright (C) 2014 <NAME>
! See http://factorcode.org/license.txt for BSD license

USING: accessors byte-arrays colors.constants combinators
formatting fry images images.loader images.loader.private
images.viewer io io.encodings.binary io.encodings.string
io.encodings.utf8 io.sockets io.styles kernel make math
math.parser namespaces present prettyprint sequences splitting
summary urls vocabs ;

IN: gopher

<PRIVATE

CONSTANT: A_TEXT CHAR: 0
CONSTANT: A_MENU CHAR: 1
CONSTANT: A_CSO CHAR: 2
CONSTANT: A_ERROR CHAR: 3
CONSTANT: A_MACBINHEX CHAR: 4
CONSTANT: A_PCBINHEX CHAR: 5
CONSTANT: A_UUENCODED CHAR: 6
CONSTANT: A_INDEX CHAR: 7
CONSTANT: A_TELNET CHAR: 8
CONSTANT: A_BINARY CHAR: 9
CONSTANT: A_DUPLICATE CHAR: +
CONSTANT: A_SOUND CHAR: s
CONSTANT: A_EVENT CHAR: e
CONSTANT: A_CALENDAR CHAR: c
CONSTANT: A_HTML CHAR: h
CONSTANT: A_TN3270 CHAR: T
CONSTANT: A_MIME CHAR: M
CONSTANT: A_IMAGE CHAR: I
CONSTANT: A_WHOIS CHAR: w
CONSTANT: A_QUERY CHAR: q
CONSTANT: A_GIF CHAR: g
CONSTANT: A_WWW CHAR: w
CONSTANT: A_PLUS_IMAGE CHAR: :
CONSTANT: A_PLUS_MOVIE CHAR: ;
CONSTANT: A_PLUS_SOUND CHAR: <

: get-binary ( selector -- binary )
    "\r\n" append utf8 encode write flush
    input-stream get (stream-contents-by-block) ;

: get-gif ( selector -- image )
    get-binary "gif" (image-class) load-image* ;

: get-text ( selector -- lines )
    "?" split1 [ "\t" glue ] when* "\r\n" append
    utf8 encode write flush
    input-stream get (stream-contents-by-block)
    utf8 decode string-lines
    "." over index [ head ] when* ;

TUPLE: gopher-link type name selector host port ;

M: gopher-link summary >url present ;

: <gopher-link> ( item -- gopher-link )
    [ "" ] [
        unclip swap "\t" split first4 gopher-link boa
    ] if-empty ;

M: gopher-link >url
    dup type>> CHAR: h = [
        selector>> "URL:" ?head drop
    ] [
        {
            [ host>> ] [ port>> ] [ type>> ] [ selector>> ]
        } cleave "gopher://%s:%s/%s%s" sprintf
    ] if >url ;

: get-menu ( selector -- lines )
    get-text [ <gopher-link> ] map ;

: get-selector ( selector -- stuff )
    "/" split1 "" or swap
    dup length 1 > [ string>number ] [ first ] if
    {
        { A_TEXT [ get-text ] }
        { A_MENU [ get-menu ] }
        { A_INDEX [ get-menu ] }
        { A_GIF [ get-gif ] }
        [ drop get-binary ]
    } case ;

PRIVATE>

ERROR: not-a-gopher-url url ;

: gopher ( url -- object )
    dup url? [ >url ] unless
    dup protocol>> "gopher" = [ not-a-gopher-url ] unless {
        [ host>> ]
        [ port>> 70 or <inet> binary ]
        [ path>> rest ]
    } cleave '[ _ get-selector ] with-client ;

: gopher. ( url -- )
    gopher {
        { [ dup byte-array? ] [ . ] }
        { [ dup image? ] [ image. ] }
        [
            [
                dup gopher-link? [
                    dup type>> CHAR: i = [
                        name>> print
                    ] [
                        [ name>> ] keep [
                            presented ,,
                            COLOR: blue foreground ,,
                        ] H{ } make format nl
                    ] if
                ] [
                    print
                ] if
            ] each
        ]
    } cond ;
{'fraction_non_alphanumeric': 0.12089598036207426, 'fraction_numerical': 0.00859159251304081, 'mean_word_length': 1.9889958734525448, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4980356', 'n_tokens_mistral': 2315, 'n_tokens_neox': 2183, 'n_words': 626}