summaryrefslogtreecommitdiff
path: root/Applications/ChanViewer/ThreadCatalogModel.cpp
blob: 328a3f8e983f1ba570f025c0b3822e10424f8651 (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "ThreadCatalogModel.h"
#include <AK/JsonArray.h>
#include <AK/JsonObject.h>
#include <AK/JsonValue.h>
#include <LibCore/CHttpRequest.h>
#include <LibCore/CNetworkJob.h>
#include <LibCore/CNetworkResponse.h>
#include <stdio.h>

ThreadCatalogModel::ThreadCatalogModel()
{
    update();
}

ThreadCatalogModel::~ThreadCatalogModel()
{
}

void ThreadCatalogModel::update()
{
    CHttpRequest request;
    request.set_hostname("a.4cdn.org");
    request.set_path("/g/catalog.json");

    auto* job = request.schedule();

    job->on_finish = [job, this](bool success) {
        auto* response = job->response();
        dbg() << "Catalog download finished, success=" << success << ", response=" << response;

        if (!success)
            return;

        dbg() << "Catalog payload size: " << response->payload().size();

        auto json = JsonValue::from_string(response->payload());

        if (json.is_array()) {
            JsonArray new_catalog;

            for (auto& page : json.as_array().values()) {
                if (!page.is_object())
                    continue;
                auto threads_value = page.as_object().get("threads");
                if (!threads_value.is_array())
                    continue;
                for (auto& thread : threads_value.as_array().values()) {
                    new_catalog.append(thread);
                }
            }

            m_catalog = move(new_catalog);
        }

        did_update();
    };
}

int ThreadCatalogModel::row_count(const GModelIndex&) const
{
    return m_catalog.size();
}

String ThreadCatalogModel::column_name(int column) const
{
    switch (column) {
    case Column::ThreadNumber:
        return "#";
    case Column::Text:
        return "Text";
    case Column::ReplyCount:
        return "Replies";
    case Column::ImageCount:
        return "Images";
    case Column::PostTime:
        return "Time";
    default:
        ASSERT_NOT_REACHED();
    }
}

GModel::ColumnMetadata ThreadCatalogModel::column_metadata(int column) const
{
    switch (column) {
    case Column::ThreadNumber:
        return { 70, TextAlignment::CenterRight };
    case Column::Text:
        return { 290, TextAlignment::CenterLeft };
    case Column::ReplyCount:
        return { 45, TextAlignment::CenterRight };
    case Column::ImageCount:
        return { 40, TextAlignment::CenterRight };
    case Column::PostTime:
        return { 120, TextAlignment::CenterLeft };
    default:
        ASSERT_NOT_REACHED();
    }
}

GVariant ThreadCatalogModel::data(const GModelIndex& index, Role role) const
{
    auto& thread = m_catalog.at(index.row()).as_object();
    if (role == Role::Display) {
        switch (index.column()) {
        case Column::ThreadNumber:
            return thread.get("no").to_u32();
        case Column::Text:
            return thread.get("com").to_string();
        case Column::ReplyCount:
            return thread.get("replies").to_u32();
        case Column::ImageCount:
            return thread.get("images").to_u32();
        case Column::PostTime:
            return thread.get("now").to_string();
        default:
            ASSERT_NOT_REACHED();
        }
    }
    return {};
}