Repository
https://github.com/lion-200/CurationAssistant
URL
http://www.curationassistant.com
What is Curation Assistant?
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
,
,
etc.
New Features
I have implemented the following features as already defined in the Roadmap of my introduction post.
- Feature 1: Validation Rule - Total pending payout
- Feature 2: Validation Rule - Max payout value within x days
- Feature 3: Validation Rule - Min # days since last upvote
- Frontend changes
Feature 1: Validation Rule - Total pending payout
Description
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
Implementation
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.
Feature 2: Validation Rule - Max payout value within x days
Description
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:
- Max received payout for a post in value ($)
- Max received payout for a post within x days
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
Implementation
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.
- First we need to define the range of dates based on the filled x days value by the curator in the validation rules.
- Then we need to check whether the data we have retrieved is sufficient to run this validation. If the author is a highly engaging blogger, we might not have the necessary data set to validate this rule. In the end, we only retrieve the last 30 posts of the author including the ReSteems.
- As last step, we order the posts of the user based on the PaidOut value in a descending order to take the highest value first. If the highest paid out value is less than the variable the curator has filled as max value, the rule is passed.
(In Progress) Feature 3: Validation Rule - Min # days since last upvote
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.
Frontend changes
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:
- main image
- payout value
- paid out value
- title
- post date
- posted x days ago
- etc.
In the screenshot below you will see that the Author transaction history is improved a lot compared to the initial post:
How to contribute?
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.
List of commits
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
Roadmap
Rule for total pending payout of the authorRule for minimum amount of days ago the author received a big upvote- (In Progress) Rule for min amount of days since last upvote
- Rule for how many times an author received an upvote from the Upvote account of the curation community
- SteemConnect or other type of authentication
- Adding functionality to upvote a post right from the tool
- I also consider using other sources (like SteemSQL or hivemind) besides the Steem API. There are also other alternatives like streaming the blockchain and store the data I use in the app. This still needs some thinking...
This list can grow with some feedback from Curation Groups and individual curators.
Ways to reach me?
Steem account obviously:
Discord channel: Curation Assistant (https://discord.gg/bmJFXn)
Discord account: @Lion_200
E-mail: lion200.dev@gmail.com or info@curationassistant.com