65.9K
CodeProject 正在变化。 阅读更多。
Home

获取最新 Minds.com 帖子

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2021年2月26日

CPOL

1分钟阅读

viewsIcon

4082

Minds.com 是一个基于区块链的社交网络,用户可以通过使用它来赚取金钱或加密货币。

引言

我需要获取给定 Minds.com 用户 ID 的最新帖子。为此,我想使用 Minds.com API。

构建块

这样一个项目的关键构建块之一将是 libCurl。我将其用作static库。.lib 文件包含在文章的源代码中,但是你可以在 这里 了解如何将 libCurl 作为 static 库使用。

注意WriteLogFile() 是我旧的日志记录函数之一,在 这篇文章 中有描述。

获取用户唯一编号

通常,我们需要向我们的函数提供一个用户 ID,例如“minds”。你也可以查看我的个人资料“haephrati”(https://www.minds.com/haephrati)。

Minds.com 请求 API 的工作方式

Minds.com 提供了一个 API 调用,其形式如下

?sync=1&limit=2&as_activities=0&export_user_counts=0&from_timestamp=

如果我们将它分解成其组成部分,我们将得到以下属性,以及建议值如下

    int sync                      = 1;
    int limit                     = 150;
    int as_activities             = 0;
    int export_user_counts        = 0;
    string from_timestamp         = "";

启动 libCurl

首先,我们启动 Curl 对象

curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init();

读取帖子

我想要一个简单的函数,可以用来读取给定用户的全部帖子。所以如果用户是 ottman,我会调用

SG_ReadMindsFeed("ottman");

我创建了一个类,SG_ReadMindsFeed 的代码如下

bool SG_ReadMindsFeed(string userID)
{
    int count = 100;

    MindsFeedReader reader(count);
    return reader.read(userID);
}

然后调用 read 函数

bool MindsFeedReader::read(string userID)
{
    userid = userID;
    
    if (readGUID() == false)
    {
        return false;
    }

    total_read_count = 0;
    while (total_read_count < count)
    {
        if (readNext() == false)
        {
            return false;
        }

        if (read_count <= 0)
        {
            break;
        }

        total_read_count += read_count;
    }
    return true;
}

GUID

Feed 中每个用户不同的实际部分是一个很长的数字,称为 GUID。它可以按如下方式组成

bool MindsFeedReader::readGUID()
{
    string url = CHANNEL + userid;

    // Initialize the CURL request.
    CURL* curl = curl_easy_init();
    if (curl == NULL)
    {
        WriteLogFile(L"Cannot intialize the CURL request");
        return false;
    }

    CURLcode result;
    string response;

    // Perform the CURL request.
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_string);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    result = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    // Check the response success.
    if (result != CURLE_OK)
    {
        WriteLogFile(L"Fail to perform the CURL request");
        return false;
    }

    // Parse the JSON response.
    JSONValue* jsonRoot = JSON::Parse(response.c_str());
    if (response == "")
    {
        WriteLogFile(L"Response empty. CURL request failed");
        return false;

    }
    JSONObject jsonRootObject = jsonRoot->AsObject();

    // Read the post details.
    JSONValue* jsonChannel = jsonRootObject[L"channel"];
    JSONObject jsonChannelObject = jsonChannel->AsObject();

    // Read GUID.
    JSONValue* jsonGUID = jsonChannelObject[L"guid"];
    if (jsonGUID == NULL || !jsonGUID->IsString())
    {
        WriteLogFile(L"Invalid response. CURL request failed");
        return false;
    }

    wstring wguid = jsonGUID->AsString();
    guid = string(wguid.begin(), wguid.end());

    return true;
}

读取数据块

如以下源代码所示,我们读取一批帖子(在本例中最多 10 个),然后移动到下一批。

bool MindsFeedReader::readNext()
{
    // Build the query string.
    // ex. ?sync=1&limit=2&as_activities=0&export_user_counts=0&from_timestamp=
    string url_with_params = FEED + guid + ACTIVITIES;
    url_with_params += string("?") + PARAM_SYNC + "=" + to_string(sync);
    url_with_params += string("&") + PARAM_LIMIT + "=" + to_string(limit);
    url_with_params += string("&") + PARAM_AS_ACTIVITIES + "=" + to_string(as_activities);
    url_with_params += string("&") + PARAM_EXPORT_USER_COUNTS + 
                    "=" + to_string(export_user_counts);
    url_with_params += string("&") + PARAM_FROM_TIMESTAMP + "=" + from_timestamp;

    // Initialize the CURL request.
    CURL* curl = curl_easy_init();
    if (curl == NULL)
    {
        WriteLogFile(L"Cannot intialize the CURL request");
        return false;
    }

    CURLcode result;
    string response;

    // Perform the CURL request.
    curl_easy_setopt(curl, CURLOPT_URL, url_with_params.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_string);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    result = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    // Check the response success.
    if (result != CURLE_OK)
    {
        WriteLogFile(L"Fail to perform the CURL request");
        return false;
    }

    // Parse the JSON response.
    JSONValue* jsonRoot = JSON::Parse(response.c_str());
    if (response == "")
    {
        WriteLogFile(L"Response empty. CURL request failed");
        return false;
    }
    
    JSONObject jsonRootObject = jsonRoot->AsObject();

    // Update the next timestamp.
    JSONValue* jsonLoadNext = jsonRootObject[L"load-next"];
    wstring loadNext = jsonLoadNext->AsString();
    from_timestamp = string(loadNext.begin(), loadNext.end());

    // Read the post details.
    JSONValue* jsonEntities = jsonRootObject[L"entities"];
    JSONArray jsonEntitiesArray = jsonEntities->AsArray();

    read_count = 0;
    for (JSONValue* jsonEntitiesItem : jsonEntitiesArray)
    {
        ++read_count;
        WriteLogFile(L"Showing post %d", total_read_count + read_count);

        JSONObject jsonEntitiesItemObject = jsonEntitiesItem->AsObject();

        JSONValue* jsonEntity = jsonEntitiesItemObject[L"entity"];
        if (jsonEntity->IsObject())
        {
            JSONObject jsonEntityObject = jsonEntity->AsObject();

            JSONValue* jsonMessage = jsonEntityObject[L"message"];
            if (jsonMessage != NULL && jsonMessage->IsString())
            {
                wstring message = jsonMessage->AsString();
                WriteLogFile(L"\n\nMessage:\n%s\n\n", message.c_str());
            }

            JSONValue* jsonThumbnailSrc = jsonEntityObject[L"thumbnail_src"];
            if (jsonThumbnailSrc != NULL && jsonThumbnailSrc->IsString())
            {
                wstring thumbnailSrc = jsonThumbnailSrc->AsString();
                WriteLogFile(L"\n\nThumbnail Src:\n%s\n\n", thumbnailSrc.c_str());
            }

            JSONValue* jsonTimeCreated = jsonEntityObject[L"time_created"];
            if (jsonTimeCreated != NULL && jsonTimeCreated->IsString())
            {
                wchar_t buffer[TIMESTAMP_BUFFER_SIZE];
                wstring wstrTimeCreated = jsonTimeCreated->AsString();
                string strTimeCreated = string(wstrTimeCreated.begin(), wstrTimeCreated.end());
                long timestamp = atol(strTimeCreated.c_str());
                
                time_t rawtime = (const time_t)timestamp;
                struct tm* timeinfo;
                timeinfo = localtime(&rawtime);
                
                wcsftime(buffer, TIMESTAMP_BUFFER_SIZE, L"%Y-%m-%dT%H:%M:%S.%z%Z", timeinfo);
                WriteLogFile(L"\n\nTime Created:\n%s\n\n", buffer);
            }

            JSONValue* jsonTimeUpdated = jsonEntityObject[L"time_updated"];
            if (jsonTimeUpdated != NULL && jsonTimeUpdated->IsString())
            {
                wchar_t buffer[TIMESTAMP_BUFFER_SIZE];
                wstring wstrTimeUpdated = jsonTimeUpdated->AsString();
                string strTimeUpdated = string(wstrTimeUpdated.begin(), wstrTimeUpdated.end());
                long timestamp = atol(strTimeUpdated.c_str());

                time_t rawtime = (const time_t)timestamp;
                struct tm* timeinfo;
                timeinfo = localtime(&rawtime);

                wcsftime(buffer, TIMESTAMP_BUFFER_SIZE, L"%Y-%m-%dT%H:%M:%S.%z%Z", timeinfo);
                WriteLogFile(L"\n\nTime Updated:\n%s\n\n", buffer);
            }
        }
        else
            break;
    }
    return true;
}

历史

  • 2021年2月26日:初始版本
© . All rights reserved.