diff --git a/gurpsspace/output/latexout.py b/gurpsspace/output/latexout.py index 8be3daf..f8a9fa3 100644 --- a/gurpsspace/output/latexout.py +++ b/gurpsspace/output/latexout.py @@ -4,6 +4,9 @@ processing towards a nicely formatted PDF file. """ +import subprocess +import os + # from ..starsystem import StarSystem from ..tables import AtmCompAbbr @@ -13,6 +16,36 @@ def __init__(self, starsystem, filename='starsystem.tex'): self.starsystem = starsystem self.filename = filename + def make_pdf(self) -> str: + self.write() + base_name = os.path.splitext(self.filename)[0] + pdf_name = base_name + ".pdf" + + cmd = ['pdflatex', '-interaction', 'nonstopmode', self.filename] + proc = subprocess.Popen(cmd) + proc.communicate() + + retcode = proc.returncode + if not retcode == 0: + os.unlink(pdf_name) + raise ValueError('Error {} executing command: {}'.format(retcode, ' '.join(cmd))) + # PDFLaTeX has to be run twice to properly generate the ToC + cmd = ['pdflatex', '-interaction', 'nonstopmode', self.filename] + proc = subprocess.Popen(cmd) + proc.communicate() + + retcode = proc.returncode + if not retcode == 0: + os.unlink(pdf_name) + raise ValueError('Error {} executing command: {}'.format(retcode, ' '.join(cmd))) + + os.unlink(base_name + '.log') + os.unlink(base_name + '.aux') + os.unlink(base_name + '.toc') + os.unlink(base_name + '.out') + + return os.path.abspath(pdf_name) + def write(self): # Open the file file = open(self.filename, 'w') diff --git a/gurpsspace/starsystem.py b/gurpsspace/starsystem.py index 54985b5..8058c06 100644 --- a/gurpsspace/starsystem.py +++ b/gurpsspace/starsystem.py @@ -364,6 +364,15 @@ def write_latex(self, filename='starsystem.tex') -> None: writer = LW(self, filename) writer.write() + def make_pdf(self, filename='starsystem.tex'): + """ + Create a PDF document with all the information about the starsystem. + :return: Path to the PDF. + """ + + writer = LW(self, filename) + return writer.make_pdf() + def get_age(self) -> int: """Return star system age in billion years""" return self.age diff --git a/server.py b/server.py index 1deacfe..ffb865b 100644 --- a/server.py +++ b/server.py @@ -7,6 +7,7 @@ from gurpsspace import starsystem as starsys from namegenerator import namegenerator +from cherrypy.lib.static import serve_file from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader('webgui/templates')) @@ -68,6 +69,22 @@ def starsystem(self, must_have_garden="False", open_cluster=None, num_stars=0, a else: mysys = starsys.StarSystem(**arguments) + for star in mysys.stars: + for key, v in star.planetsystem.get_orbitcontents().items(): + if namegen is not None: + simple_name = v.get_name().replace("-", "") + if cherrypy.session.get('name_of_' + simple_name) is None: + name = namegen.get_random_name() + star.planetsystem.get_orbitcontents()[key].set_name(name) + # For some reason, using simple_name here leads to storing stuff improperly and + # generating new names every time. No idea why. + cherrypy.session['name_of_' + v.get_name().replace("-", "")] = name + else: + name = cherrypy.session.get('name_of_' + simple_name) + star.planetsystem.get_orbitcontents()[key].set_name(name) + + cherrypy.session.save() + tmpl = env.get_template('overview.html') cherrypy.session['starsystem'] = mysys cherrypy.response.cookie['names'] = {} @@ -83,34 +100,20 @@ def planetsystem(self, star_id=""): else: star_id = int(star_id) - namegen = cherrypy.session.get('namegen') - tmpl = env.get_template('planetsystem.html') env.globals['translate_row'] = self.translate_row t_count = 0 a_count = 0 g_count = 0 - for key, v in starsystem.stars[star_id].planetsystem.get_orbitcontents().items(): + for key, _ in starsystem.stars[star_id].planetsystem.get_orbitcontents().items(): if starsystem.stars[star_id].planetsystem.get_orbitcontents()[key].type() == 'Terrestrial': t_count += 1 if starsystem.stars[star_id].planetsystem.get_orbitcontents()[key].type() == 'Ast. Belt': a_count += 1 if starsystem.stars[star_id].planetsystem.get_orbitcontents()[key].type() == 'Gas Giant': g_count += 1 - if namegen is not None: - simple_name = v.get_name().replace("-", "") - if cherrypy.session.get('name_of_' + simple_name) is None: - name = namegen.get_random_name() - starsystem.stars[star_id].planetsystem.get_orbitcontents()[key].set_name(name) - # For some reason, using simple_name here leads to storing stuff improperly and - # generating new names every time. No idea why. - cherrypy.session['name_of_' + v.get_name().replace("-", "")] = name - else: - name = cherrypy.session.get('name_of_' + simple_name) - starsystem.stars[star_id].planetsystem.get_orbitcontents()[key].set_name(name) - cherrypy.session.save() cherrypy.session['planetsystem'] = starsystem.stars[star_id].planetsystem return tmpl.render(planetsystem=starsystem.stars[star_id].planetsystem, terrestrial_count=t_count, asteroid_count=a_count, gas_giant_count=g_count) @@ -140,6 +143,30 @@ def satellites(self, planet_id=""): tmpl = env.get_template('moons.html') return tmpl.render(moons=moons, planet_name=planet.get_name()) + @cherrypy.expose + def printable(self): + try: + starsystem = cherrypy.session['starsystem'] + except KeyError: + raise cherrypy.HTTPError(404) + + t_count = 0 + a_count = 0 + g_count = 0 + for star in starsystem.stars: + for key, _ in star.planetsystem.get_orbitcontents().items(): + if star.planetsystem.get_orbitcontents()[key].type() == 'Terrestrial': + t_count += 1 + if star.planetsystem.get_orbitcontents()[key].type() == 'Ast. Belt': + a_count += 1 + if star.planetsystem.get_orbitcontents()[key].type() == 'Gas Giant': + g_count += 1 + + tmpl = env.get_template('printable.html') + env.globals['translate_row'] = self.translate_row + + return tmpl.render(starsystem=starsystem, seed=self.random_seed, terrestrial_count=t_count, asteroid_count=a_count, gas_giant_count=g_count) + def translate_row(self, planet, row): """ It is difficult in HTML and Jinja to make a table where each column is a single item, rather than each row. diff --git a/webgui/templates/overview.html b/webgui/templates/overview.html index 5eb2b62..caa04e3 100644 --- a/webgui/templates/overview.html +++ b/webgui/templates/overview.html @@ -14,6 +14,7 @@
Click here if you want to change the settings.
Seed: {{seed}}
+Printable view here.
You have successfully generated the following star system:
Seed: {{seed}}
+The star system is located in an open cluster.
+ {% endif %} + {% if starsystem.stars|count == 1 %} +| Name | + {% if starsystem.stars|count > 1 %} +Orbital Radius | +Orbital Period | + {% endif %} +Sequence | +Mass* | +Avg. Temp. | +Luminosity* | +Radius* | +Inner Limit | +Outer Limit | +Snow Line | + {% if starsystem.stars|count > 1 %} +Forbidden Zone | + {% endif %} +Planetary System | +||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{star.get_letter()}} | + {% if star.get_letter() == 'A' and starsystem.stars|count > 1 %} +- | +- | + {% elif star.get_letter() != 'A' %} +{{starsystem.get_orbits()[loop.index0 - 1][0]|round(2)}} AU | +{{starsystem.get_period()[loop.index0 - 1]|round(1, 'common')}} days | + {% endif %} +{{star.get_sequence()}} | +{{star.get_mass()|round(2)}} | +{{star.get_temp()|round(2)}} K | +{{star.get_luminosity()|round(4)}} | +{{(star.get_radius() * 214.93) | round(2)}} | +{{star.get_orbit_limits()[0]|round(2)}} AU | +{{star.get_orbit_limits()[1]|round(2)}} AU | +{{star.get_snowline()|round(2)}} AU | + {% if star.get_letter() == 'A' and starsystem.stars|count > 1 %} +- | + {% elif star.get_letter() != 'A' %} +{{star.get_forbidden_zone()[0]|round(2)}} AU - {{star.get_forbidden_zone()[1]|round(2)}} AU | + {% endif %} + {% if star.planetsystem.get_orbitcontents()|count > 0 %} ++ {{star.planetsystem.get_orbitcontents()|count }} Planets in System + | + {% else %} +No Planetary System | + {% endif %} +
*: Mass, Luminosity and Radius are given relative to the Sun: 1.0 is equal to the Sun.
++ This planetary system orbits star {{planetsystem.parentstar.get_letter()}} of the star system. +
+ + +This planetary system contains the following planets and other astronomical objects:
+| Name | +Type | +Size | +World | +Orbital Radius | +Orbital Period | +Orbital Eccentricity | +Minimum Radius | +Maximum Radius | +Moons | +Moonlets | +
|---|---|---|---|---|---|---|---|---|---|---|
| {{astro_body.get_name()|e}} | +{{astro_body.type()}} | +{% if astro_body.get_size() != '' %}{{astro_body.get_size()}}{% else %} N/A {% endif %} | +{% if astro_body.get_type() != '' %}{{astro_body.get_type()}}{% else %} N/A {% endif %} | +{{astro_body.get_orbit()|round(2)}} AU | +{{(astro_body.get_period() * 365)|round(2)}} days | +{{astro_body.get_eccentricity()}} | +{{astro_body.get_min_max()[0]|round(2)}} AU | +{{astro_body.get_min_max()[1]|round(2)}} AU | ++ {% if astro_body.num_moons() != '' %} + {{astro_body.num_moons()|round(2)}} + {% else %} + N/A + {% endif %} + | +{% if astro_body.num_moonlets() != '' %}{{astro_body.num_moonlets()|round(2)}}{% else %} N/A {% endif %} | +
| + {% else %} | {{row}} | + {% endif %} + + {% for astro_body in moons%} + {% if row == "" %} +{{translate_row(astro_body, row)}} | + {% else %} +{{translate_row(astro_body, row)}} | + {% endif %} + {% endfor %} +
|---|
*: Atmospheric mass, density, diameter, and mass are all relative to Earth dimensions; 1.0 is what you'd expect on Earth. The rotation of the body is prograde by default, negative rotational period values indicate retrograde rotation.
+| Name | +Avg. Surface Temperature | +Climate Type | +Resource Value Modifier | +Affinity | +
|---|---|---|---|---|
| {{astro_body.get_name()|e}} | +{{astro_body.get_average_surface_temp()|round(2)}} K / {{(astro_body.get_average_surface_temp()-273.15)|round(2)}}°C | +{{astro_body.get_climate()}} | +{{astro_body.get_rvm()}} | +{{astro_body.get_affinity()}} | +
| + {% else %} | {{row}} | + {% endif %} + + {% for key, _ in planetsystem.get_orbitcontents().items()|sort if planetsystem.get_orbitcontents()[key].type() == 'Terrestrial'%} + {% set astro_body = planetsystem.get_orbitcontents()[key] %} + + {% if row == "" %} +{{translate_row(astro_body, row)}} | + {% else %} +{{translate_row(astro_body, row)}} | + {% endif %} + {% endfor %} +
|---|
*: Atmospheric mass, density, diameter, and mass are all relative to Earth dimensions; 1.0 is what you'd expect on Earth. The rotation of the body is prograde by default, negative rotational period values indicate retrograde rotation.
+| + {% else %} | {{row}} | + {% endif %} + + {% for key, _ in planetsystem.get_orbitcontents().items()|sort if planetsystem.get_orbitcontents()[key].type() == 'Gas Giant'%} + {% set astro_body = planetsystem.get_orbitcontents()[key] %} + + {% if row == "" %} +{{translate_row(astro_body, row)}} | + {% else %} +{{translate_row(astro_body, row)}} | + {% endif %} + {% endfor %} +
|---|
*: Atmospheric mass, density, diameter, and mass are all relative to Earth dimensions; 1.0 is what you'd expect on Earth.
+