aboutsummaryrefslogtreecommitdiff
path: root/src/bookmarks/builtins.cpp
blob: f7b6f3f628d4060d7e3039a33295b32d19c71e38 (plain)
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
96
97
98
99
100
101
102
103
104
105
/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#include "builtins.h"
#include "bookmarkmodel.h"
#include "configuration.h"
#include <QBuffer>
#include <QFile>
#include <iostream>
#include <spdlog/spdlog.h>

int builtins::bookmarks(const std::string &progname, std::vector<std::string>::const_iterator beginargs, std::vector<std::string>::const_iterator endargs)
{
    args::ArgumentParser parser("bookmarks",
        "If an output location is not specified, this command will append imported bookmarks to the browser's bookmarks.\n"
        "If an output location is specified, this command will load all XBEL-format bookmarks, then all JSON-format bookmarks, and write them to the output location.");
    parser.Prog(progname);

    args::HelpFlag help(parser, "help", "Display this help message and exit.", { 'h', "help" });
    args::ValueFlag<std::string> save(parser, "file, stdout", "Output location.", { 'e', "export" });
    args::ValueFlagList<std::string> import_xbel(parser, "bookmarks.xbel", "Import xbel format.", { 'x', "import-xbel" });
    args::ValueFlagList<std::string> import_json(parser, "bookmarks.json", "Import json format.", { 'j', "import-json" });

    try {
        parser.ParseArgs(beginargs, endargs);
    } catch(args::Help &) {
        std::cout << parser;
        return 0;
    } catch(args::Error &e) {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return -1;
    }

    auto *model = new BookmarkModel;

    // implicit bookmarks.path import
    if(!save) {
        Configuration conf;
        QFile f(conf.value<QString>("bookmarks.path").value());
        if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            BookmarkFormat<XbelFormat>(&f) >> model;
            f.close();
        }
    }

    for(const auto &i : args::get(import_xbel)) {
        QFile f(QString::fromStdString(i));
        if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            BookmarkFormat<XbelFormat>(&f) >> model;
            f.close();
        } else {
            spdlog::error("Could not open %s", i);
            return -1;
        }
    }

    for(const auto &i : args::get(import_json)) {
        QFile f(QString::fromStdString(i));
        if(f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            BookmarkFormat<FirefoxJsonFormat>(&f) >> model;
            f.close();
        } else {
            spdlog::error("Could not open %s", i);
            return -1;
        }
    }

    QIODevice *output = nullptr;
    if(save && args::get(save) == "stdout") {
        output = new QBuffer;
        QObject::connect(output, &QIODevice::aboutToClose, [output]() {
            output->seek(0);
            std::cout << qUtf8Printable(output->readAll()) << std::endl;
        });

        output->open(QIODevice::ReadWrite | QIODevice::Text);

    } else if(!save) {
        Configuration conf;
        output = new QFile(conf.value<QString>("bookmarks.path").value());
    } else {
        output = new QFile(QString::fromStdString(args::get(save)));
    }

    if(!output->isOpen()) {
        if(!output->open(QIODevice::ReadWrite | QIODevice::Text)) {
            spdlog::error("Could not open output");
            return -1;
        }
    }

    BookmarkFormat<XbelFormat> format(output);
    format << model;
    output->close();

    delete output;

    return 0;
}