Skip to content

Commit

Permalink
v2.0.0
Browse files Browse the repository at this point in the history
- Added external configuration file support ( #35 )

- Implemented argparse (BREAKING CHANGE)!
  • Loading branch information
Jon-Becker committed May 2, 2022
1 parent a327363 commit 14b07d1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ workspace.code-workspace
metadata/*.json
images/*.png
.ipynb_checkpoints/
*.pyc
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
nft-generator-py is a python based NFT generator which programatically generates unique images using weighted layer files. The program is simple to use, and new layers can be added by adding a new layer object and adding names, weights, and image files to the object.
You can [View The Demo](https://jbecker.dev/demos/nft-generator-py) here.

## Usage
As of v2.0.0, nft-generator-py will use the argparse library in order to support external configuration files and won't require users to interact with the python files themselves.

1. Install requirements: `python3 -m pip install -r requirements.txt`
2. Make a configuration JSON file. See the configuration section below for specifications.
3. Add layer files into the `/images` folder.
4. Run the command `python3 generate.py --amount AMOUNT --config CONFIG`

where:
1. `AMOUNT` is the amount of images to generate
2. `CONFIG` is the path pointing to a `.json` file containing valid program configuration.

## How it works
- A call to `generate_unique_images(amount, config)` is made, which is the meat of the application where all the processing happens.
Expand Down
35 changes: 35 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"layers": [
{
"name": "Background",
"values": ["Blue", "Orange", "Purple", "Red", "Yellow"],
"trait_path": "./trait-layers/backgrounds",
"filename": ["blue", "orange", "purple", "red", "yellow"],
"weights": [20,20,20,20,20]
},
{
"name": "Foreground",
"values": ["Python Logo", "Python Logo 32"],
"trait_path": "./trait-layers/foreground",
"filename": ["logo", "logo"],
"weights": [50, 50]
},
{
"name": "Branding",
"values": ["A Name", "Another Name"],
"trait_path": "./trait-layers/text",
"filename": ["text", "text"],
"weights": [50, 50]
}
],
"incompatibilities": [
{
"layer": "Background",
"value": "Blue",
"incompatible_with": ["Python Logo 2"]
}
],
"baseURI": ".",
"name": "NFT #",
"description": "This is a description for this NFT series."
}
57 changes: 22 additions & 35 deletions index.py → generate.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from IPython.display import display
from PIL import Image
import argparse
import random
import json
import os

from lib.util.io import loadJSON, pathExists

os.system('cls' if os.name=='nt' else 'clear')

def create_new_image(all_images, config):
Expand Down Expand Up @@ -100,41 +103,25 @@ def generate_unique_images(amount, config):
with open('./metadata/' + str(item["tokenId"]) + '.json', 'w') as outfile:
json.dump(original_json, outfile, indent=4)

generate_unique_images(11, {
"layers": [
{
"name": "Background",
"values": ["Blue", "Orange", "Purple", "Red", "Yellow"],
"trait_path": "./trait-layers/backgrounds",
"filename": ["blue", "orange", "purple", "red", "yellow"],
"weights": [20,20,20,20,20]
},
{
"name": "Foreground",
"values": ["Python Logo", "Python Logo 32"],
"trait_path": "./trait-layers/foreground",
"filename": ["logo", "logo"],
"weights": [50, 50]
},
{
"name": "Branding",
"values": ["A Name", "Another Name"],
"trait_path": "./trait-layers/text",
"filename": ["text", "text"],
"weights": [50, 50]
}
],
"incompatibilities": [
{
"layer": "Background",
"value": "Blue",
"incompatible_with": ["Python Logo 2"]
}, # @dev : Blue backgrounds will never have the attribute "Python Logo 2".
],
"baseURI": ".",
"name": "NFT #",
"description": "This is a description for this NFT series."
})


#Additional layer objects can be added following the above formats. They will automatically be composed along with the rest of the layers as long as they are the same size as eachother.
#Objects are layered starting from 0 and increasing, meaning the front layer will be the last object. (Branding)


generator = argparse.ArgumentParser(prog='generate', usage='generate.py [options]')

generator.add_argument('-n', '--amount', help="Amount to generate")
generator.add_argument('-c', '--config', help="Path to configuration file")

args = generator.parse_args()

if args.amount and args.config:
if pathExists(args.config):
generate_unique_images(int(args.amount), loadJSON(args.config))
else:
print('heimdall: error: Configuration file specified doesn\'t exist.\n')

else:
print('heimdall: error: Missing a mandatory option (-n or -c). Use -h to show the help menu.\n')
#generate_unique_images(args.amo, )
Empty file added lib/__init__.py
Empty file.
Empty file added lib/util/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions lib/util/io.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import os
import json

def pathExists(dirPath):
return os.path.exists(dirPath)

def loadJSON(path):
with open(path) as pathFile:
contents = json.loads("".join(pathFile.readlines()))
return contents
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ ptyprocess==0.7.0
Pygments==2.11.0
traitlets==5.1.1
wcwidth==0.2.5
argparse==1.4.0

0 comments on commit 14b07d1

Please sign in to comment.