Passed
Pull Request — master (#6)
by Erik
52s
created

pypen.__main__.cli()   B

Complexity

Conditions 7

Size

Total Lines 30
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 24
dl 0
loc 30
rs 7.904
c 0
b 0
f 0
cc 7
nop 0
1
import sys
2
import argparse
3
import time
4
from os import path, getcwd
5
6
from importlib import util as import_util
7
8
from pypen.settings import settings
9
import pygame
10
11
_argument_parser = argparse.ArgumentParser()
12
13
def space_print(msg=""):
14
    print()
15
    print(msg)
16
    print()
17
18
def print_help(msg=""):
19
    if msg:
20
        space_print(msg)
21
22
    _argument_parser.print_help(sys.stderr)
23
    sys.exit(0)
24
25
def cli():
26
    global _argument_parser
27
    try:
28
        _argument_parser = argparse.ArgumentParser(description="The PyPen CLI for managing PyPen Sketches", prog="pypen")
29
        _argument_parser.add_argument(
30
            "-i",
31
            "--init",
32
            action="store_true",
33
            help="Flag to create a new PyPen sketch which imports pypen and contains default functions.")
34
35
        _argument_parser.add_argument("filename", nargs="?", help="The name/path of your PyPen Sketch.", default="")
36
        _argument_parser.add_argument("-f", "--fullscreen", action="store_true")
37
        _argument_parser.add_argument("--timeout", help="Timeout in seconds. Window will close once done.", type=float, required=False, default=0.0)
38
39
        arguments = _argument_parser.parse_args()
40
41
        if len(sys.argv) == 1:
42
            print_help("It seems like you are running the pypen command without any arguments.\nHere is some help:")
43
44
        if not arguments.init and not arguments.filename:
45
            print_help("PyPen needs a path to a sketch in order to run it!\nPlease provide a path with 'pypen <path_to_sketch>'\nor run 'pypen --init <path_to_new_sketch>' to create a new one!")
46
47
        if arguments.init:
48
            path_to_new_sketch = arguments.filename if arguments.filename else settings.default_pypen_name
49
            init(path_to_new_sketch)
50
51
        main(arguments)
52
    except argparse.ArgumentError as error:
53
        print(str(error))
54
        sys.exit(1)
55
56
57
def init(path_to_new_file):
58
    if path.splitext(path_to_new_file)[1] != ".py":
59
        path_to_new_file += ".py"
60
61
    pypen_path = path.join(getcwd(), path_to_new_file)
62
    template = ""
63
64
    try:
65
        with open(path.join(path.realpath(__file__), "..", "pypen_template.py"), "r") as template_file:
66
            template = template_file.read()
67
    except EnvironmentError:
68
        # In case PyPen is installed in a directory that doesn't have read access,
69
        # it uses the below template instead of reading the template file
70
        template = """from pypen import *
71
72
73
def start():
74
    settings.fps = 60
75
76
77
def update():
78
    clear()
79
    rectangle(20, 20, 300, 400, "red")
80
"""
81
82
    try:
83
        with open(pypen_path, "w") as new_file:
84
            new_file.writelines(template)
85
    except EnvironmentError:
86
        space_print("Could not create file {}\nDo you have the right permissions?".format(pypen_path))
87
        sys.exit(1)
88
89
    space_print("'{0}' has been created!\nRun it using 'pypen {0}'".format(path_to_new_file))
90
    sys.exit(0)
91
92
93
def main(arguments):
94
    if not arguments.init:
95
        try:
96
            file_path = path.join(getcwd(), arguments.filename)
97
            spec = import_util.spec_from_file_location("", file_path)
98
            user_sketch = import_util.module_from_spec(spec)
99
            spec.loader.exec_module(user_sketch)
100
        except FileNotFoundError:
101
            print()
102
            print(f"Hmm, PyPen can't find '{arguments.filename}'.")
103
            print("Are you sure that's the right path?")
104
            print()
105
            sys.exit(1)
106
107
    try:
108
        user_sketch.TIME
0 ignored issues
show
introduced by
The variable user_sketch does not seem to be defined in case BooleanNotNode on line 94 is False. Are you sure this can never be the case?
Loading history...
109
        user_sketch.T
110
        user_sketch.rectangle
111
        user_sketch.PI
112
    except AttributeError:
113
        print()
114
        print(f"It seems like you're not importing PyPen to your sketch '{arguments.filename}'")
115
        print("Import it by writing 'from pypen import *' at the very top!")
116
        print()
117
        sys.exit(1)
118
119
    try:
120
        user_sketch.start
121
    except AttributeError:
122
        settings._user_has_start = False
123
124
    try:
125
        user_sketch.update
126
    except AttributeError:
127
        settings._user_has_update = False
128
129
    if not settings._user_has_start and not settings._user_has_update:
130
        print()
131
        print(
132
            f"Your PyPen sketch '{arguments.filename}' appears to have neither a start() nor an update() function.")
133
        print("Try to add at least one of those and run again!")
134
        print()
135
        sys.exit(1)
136
137
    def start():
138
        user_sketch.start()
0 ignored issues
show
introduced by
The variable user_sketch does not seem to be defined in case BooleanNotNode on line 94 is False. Are you sure this can never be the case?
Loading history...
139
        update()
140
141
    def update(passed_time=0, delta_time=0, frame_count=0):
142
        user_sketch.TIME = user_sketch.T = passed_time
0 ignored issues
show
introduced by
The variable user_sketch does not seem to be defined in case BooleanNotNode on line 94 is False. Are you sure this can never be the case?
Loading history...
143
        user_sketch.DELTA_TIME = user_sketch.DT = delta_time
144
        user_sketch.FRAME = user_sketch.F = frame_count
145
146
        user_sketch.update()
147
148
    pygame.display.set_mode((settings.width, settings.height), pygame.SRCALPHA)
149
150
    pygame.init()
151
    pygame.display.set_caption(f"PyPen | {arguments.filename}")
152
153
    if settings._user_has_start:
154
        start()
155
156
    pygame.display.set_mode((settings.width, settings.height), pygame.SRCALPHA)
157
    pygame.display.flip()
158
    clock = pygame.time.Clock()
159
160
    is_running = True
161
    passed_time = frame_count = 0
162
163
    while is_running:
164
        # Handle events
165
        for event in pygame.event.get():
166
            if event.type == pygame.QUIT:
167
                is_running = False
168
169
            if event.type == pygame.KEYDOWN:
170
                if event.key == pygame.K_ESCAPE:
171
                    is_running = False
172
173
        delta_time = clock.tick(settings.fps if settings.fps > 0 else 1)/1000
174
        passed_time += delta_time
175
        frame_count += 1
176
177
        if arguments.timeout > 0:
178
            if passed_time > arguments.timeout:
179
                is_running = False
180
181
        if settings._user_has_update:
182
            update(passed_time, delta_time, frame_count)
183
184
        pygame.display.flip()
185
186
187
if __name__ == "__main__":
188
    cli()
189