获取最新 Minds.com 帖子





5.00/5 (2投票s)
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日:初始版本

