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 beneficiariesallows modification of beneficiariessteemgit comment_optionsallows adding comment options`steemgit metadatafor applyingjson_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
steemgitscript for adding commands togit
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
updateand replacing withpost-update
Roadmap
- New tutorial on how to use this tool.
- Actual
gitplugin to replacesteemgit - Bug fixes
Posted on Utopian.io - Rewarding Open Source Contributors