https://github.com/lion-200/CurationAssistant
http://www.curationassistant.com
As I already explained in my initial introduction post:
Curation Assistant is an "assistant" for the curator to help him/her out by checking some basic rules defined by the curator. The intention of Curation Assistant is to reduce the time spent on checking administrative facts, so that the curator can have more time to curate good stuff, which is good for the whole community. This project is set up generic, so that it can be used by more curator groups like
@curie,
@ocd,
@c-squared etc.
I have implemented the following features as already defined in the Roadmap of my introduction post.
The main idea behind the curation communities is to reward undervalued authors & posts. Therefore when a curator checks a post & author, he/she also manually goes through the post history of the author for pending rewards. Of course the definition of "undervalued" may differ per group & curator. That's why I have made the necessary variable for "max pending rewards" can be filled with the standards of the curator.
Validation rule
Result
In the initial implementation of gathering posts of an author I was using the get_account_history method for votes, comments and posts. As this method loops through all account activities of an account, it can take a while until the desired amount of posts to be gathered was reached. And because I also wanted to calculate the total pending payout rewards of the account, I had to get more posts than initially implemented. That's why I moved to the method get_discussions_by_blog to retrieve last 30 posts of the author. Below you can see the api call necessary to retrieve this data. In order to improve the readability of the code I make screenshots instead of pasting the code unformatted:
As you can see in the code above, I map the response list items by calling the DiscussionMapper.ToDiscussionListViewModel method. An important fact to consider when calculating the rewards for the items we get from the get_discussions_by_blog method is that this method also returns the ReSteems of the author. So we only need to add the pending payout value of a post if the original author of the post is the author himself/herself.
I also added some extra data mappings like getting the main image, calculating the paid out values for already paid out posts of the author in order to enrich the data I show on the validation results section.
An important fact to emphasize here is that this validation rule only validates the pending payout rewards for the posts the author has made with comments excluded. This, in order to keep the rules simple.
As I explained above, the main idea is to find undervalued posts and authors. In order to do this he curators try to search and select in a broad selection of content. Instead of focusing on a specific group of persons, the idea is also to find people who don't get a lot of attention for their consistent work as a blogger, artist, musician etc. To meet this, curators might want to look at the last time an author received a fair/big upvote.
In order to set this requirement I have introduced 2 variables:
The curator can define with these variables, as an example, that the author's last big payout for his post need to be 21 days ago, before he/she can make a chance for a next upvote.
Validation
Result
In the previous rule, the focus was on the pending payout values for the author. But this rule is about the already received payouts. Because I extended the initial data set I retrieved for the get_discussions_by_blogmethod to 30 posts, we don't need to make a new call to validate this rule. The only thing we need to do is go through the list of posts we retrieved already, and check the highest paid out post of the author.
There are of course some checks necessary to make in order to successfully validate this rule.
I am currently working on the feature where the curator can fill the minimum amount days needs to be passed to make the post of the author eligible to receive another upvote from the upvote account. There has been some hours spent on this one. Because I use the API methods, instead of a DB solution like hivemind or SteemSQL, it is tough to get the results I want. I already bumped into multiple API related issues like the version of the method not being supported by the node host I use etc. Also, because the Steem guys are working on new implementations of API methods based on hivemind, the advise is to wait until the endpoints are there.
Still I tried to make it work by calling the get_account_history method, this time for the given Upvote account and only processing the votes received as displayed in the code below, which I committed in a branch.
private GetAccountVotesViewModel GetLastUpvoteFromUpvoteAccountToAuthor(string voter, string author, int voteLimit)
{
var model = new GetAccountVotesViewModel();
uint batchSize = 1000;
var start = -1;
var limit = Convert.ToInt32(ConfigurationHelper.VoteHistoryTransactionLimit);
int transactionsRetrieved = 0;
int voteCount = 0;
log.Info(string.Format("Votes.Batchsize: {0}", batchSize));
using (var csteemd = new CSteemd(ConfigurationHelper.HostName))
{
// stop if the max amount of transactions are reached!
while (transactionsRetrieved < limit)
{
log.Info(string.Format("Votes.TransactionsReceived: {0}", transactionsRetrieved));
log.Info(string.Format("Votes.Votecount: {0}", voteCount));
var responseHistory = csteemd.get_account_history(voter, start, batchSize);
// store last transaction datetime, so that we know until what data time value we got the transactions
model.LastTransactionDate = responseHistory[0][1]["timestamp"].ToObject<DateTime>();
var totalCount = responseHistory.Count();
// get_account_history returns last result first, but we want most recent first, so we start from the last element of the response to loop
for (var i = totalCount - 1; i >= 0; i--)
{
var el = responseHistory[i];
// get the index of the last transaction in the list to make the next call start from this index
if (transactionsRetrieved == 0)
{
var firstIndex = el[0].ToString();
Int32.TryParse(firstIndex, out start);
}
var transaction = el[1].ToObject<TransactionModel>();
var operation = el[1]["op"];
var operationType = operation[0].ToString();
var actionViewModel = new ActionViewModel();
actionViewModel.TimeStamp = el[1]["timestamp"].ToObject<DateTime>();
if (operationType == "vote" && voteCount < voteLimit)
{
var operationModel = operation[1].ToObject<OperationVoteViewModel>();
if (operationModel.voter == voter)
{
actionViewModel.Type = "vote";
actionViewModel.Details = operationModel;
if(operationModel.author == author)
{
model.LastVote = actionViewModel;
break;
}
voteCount++;
}
}
// if the required amount of counts are reached, stop
if (voteCount == voteLimit)
{
break;
}
}
transactionsRetrieved += (int)batchSize;
start -= (int)batchSize;
}
}
model.VotesAnalyzed = voteCount;
return model;
}
This piece of code works, but it is taking a long time to retrieve the desired amount of votes by the upvote account. Especially because these curation group accounts make a lot transactions, it is not feasible to implement this rule by using this method. For now I have parked this way of processing for this rule, and investigate alternative ways of doing it.
Besides the implementation of backend features, I also improved the frontend of the tool a bit.
As mentioned above in one of the features, I also gathered information like:
In the screenshot below you will see that the Author transaction history is improved a lot compared to the initial post:
For Backend as well as Frontend you are welcome to contribute to this project.
I am a C# .NET backend developer for more than a decade. Although I do some frontend work too, my skills and interests lie more on the backend.
The project I have worked on and currently I am working on are Web projects for mostly internal use for the companies I work(ed) for. That's why putting a lot of things I did on Open Source was not an option.
I will post more of my work (which can be shared) via my GitHub repo in the future.
Since there are no other developers involved, I include here the commits I directly have made to GitHub.
Master
https://github.com/lion-200/CurationAssistant/commit/be7ffc34988b166387a2c593e61b464cbb97e974
https://github.com/lion-200/CurationAssistant/commit/a94bcd601154fa48100f6929607f298f8ecfa89e
https://github.com/lion-200/CurationAssistant/commit/a376b1803977657931e38e646cb078b863964326
https://github.com/lion-200/CurationAssistant/commit/43d996db907456ff5abcc163924f07fb11f3e87d
https://github.com/lion-200/CurationAssistant/commit/7067459ae1dfb48382f64499be5d182fdfe3d7a3
Branch
https://github.com/lion-200/CurationAssistant/commit/c955070961294d44635b6de715625917d6ca113c
This list can grow with some feedback from Curation Groups and individual curators.
Steem account obviously: @lion200
Discord channel: Curation Assistant (https://discord.gg/bmJFXn)
Discord account: @Lion_200
E-mail: [email protected] or [email protected]