Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating Readme and Creating a /weapons endpoint. #5

Merged
merged 4 commits into from
Jul 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 22 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,39 @@
# open5e is being rebuilt in Django and Vue.js!

## Check the [Beta Site](https://beta.open5e.com) and [Beta API](https://api-beta.open5e.com) to see what's up!

We have a discord going for discussing the rebuild, and I hope you'll join us! https://discord.gg/9RNE2rY

Open5e is a community project driven by a small number of volunteers in their spare time. We welcome any and all contributions! Please join our Discord to help out: https://discord.gg/9RNE2rY or check out the issue board if you'd like to see what's being worked on!

# Starting the Server

The Django API uses Django REST Framework for its browsability and ease of use when developing CRUD endpoints.

## Server Quickstart

The server runs in a docker container. You'll need to first install docker on your system, then getting it running is extremely simple:
The Django API uses Django REST Framework for its browsability and ease of use when developing CRUD endpoints. It uses django's default SQLite database, and pulls the data from the /data directory.

First, you will need to [install Docker](https://docs.docker.com/v17.12/install/)
If you are using Windows, you will need to either run a linux VM, or install the Ubuntu CLI from the microsoft store.
This is due to the scripts causing syntax errors in windows, as they are designed for bash.
If you install Ubuntu from the microsoft store follow these steps: (https://medium.com/@sebagomez/installing-the-docker-client-on-ubuntus-windows-subsystem-for-linux-612b392a44c4)
# Quickstart
The API uses docker-compose to run, and by default binds https:// on port 443, which may not work for your system (I believe windows has problems binding on low ports.) Here's the default command, run from the root.
> docker-compose up

`cd` into the root `/open5e` directory in the shell program of your choice, then:
This will allow you to access the project on https://localhost.

``` bash
export OPEN_5E_ROOT=`pwd` #set the /server folder as the root of the Python project
export SECRET_KEY='@pt#ouh)@!c+2eh(!aj_vtc=s7t$uk-l1!ry3^fcercz%si01@' # this should be a nukable test key that you're manually replacing at startup time for production
docker-compose build dev
docker-compose up dev
```
If you'd like to use docker and docker-compose for development, I would suggest rebinding the ports. Here's an example command that would allow for running the project on a non-standard port.

> docker-compose run --publish 8888:8888 server

If you need to work with the db, serializers, or other django-level elements, you will need to be running the docker container then exec into it:
This command runs the Server module (defined in docker-compose.yml), binding the port 8888 to 8888 locally. This should allow you to access the site on https://localhost:8888.

``` bash
bash -c "clear && docker exec -it open5e_dev_1 sh"
```
# Development using Django Server
To do any python development on the django application itself, I would suggest using django's built-in server as it allows for various things (such as debug mode and quick reloads). Here's the general process for getting that up and running.

From there you can apply any typical python/django commands. Some common and useful commands include:
First, install pipenv from here (https://pipenv.readthedocs.io/en/latest/).

``` python
pipenv run python manage.py makemigrations #create a new migration for the db
pipenv run python manage.py migrate #apply any pending db migrations
pipenv run python manage.py rebuild_index #rebuild search index to reflect model or indexer changes
```
Once pipenv is installed locally, you can then use it to install of the project dependencies defined in the Pipfile.
> pipenv install

You will want to leave the server terminal running while you launch the UI in a separate termainal so you can observe requests.
Then you will need to use the built-in django migration function to define your database, making sure to run it within the pipenv environment.
> pipenv run python manage.py migrate

If all you want to test against is the API/backend, you're done! Otherwise you'll want to open another window and...
You will then need to collect the static files (this makes django-resk-framework look presentable when viewing it in html).
> pipenv run python manage.py collectstatic --noinput

Finally, you will need to load the SRD data from the json files in the /data folder. This is using the custom populatedb command.
> pipenv run python manage.py populatedb --flush ./data/WOTC_5e_SRD_v5.1/

# Build and run the UI layer
At that point, you will be able to run the django server normally (within the pipenv environment).
> pipenv run python manage.py runserver

To run the UI layer, you will need to clone the repo at https://github.com/eepMoody/open5e and follow the instructions there.
And your server should be available at http://localhost:8000.
39 changes: 38 additions & 1 deletion api/management/commands/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,4 +605,41 @@ def SpellImporter(self, options, json_object):
if new: added += 1
else: updated += 1

return self.returner('Spells',added,updated,skipped)
return self.returner('Spells',added,updated,skipped)

def WeaponImporter(self, options, json_object):
skipped,added,updated = (0,0,0) #Count for all of the different results.
if bool(options['flush']): Weapon.objects.all().delete()

for o in json_object:
new = False
exists = False
if Weapon.objects.filter(slug=slugify(o['name'])).exists():
i = Weapon.objects.get(slug=slugify(o['name']))
exists = True
else:
i = Weapon(document = self.d)
new = True
if 'name' in o:
i.name = o['name']
i.slug = slugify(o['name'])
if 'category' in o:
i.category = o['category']
if 'cost' in o:
i.cost = o['cost']
if 'damage_dice' in o:
i.damage_dice = o['damage_dice']
if 'damage_type' in o:
i.damage_type = o['damage_type']
if 'weight' in o:
i.weight = o['weight']
if 'properties' in o:
i.properties_json = json.dumps(o['properties'])
if bool(options['testrun']) or (exists and options['append']):
skipped += 1
else:
i.save()
if new: added += 1
else: updated += 1

return self.returner('Weapons',added,updated,skipped)
3 changes: 3 additions & 0 deletions api/management/commands/populatedb.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,6 @@ def handle(self, *args, **options):
spl = json.load(spl_data)
self.stdout.write(self.style.SUCCESS(importer.SpellImporter(options, spl)))

with open(dir+'weapons.json') as spl_data:
spl = json.load(spl_data)
self.stdout.write(self.style.SUCCESS(importer.WeaponImporter(options, spl)))
35 changes: 35 additions & 0 deletions api/migrations/0003_weapon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generated by Django 2.1 on 2019-07-18 02:51

from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

dependencies = [
('api', '0002_auto_20190709_0153'),
]

operations = [
migrations.CreateModel(
name='Weapon',
fields=[
('slug', models.SlugField(default=uuid.uuid1, primary_key=True, serialize=False, unique=True)),
('name', models.TextField()),
('desc', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('route', models.TextField(default='weapons/')),
('category', models.TextField()),
('cost', models.TextField()),
('damage_dice', models.TextField()),
('damage_type', models.TextField()),
('weight', models.TextField()),
('properties_json', models.TextField()),
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Document')),
],
options={
'abstract': False,
},
),
]
14 changes: 13 additions & 1 deletion api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,16 @@ class MagicItem(GameContent):
type = models.TextField()
rarity = models.TextField()
requires_attunement = models.TextField()
route = models.TextField(default="magicitems/")
route = models.TextField(default="magicitems/")

class Weapon(GameContent):
category = models.TextField()
cost = models.TextField()
damage_dice = models.TextField()
damage_type = models.TextField()
weight = models.TextField()
properties_json = models.TextField()
def properties(self):
if self.properties_json:
return json.loads(self.properties_json)
route = models.TextField(default="weapons/")
15 changes: 15 additions & 0 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ class Meta:
model = MagicItem
fields = ('slug','name','type','desc','rarity','requires_attunement','document_slug')

class WeaponSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Weapon
fields = (
'name',
'slug',
'category',
'document_slug',
'cost',
'damage_dice',
'damage_type',
'weight',
'properties')


class AggregateSerializer(HighlighterMixin, HaystackSerializer):

class Meta:
Expand Down
10 changes: 10 additions & 0 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ class MagicItemViewSet(viewsets.ModelViewSet):
"""
queryset = MagicItem.objects.all()
serializer_class = MagicItemSerializer
filter_fields=(
'name',
)

class WeaponViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows viewing of Archetypes.
"""
queryset = Weapon.objects.all()
serializer_class = WeaponSerializer
filter_fields=(
'name',
)
Loading