Some time ago, @remlaps introduced an improved version of its browser extension. This marks posts in colour that either contain a beneficiary to @null or that have been promoted with a transfer to @null.
Especially the second possibility has been in the focus for some time. It was therefore interesting for me to find out how many users have promoted a post and whether it was also promoted by the author himself.
Since @remlaps has released his browser extension for further development, it made sense to upgrade it for this purpose ;-)
In order to find out which user has promoted which post, the first step is to retrieve the transfers to @null.
Steemchiller has the right query for this with his SDS. I am currently analysing the last 250 transfers to @null. I think that should be enough for now. Then the data are prepared so that they can be accessed quickly with the post identifier.
It was more difficult to get to the post identifier on the Steemit page. @remlaps loops through all li
elements. But the identifier is not contained in a list element. Here I had to loop through to the matching parent element. Obviously there is no method to retrieve all parent elements of an element.
At first I had considered displaying the number directly in the post card on the page. I then decided to display the data in the elements used by @remlaps in the payout pane after all.
I add the following data to the elements with the entry in each post:
I have tried to change as few as possible the original code.
promoAmount
because there are now more characters after „Promotion cost“.highLight
function. Thus, a call in the corresponding else if
branch is sufficient for the new functionality.highLight
function. I have inserted this into the then
branch of fetch to provide for the asynchronous process. Otherwise, the promotedPosts
would still be undefined when called for the first time.That was it!
Otherwise, I'm with @remlaps: Feel free to modify the extension. I would be happy to receive further ideas and implementations.
You find the code below.
Vor einiger Zeit hat @remlaps seine Browser Extension. Damit werden Posts farblich markiert, die entweder eine Beneficiary an @null enthalten, oder für die mit einem Transfer an @null geworben wurde.
Besonders die zweite Möglichkeit rückt seit einiger Zeit wieder vermehrt in den Focus. Für mich war es daher interessant, zu erfahren, wie viele User haben einen Beitrag beworben und ob dieser auch vom Autor selbst beworben wurde. Da @remlaps seine Browser Extension zur weiteren Entwicklung freigegeben hat, lag es nahe, sie für diesen Zweck aufzubohren ;-)
Um herauszufinden, welcher User für welchen Post geworben hat, müssen als erstes die Transfers an @null ermittelt werden.
Steemchiller hat mit seinem SDS hierfür die passende Anfrage. Aktuell werte ich die letzten 250 Transfers an @null aus. Ich denke, das sollte aktuell genügen. Danach werden die Daten aufbereitet, so dass ein schneller Zugriff mit dem Post-Identifier erfolgen kann.
Schwieriger war es, an den Post-Identifier auf der Steemit-Seite zu gelangen. @remlaps durchläuft ja alles li
-Elemente. Der Identifier ist aber nicht in einem Listenelement enthalten. Hier musste ich die eine Schleife bis zum passenden Eltern-Element einbauen. Offensichtlich gibt es keine Methode, alle Elternelemente eines Elements abzurufen.
Zunächst hatte ich überlegt, die Anzahl direkt in der Post-Card auf der Seite anzeigen zu lassen. Ich habe mich dann doch dafür entschieden, die Daten in den von @remlaps verwendeten Elemente in der Payout-Pane anzuzeigen.
Ich ergänze die Elemente mit dem Eintrag „Promotion Cost“ in jedem Post mit folgenden Daten:
Ich habe versucht, so wenig wie möglich am ursprünglichen Code zu ändern.
promoAmount
, da jetzt hinter „Promotion Cost“ weitere Zeichen stehen.highLight
-Funktion deklariert. Somit genügt ein Aufruf im entsprechenden else if
-Zweig für die neue Funktionalität.highLight
-Funktion. Diese habe ich in den then
-Zweig von fetch eingefügt, um den asyncronen Ablauf zu ermöglichen. Ansonsten wären beim ersten Aufruf die promotedPosts
noch undefiniert.Das war's schon!
Ich halte es ansonsten wie @remlaps: Wer Lust und Laune hat, darf die Erweiterung gern weiterbearbeiten. Ich würde mich auf weitere Idee und Umsetzungen freuen.
Chrome-based Browser (Chrome/Brave/Edge)
Thanks to @michelangelo3 for the description and screenshots
Done!
Auf Chrome basierende Browser (Chrome/Brave/Edge)
Dank an @michelangelo3 für die Beschreibung und Screenshots
Fertig!
The main.js has been updated:
function prepareData: lines 96 - 98: else branch added.
Intructions for Chrome added
Here is the code:
{
"manifest_version":2,
"version":"0.0.2",
"name":"Steem Curation Extension",
"content_scripts":[
{
"matches":["https://steemit.com/*"],
"js":["main.js"]
}
],
"permissions": [
"https://sds.steemworld.org/*"
]
}
console.log("The extension is up and running");
var promotedPosts = {}; // contains all transactions for promoted posts with accounts, count and whether self promoted
const urlRequest = "https://sds.steemworld.org/transfers_api/getTransfersByTypeTo/transfer/null/time/DESC/250/0";
const highLight = () => {
var curatorBackgroundColor;
const listItem = document.querySelectorAll('li');
for (let i=listItem.length-1; i>=0; i--) {
if ( listItem[i].textContent.match('null: .*%' ) && listItem[i].textContent.match('Promotion Cost .*\$') ) {
console.log("Found a /promoted post in #burnsteem25 (outer block)");
curatorBackgroundColor = '#1E90FF';
listItem[i].style['background-color'] = curatorBackgroundColor;
} else if ( listItem[i].textContent.match('null: .*%' )) {
console.log("#burnsteem25 outer match: ");
if ( listItem[i].textContent.match('^null:.*\%') ) {
console.log("Found #burnsteem25");
var str = listItem[i].textContent;
var nullPct = str.substring(
str.indexOf(" ") + 1,
str.lastIndexOf("%")
);
if ( nullPct > 0 && nullPct < 25 ) {
curatorBackgroundColor = "coral";
} else if ( nullPct < 50 ) {
curatorBackgroundColor = "orange";
} else if ( nullPct < 75 ) {
curatorBackgroundColor = "darkorange";
} else if ( nullPct > 0 ) {
curatorBackgroundColor = "orangered";
}
}
listItem[i].style['background-color'] = curatorBackgroundColor;
} else if ( listItem[i].textContent.match('Promotion Cost .*\$') ) {
console.log("Found a /promoted post (outer block)");
if ( listItem[i].textContent.match('^Promotion Cost .*\$$') ) {
console.log("Found a /promoted post");
var str = listItem[i].textContent;
var indexEnd = (str.indexOf("(") >= 0) ? str.indexOf("(") - 1 : str.length;
var promoAmount = str.substring(
str.indexOf("$") + 1,
indexEnd
);
console.log ("Promotion amount: " + promoAmount);
if ( promoAmount > 0 && promoAmount < 0.26 ) {
curatorBackgroundColor = "paleturquoise";
} else if ( promoAmount < 0.51 ) {
curatorBackgroundColor = "aquamarine";
} else if ( promoAmount < 1.01 ) {
curatorBackgroundColor = "turquoise";
} else if ( promoAmount > 0 ) {
curatorBackgroundColor = "lightseagreen";
}
// now edit the textContent
addText(listItem[i]);
}
listItem[i].style['background-color'] = curatorBackgroundColor;
} else {
listItem[i].style['background-color'] = "initial";
}
}
}
// load transfers to null and prepare promotedPosts for further use
fetch (urlRequest).then (function (response) {
return response.json();
}).then (function (data) {
prepareData(data);
// execute hihgLight after providing the data
highLight();
}).catch (function (error) {
console.log ("error: " + error);
});
function prepareData(data) {
if (data) {
const cols = data.result.cols;
const rows = data.result.rows;
rows.forEach(trf => {
let trfData = getAuthorPost(trf[cols["memo"]]);
if (trfData) {
let from = trf[cols["from"]];
let self = (from == trfData["author"])
let props = {"user": [from], "count": 1, "self": self};
let key = trfData["post"];
if (promotedPosts && key in promotedPosts) {
let oldProps = promotedPosts[key];
if ( !(oldProps["user"].includes(from)) ) {
props["user"] = props["user"].concat(oldProps["user"]);
props["count"] += oldProps["count"];
props["self"] = props["self"] || oldProps["self"];
} else {
props = oldProps;
}
}
promotedPosts[key] = props;
}
});
};
}
function getAuthorPost(memoStr) {
// const re = /^@(?<author>[\w-.]+)[\/](?<permlink>[\w-\|]+)$/;
// const objMatch = memoStr.match(re);
const objMatch = regexMatch(true, memoStr);
let result = (objMatch && objMatch.length == 3) ? {
"post": objMatch.groups["author"] + "/" + objMatch.groups["permlink"],
"author": objMatch.groups["author"]
} : null ;
return result;
}
function addText(listItem) {
var added = false;
// console.log("include User? " + listItem.textContent.includes('User'));
if ( !listItem.textContent.includes('User') ) {
// get the postid
let address = getAddress(listItem);
// console.log("Address: " + address);
if ( address !== null ) {
let key = getPost(address);
// console.log("Key: " + key);
// console.log("Promoted: " + promotedPosts[key]);
if ( promotedPosts[key] ) {
let newText = ' (by ' +
promotedPosts[key]["count"] +
( promotedPosts[key]["count"] == 1 ? ' User' : ' Users' ) +
( promotedPosts[key]["self"] ? ' incl. self)' : ')' );
let newTextNode = document.createTextNode(newText);
listItem.firstChild.appendChild(newTextNode);
added = true
}
}
}
if ( added ) {
console.log("User added");
} else {
console.log("Adding User went wrong");
}
}
function getPost(address) {
const objMatch = regexMatch(false, address);
return (objMatch && objMatch.length == 3) ? objMatch.groups["author"] + "/" + objMatch.groups["permlink"] : null;
}
function regexMatch(fromBegin, textStr) {
re = fromBegin ? /^@(?<author>[\w-.]+)[\/](?<permlink>[\w-\|]+)$/ : /@(?<author>[\w-.]+)[\/](?<permlink>[\w-\|]+)$/;
return textStr.match(re);
}
function getAddress(elem) {
var link;
while ( elem.parentElement && elem.parentElement.nodeName.toLowerCase() != 'body' ) {
elem = elem.parentElement;
if ( elem.nodeName.toLowerCase() == 'div' && elem.className.includes('articles__content-block--text') ) {
let titleElemList = elem.getElementsByClassName('entry-title');
link = titleElemList[0].firstChild.href;
break;
}
}
return link ? link : null;
}
// highLight();
window.addEventListener('scroll', () => {
highLight();
});
window.addEventListener('load', () => {
highLight();
});
console.log("The extension is done.");