~alcinnz/rhapsode

ref: 395b9e4658ba4e702c014f2b0f91816debdb9a77 rhapsode/src/main.c -rw-r--r-- 3.2 KiB
395b9e46 — Adrian Cochrane Add commandline flags. 4 years ago
                                                                                
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();
}