# Python3 version 0.0.1.0-beta by Oaldamster
_Originally forked from Steem Engine Airdrop Tool {[seairdrop](https://github.com/themarkymark-steem/seairdrop)} by [The Marky Mark](https://steemit.com/@themarkymark)._
## [+] Load Config, autoload Airdrop file
**Creating a Token on [Steem-Engine dot com](https://steem-engine.com) can be one thing, spreading the love is another. Thanks to a few fellow Steemians though, [The Marky Mark](https://steemit.com/@themarkymark) and [Holger80](https://steemit.com/@holger80), it now has become as easy as _Py(thon 3)_. This second version, ATE, of the original go.py file will load a separate config file, that will have the airdrop file loaded. The main file is now called _gogogo.py_.**
## About ATE (Sounds like Aid)
Easy emission of any Token on Steem-Engine dot com in an airdrop alike fashion, using [the Beem Python Module](https://github.com/holgern/beem) and [Python3](https://www.python.org/downloads/) on Linux. This version adds the user defined loading of a Config-'TokenName'.JSON file. That will point to an Airdrop-'TokenName'.dat file, to be loaded. It is presumed that the .dat files are in a sub-folder. Relative to the working directory.
### Supported methods:
* Transfer
* [-] Issue
* [-] Stake
### Required:
* Python3 :: https://www.python.org/downloads/
* Beem Python Module :: https://github.com/holgern/beem
Eventually for reference:
* Original version :: https://github.com/themarkymark-steem/seairdrop
### How to use
**It is best to use Beem(PY) to first create a (Key-)Wallet. Only to store a Post and an Active key in there. Then secure it with a password. That will be used to unlock the (Key-)Wallet, instead of using the Post and or Active key. The Beem Python Module has all kinds of easy to use commands. And in $BASH (command-line) it is even easier to use beempy to create a (Key-)Wallet. (Use "beempy --help" first, if you are new to BEEM.)**
After all the needed setups, create a _config-'tokename'.json_ file that has all the settings for a Token emission. First try a so called '_Dry-Run_' by setting _"dry_run" : true_. (Make that a default setting.) If it all goes well, change it to _false_ and it goes live. Then create an _airdrop-'tokenname'.dat_ file, in a sub-folder, in a CSV {Comma Seperated Values} fashion. In there put the name of the Steem account first, then a comma and after that the amount to send. (See the example (s) below the gogogo.py source.)
### Notes
This version is mainly aimed at the '_Transfer_' of [Steem-Engine dot com](https://steem-engine.com) Tokens. Although it might seem relatively easy to add some functionality to it to '_Issue_' and/or '_Stake_'. (Suggestion: Forked code can be put in a reply at '_SteemHub_') Maybe create a front-end in Kivy? In essence it is possible to use all kinds of different setups, using unique config and dat files. Even automate it more using data pulled from the Steem blockchain first.
Please note that this is software is something that comes as it is. Use at your own responsibility. And keep the time-out at 10 seconds or more.
> Original copyrights seAirdrop project by: _The Marky Mark_.
Some tutorials on Python3, and the usage of Beem, can be found at fellow Steemian [Felixxx' his blog](https://steemit.com/busy/@felixxx/python-for-steem-how-to-beem).
(_Developed on a Linux driven Laptop by Oaldamster._)
###
- [x] Use it with a combination of unique config. json and airdrop.dat files.
- [-] Make it work for '_Issue_' and '_Stake_', right out of the box.
- [-] Switch between different servers.
- [-] Create a GUI, in Kivy for instance. :: https://kivy.org/#download
- [-] Grab data from Steem blockchain, then create a Transfer list, completely automated.
#### [+] Command line
`python3 gogogo.py config-tkn.json`
> (Where tkn is the one to be send.)
#### [+] FILES
* gogogo.py
The main file, will do the actual airdropping
* ./config-'tokenname'.json
A JSON preferences file, in the same folder as gogogo.py
* data/airdrop-'tokenname'.dat
A CSV data file that holds the Steem accounts and the values, in a data subfolder.
#### \FILE: gogogo.py
```python
#
# Automated Token Emission, ATE, for Steem
# A fork from the Steem Engine Airdrop project, by The Marky Mark
# Version 202002120850 - 0.0.1.0 - beta, by Oaldamster
#
# Import some Python modules
import csv
import json
import sys
import time
import os
# Import the Beem Steem module by Holger80
from beem import Steem
from beem.account import Account
from beem.exceptions import AccountDoesNotExistsException
from beem.instance import set_shared_steem_instance
# Some global variables
config = {}
user_list = []
# Get the Current Working Directory
# Assume files are stored relative from here
current_Dir = os.getcwd() + "/"
print (current_Dir)
load_Configfile = current_Dir + (sys.argv[1])
# Load the config file
def load_config():
global config
if len(sys.argv) == 1:
# Instead of this create a default?
print("ERROR: Please specify a config file")
quit()
else:
print (load_Configfile)
try:
with open(load_Configfile) as config_file:
config = json.load(config_file)
print(f"Loading emission file: {config['loadfile']}\n")
except:
print("Unable to open configuration file")
quit()
# Load the user list to airdrop to
def load_users():
global user_list
# Add Try etc later
if config['loadfile']:
get_file = current_Dir + config['data_path'] + config['data_file'] + "-" + config['token'] + "." + config['data_file_ext']
try:
with open(get_file) as user_file:
reader = csv.reader(user_file)
user_list = list(reader)
print("Loaded emission file.\n")
except:
print("Unable to open emission file")
quit()
# Build from the data to store on the Steem blockchain
def build_payload(user, amount):
data = {}
data['contractName'] = 'tokens'
data['contractAction'] = config['mode']
data['contractPayload'] = {}
data['contractPayload']['to'] = user
data['contractPayload']['symbol'] = config['token'].upper()
data['contractPayload']['quantity'] = f"{amount}"
data['contractPayload']['memo'] = config['memo']
return data
# Hey Hoo, let's go! Send them Tokens
def send_tokens(stm, user, amount, retries=0):
data = build_payload(user, amount)
if not config['dry_run']:
try:
stm.custom_json('ssc-mainnet1', data,
required_auths=[config['account_name']])
except:
if retries < 3:
send_tokens(stm, user, amount, retries=retries)
else:
print(f"Airdrop aborted at user: {user[0]}")
quit()
# Prepare for launch, check for Dry Run.
def do_airdrop(stm):
estimated_time = round((len(user_list) * config['delay']) / 60, 1)
estimated_tokens = 0
for user in user_list:
estimated_tokens += float(user[1])
print("Starting Airdrop\n")
if config['dry_run']:
print("DRY RUN! - Tokens will not be transfered.\n")
print(f"Estimated Time: {estimated_time} minutes")
print(f"Estimated Tokens Used: {estimated_tokens}")
print("")
for x in range(10, -1, -1):
print(f"Starting in {x} seconds...", end='\r')
time.sleep(1)
sys.stdout.flush()
for user in user_list:
try:
Account(user[0])
except AccountDoesNotExistsException:
print(f"Skipping user {user[0]} - Does not exist")
continue
print(f"Sending {user[1]} {config['token']} tokens to @{user[0]}")
if not config['dry_run']:
send_tokens(stm, user[0], user[1])
time.sleep(config['delay'])
# The main file, ground control
def main():
print("\n")
load_config()
load_users()
stm = Steem(node=["https://api.steemit.com"])
stm.wallet.unlock(config['pw'])
set_shared_steem_instance(stm)
do_airdrop(stm)
# Start it all
if __name__ == '__main__':
main()
```
/FILE: gogogo.py ####
<hr/>
#### \FILE: config.json
```json
{
"dry_run" : true,
"account_name" : "youraccount",
"pw" : "beemwalletopenup",
"token" : "tokenname",
"memo" : "A message, could be a random qoute even.",
"issue_first" : false,
"mode" : "transfer",
"loadfile" : true,
"data_path" : "data/",
"data_file" : "airdrop",
"data_file_ext" : "dat",
"delay" : 10
}
```
/FILE: config.json ####
<hr/>
#### \FILE: airdrop.dat
```cvs
smasssh, 10
meesterboom, 10
mistakili, 5
geekgirl, 5
rodino, 5
```
/FILE: airdrop.dat ####
<hr/>
<center>
**Testing ATE with some ENGAGE.**
![send_engage_with_ate.png](https://cdn.steemitimages.com/DQmcxbZeMhQ67PUzcjuWckg8oAmoZkPyWZn3TaW6ueRbSYT/send_engage_with_ate.png)
_Screenshot taken at https://steem-engine.com_
</center>
***Please note that _SteemHub_ (STMhub?) is merely an idea. Whomever is able to create it for real: Make it so!***