Alt Coins, Backlinks, and More to Come

in #utopian-io6 years ago (edited)

I've created a new script (posts.sh) and I've added features to the balances.sh script. You can find this in the project repo on Github.

Thanks to the feature additions to balances.sh (not to mention @evilest-fiend's awesome additions! Thanks!) I've also removed the old ticker example because the balances.sh script does everything that it did and more. cc362268

Bug Fixes

  • Issue #5 - altcoins parsing problem fixed 2ffe7c43
    The logic for adding new altcoins to the list of altcoins was using the length of the first value as the index into the array instead of the length of the array itself.
  • Issue #6 - ticker delay should be configurable fixed 2ffe7c43
    Added a -T option for the ticker time to the balances script and then passed the value to the invocation of tickline, which already supported the option, it just needed to be parsed and passed in.
    When lots of output was selected (for example, balance and worth information or just information for a lot of users) the scrolling felt painfully slow, so now there is a -T option where the scrolling speed can be controlled. It's in number of seconds to wait before updating the ticker line. So make it smaller to get a faster scroll. 2ffe7c43
  • Issue #7 - Altcoins should allow display in other currency, too fixed 2ffe7c43
    The "${CURRENCY}" value was not being passed to the invocation of get_prices. This is now fixed, the result is that you can actually leverage this to do things like show the ratio of STEEM to SBD. For example, balances.sh -a STEEM -c SBD and put it in a ticker, and you can now see when the best time is to convert that spare SBD into STEEM.
  • Issue #8 - balance temp files not cleaned up on exit fixed 9a80e243 and 8ba4573e
    Modified the exit hook so that instead of setting the cursor visible it invokes a cleanup function that checks to see if a temporary file was created, removes it if so, and then sets the cursor to visible again.

Readability:

  • Added some more spaces around names and fields for easier reading in the ticker display.
  • Added some brackets around coin values. Added US style formatting of numbers (commas on thousands, etc.)

New Features

balances.sh

I've made some improvements to the existing functions and the balances.sh
script.

Display arbitrarily many alt coins 25697557 and their values in any given currency 2ffe7c43.

So, you can use this one shot with:

$ ./balances.sh -a STEEM -c SBD
[[STEEM: 0.7832]]

Display ratio of STEEM to SBD.

Or you can make a ticker out of it with -t and it will scroll and update every time it hits the edge of the screen.

Here's an illustration of the speed option and various outputs selected:

Default Speed
Faster
Not quite default
Still faster

posts.sh 31ee2a5b

Added a script that can fetch posts for a given user. The main goal of this script was to recreate the functionality that coffeesource.net has where it lets you create backlinks. Back links are those links in the bottom of steem posts that link to related content by the same author. So-called back links because they link back to previous posts.

This was my original ideal usage:

$ ./posts.sh -b not-a-bird
[Sorcery - 16](/fiction/@not-a-bird/sorcery-16)
[Sorcery - 15](/fiction/@not-a-bird/sorcery-15)
[Friends & Family - Posting](/welcome/@not-a-bird/friends-and-family)
[Massive Updates, Steem RPC Calls, Ticker Scripts](/utopian-io/@not-a-bird/massive-updates-steem-rpc-calls-ticker-scripts)
[STEEM-Bash](/utopian-io/@not-a-bird/steem-bash)
[Bash Script Examples (Pipes & Redirection in Bash)](/bash/@not-a-bird/bash-script-examples-pipes-and-redirection-in-bash)
[Coffeesource.net utils.py cleanup](/utopian-io/@not-a-bird/coffeesource-net-utils-py-cleanup)
[5 Minute Freewrite: Friday - Prompt: corn](/freewrite/@not-a-bird/5-minute-freewrite-friday-prompt-corn)
[Sorcery - 14](/fiction/@not-a-bird/sorcery-14)
[004 - Learning Japanese - Katakana Notes](/language/@not-a-bird/004-learning-japanese-katakana-notes)

This was implemented using the rpc_get_discussions_by_author_before_date function, using jq to select just the set of desired tags from each post, then using the root_title and url fields.

This was quite a bit of new material for me, as I hadn't used jq to extract multiple fields. I put this work in a loop and used a series of read statements to pull out the extracted values. Here's an illustrative snippet, as the process is a little convoluted, you can see the full source here:

if rpc_get_discussions_by_author_before_date "${USER}" '' "$(date -Iseconds)" "${LIMIT}" > "${WHERE}" ; then
    while true ; do
        read -r PERMLINK
        if [ -z "${PERMLINK}" ] ; then
            break;
        fi
        read -r URL
        read -r ROOT_TITLE

        if [ ! -z "${BACKLINKS}" ]  ; then
            LINE="[${ROOT_TITLE}](${URL})"
        else
            LINE="${ROOT_TITLE} (${PERMLINK})"
        fi

        echo "${LINE}"
    done < <(jq -r ".[]  | .permlink, .url, .root_title" < "${WHERE}")
fi

So the main loop takes the output from the rpc_get_discussions_by_author_before_date invocation and dumps it into the temp file pointed at by WHERE. Then if that function call succeeds, an infinite while loop begins that reads the output from jq parsing that temporary file. Then read is used to get the PERMLINK. If reading the permlink fails, or returns no value, then the test for a zero length on PERMLINK will ensure that the while loop breaks. I did this because there was no good way to test for the end of the file. Next, I read the URL and the ROOT_TITLE from jq's output and use those the create backlinks if the user has opted to do that, or to just dump the title and the permlink to the console.

But then I realized I needed tag filtering, so I added that.

$ ./posts.sh -bt fiction not-a-bird

[Sorcery - 16](/fiction/@not-a-bird/sorcery-16)
[Sorcery - 15](/fiction/@not-a-bird/sorcery-15)
[5 Minute Freewrite: Friday - Prompt: corn](/freewrite/@not-a-bird/5-minute-freewrite-friday-prompt-corn)
[Sorcery - 14](/fiction/@not-a-bird/sorcery-14)

This was a little bit trickier, as the tag data is actually in a couple of fields. The first tag is actually in the category field, so that's easy enough to pull out, but the remaining tags are actually wrapped in a JSON string within a field value, so additional processing is needed to unwrap this embedded JSON. Here's some illustrative code to show that, again, note that this is not exactly the code being used, as this has been simplified for illustrative purposes:

while true ; do
    read -r PERMLINK
    if [ -z "${PERMLINK}" ] ; then
        break;
    fi
    read -r URL
    read -r ROOT_TITLE
    read -r CATEGORY
    read -r JSON_METADATA
    TAGGED=( $(jq -r ".tags []" <<< "${JSON_METADATA}" ) )
    TAGGED[${#TAGGED[@]}]=${CATEGORY}

    PASS=yes
    if [ ! -z "${TAGS[@]}" ] ; then
        #make sure the post has the specified tags
        PASS=
        if listinlist "${TAGS[*]}" "${TAGGED[*]}" ; then
            PASS=yes
        fi
    fi
    if [ -z "${PASS}" ] ; then
        continue
    fi
    if [ ! -z "${BACKLINKS}" ]  ; then
        LINE="[${ROOT_TITLE}](${URL})"
    else
        LINE="${ROOT_TITLE} (${PERMLINK})"
    fi

    echo "${LINE}"

done < <(jq -r ".[]  | .permlink, .url, .root_title, .category, .json_metadata" < "${WHERE}")

Of particular interest, the TAGGED variable here is being used to hold all of the tags. So, jq on that last line is used to provide the value of several fields, including the json_metadata field. This value is read out by the read -r JSON_METADATA command, and then the value is put into the TAGGED array by processing it a second time with jq via a Here-String. Once the value exists in the array, then the category field is appended to the TAGGED list so that all of the fields can be used for filtering. Next, the PASS variable is set to yes (any non-empty string would suffice) so that if the user has specified tag filtering (the TAGS variable holds any user provided tags) then a helper function listinlist is invoked to see if any of the tags provided by the user (TAGS) exist in the list of any of the tags from the article (TAGGED). Notice that PASS is emptied before doing the listinlist check. If listinlist finds any user tags in the post tags, then it will again set PASS to yes, but if it didn't hold any values, then PASS is left as empty. That way, when it hits the test for PASS being a non-zero length string, it can kick out of the loop and skip over the current article for the case that the user supplied tags and none of the tags were in the post. The logic here is that if the user didn't pass any tags, then the value of PASS would still be yes and so it would keep the post for the list.

Then I realized I needed exclusion tag support because maybe I didn't want to see freewrite stuff when looking for general fiction, so I added that.

$ ./posts.sh -b -t fiction -e freewrite not-a-bird
Sorcery - 16 (sorcery-16)
Sorcery - 15 (sorcery-15)
Sorcery - 14 (sorcery-14)

The logic for this was very similar to the logic for the tag filtering, except this time, if the user provided any EXCLUDE tags, then if they were found in the post, the post would be skipped. An illustrative example of this:

if [ ! -z "${EXCLUDES}"  ]  ; then
    if listinlist "${EXCLUDES[*]}" "${TAGGED[*]}"; then
        continue
    fi
fi

This is actually a little bit simpler than the check for tags because the goal is to skip the article only if one of the exclude tags are also in the article's tags.

Then I thought it would be nice to be able to sort them in reverse order:

$ ./posts.sh -t fiction -e freewrite -r not-a-bird
Sorcery - 14 (sorcery-14)
Sorcery - 15 (sorcery-15)
Sorcery - 16 (sorcery-16)

This was accomplished in a slightly inefficient way as I set a command that will always be used to post process the link generating loop's output. I store the command in the ORDER variable. Then, if the user provides the -r flag, I change the command that's stored in order. You can possibly imagine that I initialize ORDER to cat. Then if the user passes a -r I switch the value to tac. So, if the user doesn't change the order, the cat command just passes it's input on to the output. If the user does provide the -r option, then the tac command reverses the order of its input. If the output ever gets so big that it's a memory issue, then the user has bigger problems than not being able to reverse the order of the output.

Other examples:

So, what itch does this actually scratch? I write up my posts in Vim and then I paste them into whatever interface I'm using. So if I do a freewrite this weekend, I could do this in Vim to pull in a bulletted list of the freewrites I've done for the end of my post:

:read !posts.sh -l 100 -t freewrite -r -b not-a-bird | tail -n 4 | sed 's/^/ * /g'

And it would insert the following into my post:

 * [5 Minute Freewrite - Prompt: callous](/freewrite/@not-a-bird/5-minute-freewrite-prompt-callous)
 * [5 Mintue Freewrite - Prompt: ducks](/freewrite/@not-a-bird/5-mintue-freewrite-prompt-ducks-1515040127)
 * [5 Minute Freewrite - Prompt: I floss my tears](/freewrite/@not-a-bird/5-minute-freewrite-prompt-i-floss-my-tears)
 * [5 Minute Freewrite: Friday - Prompt: corn](/freewrite/@not-a-bird/5-minute-freewrite-friday-prompt-corn)

It also supports multiple users, so if you wanted to fetch all the articles of a particular tag or tags from a group of friends, you could do that. And since it supports multiple users, it will also tag each title with the user that created it if you pass the -u option.

functions.sh

I've added a function for fetching coin prices on any given day in history for as long ago as cryptocompare.com has the data. I plan to use this in a new script to help me compute what I owe for quarterly taxes and help me manage my wallet to avoid paying unnecessary taxes. The current plan is to either locate a function that will allow me to fetch my reward payouts, or to use rpc_get_discussions_by_author_before_date if that doesn't exist. Then I can use the historic price data from cryptocompare to compute any income tax on the rewards from past posts and even track prices over time so that when I do cash out some of the coins I can be sure to minimize or eliminate capital gains.

Sort:  

Coin Marketplace

STEEM 0.21
TRX 0.13
JST 0.030
BTC 67096.35
ETH 3509.27
USDT 1.00
SBD 3.22