New Feature: Beneficiaries, Comment Options, and Metadata

in utopian-io •  7 years ago  (edited)

It's Finally Useful


One of the biggest issues behind this project I came up with was that I didn't quite deliver on its most important feature (collaboration). Sure, users can collaborate, but they cannot share rewards. It's not real collaboration if you can't officially give credit on the platform. Further, posts were just half-baked implementations of a post. It was still really more effective to post though steemit. I think with this PR, we now have a set of features that will make this a strong contender when deciding how to create a post.

The Implementation

The way I decided to implement this is using git notes. This is one of the features of git that helps add more information around commit messages to fix a gap in functionality not provided by tools like svn. For example, one of the problems with svn is mistaken commits, maybe hasty commits, pre-commits, early commits, or the need to edit commits. While commit --amend really helps with this, it affects the actual commit itself, and sometimes you don't want to do that because sometimes it wreaks havoc with other users when you have already done git push. The only way to get in your --amend is to push --force (may the fourth be with you). That is not idea is the only change you're making is a modification to a commit message or something like that. It is far better to use notes instead.

I decided to use this feature to also embed metadata about the content committed which is a totally valid use case. Instead of using the actual commit to store details (would be really awkward), I store metadata in notes (kinda like an afterthought).

While add information to notes, I can organize it using a ref

git notes --ref=beneficiaries add -m "{ \"beneficiaries\":\ "r351574nc3:2000\" }"

I can use --ref=beneficiaries or --ref=metadata to store my notes according to context and what the note is for. Further, I can avoid stepping on notes that might be relevant to the post.

post-update

On post-update, I collect the notes and use them as input to the steem-js api.

steemgit

For usability, had to make changes to this to be a facade on git instead of an alias. I should have just made actual git plugins (which may still happen), but I want to focus on working features before refining them.

Usage

There are now 3 new commands for steemgit

  • steemgit beneficiaries allows modification of beneficiaries
  • steemgit comment_options allows adding comment options`
  • steemgit metadata for applying json_metadata (tags, custom metadata, etc...)

Comment Options

Comment options allow users to specify the following:

  • Allowing votes
  • Allowing curation rewards
  • Beneficiaries
  • Maximum Payout
  • SBD payout percentage

There are several cases for this. Two most common would be rewards refusal and beneficiary assignment. Let's look at both cases.

Refusing Rewards

No Voting

steemgit add new-post.md
steemgit comment_options "0 SBD" 0 false false  // No rewards, no curation, no votes
steemgit commit -a -m "Title of Post"

Voting, but no rewards

steemgit add new-post.md
steemgit comment_options "0 SBD" 0 true false  // No rewards, no curation, yes votes
steemgit commit -a -m "Title of Post"

Assigning Beneficiares

steemgit add new-post.md
steemgit beneficiaries gtg:2500,drakos:2500
steemgit commit -a -m "Title of Post"

Options after the fact

Supposing that you already committed your post, you can still make changes before pushing.

steemgit add new-post.md
steemgit commit -a -m "Title of Post"
steemgit beneficiaries gtg:2500,drakos:2500
steemgit commit -a --amend

Post Metadata

It's possible to add custom metadata to posts. Custom metadata has infinite use cases, so we won't go into them. This is how to do it if you need to:

steemgit add new-post.md
steemgit metadata metadata.json
steemgit commit -a -m "Title of Post"

From stdin

steemgit add new-post.md
steemgit metadata <<EOF
json_metadata: {
    "tags": [ "awesome" ]
}
EOF
steemgit commit -a -m "Title of Post"

Actual Changes

diff --git a/bin/steemgit b/bin/steemgit
new file mode 100755
index 0000000..4c6f7bf
--- /dev/null
+++ b/bin/steemgit
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+GIT="git -C /work/$STEEMIT_GIT_PROJECT"
+
+for i in "$@"
+do
+    case $i in
+        comment_options)
+        PREFIX="${i#*=}"
+        MAX_PAYOUT=$2
+        PERCENT_SBD=$3
+        ALLOW_VOTES=$4
+        ALLOW_CURATION=$5
+        $GIT notes --ref=comment_options add -F /dev/stdin <<EOF
+{
+    "extensions":[],
+    "operations":[
+        [
+            "comment_options",
+            {
+                "author":"",
+                "permlink":"",
+                "max_accepted_payout":"$2",
+                "percent_steem_dollars": $3,
+                "allow_votes":$4,
+                "allow_curation_rewards":$5,
+                "extensions":[]
+            }
+        ]
+    ]
+}
+EOF
+        exit
+        ;;
+        beneficiaries)
+        BENEFICIARIES=$2
+        $GIT notes --ref=beneficiaries add -F /dev/stdin <<EOF
+{ "beneficiaries": "$2" }
+EOF
+        exit;
+        ;;
+        metadata)
+        METADATA_FILE=$2
+        if [ "$METADATA_FILE" -eq "" ]
+        then
+            METADATA_FILE=/dev/stdin
+        fi
+        $GIT notes --ref=metadata add -F $METADATA_FILE
+        exit;
+        ;;
+        push)
+        $GIT push --tags steem master --force
+        ;;
+        *)
+        ;;
+    esac
+done
+
+exec $GIT "$@"

New steemgit script for adding commands to git

diff --git a/hooks/index.js b/hooks/index.js
index 6bf74b8..beaefa9 100644
--- a/hooks/index.js
+++ b/hooks/index.js
@@ -1,21 +1,104 @@
 const Promise = require('bluebird')
 const steem = Promise.promisifyAll(require('steem'))
 const fs = Promise.promisifyAll(require('fs'))
+const shell = require('shelljs');
 
 
+const defaults = {
+    comment_options: {
+        "extensions":[],
+        "operations":[
+            [
+                "comment_options",
+                {
+                    "author":"",
+                    "permlink":"",
+                    "max_accepted_payout":"1000000.000 SBD",
+                    "percent_steem_dollars": "10000",
+                    "allow_votes": true,
+                    "allow_curation_rewards": true,
+                    "extensions":[]
+                }
+            ]
+        ]
+    },
+    metadata: { tags: [], app: 'r351574nc3/docker-git-steem-bot' },
+    beneficiaries: []
+}
 
 function load_post() {
     return fs.readFileAsync(0, 'utf8')
 }
 
+function load_beneficiaries(repo) {
+    if (shell.exec(`git -C ${repo} notes --ref=beneficiaries list`) == '') {
+        return defaults.beneficiaries
+    }
+    let ref = shell.exec(`git -C ${repo} notes --ref=beneficiaries list`).exec("cut -f 2 -d ' '")
+    let data = shell.exec(`git -C ${repo} notes --ref=beneficiaries show ${ref}`)
+
+    
+    if (data != '') {
+        let retval = [
+            [
+                0,
+                {
+                    beneficiaries: [
+                    ]
+                }
+            ]
+        ]
+        JSON.parse(data).beneficiaries.split(",").forEach((kvpair) => {
+            let { account, weight } = kvpair.split(":");
+            retval[0][1].beneficiaries.push({ account: account, weight: weight })            
+        })
+        return retval
+    }
+    return defaults.beneficiaries
+    
+}
+
+function load_metadata(repo) {
+    if (shell.exec(`git -C ${repo} notes --ref=metadata list`) == '') {
+        return defaults.metadata
+    }
+    let ref = shell.exec(`git -C ${repo} notes --ref=metadata list`).exec("cut -f 2 -d ' '")
+    let data = shell.exec(`git -C ${repo} notes --ref=metadata show ${ref}`)
+    if (data != '') {
+        let retval = JSON.parse(data)
+        retval.app = 'r351574nc3/docker-git-steem-bot'
+    }
+    return defaults.metadata
+}
+
+function load_comment_options(repo) {
+    if (shell.exec(`git -C ${repo} notes --ref=comment_options list`) == '') {
+        return defaults.comment_options
+    }
+
+    let ref = shell.exec(`git -C ${repo} notes --ref=comment_options list`).exec("cut -f 2 -d ' '")
+    let retval = shell.exec(`git -C ${repo} notes --ref=comment_options show ${ref}`)
+    if (retval != '') {
+        return JSON.parse(retval)
+    }
+    return defaults.comment_options
+}
+
 function main() {
     let user = process.env.STEEM_NAME || "Not set"
     let wif = process.env.STEEM_WIF || "Not set"
     let permlink = process.argv[2]
     let title = process.argv[3]
+    let repo  = process.argv[4]
+
+    let metadata = load_metadata(repo);
+    let comment_options = load_comment_options(repo);
+    comment_options.operations[0][1].author = user
+    comment_options.operations[0][1].permlink = permlink
+    comment_options.operations[0][1].extensions = load_beneficiaries(repo);
+
     load_post().then((body) => {
-        var permlink = new Date().toISOString().replace(/[^a-zA-Z0-9]+/g, '').toLowerCase();
+        console.log("Permlink ", permlink)
         return steem.broadcast.commentAsync(
             wif,
             '', // Leave parent author empty
@@ -24,12 +107,23 @@ function main() {
             permlink + '-post', // Permlink
             title, // Title
             body, // Body
-            { tags: [], app: 'r351574nc3/docker-git-steem-bot' }
+            metadata
         )
-    }).then((results) => {
-        console.log(results)
-    }) 
+    })
+    .then((results) => {
+        steem.broadcast.send(wif, comment_options, function(err, results) {
+            if (err) {
+                console.log("Unable to set comment options ", JSON.stringify(err));
+                return
+            }
+            console.log("Results ", results)
+        });
+    })
+        .catch((err) => {
+            console.log(err)
+        })
+    
+    console.log("Exiting")
 }
-main()

Notes implementation for post-update

diff --git a/hooks/post-update b/hooks/post-update
new file mode 100755
index 0000000..764ede9
--- /dev/null
+++ b/hooks/post-update
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# STEEM_USER
+# STEEM_WIF
+#
+
+# --- Command line
+set -x
+
+
+FILES_MODIFIED=$(git diff-tree  --name-only -r HEAD | tail -n $(expr $(git diff-tree  --name-only -r HEAD | wc -l) - 1))
+
+
+for file in $FILES_MODIFIED
+do
+    permlink=$(basename $file .md)
+    title=$(git show --pretty=tformat:%s HEAD | head -1)
+    git show HEAD:$file > /tmp/body
+    cd hooks
+    cat /tmp/body | npm run post $permlink "$title" "$OLDPWD"
+    cd -
+    rm /tmp/body
+done
+
+git push origin refs/notes/* master --force
+
+# --- Finished
+exit 0

Removing the old update and replacing with post-update

Roadmap

  1. New tutorial on how to use this tool.
  2. Actual git plugin to replace steemgit
  3. Bug fixes



Posted on Utopian.io - Rewarding Open Source Contributors

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Make posts to steemit with git? Setup beneficiaries for people to collaborate? Game changer.

Ahhh now i understand 100% you just Skript Kid
try be must big but you = LOW LEVEL INTELECT PERSONE = THIS WHY YOU PUT YOUR FACE MY LIFE
who are tyou? if you come provocation me?

Why reason

you put your face my life

i hope you freal my pain

i never tuch you i not know you you come provocation me? why you msg your abrakadabra my page? who are you?

i have seen many new tools in your post about which i don't know thanks for sharing this information i get much knowledge and i must do implement on it.

Thank you for the contribution. It has been approved.

I have a feeling people familiar with git will find this tool fun to use. Instead of creating a post in a web browser or a mobile app, one can create a *.md and push it to steem.

You can contact us on Discord.
[utopian-moderator]

Awesome! I hope people do use it. That's the best way to improve it is with feedback from users.

Well done. Looking forward to your updated tutorial on steemgit. Let me know when you published​ it.

Hey @r351574nc3 I am @utopian-io. I have just upvoted you!

Achievements

  • You have less than 500 followers. Just gave you a gift to help you succeed!
  • Seems like you contribute quite often. AMAZING!

Community-Driven Witness!

I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!

mooncryption-utopian-witness-gif

Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x

This is very cool. Sorry about all the comments on your blog just now. I'm reading through all of your tutorials :)

I'm trying to learn how to make a page (on my own domain) that lets me submit a post to the blockchain using Steemconnect that permits the use of the advanced features. It seems each interface has some, but not all.

Thanks for posting this. I'm a little closer to understanding.

Sounds good. I think it's a good idea to have a broad utility page that gives you access to the kitchen sink once in awhile.