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 @curie, @ocd, @c-squared 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_blog
method 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: @lion200
Discord channel: Curation Assistant (https://discord.gg/bmJFXn)
Discord account: @Lion_200
E-mail: [email protected] or [email protected]
I'm not really a curator myself (I only really upvote Utopian posts), but I still think this is a pretty cool project. It seems well thought out and works very well -- great stuff! I bet it's useful to all the people who, unlike me, manually curate posts.
Btw, it would be better to add a certificate etc. so it is available via HTTPS.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thanks a lot @amosbastian!
Yes, I think it can be very useful for manual curators and curation group reviewers.
Adding a SSL Certificate is also on my list indeed :)
Thanks again for the review!
Thank you for your review, @amosbastian! Keep up the good work!
@lion200 you are wonderful \o/
I love this tool and your work is super appreciated \o/ !!!
Thanks @veryspider! I’m glad you like it :) There is always room for improvement of course, so if you have any suggestions feel free to contact me.
Posted using Partiko iOS
Congratulations @lion200! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
Do not miss the last post from @steemitboard:
This post was shared in the Curation Collective Discord community for curators, and upvoted and resteemed by the @c-squared community account after manual review.
@c-squared runs a community witness. Please consider using one of your witness votes on us here
Congratulations! Your post has been selected as a daily Steemit truffle! It is listed on rank 12 of all contributions awarded today. You can find the TOP DAILY TRUFFLE PICKS HERE.
I upvoted your contribution because to my mind your post is at least 9 SBD worth and should receive 155 votes. It's now up to the lovely Steemit community to make this come true.
I am
TrufflePig
, an Artificial Intelligence Bot that helps minnows and content curators using Machine Learning. If you are curious how I select content, you can find an explanation here!Have a nice day and sincerely yours,
TrufflePig
Hi @lion200!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @lion200!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
This is a pretty cool program! You just made a bunch of curators very happy, nice work.