Browse Source

Convert os.path usage to pathlib. ++code_quality

This closes #26
pull/31/head
Adam Johnson 9 years ago
parent
commit
55566c908a
  1. 1
      korman/exporter/__init__.py
  2. 6
      korman/exporter/convert.py
  3. 9
      korman/exporter/logger.py
  4. 25
      korman/exporter/manager.py
  5. 13
      korman/exporter/material.py
  6. 27
      korman/exporter/sumfile.py
  7. 6
      korman/nodes/node_python.py
  8. 15
      korman/operators/op_export.py
  9. 9
      korman/plasma_attributes.py

1
korman/exporter/__init__.py

@ -14,7 +14,6 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import os.path
from PyHSPlasma import * from PyHSPlasma import *
from .convert import * from .convert import *

6
korman/exporter/convert.py

@ -14,7 +14,7 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import os.path from pathlib import Path
from PyHSPlasma import * from PyHSPlasma import *
import time import time
@ -38,7 +38,7 @@ class Exporter:
@property @property
def age_name(self): def age_name(self):
return os.path.splitext(os.path.split(self._op.filepath)[1])[0] return Path(self._op.filepath).stem
def run(self): def run(self):
with logger.ExportLogger(self._op.filepath) as _log: with logger.ExportLogger(self._op.filepath) as _log:
@ -80,7 +80,7 @@ class Exporter:
self.mesh.finalize() self.mesh.finalize()
# Step 5: FINALLY. Let's write the PRPs and crap. # Step 5: FINALLY. Let's write the PRPs and crap.
self.mgr.save_age(self._op.filepath) self.mgr.save_age(Path(self._op.filepath))
# Step 5.1: Save out the export report. # Step 5.1: Save out the export report.
# If the export fails and this doesn't save, we have bigger problems than # If the export fails and this doesn't save, we have bigger problems than

9
korman/exporter/logger.py

@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import os.path from pathlib import Path
import sys import sys
class ExportAnalysis: class ExportAnalysis:
@ -46,10 +46,9 @@ class ExportLogger:
def __init__(self, ageFile): def __init__(self, ageFile):
# Make the log file name from the age file path -- this ensures we're not trying to write # Make the log file name from the age file path -- this ensures we're not trying to write
# the log file to the same directory Blender.exe is in, which might be a permission error # the log file to the same directory Blender.exe is in, which might be a permission error
path, ageFile = os.path.split(ageFile) my_path = Path(ageFile)
ageName, _crap = os.path.splitext(ageFile) my_path = my_path.with_name("{}_export".format(my_path.stem)).with_suffix(".log")
fn = os.path.join(path, "{}_export.log".format(ageName)) self._file = open(str(my_path), "w")
self._file = open(fn, "w")
for i in dir(self._file): for i in dir(self._file):
if not hasattr(self, i): if not hasattr(self, i):

25
korman/exporter/manager.py

@ -14,7 +14,7 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import os.path from pathlib import Path
from PyHSPlasma import * from PyHSPlasma import *
import weakref import weakref
@ -221,27 +221,26 @@ class ExportManager:
return key.location return key.location
def save_age(self, path): def save_age(self, path):
relpath, ageFile = os.path.split(path) ageName = path.stem
ageName = os.path.splitext(ageFile)[0]
sumfile = self._exporter().sumfile sumfile = self._exporter().sumfile
sumfile.append(path) sumfile.append(path)
self.mgr.WriteAge(path, self._age_info) self.mgr.WriteAge(str(path), self._age_info)
self._write_fni(relpath, ageName) self._write_fni(path)
self._write_pages(relpath, ageName) self._write_pages(path)
if self.getVer() != pvMoul: if self.getVer() != pvMoul:
sumpath = os.path.join(relpath, "{}.sum".format(ageName)) sumpath = path.with_suffix(".sum")
sumfile.write(sumpath, self.getVer()) sumfile.write(sumpath, self.getVer())
def _write_fni(self, path, ageName): def _write_fni(self, path):
if self.mgr.getVer() <= pvMoul: if self.mgr.getVer() <= pvMoul:
enc = plEncryptedStream.kEncXtea enc = plEncryptedStream.kEncXtea
else: else:
enc = plEncryptedStream.kEncAES enc = plEncryptedStream.kEncAES
fname = os.path.join(path, "{}.fni".format(ageName)) fname = path.with_suffix(".fni")
with plEncryptedStream(self.mgr.getVer()).open(fname, fmWrite, enc) as stream: with plEncryptedStream(self.mgr.getVer()).open(str(fname), fmWrite, enc) as stream:
fni = bpy.context.scene.world.plasma_fni fni = bpy.context.scene.world.plasma_fni
stream.writeLine("Graphics.Renderer.SetClearColor {} {} {}".format(*fni.clear_color)) stream.writeLine("Graphics.Renderer.SetClearColor {} {} {}".format(*fni.clear_color))
if fni.fog_method != "none": if fni.fog_method != "none":
@ -253,7 +252,7 @@ class ExportManager:
stream.writeLine("Graphics.Renderer.SetYon {}".format(fni.yon)) stream.writeLine("Graphics.Renderer.SetYon {}".format(fni.yon))
self._exporter().sumfile.append(fname) self._exporter().sumfile.append(fname)
def _write_pages(self, path, ageName): def _write_pages(self, path):
for loc in self._pages.values(): for loc in self._pages.values():
page = self.mgr.FindPage(loc) # not cached because it's C++ owned page = self.mgr.FindPage(loc) # not cached because it's C++ owned
# I know that plAgeInfo has its own way of doing this, but we'd have # I know that plAgeInfo has its own way of doing this, but we'd have
@ -262,6 +261,6 @@ class ExportManager:
chapter = "_District_" chapter = "_District_"
else: else:
chapter = "_" chapter = "_"
f = os.path.join(path, "{}{}{}.prp".format(ageName, chapter, page.page)) f = path.with_name("{}{}{}".format(path.stem, chapter, page.page)).with_suffix(".prp")
self.mgr.WritePage(f, page) self.mgr.WritePage(str(f), page)
self._exporter().sumfile.append(f) self._exporter().sumfile.append(f)

13
korman/exporter/material.py

@ -15,7 +15,7 @@
import bpy import bpy
import math import math
import os.path from pathlib import Path
from PyHSPlasma import * from PyHSPlasma import *
import weakref import weakref
@ -61,20 +61,13 @@ class _Texture:
def __str__(self): def __str__(self):
if self.mipmap: if self.mipmap:
name = self._change_extension(self.image.name, ".dds") name = str(Path(self.image.name).with_suffix(".dds"))
else: else:
name = self._change_extension(self.image.name, ".bmp") name = str(Path(self.image.name).with_suffix(".bmp"))
if self.calc_alpha: if self.calc_alpha:
name = "ALPHAGEN_{}".format(name) name = "ALPHAGEN_{}".format(name)
return name return name
def _change_extension(self, name, newext):
# Blender likes to add faux extensions such as .001 :(
if name.find(".") == -1:
return "{}{}".format(name, newext)
name, end = os.path.splitext(name)
return "{}{}".format(name, newext)
def _update(self, other): def _update(self, other):
"""Update myself with any props that might be overridable from another copy of myself""" """Update myself with any props that might be overridable from another copy of myself"""
if other.use_alpha: if other.use_alpha:

27
korman/exporter/sumfile.py

@ -14,11 +14,11 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import hashlib import hashlib
import os.path from pathlib import Path
from PyHSPlasma import * from PyHSPlasma import *
def _hashfile(filename, hasher, block=0xFFFF): def _hashfile(filename, hasher, block=0xFFFF):
with open(filename, "rb") as handle: with open(str(filename), "rb") as handle:
h = hasher() h = hasher()
data = handle.read(block) data = handle.read(block)
while data: while data:
@ -36,26 +36,25 @@ class SumFile:
def _collect_files(self, version): def _collect_files(self, version):
files = [] files = []
for file in self._files: for file in self._files:
filename = os.path.split(file)[1] filename, extension = file.name, file.suffix.lower()
extension = os.path.splitext(filename)[1].lower()
if extension in {".age", ".csv", ".fni", ".loc", ".node", ".p2f", ".pfp", ".sub"}: if extension in {".age", ".csv", ".fni", ".loc", ".node", ".p2f", ".pfp", ".sub"}:
filename = os.path.join("dat", filename) filename = Path("dat") / filename
elif extension == ".prp" and version > pvPrime: elif extension == ".prp" and version > pvPrime:
# ABM and UU don't want the directory for PRPs... Bug? # ABM and UU don't want the directory for PRPs... Bug?
filename = os.path.join("dat", filename) filename = Path("dat") / filename
elif extension in {".pak", ".py"}: elif extension in {".pak", ".py"}:
filename = os.path.join("Python", filename) filename = Path("Python") / filename
elif extension in {".avi", ".bik", ".oggv", ".webm"}: elif extension in {".avi", ".bik", ".oggv", ".webm"}:
filename = os.path.join("avi", filename) filename = Path("avi") / filename
elif extension in {".ogg", ".opus", ".wav"}: elif extension in {".ogg", ".opus", ".wav"}:
filename = os.path.join("sfx", filename) filename = Path("sfx") / filename
elif extension == ".sdl": elif extension == ".sdl":
filename = os.path.join("SDL", filename) filename = Path("SDL") / filename
# else the filename has no directory prefix... oh well # else the filename has no directory prefix... oh well
md5 = _hashfile(file, hashlib.md5) md5 = _hashfile(file, hashlib.md5)
timestamp = os.path.getmtime(file) timestamp = file.stat().st_mtime
files.append((filename, md5, int(timestamp))) files.append((str(filename), md5, int(timestamp)))
return files return files
@ -64,11 +63,11 @@ class SumFile:
files = self._collect_files(version) files = self._collect_files(version)
enc = plEncryptedStream.kEncAes if version >= pvEoa else plEncryptedStream.kEncXtea enc = plEncryptedStream.kEncAes if version >= pvEoa else plEncryptedStream.kEncXtea
with plEncryptedStream(version).open(sumpath, fmWrite, enc) as stream: with plEncryptedStream(version).open(str(sumpath), fmWrite, enc) as stream:
stream.writeInt(len(files)) stream.writeInt(len(files))
stream.writeInt(0) stream.writeInt(0)
for file in files: for file in files:
stream.writeSafeStr(file[0]) stream.writeSafeStr(str(file[0]))
stream.write(file[1]) stream.write(file[1])
stream.writeInt(file[2]) stream.writeInt(file[2])
stream.writeInt(0) stream.writeInt(0)

6
korman/nodes/node_python.py

@ -15,7 +15,7 @@
import bpy import bpy
from bpy.props import * from bpy.props import *
import os.path from pathlib import Path
from PyHSPlasma import * from PyHSPlasma import *
from .node_core import * from .node_core import *
@ -149,7 +149,7 @@ class PlasmaPythonFileNode(PlasmaNodeBase, bpy.types.Node):
row = layout.row(align=True) row = layout.row(align=True)
if self.filename: if self.filename:
row.prop(self, "filename") row.prop(self, "filename")
if os.path.isfile(self.filepath): if Path(self.filepath).exists():
operator = row.operator("node.plasma_attributes_to_node", icon="FILE_REFRESH", text="") operator = row.operator("node.plasma_attributes_to_node", icon="FILE_REFRESH", text="")
operator.python_path = self.filepath operator.python_path = self.filepath
operator.node_path = self.node_path operator.node_path = self.node_path
@ -166,7 +166,7 @@ class PlasmaPythonFileNode(PlasmaNodeBase, bpy.types.Node):
def export(self, exporter, bo, so): def export(self, exporter, bo, so):
pfm = self.get_key(exporter, so).object pfm = self.get_key(exporter, so).object
pfm.filename = os.path.splitext(self.filename)[0] pfm.filename = Path(self.filename).stem
attrib_sockets = (i for i in self.inputs if i.is_linked) attrib_sockets = (i for i in self.inputs if i.is_linked)
for socket in attrib_sockets: for socket in attrib_sockets:
attrib = socket.attribute_type attrib = socket.attribute_type

15
korman/operators/op_export.py

@ -16,7 +16,7 @@
import bpy import bpy
from bpy.props import * from bpy.props import *
import cProfile import cProfile
import os, os.path from pathlib import Path
import pstats import pstats
from .. import exporter from .. import exporter
@ -80,15 +80,15 @@ class ExportOperator(bpy.types.Operator):
def execute(self, context): def execute(self, context):
# Before we begin, do some basic sanity checking... # Before we begin, do some basic sanity checking...
path = Path(self.filepath)
if not self.filepath: if not self.filepath:
self.error = "No file specified" self.error = "No file specified"
return {"CANCELLED"} return {"CANCELLED"}
else: else:
dir = os.path.split(self.filepath)[0] if not path.exists:
if not os.path.exists(dir):
try: try:
os.mkdirs(dir) path.mkdir(parents=True)
except os.error: except:
self.report({"ERROR"}, "Failed to create export directory") self.report({"ERROR"}, "Failed to create export directory")
return {"CANCELLED"} return {"CANCELLED"}
@ -97,11 +97,12 @@ class ExportOperator(bpy.types.Operator):
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
# Separate blender operator and actual export logic for my sanity # Separate blender operator and actual export logic for my sanity
ageName = path.stem
with _UiHelper() as _ui: with _UiHelper() as _ui:
e = exporter.Exporter(self) e = exporter.Exporter(self)
try: try:
if self.profile_export: if self.profile_export:
profile = "{}_cProfile".format(os.path.splitext(self.filepath)[0]) profile = "{}_cProfile".format(ageName)
cProfile.runctx("e.run()", globals(), locals(), profile) cProfile.runctx("e.run()", globals(), locals(), profile)
else: else:
e.run() e.run()
@ -110,7 +111,7 @@ class ExportOperator(bpy.types.Operator):
return {"CANCELLED"} return {"CANCELLED"}
else: else:
if self.profile_export: if self.profile_export:
stats_out = "{}_profile.log".format(os.path.splitext(self.filepath)[0]) stats_out = "{}_profile.log".format(ageName)
with open(stats_out, "w") as out: with open(stats_out, "w") as out:
stats = pstats.Stats(profile, stream=out) stats = pstats.Stats(profile, stream=out)
stats = stats.sort_stats("time", "calls") stats = stats.sort_stats("time", "calls")

9
korman/plasma_attributes.py

@ -93,7 +93,7 @@ def get_attributes(scriptFile):
"""Scan the file for assignments matching our regex, let our visitor parse them, and return the """Scan the file for assignments matching our regex, let our visitor parse them, and return the
file's ptAttribs, if any.""" file's ptAttribs, if any."""
attribs = None attribs = None
with open(scriptFile) as script: with open(str(scriptFile)) as script:
results = funcregex.findall(script.read()) results = funcregex.findall(script.read())
if results: if results:
# We'll fake the ptAttribs being all alone in a module... # We'll fake the ptAttribs being all alone in a module...
@ -105,21 +105,20 @@ def get_attributes(scriptFile):
return attribs return attribs
if __name__ == "__main__": if __name__ == "__main__":
import glob
import json import json
import os from pathlib import Path
import sys import sys
if len(sys.argv) != 2: if len(sys.argv) != 2:
print("Specify a path containing Plasma Python!") print("Specify a path containing Plasma Python!")
else: else:
readpath = sys.argv[1] readpath = sys.argv[1]
files = glob.glob(os.path.join(readpath, "*.py")) files = Path(readpath).glob("*.py")
ptAttribs = {} ptAttribs = {}
for scriptFile in files: for scriptFile in files:
attribs = get_attributes(scriptFile) attribs = get_attributes(scriptFile)
if attribs: if attribs:
ptAttribs[os.path.basename(scriptFile)] = attribs ptAttribs[scriptFile.stem] = attribs
jsonout = open("attribs.json", "w") jsonout = open("attribs.json", "w")
jsonout.write(json.dumps(ptAttribs, sort_keys=True, indent=2)) jsonout.write(json.dumps(ptAttribs, sort_keys=True, indent=2))

Loading…
Cancel
Save