Compare commits
7 commits
218928f033
...
ebdac7c89d
Author | SHA1 | Date | |
---|---|---|---|
ebdac7c89d | |||
2076e7341d | |||
84b8c1b626 | |||
66fd1bfe11 | |||
dace0de99b | |||
69ce445225 | |||
80070e3a5e |
7 changed files with 174 additions and 126 deletions
54
dcc/ls.py
54
dcc/ls.py
|
@ -1,27 +1,39 @@
|
||||||
import dcc.config
|
import dcc.config
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class List(dcc.config.Base):
|
class List(dcc.config.Base):
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super().get_parser(prog_name)
|
parser = super().get_parser(prog_name)
|
||||||
parser.add_argument("target")
|
parser.add_argument("target")
|
||||||
parser.add_argument("--wad")
|
parser.add_argument("--wad")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
match parsed_args.target:
|
match parsed_args.target:
|
||||||
case "pwads":
|
case "pwads":
|
||||||
self.list(x.name for x in os.scandir(self.pwads) if x.is_dir())
|
self.list(x.name for x in os.scandir(self.pwads) if x.is_dir())
|
||||||
case "iwads":
|
case "iwads":
|
||||||
self.list(x.name for x in os.scandir(self.iwads) if x.is_file())
|
self.list(
|
||||||
case "demos":
|
x.name for x in os.scandir(self.iwads)
|
||||||
self.list(x.name for x in os.scandir(self.demos.joinpath(parsed_args.wad)) if x.name.endswith(".lmp"))
|
if x.is_file()
|
||||||
case "videos":
|
)
|
||||||
self.list(x.name for x in os.scandir(self.fabricate.joinpath(parsed_args.wad)) if x.name.endswith(".mp4"))
|
case "demos":
|
||||||
case _:
|
self.list(
|
||||||
raise Exception(f"unknown target {parsed_args.target}")
|
x.name for x in
|
||||||
|
os.scandir(self.demos.joinpath(parsed_args.wad))
|
||||||
|
if x.name.endswith(".lmp")
|
||||||
|
)
|
||||||
|
case "videos":
|
||||||
|
self.list(
|
||||||
|
x.name for x in
|
||||||
|
os.scandir(self.fabricate.joinpath(parsed_args.wad))
|
||||||
|
if x.name.endswith(".mp4")
|
||||||
|
)
|
||||||
|
case _:
|
||||||
|
raise Exception(f"unknown target {parsed_args.target}")
|
||||||
|
|
||||||
def list(self, gen):
|
def list(self, gen):
|
||||||
# TODO: fancy text?
|
# TODO: fancy text?
|
||||||
for i in sorted(gen):
|
for i in sorted(gen):
|
||||||
print(i)
|
print(i)
|
||||||
|
|
35
dcc/main.py
35
dcc/main.py
|
@ -3,27 +3,30 @@ import sys
|
||||||
from cliff.app import App
|
from cliff.app import App
|
||||||
from cliff.commandmanager import CommandManager
|
from cliff.commandmanager import CommandManager
|
||||||
|
|
||||||
|
|
||||||
class DCC(App):
|
class DCC(App):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
description="Doom Command Center",
|
description="Doom Command Center",
|
||||||
version="0.0.1",
|
version="0.0.1",
|
||||||
command_manager=CommandManager("dcc"),
|
command_manager=CommandManager("dcc"),
|
||||||
deferred_help=True,
|
deferred_help=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize_app(self, argv):
|
def initialize_app(self, argv):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def prepare_to_run_command(self, cmd):
|
def prepare_to_run_command(self, cmd):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def clean_up(self, cmd, result, err):
|
||||||
|
pass
|
||||||
|
|
||||||
def clean_up(self, cmd, result, err):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def main(argv=sys.argv[1:]):
|
def main(argv=sys.argv[1:]):
|
||||||
dcc = DCC()
|
dcc = DCC()
|
||||||
return dcc.run(argv)
|
return dcc.run(argv)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
|
@ -2,6 +2,7 @@ import dcc.config
|
||||||
import dcc.doom_base
|
import dcc.doom_base
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
class PB(dcc.doom_base.WadMap):
|
class PB(dcc.doom_base.WadMap):
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
subprocess.run(["ffplay", self.video_path()])
|
subprocess.run(["ffplay", self.video_path()])
|
||||||
|
|
30
dcc/put.py
30
dcc/put.py
|
@ -2,16 +2,22 @@ import boto3
|
||||||
import dcc.config
|
import dcc.config
|
||||||
import dcc.doom_base
|
import dcc.doom_base
|
||||||
|
|
||||||
class Put(dcc.doom_base.WadMap):
|
|
||||||
def get_parser(self, prog_name):
|
|
||||||
parser = super().get_parser(prog_name)
|
|
||||||
return parser
|
|
||||||
|
|
||||||
# TODO: accept configuration for bucket name
|
class Put(dcc.doom_base.WadMap):
|
||||||
def take_action(self, parsed_args):
|
def get_parser(self, prog_name):
|
||||||
s3_client = boto3.client('s3')
|
parser = super().get_parser(prog_name)
|
||||||
demo = self.demo_in_path()
|
return parser
|
||||||
bucket = self.target_bucket()
|
|
||||||
print("Uploading {} to bucket {}.".format(demo, bucket))
|
# TODO: accept configuration for bucket name
|
||||||
s3_client.upload_file(demo, 'yrriban', bucket,
|
def take_action(self, parsed_args):
|
||||||
ExtraArgs={'ContentType': 'binary/octet-stream', 'ACL': 'public-read'})
|
s3_client = boto3.client('s3')
|
||||||
|
demo = self.demo_in_path()
|
||||||
|
bucket = self.target_bucket()
|
||||||
|
print("Uploading {} to bucket {}.".format(demo, bucket))
|
||||||
|
s3_client.upload_file(
|
||||||
|
demo, 'yrriban', bucket,
|
||||||
|
ExtraArgs={
|
||||||
|
'ContentType': 'binary/octet-stream',
|
||||||
|
'ACL': 'public-read'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
68
dcc/ss.py
68
dcc/ss.py
|
@ -5,32 +5,48 @@ import sys
|
||||||
import wand.display
|
import wand.display
|
||||||
import wand.image
|
import wand.image
|
||||||
|
|
||||||
|
|
||||||
class SS(dcc.doom_base.WadMap):
|
class SS(dcc.doom_base.WadMap):
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super().get_parser(prog_name)
|
parser = super().get_parser(prog_name)
|
||||||
parser.add_argument("-g", "--gravity", default="center")
|
parser.add_argument("-g", "--gravity", default="center")
|
||||||
parser.add_argument("-y", "--yolo", action="store_true")
|
parser.add_argument("-y", "--yolo", action="store_true")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
def try_screenshot():
|
while not self._try_screenshot(parsed_args.gravity, parsed_args.yolo):
|
||||||
with wand.image.Image(width=dcc.config.THUMB_WIDTH, height=dcc.config.THUMB_HEIGHT, pseudo="x:") as img:
|
pass
|
||||||
img.reset_coords()
|
|
||||||
if img.size[0] < dcc.config.THUMB_WIDTH or img.size[1] < dcc.config.THUMB_HEIGHT:
|
|
||||||
if not messagebox.askretrycancel(title="DCC", message="Image too small. Try again?"):
|
|
||||||
sys.exit("Gave up trying to select an image.")
|
|
||||||
return False
|
|
||||||
img.crop(width=dcc.config.THUMB_WIDTH,height=dcc.config.THUMB_HEIGHT,gravity=parsed_args.gravity)
|
|
||||||
img.reset_coords()
|
|
||||||
if not parsed_args.yolo:
|
|
||||||
wand.display.display(img)
|
|
||||||
accepted = messagebox.askyesnocancel(title="DCC", message="Is this image acceptable?")
|
|
||||||
if accepted is None:
|
|
||||||
sys.exit("Gave up on image verification")
|
|
||||||
if not accepted:
|
|
||||||
return False
|
|
||||||
img.save(filename=self.base_thumb_path())
|
|
||||||
return True
|
|
||||||
|
|
||||||
while not try_screenshot():
|
def _try_screenshot(self, gravity, yolo):
|
||||||
pass
|
with wand.image.Image(
|
||||||
|
width=dcc.config.THUMB_WIDTH,
|
||||||
|
height=dcc.config.THUMB_HEIGHT,
|
||||||
|
pseudo="x:"
|
||||||
|
) as img:
|
||||||
|
img.reset_coords()
|
||||||
|
if (
|
||||||
|
img.size[0] < dcc.config.THUMB_WIDTH
|
||||||
|
or img.size[1] < dcc.config.THUMB_HEIGHT
|
||||||
|
):
|
||||||
|
if not messagebox.askretrycancel(
|
||||||
|
title="DCC", message="Image too small. Try again?"
|
||||||
|
):
|
||||||
|
sys.exit("Gave up trying to select an image.")
|
||||||
|
return False
|
||||||
|
img.crop(
|
||||||
|
width=dcc.config.THUMB_WIDTH,
|
||||||
|
height=dcc.config.THUMB_HEIGHT,
|
||||||
|
gravity=gravity
|
||||||
|
)
|
||||||
|
img.reset_coords()
|
||||||
|
if not yolo:
|
||||||
|
wand.display.display(img)
|
||||||
|
accepted = messagebox.askyesnocancel(
|
||||||
|
title="DCC", message="Is this image acceptable?"
|
||||||
|
)
|
||||||
|
if accepted is None:
|
||||||
|
sys.exit("Gave up on image verification")
|
||||||
|
if not accepted:
|
||||||
|
return False
|
||||||
|
img.save(filename=self.base_thumb_path())
|
||||||
|
return True
|
||||||
|
|
60
dcc/text.py
60
dcc/text.py
|
@ -3,36 +3,40 @@ import sys
|
||||||
import wand.drawing
|
import wand.drawing
|
||||||
import wand.image
|
import wand.image
|
||||||
|
|
||||||
|
|
||||||
def draw_text(img, text, font_size=64):
|
def draw_text(img, text, font_size=64):
|
||||||
with wand.drawing.Drawing() as draw:
|
with wand.drawing.Drawing() as draw:
|
||||||
draw.font = dcc.config.FONT
|
draw.font = dcc.config.FONT
|
||||||
draw.font_size=font_size
|
draw.font_size = font_size
|
||||||
draw.fill_color=wand.color.Color(dcc.config.TEXT_FILL_COLOR)
|
draw.fill_color = wand.color.Color(dcc.config.TEXT_FILL_COLOR)
|
||||||
draw.stroke_color=wand.color.Color(dcc.config.TEXT_STROKE_COLOR)
|
draw.stroke_color = wand.color.Color(dcc.config.TEXT_STROKE_COLOR)
|
||||||
draw.stroke_width=font_size*5/32
|
draw.stroke_width = font_size * 5 / 32
|
||||||
draw.text_interline_spacing=-font_size/4
|
draw.text_interline_spacing = -font_size / 4
|
||||||
draw.text(5,int(draw.font_size)+5,text)
|
draw.text(5, int(draw.font_size) + 5, text)
|
||||||
draw(img)
|
draw(img)
|
||||||
draw.stroke_color=wand.color.Color("none")
|
draw.stroke_color = wand.color.Color("none")
|
||||||
draw.stroke_width=0
|
draw.stroke_width = 0
|
||||||
draw.text(5,int(draw.font_size)+5,text)
|
draw.text(5, int(draw.font_size)+5, text)
|
||||||
draw(img)
|
draw(img)
|
||||||
|
|
||||||
|
|
||||||
class Text(dcc.doom_base.WadMap):
|
class Text(dcc.doom_base.WadMap):
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super().get_parser(prog_name)
|
parser = super().get_parser(prog_name)
|
||||||
parser.add_argument("--nomap", action="store_true")
|
parser.add_argument("--nomap", action="store_true")
|
||||||
parser.add_argument("--demotype", default="UV-Max Demo")
|
parser.add_argument("--demotype", default="UV-Max Demo")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
text = sys.stdin.read().rstrip()
|
text = sys.stdin.read().rstrip()
|
||||||
if not parsed_args.nomap:
|
if not parsed_args.nomap:
|
||||||
text = "MAP{}: {}".format(parsed_args.map, text)
|
text = "MAP{}: {}".format(parsed_args.map, text)
|
||||||
text = "{}\n{}".format(text, parsed_args.demotype)
|
text = "{}\n{}".format(text, parsed_args.demotype)
|
||||||
with wand.image.Image(height=dcc.config.THUMB_HEIGHT,width=dcc.config.THUMB_WIDTH) as img:
|
with wand.image.Image(
|
||||||
draw_text(img, text)
|
height=dcc.config.THUMB_HEIGHT,
|
||||||
img.trim()
|
width=dcc.config.THUMB_WIDTH
|
||||||
img.reset_coords()
|
) as img:
|
||||||
img.save(filename=self.text_thumb_path())
|
draw_text(img, text)
|
||||||
|
img.trim()
|
||||||
|
img.reset_coords()
|
||||||
|
img.save(filename=self.text_thumb_path())
|
||||||
|
|
46
dcc/thumb.py
46
dcc/thumb.py
|
@ -3,28 +3,34 @@ import dcc.doom_base
|
||||||
import wand.color
|
import wand.color
|
||||||
import wand.image
|
import wand.image
|
||||||
|
|
||||||
|
|
||||||
class Thumb(dcc.doom_base.WadMap):
|
class Thumb(dcc.doom_base.WadMap):
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super().get_parser(prog_name)
|
parser = super().get_parser(prog_name)
|
||||||
parser.add_argument("--index", action="store_true")
|
parser.add_argument("--index", action="store_true")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
base = self.base_thumb_path()
|
base = self.base_thumb_path()
|
||||||
text = self.text_thumb_path()
|
text = self.text_thumb_path()
|
||||||
mdoom = self.m_doom_path()
|
mdoom = self.m_doom_path()
|
||||||
with wand.image.Image(filename=base) as bi, wand.color.Color("transparent") as tc:
|
with (
|
||||||
with wand.image.Image(filename=text) as ti:
|
wand.image.Image(filename=base) as bi,
|
||||||
ti.border(tc, 5, 5)
|
wand.color.Color("transparent") as tc
|
||||||
bi.composite(ti, gravity="south_west")
|
):
|
||||||
|
with wand.image.Image(filename=text) as ti:
|
||||||
|
ti.border(tc, 5, 5)
|
||||||
|
bi.composite(ti, gravity="south_west")
|
||||||
|
|
||||||
with wand.image.Image(filename=mdoom) as mdi:
|
with wand.image.Image(filename=mdoom) as mdi:
|
||||||
mdi.border(tc, 5, 5)
|
mdi.border(tc, 5, 5)
|
||||||
bi.composite(mdi, gravity="north_west")
|
bi.composite(mdi, gravity="north_west")
|
||||||
|
|
||||||
if parsed_args.index:
|
if parsed_args.index:
|
||||||
with wand.image.Image(filename=self.output.joinpath("doomed_index.png")) as di:
|
with wand.image.Image(
|
||||||
di.border(tc, 1, 1)
|
filename=self.output.joinpath("doomed_index.png")
|
||||||
bi.composite(di, gravity="north_east")
|
) as di:
|
||||||
|
di.border(tc, 1, 1)
|
||||||
|
bi.composite(di, gravity="north_east")
|
||||||
|
|
||||||
bi.save(filename=self.thumb_path())
|
bi.save(filename=self.thumb_path())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue