mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-02 04:20:28 +00:00
bdf23a3d23
Subclasses of CNetworkJob handle this by overriding shutdown(). This patch implements it for CHttpJob by simply tearing down the underlying socket. We also automatically call shutdown() after the job finishes, regardless of success or failure. :^)
144 lines
3.8 KiB
C++
144 lines
3.8 KiB
C++
#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::set_board(const String& board)
|
|
{
|
|
if (m_board == board)
|
|
return;
|
|
m_board = board;
|
|
update();
|
|
}
|
|
|
|
void ThreadCatalogModel::update()
|
|
{
|
|
CHttpRequest request;
|
|
request.set_url(String::format("http://a.4cdn.org/%s/catalog.json", m_board.characters()));
|
|
|
|
if (m_pending_job)
|
|
m_pending_job->cancel();
|
|
m_pending_job = request.schedule();
|
|
|
|
if (on_load_started)
|
|
on_load_started();
|
|
|
|
m_pending_job->on_finish = [this](bool success) {
|
|
auto* response = m_pending_job->response();
|
|
dbg() << "Catalog download finished, success=" << success << ", response=" << response;
|
|
|
|
if (!success) {
|
|
if (on_load_finished)
|
|
on_load_finished(false);
|
|
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();
|
|
|
|
if (on_load_finished)
|
|
on_load_finished(true);
|
|
};
|
|
}
|
|
|
|
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::Subject:
|
|
return "Subject";
|
|
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::Subject:
|
|
return { 170, TextAlignment::CenterLeft };
|
|
case Column::Text:
|
|
return { 270, 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::Subject:
|
|
return thread.get("sub").as_string_or({});
|
|
case Column::Text:
|
|
return thread.get("com").as_string_or({});
|
|
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 {};
|
|
}
|