1- Motivation:
First, I want to thank @leo-curation for providing reports from its curation. This is an example of every curation program to bring transparency to our community. I saw the post from @anonyi about one of its curators speculating about possible "self-voting" from a curators to its accounts. I remembered that inleo has this posts about its curations and went to check it, and I saw some trends there associated to the name and commented on @anonyi post about that. But then my programming curiosity thought about, the possibility of parsing all the curation reports, at least the organic ones since in theory the curated user is organically curated without any other type of influence. Inleo has other types of curation programs including the stake, X and threads curation. Those are more directed since the author triggers the possibility of curation. But the organic curation is different, more similar to a regular curation program which is independent of anything. The curator checks a post under the community and curates it if they like it. The full scripts are available at github .
2- Script building:
I used Python since it is the language that I am currently using more around here, I started to use some JS but I stopped a bit. I am aware by some nice clients built for hive, but I decided to use the regular "request" library to perform get HTTP methods. I wanted to be simple and the job requires simple tools. Just gathering comment transactions from permlinks that follow the trend of the organic curation reports from inleo! They started to post these reports on their week 24 of "curation" so I am not sure what I missed before there. This type of condition can be used for other curation reports published by other users so I am showing bellow where you can find that in the script:
author = post["author"]
permlink = post["permlink"]
if author == "leo-curation" and permlink.startswith("organic-curation-report"):
My idea for the stats was to find highly curated users and show their curators how many times each curator upvoted this specific user. First I made a regular expression to capture the rows where you had the user in the beginning of the row (curated user) and also at the end of the row after the last "|" and a space you can find the curator username. You can find this in the exctract_stats function in the script. I build a dictionary where the parent key is the curated user, and the value is another dictionary where you can have 1 or more keys (curators) and the value of that is the number of times, so for example if I am curated by John and Mary one time we have stats['gwajnberg']= { 'John':1, 'Mary':1} .
In the end I process the final dictionary of dictionaries with the numbers ordering and organize the print. First I sort by the total number of curation using this code below:
def print_stats(stats):
sorted_stats = sorted(
stats.items(),
key=lambda item: sum(item[1].values()), # Total curations
reverse=True
)
The last part of the function I just print the organized list with one curated user by each row in this format: "User1 5 (2 by curator1, 3 by curator2)". The loop to create these prints are bellow:
for curated_user, curators in sorted_stats:
total_curations = sum(curators.values())
curators_str = ", ".join(
f"{count} by {curator}" for curator, count in curators.items()
)
print(f"{curated_user} {total_curations} ({curators_str})"
3- Results:
Here are some top results of these findings, giving results with users more than 8 times curated, maybe that agrees with @hivewatchers and @anonyi discussion in that post, we can find two supposed alts from the curator being highly curated by this one in the top 3.
User | Total Curation | Breakdown |
---|---|---|
davidpena21 | 23 | 5 by olujay, 8 by vikvitnik, 10 by joheredia21 |
reeta0119 | 23 | 23 by alokkumar121 |
shriram19 | 21 | 21 by alokkumar121 |
abenad | 20 | 18 by olujay, 2 by vikvitnik |
jhymi | 16 | 4 by princessbusayo, 11 by olujay, 1 by vikvitnik |
joyben | 15 | 14 by uyobong, 1 by princessbusayo |
mickymouse | 15 | 14 by uyobong, 1 by thetimetravelerz |
utibeabasi | 14 | 14 by uyobong |
mclarenf11 | 14 | 13 by joheredia21, 1 by vikvitnik |
nancydominic | 13 | 1 by princessbusayo, 11 by uyobong, 1 by alokkumar121 |
daniasi | 13 | 7 by olujay, 1 by thetimetravelerz, 3 by joheredia21, 1 by princessbusayo, 1 by alokkumar121 |
milik80 | 13 | 4 by vikvitnik, 4 by alokkumar121, 3 by joheredia21, 1 by olujay, 1 by princessbusayo |
mistakili | 13 | 12 by idiosyncratic1, 1 by alokkumar121 |
pricelessudy | 12 | 11 by uyobong, 1 by princessbusayo |
newbreed | 12 | 9 by uyobong, 2 by alokkumar121, 1 by princessbusayo |
creativepearl | 12 | 11 by olujay, 1 by vikvitnik |
nkemakonam89 | 11 | 6 by princessbusayo, 4 by olujay, 1 by alokkumar121 |
behiver | 11 | 1 by vikvitnik, 10 by alokkumar121 |
franz54 | 11 | 7 by joheredia21, 3 by vikvitnik, 1 by olujay |
bitcoinflood | 11 | 4 by thetimetravelerz, 2 by idiosyncratic1, 4 by vikvitnik, 1 by alokkumar121 |
mummygo | 11 | 10 by uyobong, 1 by alokkumar121 |
bala41288 | 11 | 8 by thetimetravelerz, 3 by alokkumar121 |
psalmmy264 | 10 | 8 by olujay, 1 by princessbusayo, 1 by vikvitnik |
bipolar95 | 10 | 1 by uyobong, 6 by olujay, 1 by alokkumar121, 2 by princessbusayo |
fonpet | 10 | 9 by uyobong, 1 by princessbusayo |
shawnnft | 10 | 2 by vikvitnik, 6 by olujay, 2 by alokkumar121 |
ukotex | 10 | 9 by uyobong, 1 by princessbusayo |
eliany | 9 | 8 by uyobong, 1 by vikvitnik |
deraaa | 9 | 7 by olujay, 1 by princessbusayo, 1 by vikvitnik |
cjlugo | 9 | 2 by vikvitnik, 7 by joheredia21 |
nhaji01 | 9 | 8 by olujay, 1 by princessbusayo |
coolguy123 | 9 | 8 by alokkumar121, 1 by olujay |
empressjay | 9 | 1 by princessbusayo, 3 by alokkumar121, 5 by fokusnow |
luckyali | 9 | 2 by thetimetravelerz, 7 by alokkumar121 |
sofiaquino98 | 9 | 1 by alokkumar121, 3 by joheredia21, 2 by olujay, 3 by vikvitnik |
gadrian | 9 | 9 by alokkumar121 |
etorobong | 9 | 8 by uyobong, 1 by alokkumar121 |
lileisabel | 8 | 2 by princessbusayo, 4 by alokkumar121, 1 by vikvitnik, 1 by olujay |
omarcitorojas | 8 | 6 by vikvitnik, 1 by alokkumar121, 1 by joheredia21 |
sylvasticks | 8 | 6 by uyobong, 2 by princessbusayo |
ibbtammy | 8 | 6 by olujay, 2 by princessbusayo |
4- Extra Results:
Before posting I had the curiosity in seeing this as a monthly trend, it was an interesting result as well, I added another script to the same repo where we can group the same github . In this case I used the "last_updated" object in the Get result from the same comment transactions. Here we go for the last 3 months.
November 2024
User | Total Curation | Breakdown |
---|---|---|
mamaemigrante | 5 | 1 by olujay, 2 by vikvitnik, 2 by joheredia21 |
peckypeace | 5 | 4 by uyobong, 1 by olujay |
wbrandt | 4 | 4 by joheredia21 |
cjlugo | 4 | 2 by vikvitnik, 2 by joheredia21 |
nkemakonam89 | 4 | 3 by princessbusayo, 1 by olujay |
utibeabasi | 4 | 4 by uyobong |
sperosamuel15 | 4 | 4 by princessbusayo |
mickymouse | 4 | 4 by uyobong |
shriram19 | 4 | 4 by alokkumar121 |
joyben | 3 | 3 by uyobong |
lileisabel | 3 | 2 by princessbusayo, 1 by alokkumar121 |
omarcitorojas | 3 | 3 by vikvitnik |
duncanek | 3 | 3 by uyobong |
eniolaabioye | 3 | 3 by princessbusayo |
sylvasticks | 3 | 2 by uyobong, 1 by princessbusayo |
nancydominic | 3 | 1 by princessbusayo, 2 by uyobong |
pricelessudy | 3 | 3 by uyobong |
abenad | 3 | 3 by olujay |
hylene74 | 3 | 2 by vikvitnik, 1 by olujay |
ibbtammy | 3 | 3 by olujay |
lisbethseijas | 3 | 1 by olujay, 1 by vikvitnik, 1 by joheredia21 |
soyunasantacruz | 3 | 2 by olujay, 1 by joheredia21 |
milik80 | 3 | 2 by vikvitnik, 1 by alokkumar121 |
reeta0119 | 3 | 3 by alokkumar121 |
October 2024
User | Total Curation | Breakdown |
---|---|---|
mclarenf11 | 5 | 1 by vikvitnik, 4 by joheredia21 |
abenad | 4 | 3 by olujay, 1 by vikvitnik |
milik80 | 4 | 1 by alokkumar121, 2 by joheredia21, 1 by vikvitnik |
shriram19 | 4 | 4 by alokkumar121 |
coolguy123 | 3 | 2 by alokkumar121, 1 by olujay |
pricelessudy | 3 | 3 by uyobong |
reeta0119 | 3 | 3 by alokkumar121 |
jhymi | 3 | 2 by princessbusayo, 1 by olujay |
franz54 | 3 | 1 by vikvitnik, 1 by joheredia21, 1 by olujay |
davidpena21 | 3 | 3 by joheredia21 |
beckyroyal | 3 | 1 by olujay, 2 by princessbusayo |
daniasi | 3 | 2 by joheredia21, 1 by olujay |
September 2024
User | Total Curation | Breakdown |
---|---|---|
abenad | 8 | 8 by olujay |
ukotex | 6 | 5 by uyobong, 1 by princessbusayo |
mummygo | 5 | 4 by uyobong, 1 by alokkumar121 |
newbreed | 5 | 5 by uyobong |
bipolar95 | 5 | 4 by olujay, 1 by princessbusayo |
peckypeace | 5 | 5 by uyobong |
shriram19 | 4 | 4 by alokkumar121 |
joyben | 4 | 4 by uyobong |
milik80 | 4 | 1 by olujay, 1 by princessbusayo, 2 by alokkumar121 |
coolguy123 | 4 | 4 by alokkumar121 |
gargi | 4 | 3 by alokkumar121, 1 by thetimetravelerz |
mclarenf11 | 4 | 4 by joheredia21 |
dimeilaz | 3 | 2 by joheredia21, 1 by vikvitnik |
behiver | 3 | 3 by alokkumar121 |
fonpet | 3 | 3 by uyobong |
davidpena21 | 3 | 2 by vikvitnik, 1 by joheredia21 |
priyanarc | 3 | 3 by alokkumar121 |
daniasi | 3 | 2 by olujay, 1 by joheredia21 |
chinay04 | 3 | 1 by olujay, 2 by princessbusayo |
mmenyene | 3 | 3 by uyobong |
olujay | 3 | 3 by olujay |
viviehardika | 3 | 1 by olujay, 1 by alokkumar121, 1 by vikvitnik |
edeyglezsosa | 3 | 3 by vikvitnik |
bala41288 | 3 | 3 by thetimetravelerz |
pricelessudy | 3 | 2 by uyobong, 1 by princessbusayo |
valblesza | 3 | 2 by uyobong, 1 by princessbusayo |
5- Conclusion:
The script was interesting to build, I had a question and the script helped me to answer the question. I invite anyone to use this type to approach including @leo-curation managers to avoid trends and give some type of help in identifying the exploitation of a big curation account like this one.
[PT-BR]
Primeiro, quero agradecer a @leo-curation por fornecer relatórios de sua curadoria. Este é um exemplo de cada programa de curadoria para trazer transparência à nossa comunidade. Vi a postagem de @anonyi sobre um de seus curadores especulando sobre possível "autovotação" de um curador para suas contas. Lembrei que a inleo tem essas postagens sobre suas curadorias e fui verificar, e vi algumas tendências associadas ao nome e comentei na postagem de @anonyi sobre isso. Mas então minha curiosidade em programação pensou sobre a possibilidade de analisar todos os relatórios de curadoria, pelo menos os orgânicos, já que em teoria o usuário curado é curado organicamente sem nenhum outro tipo de influência. A Inleo tem outros tipos de programas de curadoria, incluindo a curadoria de stake, X e threads. Esses são mais direcionados, já que o autor aciona a possibilidade de curadoria. Mas a curadoria orgânica é diferente, mais parecida com um programa de curadoria regular que é independente de qualquer coisa. O curador verifica uma publicação na comunidade e faz a curadoria se gostar. Os scripts completos estão disponíveis em github .
2- Construção de script:
Usei Python, pois é a linguagem que estou usando mais por aqui no momento, comecei a usar um pouco de JS, mas parei um pouco. Estou ciente de alguns clientes legais criados para o Hive, mas decidi usar a biblioteca regular "request" para executar métodos HTTP get. Eu queria ser simples e o trabalho requer ferramentas simples. Apenas reunir transações de comentários de permlinks que seguem a tendência dos relatórios de curadoria orgânica do inleo! Eles começaram a postar esses relatórios na semana 24 de "curadoria", então não tenho certeza do que perdi antes. Esse tipo de condição pode ser usado para outros relatórios de curadoria publicados por outros usuários, então estou mostrando abaixo onde você pode encontrar isso no script:
author = post["author"]
permlink = post["permlink"]
if author == "leo-curation" and permlink.startswith("organic-curation-report"):
Minha ideia para as estatísticas era encontrar usuários altamente curados e mostrar aos curadores quantas vezes cada curador votou positivamente nesse usuário específico. Primeiro, criei uma expressão regular para capturar as linhas onde você tinha o usuário no início da linha (usuário curado) e também no final da linha após o último "|" e um espaço, você pode encontrar o nome de usuário do curador. Você pode encontrar isso na função exctract_stats no script. Eu construo um dicionário onde a chave pai é o usuário curado, e o valor é outro dicionário onde você pode ter 1 ou mais chaves (curadores) e o valor disso é o número de vezes, então, por exemplo, se eu for curado por John e Mary uma vez, temos stats['gwajnberg']= { 'John':1, 'Mary':1} .
No final, eu processo o dicionário final de dicionários com a ordenação dos números e organizo a impressão. Primeiro, eu classifico pelo número total de curadoria usando este código abaixo:
def print_stats(stats):
sorted_stats = sorted(
stats.items(),
key=lambda item: sum(item[1].values()), # Total de curadorias
reverse=True
)
A última parte da função eu apenas imprimo a lista organizada com um usuário curado por cada linha neste formato: "Usuário1 5 (2 por curador1, 3 por curador2)". O loop para criar essas impressões está abaixo:
para curated_user, curators em sorted_stats:
total_curations = sum(curators.values())
curators_str = ", ".join(
f"{count} por {curator}" para curator, count em curators.items()
)
print(f"{curated_user} {total_curations} ({curators_str})"
3- Resultados:
Aqui estão alguns dos principais resultados dessas descobertas, dando resultados com usuários mais de 8 vezes curados, talvez isso concorde com a discussão de @hivewatchers e @anonyi naquele post, podemos encontrar dois supostos alts do curador sendo altamente curados por este no top 3.
User | Total Curation | Breakdown |
---|---|---|
davidpena21 | 23 | 5 por olujay, 8 por vikvitnik, 10 por joheredia21 |
reeta0119 | 23 | 23 por alokkumar121 |
shriram19 | 21 | 21 por alokkumar121 |
abenad | 20 | 18 por olujay, 2 por vikvitnik |
jhymi | 16 | 4 por princessbusayo, 11 por olujay, 1 por vikvitnik |
joyben | 15 | 14 por uyobong, 1 por princessbusayo |
mickymouse | 15 | 14 by uyobong, 1 by thetimetravelerz |
utibeabasi | 14 | 14 by uyobong |
mclarenf11 | 14 | 13 by joheredia21, 1 by vikvitnik |
nancydominic | 13 | 1 by princessbusayo, 11 by uyobong, 1 by alokkumar121 |
daniasi | 13 | 7 by olujay, 1 by thetimetravelerz, 3 by joheredia21, 1 by princessbusayo, 1 by alokkumar121 |
milik80 | 13 | 4 by vikvitnik, 4 by alokkumar121, 3 by joheredia21, 1 by olujay, 1 by princessbusayo |
mistakili | 13 | 12 by idiosyncratic1, 1 by alokkumar121 |
pricelessudy | 12 | 11 by uyobong, 1 by princessbusayo |
newbreed | 12 | 9 by uyobong, 2 by alokkumar121, 1 by princessbusayo |
creativepearl | 12 | 11 by olujay, 1 by vikvitnik |
nkemakonam89 | 11 | 6 by princessbusayo, 4 by olujay, 1 by alokkumar121 |
behiver | 11 | 1 by vikvitnik, 10 by alokkumar121 |
franz54 | 11 | 7 by joheredia21, 3 by vikvitnik, 1 by olujay |
bitcoinflood | 11 | 4 by thetimetravelerz, 2 by idiosyncratic1, 4 by vikvitnik, 1 by alokkumar121 |
mummygo | 11 | 10 by uyobong, 1 by alokkumar121 |
bala41288 | 11 | 8 by thetimetravelerz, 3 by alokkumar121 |
psalmmy264 | 10 | 8 by olujay, 1 by princessbusayo, 1 by vikvitnik |
bipolar95 | 10 | 1 by uyobong, 6 by olujay, 1 by alokkumar121, 2 by princessbusayo |
fonpet | 10 | 9 by uyobong, 1 by princessbusayo |
shawnnft | 10 | 2 by vikvitnik, 6 by olujay, 2 by alokkumar121 |
ukotex | 10 | 9 by uyobong, 1 by princessbusayo |
eliany | 9 | 8 by uyobong, 1 by vikvitnik |
deraaa | 9 | 7 by olujay, 1 by princessbusayo, 1 by vikvitnik |
cjlugo | 9 | 2 by vikvitnik, 7 by joheredia21 |
nhaji01 | 9 | 8 by olujay, 1 by princessbusayo |
coolguy123 | 9 | 8 by alokkumar121, 1 by olujay |
empressjay | 9 | 1 by princessbusayo, 3 by alokkumar121, 5 by fokusnow |
luckyali | 9 | 2 by thetimetravelerz, 7 by alokkumar121 |
sofiaquino98 | 9 | 1 by alokkumar121, 3 by joheredia21, 2 by olujay, 3 by vikvitnik |
gadrian | 9 | 9 by alokkumar121 |
etorobong | 9 | 8 by uyobong, 1 by alokkumar121 |
lileisabel | 8 | 2 by princessbusayo, 4 by alokkumar121, 1 by vikvitnik, 1 by olujay |
omarcitorojas | 8 | 6 by vikvitnik, 1 by alokkumar121, 1 by joheredia21 |
sylvasticks | 8 | 6 by uyobong, 2 by princessbusayo |
ibbtammy | 8 | 6 by olujay, 2 by princessbusayo |
4- Extra Results:
Before posting I had the curiosity in seeing this as a monthly trend, it was an interesting result as well, I added another script to the same repo where we can group the same github . In this case I used the "last_updated" object in the Get result from the same comment transactions. Here we go for the last 3 months.
November 2024
User | Total Curation | Breakdown |
---|---|---|
mamaemigrante | 5 | 1 by olujay, 2 by vikvitnik, 2 by joheredia21 |
peckypeace | 5 | 4 by uyobong, 1 by olujay |
wbrandt | 4 | 4 by joheredia21 |
cjlugo | 4 | 2 by vikvitnik, 2 by joheredia21 |
nkemakonam89 | 4 | 3 by princessbusayo, 1 by olujay |
utibeabasi | 4 | 4 by uyobong |
sperosamuel15 | 4 | 4 by princessbusayo |
mickymouse | 4 | 4 by uyobong |
shriram19 | 4 | 4 by alokkumar121 |
joyben | 3 | 3 by uyobong |
lileisabel | 3 | 2 by princessbusayo, 1 by alokkumar121 |
omarcitorojas | 3 | 3 by vikvitnik |
duncanek | 3 | 3 by uyobong |
eniolaabioye | 3 | 3 por princessbusayo |
sylvasticks | 3 | 2 por uyobong, 1 por princessbusayo |
nancydominic | 3 | 1 por princessbusayo, 2 por uyobong |
pricelessudy | 3 | 3 por uyobong |
abenad | 3 | 3 por olujay |
hylene74 | 3 | 2 por vikvitnik, 1 por olujay |
ibbtammy | 3 | 3 por olujay |
lisbethseijas | 3 | 1 por olujay, 1 por vikvitnik, 1 por joheredia21 |
soyunasantacruz | 3 | 2 por olujay, 1 por joheredia21 |
milik80 | 3 | 2 por vikvitnik, 1 por alokkumar121 |
reeta0119 | 3 | 3 por alokkumar121 |
Outubro de 2024
User | Total Curation | Breakdown |
---|---|---|
mclarenf11 | 5 | 1 by vikvitnik, 4 by joheredia21 |
abenad | 4 | 3 by olujay, 1 by vikvitnik |
milik80 | 4 | 1 by alokkumar121, 2 by joheredia21, 1 by vikvitnik |
shriram19 | 4 | 4 by alokkumar121 |
coolguy123 | 3 | 2 by alokkumar121, 1 by olujay |
pricelessudy | 3 | 3 by uyobong |
reeta0119 | 3 | 3 by alokkumar121 |
jhymi | 3 | 2 by princessbusayo, 1 by olujay |
franz54 | 3 | 1 by vikvitnik, 1 by joheredia21, 1 by olujay |
davidpena21 | 3 | 3 by joheredia21 |
beckyroyal | 3 | 1 by olujay, 2 by princessbusayo |
daniasi | 3 | 2 by joheredia21, 1 by olujay |
September 2024
User | Total Curation | Breakdown |
---|---|---|
abenad | 8 | 8 by olujay |
ukotex | 6 | 5 by uyobong, 1 by princessbusayo |
mummygo | 5 | 4 by uyobong, 1 by alokkumar121 |
newbreed | 5 | 5 by uyobong |
bipolar95 | 5 | 4 by olujay, 1 by princessbusayo |
peckypeace | 5 | 5 by uyobong |
shriram19 | 4 | 4 by alokkumar121 |
joyben | 4 | 4 by uyobong |
milik80 | 4 | 1 by olujay, 1 by princessbusayo, 2 by alokkumar121 |
coolguy123 | 4 | 4 by alokkumar121 |
gargi | 4 | 3 by alokkumar121, 1 by thetimetravelerz |
mclarenf11 | 4 | 4 by joheredia21 |
dimeilaz | 3 | 2 by joheredia21, 1 by vikvitnik |
behiver | 3 | 3 by alokkumar121 |
fonpet | 3 | 3 by uyobong |
davidpena21 | 3 | 2 by vikvitnik, 1 by joheredia21 |
priyanarc | 3 | 3 by alokkumar121 |
daniasi | 3 | 2 by olujay, 1 by joheredia21 |
chinay04 | 3 | 1 by olujay, 2 by princessbusayo |
mmenyene | 3 | 3 by uyobong |
olujay | 3 | 3 by olujay |
viviehardika | 3 | 1 by olujay, 1 by alokkumar121, 1 by vikvitnik |
edeyglezsosa | 3 | 3 by vikvitnik |
bala41288 | 3 | 3 by thetimetravelerz |
pricelessudy | 3 | 2 by uyobong, 1 by princessbusayo |
valblesza | 3 | 2 by uyobong, 1 by princessbusayo |
5- Conclusão:
O script foi interessante de construir, eu tinha uma pergunta e o script me ajudou a respondê-la. Convido qualquer um a usar esse tipo de abordagem, incluindo os gerentes do @leo-curation, para evitar tendências e dar algum tipo de ajuda na identificação da exploração de uma grande conta de curadoria como essa.