~alcinnz/rhapsode

ref: 395b9e4658ba4e702c014f2b0f91816debdb9a77 rhapsode/src/main.c -rw-r--r-- 3.2 KiB
395b9e46 — Adrian Cochrane Add commandline flags. 4 years ago
                                                                                
489dd5c7 Adrian Cochrane
43479697 Adrian Cochrane
395b9e46 Adrian Cochrane
489dd5c7 Adrian Cochrane
505b29c3 Adrian Cochrane
489dd5c7 Adrian Cochrane
505b29c3 Adrian Cochrane
489dd5c7 Adrian Cochrane
395b9e46 Adrian Cochrane
489dd5c7 Adrian Cochrane
395b9e46 Adrian Cochrane
489dd5c7 Adrian Cochrane
395b9e46 Adrian Cochrane
489dd5c7 Adrian Cochrane
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include "HsFFI.h"

struct session;
struct session *c_newSession();
void c_freeSession(struct session*);

struct page;
struct page *c_initialReferer();
void *c_fetchURL(struct session*, char*, struct page*, char*);
//struct page **c_fetchURLs(struct session*, struct page*, char**); // FIXME segfaults.
void c_freePage(struct page*);

char *c_renderDoc(struct session*, struct page*);
char **c_extractLinks(struct page*);
char **c_docLinksAndRendering(struct session*, struct page*); // FIXME segfaults.

void write_links(FILE *dest, char **links) {
    for (int i = 0; strcmp(links[i], " ") != 0; i++) {
        fprintf(dest, "%s%c", links[i], (i % 3) == 2 ? '\n' : '\t');
    }
}

int main(int argc, char **argv) {
    hs_init(&argc, &argv);

    char *mimes = "text/html text/xml application/xml application/xhtml+xml text/plain";
    FILE *fd_ssml = NULL;
    FILE *fd_links = NULL;

    int c;
    opterr = 0;
    while ((c = getopt(argc, argv, "xs::l::h")) != -1) {
        switch (c) {
        case 'x':
            mimes = "text/xml application/xml application/xhtml+xml text/html text/plain";
            break;
        case 's':
            fd_ssml = optarg != NULL ? fopen(optarg, "w") : stdout;
            if (fd_ssml == NULL) {
                fprintf(stderr, "Failed to open file %s\n", optarg);
                hs_exit();
                return -1;
            }
            break;
        case 'l':
            fd_links = optarg != NULL ? fopen(optarg, "w") : stdout;
            if (fd_links == NULL) {
                fprintf(stderr, "Failed to open file %s\n", optarg);
                hs_exit();
                return -1;
            }
            break;
        case '?':
            fprintf(stderr, "Invalid flag %c\n\n", optopt);
        case 'h':
            fprintf(stderr, "USAGE: rhapsode [FLAGS] URL...\n");
            fprintf(stderr, "\t-x\tX(HT)ML\tIndicates to expect an X(HT)ML file.\n");
            fprintf(stderr, "\t-s\tsilent/SSML\tWrites SSML to the specified file or stdout.\n");
            fprintf(stderr, "\t\t\thttps://xkcd.com/1692/\n");
            fprintf(stderr, "\t-l\tlinks\tWrite extracted links to specifed file or stdout as TSV.\n");
            fprintf(stderr, "\t-h\thelp\tOutputs this usage information to stderr.\n");
            fprintf(stderr, "\t\t\tIf both -s & -l are enabled without an argument, writes to stderr instead.\n");

            hs_exit();
            return c == 'h' ? 0 : -1;
        }
    }
    if (fd_ssml == stdout && fd_links == stdout) fd_links = stderr;
    if (fd_ssml == NULL && fd_links == NULL) fd_ssml = stdout;

    struct session *session = c_newSession();
    struct page *referer = c_initialReferer();

    for (int i = optind; i < argc; i++) {
        printf("%s\n", argv[i]);
        struct page *page = c_fetchURL(session, mimes, referer, argv[i]);
        char *ssml = c_renderDoc(session, page);
        char **links = c_extractLinks(page);

        if (fd_ssml != NULL) fprintf(fd_ssml, "%s\n", ssml);
        if (fd_links != NULL) write_links(fd_links, links);

        c_freePage(page);
    }

    c_freePage(referer);
    c_freeSession(session);
    hs_exit();
}