kopia lustrzana https://github.com/torrinworx/Blend_My_NFTs
Adding proper logging functionality
- More general pep8 formatting - Renamed some more variables for pep8 - Modified import comments - Renamed functions - Added bpy.path.abspath() to material, logic, and debug save paths - Beginning to reformat files with new logging/console output systempull/141/head
rodzic
1c26cea5fc
commit
7474847ec6
155
__init__.py
155
__init__.py
|
@ -17,15 +17,17 @@ LAST_UPDATED = "01:02PM, Aug 24th, 2022"
|
||||||
|
|
||||||
# ======== Import handling ======== #
|
# ======== Import handling ======== #
|
||||||
|
|
||||||
|
# Blender modules:
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
from bpy.props import (IntProperty,
|
from bpy.props import (IntProperty, BoolProperty, CollectionProperty)
|
||||||
BoolProperty,
|
|
||||||
CollectionProperty)
|
|
||||||
# Python modules:
|
# Python modules:
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
import tempfile
|
||||||
import importlib
|
import importlib
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
@ -35,7 +37,7 @@ from datetime import datetime, timezone
|
||||||
# "a little hacky bs" - matt159 ;)
|
# "a little hacky bs" - matt159 ;)
|
||||||
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
|
||||||
# Local file imports:
|
# Local modules:
|
||||||
from main import \
|
from main import \
|
||||||
helpers, \
|
helpers, \
|
||||||
dna_generator, \
|
dna_generator, \
|
||||||
|
@ -51,6 +53,7 @@ from UILists import \
|
||||||
custom_metadata_ui_list, \
|
custom_metadata_ui_list, \
|
||||||
logic_ui_list
|
logic_ui_list
|
||||||
|
|
||||||
|
# Refresh Locals for development:
|
||||||
if "bpy" in locals():
|
if "bpy" in locals():
|
||||||
modules = {
|
modules = {
|
||||||
"helpers": helpers,
|
"helpers": helpers,
|
||||||
|
@ -79,7 +82,7 @@ dt = datetime.now(timezone.utc).astimezone() # Date Time in UTC local
|
||||||
|
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def Refresh_UI(dummy1, dummy2):
|
def refresh_ui(dummy1, dummy2):
|
||||||
"""
|
"""
|
||||||
Refreshes the UI upon user interacting with Blender (using depsgraph_update_post handler). Might be a better handler
|
Refreshes the UI upon user interacting with Blender (using depsgraph_update_post handler). Might be a better handler
|
||||||
to use.
|
to use.
|
||||||
|
@ -106,7 +109,7 @@ def Refresh_UI(dummy1, dummy2):
|
||||||
redraw_panel(refresh_panel_classes)
|
redraw_panel(refresh_panel_classes)
|
||||||
|
|
||||||
|
|
||||||
bpy.app.handlers.depsgraph_update_post.append(Refresh_UI)
|
bpy.app.handlers.depsgraph_update_post.append(refresh_ui)
|
||||||
|
|
||||||
|
|
||||||
# ======== Defining BMNFTs Data ======== #
|
# ======== Defining BMNFTs Data ======== #
|
||||||
|
@ -164,6 +167,8 @@ class BMNFTData:
|
||||||
enable_debug: bool
|
enable_debug: bool
|
||||||
log_path: str
|
log_path: str
|
||||||
|
|
||||||
|
enable_dry_run: str
|
||||||
|
|
||||||
custom_fields: dict = None
|
custom_fields: dict = None
|
||||||
fail_state: Any = False
|
fail_state: Any = False
|
||||||
failed_batch: Any = None
|
failed_batch: Any = None
|
||||||
|
@ -174,13 +179,14 @@ class BMNFTData:
|
||||||
self.custom_fields = {}
|
self.custom_fields = {}
|
||||||
|
|
||||||
|
|
||||||
def getBMNFTData():
|
def get_bmnft_data():
|
||||||
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
||||||
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
||||||
|
|
||||||
|
# IMPORTANT: if a new directory variable is ever added, use 'bpy.path.abspath' instead of 'os.path.abspath'.
|
||||||
data = BMNFTData(
|
data = BMNFTData(
|
||||||
nft_name=bpy.context.scene.input_tool.nft_name,
|
nft_name=bpy.context.scene.input_tool.nft_name,
|
||||||
save_path=_save_path,
|
save_path=bpy.path.abspath(_save_path), # Converting from Blender's relative path system to absolute.
|
||||||
nfts_per_batch=bpy.context.scene.input_tool.nfts_per_batch,
|
nfts_per_batch=bpy.context.scene.input_tool.nfts_per_batch,
|
||||||
batch_to_generate=bpy.context.scene.input_tool.batch_to_generate,
|
batch_to_generate=bpy.context.scene.input_tool.batch_to_generate,
|
||||||
collection_size=bpy.context.scene.input_tool.collection_size,
|
collection_size=bpy.context.scene.input_tool.collection_size,
|
||||||
|
@ -193,7 +199,7 @@ def getBMNFTData():
|
||||||
|
|
||||||
enable_logic=bpy.context.scene.input_tool.enable_logic,
|
enable_logic=bpy.context.scene.input_tool.enable_logic,
|
||||||
enable_logic_json=bpy.context.scene.input_tool.enable_logic_json,
|
enable_logic_json=bpy.context.scene.input_tool.enable_logic_json,
|
||||||
logic_file=bpy.context.scene.input_tool.logic_file,
|
logic_file=bpy.path.abspath(bpy.context.scene.input_tool.logic_file),
|
||||||
|
|
||||||
enable_images=bpy.context.scene.input_tool.image_bool,
|
enable_images=bpy.context.scene.input_tool.image_bool,
|
||||||
image_file_format=bpy.context.scene.input_tool.image_enum,
|
image_file_format=bpy.context.scene.input_tool.image_enum,
|
||||||
|
@ -229,7 +235,9 @@ def getBMNFTData():
|
||||||
receiver_to=bpy.context.scene.input_tool.receiver_to,
|
receiver_to=bpy.context.scene.input_tool.receiver_to,
|
||||||
|
|
||||||
enable_debug=bpy.context.scene.input_tool.enable_debug,
|
enable_debug=bpy.context.scene.input_tool.enable_debug,
|
||||||
log_path=bpy.context.scene.input_tool.log_path,
|
log_path=bpy.path.abspath(bpy.context.scene.input_tool.log_path),
|
||||||
|
|
||||||
|
enable_dry_run=bpy.context.scene.input_tool.enable_dry_run
|
||||||
)
|
)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -252,7 +260,7 @@ def make_directories(save_path):
|
||||||
return Blend_My_NFTs_Output, batch_json_save_path, nftBatch_save_path
|
return Blend_My_NFTs_Output, batch_json_save_path, nftBatch_save_path
|
||||||
|
|
||||||
|
|
||||||
def runAsHeadless():
|
def run_as_headless():
|
||||||
"""
|
"""
|
||||||
For use when running from the command line.
|
For use when running from the command line.
|
||||||
"""
|
"""
|
||||||
|
@ -313,26 +321,26 @@ def runAsHeadless():
|
||||||
settings.collection_size = int(pairs[1][1])
|
settings.collection_size = int(pairs[1][1])
|
||||||
settings.nfts_per_batch = int(pairs[2][1])
|
settings.nfts_per_batch = int(pairs[2][1])
|
||||||
settings.save_path = pairs[3][1]
|
settings.save_path = pairs[3][1]
|
||||||
settings.enable_rarity = pairs[4][1]=='True'
|
settings.enable_rarity = pairs[4][1] == 'True'
|
||||||
settings.enable_logic = pairs[5][1]=='True'
|
settings.enable_logic = pairs[5][1] == 'True'
|
||||||
settings.enableLogicJson = pairs[6][1] == 'True'
|
settings.enableLogicJson = pairs[6][1] == 'True'
|
||||||
settings.logic_file = pairs[7][1]
|
settings.logic_file = pairs[7][1]
|
||||||
settings.image_bool = pairs[8][1]=='True'
|
settings.image_bool = pairs[8][1] == 'True'
|
||||||
settings.image_enum = pairs[9][1]
|
settings.image_enum = pairs[9][1]
|
||||||
settings.animation_bool = pairs[10][1]=='True'
|
settings.animation_bool = pairs[10][1] == 'True'
|
||||||
settings.animation_enum = pairs[11][1]
|
settings.animation_enum = pairs[11][1]
|
||||||
settings.model_bool = pairs[12][1]=='True'
|
settings.model_bool = pairs[12][1] == 'True'
|
||||||
settings.model_enum = pairs[13][1]
|
settings.model_enum = pairs[13][1]
|
||||||
settings.batch_to_generate = int(pairs[14][1])
|
settings.batch_to_generate = int(pairs[14][1])
|
||||||
settings.cardano_metadata_bool = pairs[15][1]=='True'
|
settings.cardano_metadata_bool = pairs[15][1] == 'True'
|
||||||
settings.cardano_description = pairs[16][1]
|
settings.cardano_description = pairs[16][1]
|
||||||
settings.erc721_metadata = pairs[17][1]=='True'
|
settings.erc721_metadata = pairs[17][1] == 'True'
|
||||||
settings.erc721_description = pairs[18][1]
|
settings.erc721_description = pairs[18][1]
|
||||||
settings.solana_metadata_bool = pairs[19][1]=='True'
|
settings.solana_metadata_bool = pairs[19][1] == 'True'
|
||||||
settings.solanaDescription = pairs[20][1]
|
settings.solanaDescription = pairs[20][1]
|
||||||
settings.enable_custom_fields = pairs[21][1]=='True'
|
settings.enable_custom_fields = pairs[21][1] == 'True'
|
||||||
settings.custom_fields_file = pairs[22][1]
|
settings.custom_fields_file = pairs[22][1]
|
||||||
settings.enable_materials = pairs[23][1]=='True'
|
settings.enable_materials = pairs[23][1] == 'True'
|
||||||
settings.materials_file = pairs[24][1]
|
settings.materials_file = pairs[24][1]
|
||||||
|
|
||||||
if args.save_path:
|
if args.save_path:
|
||||||
|
@ -341,7 +349,7 @@ def runAsHeadless():
|
||||||
if args.batch_number:
|
if args.batch_number:
|
||||||
settings.batch_to_generate = args.batch_number
|
settings.batch_to_generate = args.batch_number
|
||||||
|
|
||||||
input = getBMNFTData()
|
input = get_bmnft_data()
|
||||||
|
|
||||||
if args.batch_data_path:
|
if args.batch_data_path:
|
||||||
input.batch_json_save_path = args.batch_data_path
|
input.batch_json_save_path = args.batch_data_path
|
||||||
|
@ -356,6 +364,42 @@ def runAsHeadless():
|
||||||
refactorer.reformat_nft_collection(input)
|
refactorer.reformat_nft_collection(input)
|
||||||
|
|
||||||
|
|
||||||
|
def activate_logging():
|
||||||
|
"""
|
||||||
|
Used as an intermediate activated at runtime of the following operators: CreateData, ExportNFTs, ResumeFailedBatch,
|
||||||
|
RefactorBatches, and ExportSettings. Must be independent of 'input' class to be safe, gets variables directly from
|
||||||
|
bpy.
|
||||||
|
"""
|
||||||
|
|
||||||
|
log_path = bpy.context.scene.input_tool.log_path
|
||||||
|
if log_path:
|
||||||
|
file_handler = logging.FileHandler(os.path.join(log_path, 'BMNFTs_Log.txt'), 'a')
|
||||||
|
else:
|
||||||
|
file_handler = logging.FileHandler(os.path.join(tempfile.gettempdir(), 'BMNFTs_Log.txt'), 'a')
|
||||||
|
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
'[%(asctime)s] [%(levelname)s] [%(filename)s > %(funcName)s() > Line:%(lineno)d]\n%(message)s\n'
|
||||||
|
)
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
log = logging.getLogger()
|
||||||
|
for handler in log.handlers[:]:
|
||||||
|
if isinstance(handler, logging.FileHandler):
|
||||||
|
log.removeHandler(handler)
|
||||||
|
if isinstance(handler, logging.StreamHandler):
|
||||||
|
log.removeHandler(handler)
|
||||||
|
log.addHandler(file_handler)
|
||||||
|
|
||||||
|
# Record log to console:
|
||||||
|
console_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
log.addHandler(console_handler)
|
||||||
|
|
||||||
|
if bpy.context.scene.input_tool.enable_debug:
|
||||||
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
# ======== User input Property Group ======== #
|
# ======== User input Property Group ======== #
|
||||||
class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
||||||
# Create NFT Data Panel:
|
# Create NFT Data Panel:
|
||||||
|
@ -498,8 +542,6 @@ class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
||||||
subtype="FILE_PATH"
|
subtype="FILE_PATH"
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Add 'Other' panel inputs to Headless functionality.
|
|
||||||
|
|
||||||
# Other Panel:
|
# Other Panel:
|
||||||
enable_auto_save: bpy.props.BoolProperty(
|
enable_auto_save: bpy.props.BoolProperty(
|
||||||
name="Auto Save Before Generation",
|
name="Auto Save Before Generation",
|
||||||
|
@ -541,8 +583,8 @@ class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
||||||
|
|
||||||
enable_debug: bpy.props.BoolProperty(
|
enable_debug: bpy.props.BoolProperty(
|
||||||
name="Enable Debug Mode",
|
name="Enable Debug Mode",
|
||||||
description="Allows you to run Blend_My_NFTs without generating any content files and includes more "
|
description="Allows you to run Blend_My_NFTs with debugging console messages saved to a BMNFTs_Log.txt "
|
||||||
"console information."
|
"file."
|
||||||
)
|
)
|
||||||
log_path: bpy.props.StringProperty(
|
log_path: bpy.props.StringProperty(
|
||||||
name="Debug Log Path",
|
name="Debug Log Path",
|
||||||
|
@ -552,6 +594,11 @@ class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
||||||
subtype="FILE_PATH"
|
subtype="FILE_PATH"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
enable_dry_run: bpy.props.BoolProperty(
|
||||||
|
name="Enable Dry Run",
|
||||||
|
description="Allows you to run Blend_My_NFTs without generating any content files."
|
||||||
|
)
|
||||||
|
|
||||||
# API Panel properties:
|
# API Panel properties:
|
||||||
api_key: bpy.props.StringProperty(
|
api_key: bpy.props.StringProperty(
|
||||||
name="API Key",
|
name="API Key",
|
||||||
|
@ -560,7 +607,7 @@ class BMNFTS_PGT_Input_Properties(bpy.types.PropertyGroup):
|
||||||
|
|
||||||
|
|
||||||
# ======== Main Operators ======== #
|
# ======== Main Operators ======== #
|
||||||
class Createdata(bpy.types.Operator):
|
class CreateData(bpy.types.Operator):
|
||||||
bl_idname = 'create.data'
|
bl_idname = 'create.data'
|
||||||
bl_label = 'Create Data'
|
bl_label = 'Create Data'
|
||||||
bl_description = 'Creates NFT Data. Run after any changes were made to scene. All previous data will be ' \
|
bl_description = 'Creates NFT Data. Run after any changes were made to scene. All previous data will be ' \
|
||||||
|
@ -572,8 +619,10 @@ class Createdata(bpy.types.Operator):
|
||||||
name="Reverse Order")
|
name="Reverse Order")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
activate_logging()
|
||||||
|
|
||||||
# Handling Custom Fields UIList input:
|
# Handling Custom Fields UIList input:
|
||||||
input = getBMNFTData()
|
input = get_bmnft_data()
|
||||||
|
|
||||||
if input.enable_logic:
|
if input.enable_logic:
|
||||||
if input.enable_logic_json and not input.logic_file:
|
if input.enable_logic_json and not input.logic_file:
|
||||||
|
@ -600,8 +649,9 @@ class ExportNFTs(bpy.types.Operator):
|
||||||
name="Reverse Order")
|
name="Reverse Order")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
input = getBMNFTData()
|
activate_logging()
|
||||||
# Handling Custom Fields UIList input:
|
|
||||||
|
input = get_bmnft_data()
|
||||||
|
|
||||||
intermediate.render_and_save_nfts(input)
|
intermediate.render_and_save_nfts(input)
|
||||||
|
|
||||||
|
@ -617,17 +667,19 @@ class ResumeFailedBatch(bpy.types.Operator):
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
activate_logging()
|
||||||
|
|
||||||
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
_save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
||||||
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
_Blend_My_NFTs_Output, _batch_json_save_path, _nftBatch_save_path = make_directories(_save_path)
|
||||||
|
|
||||||
_batchToGenerate = bpy.context.scene.input_tool.batch_to_generate
|
_batchToGenerate = bpy.context.scene.input_tool.batch_to_generate
|
||||||
|
|
||||||
file_name = os.path.join(_batch_json_save_path, "Batch{}.json".format(_batchToGenerate))
|
file_name = os.path.join(_batch_json_save_path, "Batch{}.json".format(_batchToGenerate))
|
||||||
batchData = json.load(open(file_name))
|
batch_data = json.load(open(file_name))
|
||||||
|
|
||||||
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = helpers.check_failed_batches(_batch_json_save_path)
|
_fail_state, _failed_batch, _failed_dna, _failed_dna_index = helpers.check_failed_batches(_batch_json_save_path)
|
||||||
|
|
||||||
render_settings = batchData["Generation Save"][-1]["Render_Settings"]
|
render_settings = batch_data["Generation Save"][-1]["Render_Settings"]
|
||||||
|
|
||||||
input = BMNFTData(
|
input = BMNFTData(
|
||||||
nft_name=render_settings["nft_name"],
|
nft_name=render_settings["nft_name"],
|
||||||
|
@ -682,6 +734,8 @@ class ResumeFailedBatch(bpy.types.Operator):
|
||||||
enable_debug=render_settings["enable_debug"],
|
enable_debug=render_settings["enable_debug"],
|
||||||
log_path=render_settings["log_path"],
|
log_path=render_settings["log_path"],
|
||||||
|
|
||||||
|
enable_dry_run=render_settings["enable_dry_run"],
|
||||||
|
|
||||||
fail_state=_fail_state,
|
fail_state=_fail_state,
|
||||||
failed_batch=_failed_batch,
|
failed_batch=_failed_batch,
|
||||||
failed_dna=_failed_dna,
|
failed_dna=_failed_dna,
|
||||||
|
@ -709,8 +763,9 @@ class RefactorBatches(bpy.types.Operator):
|
||||||
name="Reverse Order")
|
name="Reverse Order")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
# Passing info to main functions for refactoring:
|
activate_logging()
|
||||||
refactorer.reformat_nft_collection(getBMNFTData())
|
|
||||||
|
refactorer.reformat_nft_collection(get_bmnft_data())
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
@ -725,6 +780,8 @@ class ExportSettings(bpy.types.Operator):
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
activate_logging()
|
||||||
|
|
||||||
save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
save_path = bpy.path.abspath(bpy.context.scene.input_tool.save_path)
|
||||||
filename = "config.cfg"
|
filename = "config.cfg"
|
||||||
|
|
||||||
|
@ -1082,8 +1139,10 @@ class BMNFTS_PT_Other(bpy.types.Panel):
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(input_tool_scene, "enable_debug")
|
row.prop(input_tool_scene, "enable_debug")
|
||||||
if bpy.context.scene.input_tool.enable_debug:
|
if bpy.context.scene.input_tool.enable_debug:
|
||||||
|
row = layout.row()
|
||||||
row.prop(input_tool_scene, "log_path")
|
row.prop(input_tool_scene, "log_path")
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(input_tool_scene, "enable_dry_run")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
@ -1111,20 +1170,20 @@ class BMNFTS_PT_Other(bpy.types.Panel):
|
||||||
# ======== Blender add-on register/unregister handling ======== #
|
# ======== Blender add-on register/unregister handling ======== #
|
||||||
classes = (
|
classes = (
|
||||||
# Property Group Classes:
|
# Property Group Classes:
|
||||||
BMNFTS_PGT_Input_Properties,
|
BMNFTS_PGT_Input_Properties,
|
||||||
|
|
||||||
# Operator Classes:
|
# Operator Classes:
|
||||||
Createdata,
|
CreateData,
|
||||||
ExportNFTs,
|
ExportNFTs,
|
||||||
ResumeFailedBatch,
|
ResumeFailedBatch,
|
||||||
RefactorBatches,
|
RefactorBatches,
|
||||||
ExportSettings,
|
ExportSettings,
|
||||||
|
|
||||||
# Panel Classes:
|
# Panel Classes:
|
||||||
BMNFTS_PT_CreateData,
|
BMNFTS_PT_CreateData,
|
||||||
BMNFTS_PT_GenerateNFTs,
|
BMNFTS_PT_GenerateNFTs,
|
||||||
BMNFTS_PT_Refactor,
|
BMNFTS_PT_Refactor,
|
||||||
BMNFTS_PT_Other,
|
BMNFTS_PT_Other,
|
||||||
) + custom_metadata_ui_list.classes_Custom_Metadata_UIList + logic_ui_list.classes_Logic_UIList
|
) + custom_metadata_ui_list.classes_Custom_Metadata_UIList + logic_ui_list.classes_Logic_UIList
|
||||||
|
|
||||||
|
|
||||||
|
@ -1157,4 +1216,4 @@ def unregister():
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
register()
|
register()
|
||||||
runAsHeadless()
|
run_as_headless()
|
||||||
|
|
|
@ -12,11 +12,7 @@ from functools import partial
|
||||||
from . import logic, material_generator, helpers
|
from . import logic, material_generator, helpers
|
||||||
from .helpers import TextColors
|
from .helpers import TextColors
|
||||||
|
|
||||||
logging.basicConfig(
|
log = logging.getLogger(__name__)
|
||||||
level=logging.INFO,
|
|
||||||
format='[%(levelname)s][%(asctime)s]\n%(message)s\n',
|
|
||||||
datefmt='%Y-%m-%d %H:%M:%S'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_nft_dna(
|
def generate_nft_dna(
|
||||||
|
@ -110,25 +106,33 @@ def generate_nft_dna(
|
||||||
single_dna = ""
|
single_dna = ""
|
||||||
if not enable_rarity:
|
if not enable_rarity:
|
||||||
single_dna = create_dna_random(hierarchy)
|
single_dna = create_dna_random(hierarchy)
|
||||||
logging.debug(f"============\nOriginal DNA: {single_dna}")
|
log.debug(
|
||||||
print("============")
|
f"\n================"
|
||||||
print(f"Original DNA: {single_dna}")
|
f"\nOriginal DNA: {single_dna}"
|
||||||
|
)
|
||||||
|
|
||||||
if enable_rarity:
|
if enable_rarity:
|
||||||
single_dna = create_dna_rarity(hierarchy)
|
single_dna = create_dna_rarity(hierarchy)
|
||||||
logging.debug(f"Rarity DNA: {single_dna}")
|
log.debug(
|
||||||
print(f"Rarity DNA: {single_dna}")
|
f"\n================"
|
||||||
|
f"\nRarity DNA: {single_dna}"
|
||||||
|
)
|
||||||
|
|
||||||
if enable_logic:
|
if enable_logic:
|
||||||
single_dna = logic.logicafy_dna_single(hierarchy, single_dna, logic_file, enable_rarity)
|
single_dna = logic.logicafy_dna_single(hierarchy, single_dna, logic_file, enable_rarity)
|
||||||
logging.debug(f"Logic DNA: {single_dna}")
|
log.debug(
|
||||||
print(f"Logic DNA: {single_dna}")
|
f"\n================"
|
||||||
|
f"\nLogic DNA: {single_dna}"
|
||||||
|
)
|
||||||
|
|
||||||
if enable_materials:
|
if enable_materials:
|
||||||
single_dna = material_generator.apply_materials(hierarchy, single_dna, materials_file, enable_rarity)
|
single_dna = material_generator.apply_materials(hierarchy, single_dna, materials_file, enable_rarity)
|
||||||
logging.debug(f"Materials DNA: {single_dna}\n============\n")
|
log.debug(
|
||||||
print(f"Materials DNA: {single_dna}")
|
f"\n================"
|
||||||
print("============\n")
|
f"\nMaterials DNA: {single_dna}"
|
||||||
|
f"\n================\n"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
return single_dna
|
return single_dna
|
||||||
|
|
||||||
|
@ -179,9 +183,9 @@ def make_batches(
|
||||||
batch_json_save_path
|
batch_json_save_path
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Sorts through all the batches and outputs a given number of batches depending on collection_size and nfts_per_batch.
|
Sorts through all the batches and outputs a given number of batches depending on collection_size and nfts_per_batch.
|
||||||
These files are then saved as Batch#.json files to batch_json_save_path
|
These files are then saved as Batch#.json files to batch_json_save_path
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Clears the Batch Data folder of Batches:
|
# Clears the Batch Data folder of Batches:
|
||||||
batch_list = os.listdir(batch_json_save_path)
|
batch_list = os.listdir(batch_json_save_path)
|
||||||
|
@ -197,7 +201,6 @@ def make_batches(
|
||||||
nft_record_save_path = os.path.join(blend_my_nf_ts_output, "NFTRecord.json")
|
nft_record_save_path = os.path.join(blend_my_nf_ts_output, "NFTRecord.json")
|
||||||
data_dictionary = json.load(open(nft_record_save_path))
|
data_dictionary = json.load(open(nft_record_save_path))
|
||||||
|
|
||||||
num_nfts_generated = data_dictionary["num_nfts_generated"]
|
|
||||||
hierarchy = data_dictionary["hierarchy"]
|
hierarchy = data_dictionary["hierarchy"]
|
||||||
dna_list = data_dictionary["dna_list"]
|
dna_list = data_dictionary["dna_list"]
|
||||||
|
|
||||||
|
@ -206,8 +209,10 @@ def make_batches(
|
||||||
if remainder_dna > 0:
|
if remainder_dna > 0:
|
||||||
num_batches += 1
|
num_batches += 1
|
||||||
|
|
||||||
print(f"To generate batches of {nfts_per_batch} DNA sequences per batch, with a total of {num_nfts_generated}"
|
log.info(
|
||||||
f" possible NFT DNA sequences, the number of batches generated will be {num_batches}")
|
f"\nGenerating {num_batches} batch files. If the last batch isn't filled all the way the program will "
|
||||||
|
f"operate normally."
|
||||||
|
)
|
||||||
|
|
||||||
batches_dna_list = []
|
batches_dna_list = []
|
||||||
|
|
||||||
|
@ -253,38 +258,37 @@ def send_to_record(
|
||||||
repeat DNA.
|
repeat DNA.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if enable_debug:
|
|
||||||
logging.basicConfig(
|
|
||||||
filename=os.path.join(log_path, "BMNFTS_Log.txt"),
|
|
||||||
level=logging.DEBUG
|
|
||||||
)
|
|
||||||
|
|
||||||
# Checking Scene is compatible with BMNFTs:
|
# Checking Scene is compatible with BMNFTs:
|
||||||
helpers.check_scene()
|
helpers.check_scene()
|
||||||
|
|
||||||
# Messages:
|
# Messages:
|
||||||
print(
|
log.info(
|
||||||
f"\n{TextColors.OK}======== Creating NFT Data ========{TextColors.RESET}"
|
f"\n{TextColors.OK}======== Creating NFT Data ({collection_size} DNA) ========{TextColors.RESET}"
|
||||||
f"\nGenerating {collection_size} NFT DNA"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if not enable_rarity and not enable_logic:
|
if not enable_rarity and not enable_logic:
|
||||||
print(
|
log.info(
|
||||||
f"{TextColors.OK}NFT DNA will be determined randomly, no special properties or parameters are "
|
f"\n - NFT DNA will be determined randomly, no special properties or parameters are "
|
||||||
f"applied.\n{TextColors.RESET}")
|
f"applied."
|
||||||
|
)
|
||||||
|
|
||||||
if enable_rarity:
|
if enable_rarity:
|
||||||
print(
|
log.info(
|
||||||
f"{TextColors.OK}Rarity is ON. Weights listed in .blend scene will be taken into account."
|
f"\n - Rarity is ON. Weights listed in .blend scene will be taken into account."
|
||||||
f"{TextColors.RESET}"
|
f""
|
||||||
)
|
)
|
||||||
|
|
||||||
if enable_logic:
|
if enable_logic:
|
||||||
print(
|
log.info(
|
||||||
f"{TextColors.OK}Logic is ON. {len(list(logic_file.keys()))} rules detected and applied."
|
f"\n - Logic is ON. {len(list(logic_file.keys()))} rules detected, implementation will "
|
||||||
f"{TextColors.RESET}"
|
f"be attempted."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if enable_materials:
|
||||||
|
log.info(
|
||||||
|
f"\n - Materials are ON. {len(list(json.load(open(materials_file)).keys()))} materials "
|
||||||
|
f"instances detected, implementation will be attempted."
|
||||||
|
)
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
|
|
||||||
def create_nft_data():
|
def create_nft_data():
|
||||||
|
@ -339,7 +343,7 @@ def send_to_record(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Loading Animation:
|
# Loading Animation:
|
||||||
loading = helpers.Loader(f'Creating NFT DNA...', '').start()
|
loading = helpers.Loader(f'\nCreating NFT DNA...', '').start()
|
||||||
create_nft_data()
|
create_nft_data()
|
||||||
make_batches(collection_size, nfts_per_batch, save_path, batch_json_save_path)
|
make_batches(collection_size, nfts_per_batch, save_path, batch_json_save_path)
|
||||||
loading.stop()
|
loading.stop()
|
||||||
|
@ -347,5 +351,5 @@ def send_to_record(
|
||||||
time_end = time.time()
|
time_end = time.time()
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"{TextColors.OK}Created and saved NFT DNA in {time_end - time_start}s.\n{TextColors.RESET}"
|
f"\n{TextColors.OK}Created and saved NFT DNA in {time_end - time_start}s.\n{TextColors.RESET}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -98,6 +98,8 @@ def save_generation_state(input):
|
||||||
"enable_debug": input.enable_debug,
|
"enable_debug": input.enable_debug,
|
||||||
"log_path": input.log_path,
|
"log_path": input.log_path,
|
||||||
|
|
||||||
|
"enable_dry_run": input.enable_dry_run,
|
||||||
|
|
||||||
"custom_fields": input.custom_fields,
|
"custom_fields": input.custom_fields,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -36,6 +36,8 @@ def remove_file_by_extension(dirlist):
|
||||||
return return_dirs
|
return return_dirs
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: fix colours in console logs and find a way to include coloured text in .txt file.
|
||||||
|
|
||||||
class TextColors:
|
class TextColors:
|
||||||
"""
|
"""
|
||||||
The colour of console messages.
|
The colour of console messages.
|
||||||
|
|
Ładowanie…
Reference in New Issue