Skip to content

Commit

Permalink
Merge pull request #8 from DavidCEllis/settings_cleanup
Browse files Browse the repository at this point in the history
Split settings for desktop and server versions
  • Loading branch information
DavidCEllis authored Apr 25, 2023
2 parents 545be50 + 72ccbce commit d84541c
Show file tree
Hide file tree
Showing 19 changed files with 889 additions and 224 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,4 @@ $RECYCLE.BIN/

# Project settings file
src/**/settings.json
src/**/server_settings.json
57 changes: 49 additions & 8 deletions application/app_server.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,69 @@
from PySide6.QtWidgets import QApplication, QMainWindow
import waitress

from flask import cli

from splitguides.server import app, get_notes, settings
import flask.cli as cli
from splitguides.ui.server_settings_ui import ServerSettingsDialog

# Stop flask from giving users an unhelpful warning.

# Suppress some of flask's messages
cli.show_server_banner = lambda *x: None


def launch():
get_notes() # Sets internal 'notes' and 'notefile' variables
# Create a base application and main window for the dialogs to use as parent
qt_app = QApplication()
main_window = QMainWindow()

settings_dialog = ServerSettingsDialog(
parent=main_window,
settings=settings,
)

result = settings_dialog.exec()
if result == 0: # Rejected, close without launching server
print("Settings cancelled, closing application.")
qt_app.quit()
return

success = get_notes(main_window) # Sets internal 'notes' and 'notefile' variables
if not success:
print("No notes file selected, closing application.")
qt_app.quit()
return

print(
"This server version of SplitGuides allows you view notes via a browser window "
"and should work across a local network.\n"
"It is not intended to be used over the internet and as such is not based on a "
"production server."
"This uses a development server and is not intended "
"to be used over the internet."
)

print(
f"Connect a browser to http://{settings.server_hostname}:{settings.server_port}/ "
f"Connect a browser to "
f"http://{settings.server_hostname}:{settings.server_port}/ "
f"in order to view the notes."
)

print(f"This hostname and port can be changed in {settings.output_file} if needed.")
print("Press ctrl+c to close the server.")

try:
# app.run(
# threaded=True,
# host=settings.server_hostname,
# port=settings.server_port
# )

app.run(threaded=True, host=settings.server_hostname, port=settings.server_port)
waitress.serve(
app,
host=settings.server_hostname,
port=settings.server_port
)
except KeyboardInterrupt:
print("Interrupt received, closing application.")
finally:
qt_app.quit()


if __name__ == "__main__":
Expand Down
129 changes: 81 additions & 48 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ Includes a server version for rendering notes in browsers on another device
## Install/Setup ##

1. Under the Livesplit layout editor add 'LiveSplit Server' (listed under 'control')
* Take note of the port number here, this is the value needed for
'Livesplit Server Port' in settings.
* Livesplit Server Hostname can be the local ip given. If SplitGuides is running
on the same machine as Livesplit 'localhost' (the default) should also work.
2. Download SplitGuides from the [**releases page**](https://github.com/DavidCEllis/SplitGuides/releases)
3. Extract anywhere and run *splitguides.exe*

## Usage ##

1. Connect with livesplit by starting the livesplit server component selecting
'Control' and 'Start Server'
'Control' and 'Start Server' in livesplit.
2. Right click in the splitguides window and select 'Open Notes' and find the text file
containing the notes you wish to use.
3. Some configuration is available from the settings dialog.

Plain text formatting works the same way as SplitNotes.
Notes made for that should function fine in SplitGuides.
Expand All @@ -31,65 +36,91 @@ inserted in between lines.

1. Comment lines still use square brackets.
2. By default splits will break on newlines, multiple newlines are ignored in this case.
3. The rendering is done as HTML so HTML formatting can be used.
* If a split separator is given, newlines are left as in the input to the
markdown/html processors.

## splitguides_server.exe ##
## SplitGuides Server ##

Now included is a server version which launches a (local) webhost so you can view the notes
on another device on your local network. Launch splitguides_server.exe to start the service.
Included is a separate server version which launches a (local) webhost so you can view
the notes on another device on your local network.

If the hostname and port defaults aren't usable you can set them by editing server_hostname
and server_port in settings.json. There is no dialog for editing these settings yet.
Launch **splitguides_server.exe** to start the service. A settings dialog will appear
so you can customise this version separately from the desktop version. After asking
for the notes file the server will launch serving those notes and will update
automatically as you split.

If the hostname and port defaults aren't usable you can edit them
in the settings dialog.

This version is intended for people doing runs on a single monitor so the notes can be
displayed on another device (a tablet or phone for example). Just connect to the host
and port given in a web browser.

### Example Notes ###
## Configuration ##

Configuration Options:

#### Source ####
* Livesplit server hostname and port
* Display previous/next splits
* Split separator (leave blank for empty line separator)
* Font Size
* Text and Background Colour
* Alternative template HTML and CSS files
* Jinja2 templating is used for the HTML, use the included file as a guide
* Allows for further customising of the appearance if desired
* Hotkeys to offset the notes from the splits (not available in splitnotes server)
* This allows for some adjustment if the notes have ended up in the wrong place
relative to the splits.
* Server hostname and port (server only)
* This should be your local machine name on the network and an open port to
connect to from the device you wish to use to display the notes.

## Example Notes ##

### Source ###

```markdown
## High Hedge ##
### Friendly Arm Inn ###
* *East*
* *Pick up the ring*
* **Peldvale**

### Peldvale ###
* *South*
* **High Hedge**

### High Hedge ###
* Rest and Spin
* *South to Shop*
* Thalantyr (1, 1)
* Shop:
* Sell the wand
* Identify the ring
* Sell the ring
* 3x Potion of Explosions
* Potion of Magic Blocking
* Protection from Magic
* Identify
* Shield
* Mirror Image
* 3x Invisibility
* *South*
* Go to Wilderness Map
/split
# Dark Souls Remastered - SL1 NWW #
## Asylum ##
* Start Pyro + MK
* Keep Hilt
* Get Axe/Estus/Flame
* Asylum Skip
* Pick up a 200 soul
* Dupe the soul 99x
* Leave

## Laurentius ##
* Pick up the firebombs
* Grab the 200 soul
* Ladder glitch
* Buy
* Max wooden arrows
* 4 blooming moss
* 2 throwing knifes
* Max (25) homeward bones
* Free Laurentius
* Darksign

## GCS ##
* Dupe souls with the arrows
* Ascend flame to +15
* Buy flash sweat, combustion, fire orb
* Valley Run
* Get DCS/RTSR
* Upwarp
* Get GCS
```

#### Result ####
### Result ###

![Image of splitguides rendering](resources/demo_notes_md.png)
On Desktop:

## Configuration ##
![Image of splitguides rendering](resources/splits_example.png)

The settings page offers some customisation and connection settings including:
Via Splitnotes Server on Tablet:

* Server hostname and port
* Show previous/next N splits
* Custom split separator
* Base font size
* Default text and background colour
* HTML (Jinja2) template and CSS files to use for rendering
![Image of splitguides server - yes this is an old iPad](resources/splitguides_server_example.jpg)

## Dependencies ##
* pyside6 - QT Gui Bindings
Expand All @@ -98,7 +129,9 @@ The settings page offers some customisation and connection settings including:
* flask - Handling the server version
* markdown - Converting markdown to html for rendering
* keyboard - Global hotkeys to advance/reverse note offset to splits
* waitress - wsgi server for splitguides server

---

Inspired by (but otherwise unassociated with) the original splitnotes: https://github.com/joeloskarsson/SplitNotes
Inspired by (but otherwise unassociated with) the original splitnotes:
https://github.com/joeloskarsson/SplitNotes
Binary file removed resources/demo_notes_md.png
Binary file not shown.
Binary file added resources/splitguides_server_example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/splits_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
install_requires=[
"pyside6",
"jinja2",
"bleach[css]",
"bleach[css]==6.0", # Each upgrade to bleach has broken something so pin it.
"flask",
"markdown",
"keyboard",
"prefab-classes",
"waitress",
],
tests_require=test_requirements,
extras_require={
Expand Down
2 changes: 1 addition & 1 deletion src/splitguides/hotkeys/keyboard_fixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def read_hotkey(suppress=True):
"""
Modified read_hotkey function to correctly support numpad keys.
The original function returns just the names, this returns a ([scancodes], name) tuple.
The original function returns just the names, this returns a Hotkey object.
The scancodes can then be stored while the name can be displayed.
"""

Expand Down
45 changes: 22 additions & 23 deletions src/splitguides/server/split_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,24 @@
from pathlib import Path

from flask import Flask, render_template, Response
from PySide6.QtWidgets import QApplication, QFileDialog
from PySide6.QtWidgets import QFileDialog

from ..settings import Settings
from ..settings import ServerSettings
from ..livesplit_client import get_client
from ..note_parser import Notes

KEEP_ALIVE = 10

settings = Settings.load()

template_folder = str(Path(__file__).parent / "templates")
static_folder = str(Path(__file__).parent / "static")
settings = ServerSettings.load()

app = Flask(
"splitguides",
template_folder=settings.server_template_folder,
static_folder=settings.server_static_folder,
template_folder=settings.html_template_folder,
static_folder=settings.css_folder,
)

notefile = None
notes = None
notefile: None | Path = None
notes: None | Notes = None

app.secret_key = "".join(
secrets.choice(string.printable) for _ in range(random.randint(30, 40))
Expand All @@ -40,7 +37,7 @@ def notes_page():
:return:
"""
global notefile
return render_template(settings.server_html_template_file, notefile=notefile.stem)
return render_template(settings.html_template_file, notefile=notefile.stem)


@app.route("/splits")
Expand Down Expand Up @@ -82,12 +79,12 @@ def event_stream():
last_update = now
current_note_index = new_index
split_text = notes.render_splits(
new_index - settings.server_previous_splits,
new_index + settings.server_next_splits + 1,
new_index - settings.previous_splits,
new_index + settings.next_splits + 1,
)
if len(split_text) > 0:
# Remove newlines from the notes as they break the send
data = split_text[0].replace("\n", "")
data = "".join(split_text).replace("\n", "")
yield f"data: {data}\n\n"
else:
yield f"data: End of Notes.\n\n"
Expand All @@ -106,21 +103,23 @@ def event_stream():
return Response(event_stream(), mimetype="text/event-stream")


def get_notes():
def get_notes(parent):
global notes, notefile
temp_app = QApplication()

# noinspection PyTypeChecker
filepath, _ = QFileDialog.getOpenFileName(
None,
parent,
"Open Notes",
settings.notes_folder,
"Note Files (*.txt *.md);;All Files (*.*)",
)

temp_app.quit()

notefile = Path(filepath)
notes = Notes.from_file(notefile, settings.split_separator)
if filepath:
notefile = Path(filepath)
notes = Notes.from_file(notefile, settings.split_separator)

settings.notes_folder = str(notefile.parent)
settings.save()
settings.notes_folder = str(notefile.parent)
settings.save()
return True
else:
return False
Loading

0 comments on commit d84541c

Please sign in to comment.