├── __init__.py ├── browse ├── __init__.py ├── models.py ├── static │ └── browse │ │ ├── img │ │ ├── star.png │ │ ├── star-dim.png │ │ └── _readme_free.txt │ │ └── css │ │ └── like.css ├── urls.py ├── views.py ├── templates │ └── browse │ │ ├── favorites.html │ │ ├── feat.html │ │ ├── spell.html │ │ └── monster.html └── tests.py ├── search ├── __init__.py ├── views.py ├── forms.py ├── templates │ └── search │ │ ├── start.html │ │ ├── search_site_search.html │ │ ├── results.html │ │ └── results_site_search.html └── search_site.py ├── srd20 ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0006_auto__del_field_spell_full_text.py │ ├── 0007_auto__chg_field_spell_components.py │ ├── 0005_auto__chg_field_spell_altname.py │ ├── 0004_altname_to_slug.py │ ├── 0003_auto__del_field_spell_sorcerer_focus__del_field_spell_wizard_focus__de.py │ ├── 0002_update_arcane_focus.py │ ├── 0010_auto__del_field_feat_full_text.py │ ├── 0009_set_feat_altnames.py │ ├── 0016_auto__chg_field_feat_altname.py │ ├── 0012_backup_multiple_and_stack.py │ ├── 0014_convert_multiple_and_stack.py │ ├── 0015_auto__del_field_feat_multiple_copy__del_field_feat_stack_copy.py │ ├── 0011_auto__add_field_feat_multiple_copy__add_field_feat_stack_copy.py │ ├── 0013_auto__chg_field_feat_multiple__chg_field_feat_stack.py │ ├── 0008_auto__add_feat.py │ ├── 0001_initial.py │ ├── 0018_auto__add_field_feat_description.py │ ├── 0021_auto__chg_field_spell_casting_time__chg_field_spell_subschool.py │ ├── 0020_auto__chg_field_spell_short_description__chg_field_spell_saving_throw.py │ ├── 0019_auto__chg_field_spell_descriptor__chg_field_spell_components__chg_fiel.py │ └── 0017_auto__add_characterclass.py ├── tests.py ├── admin.py ├── fixtures │ └── README └── models.py ├── encounter ├── __init__.py ├── migrations │ ├── __init__.py │ └── 0001_initial.py ├── admin.py └── models.py ├── templates ├── 404.html ├── registration │ ├── logout.html │ ├── registration_form.html │ └── login.html ├── phileo │ └── _script.html └── base.html ├── urls.py ├── manage.py ├── apache └── django.wsgi ├── LICENSE ├── static └── phileo │ └── js │ └── jquery.phileo.js ├── README.rst ├── pathfinder ├── spell-descriptions.py ├── feats.py └── spells.py └── settings.py /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /browse/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /srd20/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encounter/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /srd20/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encounter/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /browse/models.py: -------------------------------------------------------------------------------- 1 | # Added this file because django won't let me run tests otherwise -------------------------------------------------------------------------------- /search/views.py: -------------------------------------------------------------------------------- 1 | import search_site 2 | 3 | search_start = search_site.site.category_search_view() 4 | -------------------------------------------------------------------------------- /browse/static/browse/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmoisset/django-srd20/HEAD/browse/static/browse/img/star.png -------------------------------------------------------------------------------- /browse/static/browse/img/star-dim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmoisset/django-srd20/HEAD/browse/static/browse/img/star-dim.png -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Not found

6 |
7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /encounter/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from encounter.models import Encounter, Participant 3 | 4 | class ParticipantInline(admin.TabularInline): 5 | model = Participant 6 | 7 | class EncounterAdmin(admin.ModelAdmin): 8 | inlines = [ParticipantInline] 9 | 10 | admin.site.register(Encounter, EncounterAdmin) 11 | -------------------------------------------------------------------------------- /search/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | class SearchForm(forms.Form): 4 | SEARCH_TYPES = ( 5 | ('name', 'By Title'), 6 | ('all', 'Full Text Search') 7 | ) 8 | 9 | q = forms.CharField(label='Search', max_length=64) 10 | search_type = forms.ChoiceField(choices=SEARCH_TYPES, widget=forms.RadioSelect, initial='name') 11 | 12 | -------------------------------------------------------------------------------- /browse/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | 3 | urlpatterns = patterns('browse.views', 4 | url(r'^spell/(?P[\w-]+)/$', 'spell_detail', name='spell_detail'), 5 | url(r'^feat/(?P[\w-]+)/$', 'feat_detail', name='feat_detail'), 6 | url(r'^monster/(?P[\w-]+)/$', 'monster_detail', name='monster_detail'), 7 | 8 | url(r'^favorites/$', 'favorites', name='favorite_lists'), 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /templates/registration/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Log out{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 12 | {% endblock %} 13 | 14 | {% block content_title %}

You have been logged out

{% endblock %} 15 | 16 | {% block content %} 17 |
18 | Go back to home 19 |
20 | {% endblock %} 21 | -------------------------------------------------------------------------------- /urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | import browse.urls 3 | import search.search_site 4 | 5 | from django.contrib import admin 6 | admin.autodiscover() 7 | 8 | urlpatterns = patterns('', 9 | (r'^admin/', include(admin.site.urls)), 10 | (r'^browse/', include(browse.urls)), 11 | (r'^$', 'search.views.search_start'), 12 | (r'^search/', include(search.search_site.urls)), 13 | (r'^account/', include('registration.backends.simple.urls')), 14 | (r"^likes/", include("phileo.urls")), 15 | ) 16 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | try: 4 | import settings # Assumed to be in the same directory. 5 | except ImportError: 6 | import sys 7 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 8 | sys.exit(1) 9 | 10 | if __name__ == "__main__": 11 | execute_manager(settings) 12 | -------------------------------------------------------------------------------- /browse/static/browse/css/like.css: -------------------------------------------------------------------------------- 1 | form.phileo { 2 | display: inline; 3 | } 4 | input.phileo-toggle { 5 | border: 0; 6 | padding: 0; 7 | cursor: pointer; 8 | text-indent: -1000em; 9 | width: 20px; 10 | height: 20px; 11 | } 12 | form.phileo.like input.phileo-toggle { 13 | background: url(/static/browse/img/star-dim.png) no-repeat; 14 | background-size: 100%; 15 | } 16 | form.phileo.like.phileo-liked input.phileo-toggle { 17 | background: url(/static/browse/img/star.png) no-repeat; 18 | background-size: 100%; 19 | } 20 | .phileo-count {display: none;} 21 | 22 | -------------------------------------------------------------------------------- /search/templates/search/start.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}d20/SRD Search{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 11 | {% endblock %} 12 | 13 | {% block content_title %}

d20/SRD Search

{% endblock %} 14 | 15 | {% block content %} 16 |
17 |
18 | 19 | {{ form }} 20 |
21 | 22 |
23 |
24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /search/templates/search/search_site_search.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}d20/SRD Search{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 11 | {% endblock %} 12 | 13 | {% block content_title %}

d20/SRD Search

{% endblock %} 14 | 15 | {% block content %} 16 |
17 |
18 | 19 | {{ form }} 20 |
21 | 22 |
23 |
24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /templates/registration/registration_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Create an account{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 12 | {% endblock %} 13 | 14 | {% block content_title %}

Register

{% endblock %} 15 | 16 | {% block content %} 17 |
18 |
19 | {% csrf_token %} 20 | 21 | {{ form }} 22 |
23 | 24 |
25 |
26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Log in{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 12 | {% endblock %} 13 | 14 | {% block content_title %}

Log in

{% endblock %} 15 | 16 | {% block content %} 17 |
18 |
19 | {% csrf_token %} 20 | 21 | {{ form }} 22 |
23 | 24 |
25 | 26 |

Other options

27 | 30 |
31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /apache/django.wsgi: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import site 4 | 5 | BASE_PATH = os.path.join(os.path.dirname(__file__), '..', '..') 6 | vepath= os.path.join(BASE_PATH, 'env', 'lib', 'python2.%d' % sys.version_info[1], 'site-packages') 7 | 8 | prev_sys_path = list(sys.path) 9 | # add the site-packages of our virtualenv as a site dir 10 | site.addsitedir(vepath) 11 | # add the app's directory to the PYTHONPATH 12 | sys.path.append(BASE_PATH) 13 | sys.path.append(os.path.join(BASE_PATH, 'django_srd20')) 14 | 15 | new_sys_path = [p for p in sys.path if p not in prev_sys_path] 16 | for item in new_sys_path: 17 | sys.path.remove(item) 18 | sys.path[:0] = new_sys_path 19 | 20 | os.environ['DJANGO_SETTINGS_MODULE'] = 'django_srd20.settings' 21 | 22 | import django.core.handlers.wsgi 23 | application = django.core.handlers.wsgi.WSGIHandler() 24 | 25 | -------------------------------------------------------------------------------- /templates/phileo/_script.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /search/templates/search/results.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}{% if query %}{{ query }} — {% endif %}Search Results{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 12 | {% endblock %} 13 | 14 | {% block content_title %}

Search results{% if query %} for '{{ query }}'{% endif %}

{% endblock %} 15 | 16 | {% block content %} 17 |
18 | 19 | {{ form }} 20 |
21 | 22 |
23 | 24 |
    25 | {% for r in results %} 26 |
  • {{ r }}: {{ r.short_description|safe }}
  • 27 | {% empty %} 28 | No results found 29 | {% endfor %} 30 |
31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /browse/static/browse/img/_readme_free.txt: -------------------------------------------------------------------------------- 1 | THANK YOU FOR USING GLYPHICONS! 2 | 3 | If you would like to be among the first ones to hear about all the news, follow @glyphicons on Twitter. 4 | 5 | LICENSE: 6 | ------------------- 7 | GLYPHICONS FREE are released under Creative Commons Attribution 3.0 Unported (CC BY 3.0). GLYPHICONS can be used both commercially and for personal use, but you must always add a link to www.glyphicons.com. You must not resell any icons or distribute them in any other way than referring to www.glyphicons.com. The Icons as such are the property of the author. The Icons cannot be placed on any other website or downloadable format. 8 | 9 | All logos and trademarks in social icons are the property of the respective trademark owners.® 10 | 11 | CONTACT: 12 | ------------------- 13 | Web: http://glyphicons.com/ 14 | Email: glyphicons@gmail.com 15 | Twitter: http://twitter.com/glyphicons 16 | 17 | If you want to use the icons without restrictions, please buy any version on www.glyphicons.com, thank you. 18 | 19 | Jan Kovařík 20 | -------------------------------------------------------------------------------- /srd20/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from .models import Spell 3 | 4 | class SpellModelTest(TestCase): 5 | fixtures = ['srd.json'] 6 | 7 | def test_absolute_url(self): 8 | """Checks that get_absolute_url produces an URL that works""" 9 | spell = Spell.objects.get(id=1) 10 | url = spell.get_absolute_url() 11 | response = self.client.get(url) 12 | self.assertEqual(200, response.status_code) 13 | 14 | def test_absolute_url_unique(self): 15 | """Checks that get_absolute_url returns different URLs for different objects""" 16 | spell1 = Spell.objects.get(id=1) 17 | spell2 = Spell.objects.get(id=2) 18 | url1 = spell1.get_absolute_url() 19 | url2 = spell2.get_absolute_url() 20 | self.assertNotEqual(url1, url2) 21 | 22 | def test_unicode_unique(self): 23 | """Checks that __unicode__ returns different values for different objects""" 24 | spell1 = Spell.objects.get(id=1) 25 | spell2 = Spell.objects.get(id=2) 26 | u1 = unicode(spell1) 27 | u2 = unicode(spell2) 28 | self.assertNotEqual(u1, u2) 29 | 30 | 31 | -------------------------------------------------------------------------------- /search/templates/search/results_site_search.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}{% if query %}{{ query }} — {% endif %}Search Results{% endblock %} 4 | 5 | {% block bodyclass %}flex{% endblock %} 6 | 7 | {% block breadcrumbs %} 8 | 12 | {% endblock %} 13 | 14 | {% block content_title %}

Search results{% if query %} for '{{ query }}'{% endif %}

{% endblock %} 15 | 16 | {% block content %} 17 |
18 |
19 | 20 | {{ form }} 21 |
22 | 23 |
24 | 25 | {% for category,items in results %} 26 | {% if items %} 27 |

{{ category.verbose_name|title }}

28 |
    29 | {% for r in items %} 30 |
  • {{ r }}: {{ r.short_description|safe }}
  • 31 | {% endfor %} 32 |
33 | {% endif %} 34 | {% empty %} 35 | No results found 36 | {% endfor %} 37 |
38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /search/search_site.py: -------------------------------------------------------------------------------- 1 | from django_search_views.search import SearchCategory, Search 2 | 3 | from srd20.models import Spell, Feat, Monster 4 | 5 | # These are the fields searched by the full text search 6 | SEARCH_FIELDS = ( 7 | 'name', 8 | 'altname', 9 | 'short_description', 10 | 'description', 11 | 'school', 12 | 'subschool', 13 | 'descriptor', 14 | 'material_components', 15 | 'reference', 16 | ) 17 | 18 | 19 | class SpellByName(SearchCategory): 20 | model = Spell 21 | lookups = ['name__icontains'] 22 | def verbose_name(self): return u'spells' 23 | 24 | class SpellFullText(SearchCategory): 25 | model = Spell 26 | lookups = [field+'__icontains' for field in SEARCH_FIELDS] 27 | def verbose_name(self): return u'spells (full text)' 28 | 29 | class FeatByName(SearchCategory): 30 | model = Feat 31 | lookups = ['name__icontains'] 32 | def verbose_name(self): return u'feats' 33 | 34 | class MonsterByName(SearchCategory): 35 | model = Monster 36 | lookups = ['name__icontains'] 37 | def verbose_name(self): return u'monsters' 38 | 39 | class SiteSearch(Search): 40 | categories = [SpellByName, SpellFullText, FeatByName, MonsterByName] 41 | 42 | site = SiteSearch() 43 | urls = site.urls() 44 | 45 | -------------------------------------------------------------------------------- /encounter/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class Encounter(models.Model): 4 | name = models.CharField(max_length=255) 5 | current_round = models.PositiveIntegerField(default=0) 6 | current_initiative = models.IntegerField(default=999) 7 | notes = models.TextField(blank=True) 8 | # participants = reverse from Participant.encounter 9 | #treasure = models.TextField(blank=True) 10 | 11 | def __unicode__(self): 12 | return self.name 13 | 14 | def current_actors(self): 15 | """The list of actors in the current initiative""" 16 | return self.participants.filter(initiative=self.current_initiative) 17 | 18 | class Participant(models.Model): 19 | encounter = models.ForeignKey(Encounter, related_name='participants') 20 | label = models.CharField(max_length=32) 21 | current_hp = models.IntegerField(blank=True, null=True) 22 | initiative = models.IntegerField(blank=True, null=True) 23 | notes = models.TextField(blank=True) 24 | #stats = ... 25 | #conditions = [(Condition, final_round, final_initiative)] 26 | 27 | #class ParticipantCondition 28 | # who = Participant 29 | # what = Condition 30 | # until_round = int 31 | # until_initiative = int 32 | # notes = ... 33 | 34 | 35 | #class Condition: 36 | # affects_defense = True 37 | # affects_offense = True 38 | # can_act = True 39 | 40 | -------------------------------------------------------------------------------- /browse/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import get_object_or_404, render_to_response 2 | from django.template import RequestContext 3 | from django.views.generic import TemplateView 4 | 5 | from srd20.models import Spell, Feat, Monster 6 | 7 | def spell_detail(request, slug): 8 | spell = get_object_or_404(Spell, altname=slug) 9 | return render_to_response('browse/spell.html', 10 | { 11 | 'spell': spell, 12 | 'editable': request.user.has_perm('srd20.change_spell'), 13 | }, 14 | context_instance=RequestContext(request) 15 | ) 16 | 17 | 18 | def feat_detail(request, slug): 19 | feat = get_object_or_404(Feat, altname=slug) 20 | return render_to_response('browse/feat.html', 21 | { 22 | 'feat': feat, 23 | 'editable': request.user.has_perm('srd20.change_feat'), 24 | }, 25 | context_instance=RequestContext(request) 26 | ) 27 | 28 | def monster_detail(request, slug): 29 | monster = get_object_or_404(Monster, altname=slug) 30 | return render_to_response('browse/monster.html', 31 | { 32 | 'monster': monster, 33 | 'editable': request.user.has_perm('srd20.change_monster'), 34 | }, 35 | context_instance=RequestContext(request) 36 | ) 37 | 38 | class Favorites(TemplateView): 39 | template_name = "browse/favorites.html" 40 | 41 | favorites = Favorites.as_view() 42 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base.html" %} 2 | 3 | {% block title %}SRD/d20 browser{% endblock title%} 4 | 5 | {% block extrastyle %} 6 | 7 | {% endblock %} 8 | 9 | {% block bodyclass %}dashboard{% endblock %} 10 | 11 | {% block coltype %}colSM{% endblock %} 12 | 13 | {% block branding %} 14 |

SRD/d20 browser

15 | {% endblock %} 16 | 17 | {% block nav-global %}{% if not user.is_active or not user.is_staff %} 18 |
19 | {% if not user.is_authenticated %}Log in{% else %}Welcome {{user}} | Logout {% endif%} |
Search:
20 |
21 | {% endif %}{% endblock %} 22 | 23 | {% block userlinks %} 24 | {{ block.super }} |
Search:
25 | {% endblock %} 26 | 27 | {% block sidebar %} 28 | {% if user.is_authenticated %} 29 | 35 | {% endif %} 36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Daniel F. Moisset and individual contributors. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of SRD20 nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /static/phileo/js/jquery.phileo.js: -------------------------------------------------------------------------------- 1 | jQuery(function($) { 2 | 3 | var PhileoLikes = function(form, options) { 4 | this.options = $.extend({}, $.fn.phileo.defaults, options); 5 | this.$form = $(form); 6 | 7 | this.$count = $(this.options.count); 8 | 9 | var self = this; 10 | this.$form.submit(function(event) { 11 | event.preventDefault(); 12 | 13 | $.ajax({ 14 | url: self.$form.attr('action'), 15 | type: "POST", 16 | data: self.$form.serialize(), 17 | success: function(data, textStatus, jqXHR) { 18 | self.$form[data.liked ? 'addClass' : 'removeClass'](self.options.toggle_class); 19 | var submit = self.$form.find("input[type=submit]"); 20 | submit.val(data.liked ? submit.attr("data-unlike-text") : submit.attr("data-like-text")); 21 | var count_text = (data.likes_count > 1 || data.likes_count == 0) ? self.$count.attr("data-counts-text-plural") : self.$count.attr("data-counts-text") 22 | self.$count.text(data.likes_count + " " + count_text); 23 | } 24 | }); 25 | }); 26 | }; 27 | 28 | $.fn.phileo = function(options) { 29 | $(this).each(function(i, el) { 30 | var phileo = new PhileoLikes(el, options); 31 | $(el).data('Phileo', {instance: phileo}); 32 | }); 33 | return this; 34 | }; 35 | 36 | $.fn.phileo.defaults = { 37 | toggle_class: 'phileo-liked', 38 | count: false 39 | }; 40 | }); 41 | -------------------------------------------------------------------------------- /browse/templates/browse/favorites.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load phileo_tags %} 4 | 5 | {% block title %}Favorites{% endblock %} 6 | 7 | {% block bodyclass %}flex{% endblock %} 8 | 9 | {% block breadcrumbs %} 10 | 14 | {% endblock %} 15 | 16 | {% block content_title %}

Favorites for {{ user.username }}

{% endblock %} 17 | 18 | {% block content %} 19 |
20 | 21 |

Feats

22 | 23 | {% likes user "srd20.Feat" as like_list %} 24 | 25 |
    26 | {% for l in like_list %} 27 |
  • {{ l.receiver }}: {{ l.receiver.short_description }}
  • 28 | {% empty %} 29 |
  • No favorite feats
  • 30 | {% endfor %} 31 |
32 | 33 |

Spells

34 | 35 | {% likes user "srd20.Spell" as like_list %} 36 | 37 |
    38 | {% for l in like_list %} 39 |
  • {{ l.receiver }}: {{ l.receiver.short_description }}
  • 40 | {% empty %} 41 |
  • No favorite spells
  • 42 | {% endfor %} 43 |
44 | 45 | {% likes user "srd20.Monster" as like_list %} 46 | 47 |

Monsters

48 | 49 |
    50 | {% for l in like_list %} 51 |
  • {{ l.receiver }}: {{ l.receiver.short_description }}
  • 52 | {% empty %} 53 |
  • No favorite monsters
  • 54 | {% endfor %} 55 |
56 | 57 |
58 | {% endblock %} 59 | 60 | 61 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | This software is a browser for D20 system data. 2 | 3 | This is capable of using Open Game Content licensed SRD data, and custom 4 | personal data. 5 | 6 | Requirements 7 | ============ 8 | 9 | * Python 2.6 or a higher version of Python 2.x 10 | * Django 1.2 11 | * Django South 0.7.x (tested with 0.7.3) 12 | * Some database engine supported by Django (SQLite3 used in the default config) 13 | 14 | Quick start instructions 15 | ======================== 16 | 17 | The following instructions are for installing and deploying locally. If you 18 | need to install this in a public server read the Django documentation about 19 | deploying Django sites. 20 | 21 | Install the requirements, and virtualenv. virtualenv is not a requirement, but 22 | it is a good idea to have. Then run the following commands:: 23 | 24 | virtualenv --no-site-packages srd20 25 | source srd20/bin/activate 26 | cd srd20 27 | easy_install django south 28 | git clone https://github.com/machinalis/django-srd20.git django_srd20 29 | cd django_srd20 30 | 31 | At this point you can customize settings.py or add a local_settings.py; but 32 | the defaults should work. 33 | 34 | The first time you should should setup the database in the following way:: 35 | 36 | ./manage.py syncdb # This will ask for an admin password 37 | ./manage migrate 38 | 39 | Doing this again later won't break anything, but is not required. You can also 40 | load some of the provided OGL licensed content into the database with the 41 | following command:: 42 | 43 | ./manage.py loaddata srd20/fixtures/srd.json 44 | 45 | To run a development server that you can access with a web browser:: 46 | 47 | ./manage runserver 48 | 49 | While the above is running (until interrupting with CTRL+C) you can point a 50 | browser to http://127.0.0.1:8000/ and use the application 51 | 52 | -------------------------------------------------------------------------------- /pathfinder/spell-descriptions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | # Importer for spell description. This is separate from the spell 5 | # importer because descriptions are only on the spell lists 6 | # This outputs a csv with two columns: slug and description 7 | 8 | import sys, os, csv 9 | from pyquery import PyQuery as Q 10 | import lxml.etree 11 | 12 | def pqiter(pq): 13 | """ 14 | Iterator on a PyQuery object that produces PyQuery objects, instead 15 | of plain XML elements 16 | """ 17 | index = 0 18 | while index < len(pq): 19 | yield pq.eq(index) 20 | index += 1 21 | 22 | # Iterate over input files 23 | output = csv.writer(sys.stdout) 24 | for filename in sys.argv[1:]: 25 | list_html = Q(filename=filename, parser='html') 26 | spells = list_html("#body p b a") 27 | 28 | for s in pqiter(spells): 29 | target = s.attr('href') 30 | try: 31 | target = target.split('#')[1] 32 | except IndexError: 33 | target = os.path.basename(target) 34 | sys.stderr.write("Looking up rename for %s\n" % target) 35 | target = { 36 | 'deathwatch.html': '_deathwatch', 37 | 'fly.html': '_fly', 38 | 'fogCloud.html': '_fog-cloud', 39 | }[target] 40 | if target.startswith('_'): 41 | target = target[1:] 42 | target = target.replace(',', '') # Remove commas (usde in ", mass" ", greater", etc) 43 | 44 | desc_elem = s[0].getparent() 45 | description = desc_elem.tail or '' 46 | while desc_elem.getnext() is not None: 47 | desc_elem = desc_elem.getnext() 48 | description += lxml.etree.tostring(desc_elem) 49 | 50 | description = description.split(':')[1].strip() 51 | output.writerow([target.encode('utf-8'), description.encode('utf-8')]) 52 | -------------------------------------------------------------------------------- /browse/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from django.contrib.auth.models import User, Permission 3 | 4 | class BrowseTest(TestCase): 5 | fixtures = ['srd.json'] 6 | 7 | def test_get(self): 8 | response = self.client.get('/browse/spell/alarm/') 9 | # Check that we got a result 10 | self.assertEqual(200, response.status_code) 11 | # Check that the requested spellwas in the context 12 | self.assertEqual('alarm', response.context['spell'].altname) 13 | 14 | def test_get_complex_slug(self): 15 | """This test intended to check that the slug regex is OK and works with dashes and uppercase""" 16 | response = self.client.get('/browse/spell/summon-natures-ally-VI/') 17 | self.assertEqual(200, response.status_code) 18 | self.assertEqual('summon-natures-ally-VI', response.context['spell'].altname) 19 | 20 | def test_get_404(self): 21 | response = self.client.get('/browse/spell/does-not-exist/') 22 | # Check that we got a 404 result 23 | self.assertEqual(404, response.status_code) 24 | 25 | def test_anonymous_cant_edit(self): 26 | response = self.client.get('/browse/spell/alarm/') 27 | self.assertEqual(200, response.status_code) 28 | self.assertEqual(False, response.context['editable']) 29 | 30 | def test_authenticated_cantedit(self): 31 | authenticated, _ = User.objects.get_or_create( 32 | username='testuser', 33 | password='*', 34 | is_staff=True 35 | ) 36 | authenticated.set_password('test') 37 | authenticated.user_permissions.add(Permission.objects.get(codename='change_spell', content_type__app_label='srd20')) 38 | authenticated.save() 39 | self.client.login(username='testuser',password='test') 40 | response = self.client.get('/browse/spell/alarm/') 41 | self.assertEqual(200, response.status_code) 42 | self.assertEqual(True, response.context['editable']) 43 | 44 | -------------------------------------------------------------------------------- /srd20/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from srd20.models import Spell, Feat, CharacterClass, Monster, MonsterAbility 3 | 4 | class SpellAdmin(admin.ModelAdmin): 5 | list_display = ('name', 'level', 'short_description') 6 | list_filter = ('school',) 7 | search_fields = ('name',) 8 | prepopulated_fields = {'altname': ('name',)} 9 | 10 | fieldsets = ( 11 | (None, { 12 | 'fields': ('name', 'altname', ('school', 'subschool'), 'descriptor', 'level', 'reference') 13 | }), 14 | ('Properties', { 15 | 'fields': ('components', 'range', ('target', 'area', 'effect'), 'duration', 'saving_throw', 'spell_resistance') 16 | }), 17 | ('Epic requirements', { 18 | 'fields': ('spellcraft_dc', 'to_develop'), 19 | 'classes': ("collapse",) 20 | }), 21 | ('Description', { 22 | 'fields': ('short_description', 'description', 'verbal_components', 23 | 'material_components', 'arcane_material_components', 'focus', 24 | 'arcane_focus', 'cleric_focus', 'druid_focus','xp_cost') 25 | }), 26 | ) 27 | 28 | class FeatAdmin(admin.ModelAdmin): 29 | list_display = ('name', 'type') 30 | list_filter = ('type',) 31 | search_fields = ('name',) 32 | prepopulated_fields = {'altname': ('name',)} 33 | 34 | fieldsets = ( 35 | (None, { 36 | 'fields': ('name', 'altname', 'type', ('multiple', 'stack'), 'prerequisite', 'choice') 37 | }), 38 | ('Description', { 39 | 'fields': ('benefit', 'normal', 'special') 40 | }), 41 | ('Source', { 42 | 'fields': ('reference',), 43 | }), 44 | ) 45 | 46 | class MonsterAbilityInline(admin.TabularInline): 47 | model = MonsterAbility 48 | 49 | class MonsterAdmin(admin.ModelAdmin): 50 | list_display = ('name', 'alignment', 'size', 'type', 'environment', 'cr') 51 | list_filter = ('cr', 'type', 'size', 'alignment', 'reference') 52 | search_fields = ('name',) 53 | inlines = [MonsterAbilityInline] 54 | 55 | admin.site.register(Spell, SpellAdmin) 56 | admin.site.register(Feat, FeatAdmin) 57 | admin.site.register(Monster, MonsterAdmin) 58 | admin.site.register(CharacterClass) 59 | 60 | -------------------------------------------------------------------------------- /browse/templates/browse/feat.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load phileo_tags %} 4 | 5 | {% block extrastyle %} 6 | {{ block.super }} 7 | {% phileo_css %} 8 | 9 | {% endblock %} 10 | {% block extrahead %} 11 | {{ block.super }} 12 | 13 | {% phileo_js %} 14 | {% endblock %} 15 | 16 | {% block title %}{{ feat.name }} | Feat description{% endblock %} 17 | 18 | {% block bodyclass %}flex{% endblock %} 19 | 20 | {% block breadcrumbs %} 21 | 25 | {% endblock %} 26 | 27 | {% block content_title %}

{{ feat }} {% phileo_widget user feat %}

{% endblock %} 28 | 29 | {% block content %} 30 |
31 | 32 | {% phileo_widget_js user feat %} 33 | 34 | {% if editable %} 35 |

36 | [edit] 37 |

38 | {% endif %} 39 | 40 |

{{ feat.type }}

41 | 42 | {{ feat.description|safe }} 43 | 44 |

Benefit:{{ feat.benefit|safe }}

45 | 46 | {% if feat.normal %} 47 |

Normal: {{ feat.normal|safe }}

48 | {% endif %} 49 | {% if feat.special %} 50 |

Special: {{ feat.special|safe }}

51 | {% endif %} 52 | 53 |
54 | {% endblock %} 55 | 56 | {% block sidebar %} 57 | 84 | {% endblock %} 85 | -------------------------------------------------------------------------------- /encounter/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding model 'Encounter' 12 | db.create_table('encounter_encounter', ( 13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), 15 | ('current_round', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), 16 | ('current_initiative', self.gf('django.db.models.fields.IntegerField')(default=999)), 17 | ('notes', self.gf('django.db.models.fields.TextField')(blank=True)), 18 | )) 19 | db.send_create_signal('encounter', ['Encounter']) 20 | 21 | # Adding model 'Participant' 22 | db.create_table('encounter_participant', ( 23 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 24 | ('encounter', self.gf('django.db.models.fields.related.ForeignKey')(related_name='participants', to=orm['encounter.Encounter'])), 25 | ('label', self.gf('django.db.models.fields.CharField')(max_length=32)), 26 | ('current_hp', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), 27 | ('initiative', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)), 28 | ('notes', self.gf('django.db.models.fields.TextField')(blank=True)), 29 | )) 30 | db.send_create_signal('encounter', ['Participant']) 31 | 32 | 33 | def backwards(self, orm): 34 | 35 | # Deleting model 'Encounter' 36 | db.delete_table('encounter_encounter') 37 | 38 | # Deleting model 'Participant' 39 | db.delete_table('encounter_participant') 40 | 41 | 42 | models = { 43 | 'encounter.encounter': { 44 | 'Meta': {'object_name': 'Encounter'}, 45 | 'current_initiative': ('django.db.models.fields.IntegerField', [], {'default': '999'}), 46 | 'current_round': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), 47 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 48 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 49 | 'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 50 | }, 51 | 'encounter.participant': { 52 | 'Meta': {'object_name': 'Participant'}, 53 | 'current_hp': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), 54 | 'encounter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'participants'", 'to': "orm['encounter.Encounter']"}), 55 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 56 | 'initiative': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), 57 | 'label': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 58 | 'notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 59 | } 60 | } 61 | 62 | complete_apps = ['encounter'] 63 | -------------------------------------------------------------------------------- /pathfinder/feats.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | import sys 5 | import json 6 | from pyquery import PyQuery as Q 7 | 8 | def pqiter(pq): 9 | """ 10 | Iterator on a PyQuery object that produces PyQuery objects, instead 11 | of plain XML elements 12 | """ 13 | index = 0 14 | while index < len(pq): 15 | yield pq.eq(index) 16 | index += 1 17 | 18 | def normalize_attribute(attr): 19 | """ 20 | Normalizes the name of an attribute which is spelled in slightly different 21 | ways in paizo HTMLs 22 | """ 23 | attr = attr.strip() 24 | if attr.endswith(':'): 25 | attr = attr[:-1] # Remove trailing ':' if any 26 | if attr == 'Prerequisites': 27 | attr = 'Prerequisite' # Normalize 28 | if attr == 'Note': 29 | attr = 'Prerequisite' # Normalize a very special case (Versatile Channeler) 30 | if attr == 'Benefits': 31 | attr = 'Benefit' # Normalize 32 | if attr == 'Leadership Modifiers': 33 | attr = 'Benefit' # Normalize a very special case (Leadership) 34 | assert attr in ('Prerequisite', 'Benefit', 'Normal', 'Special') 35 | return attr.lower() 36 | 37 | # Iterate over input files 38 | result = [] 39 | for filename in sys.argv[1:]: 40 | feats_html = Q(filename=filename, parser='html') 41 | feats = feats_html("#feats-text h2") 42 | 43 | for f in pqiter(feats): 44 | slug = f.attr('id') 45 | if '-(' in slug: 46 | # Some id's include descriptors. remove them 47 | slug = slug.split('-(')[0] 48 | title = f[0].text_content().strip() # Use this instead of html() to remove embedded links 49 | descriptors = [] 50 | attributes = {} 51 | if '(' in title: 52 | title, descriptors = title.split('(') 53 | title = title.strip() 54 | assert descriptors.endswith(')') 55 | descriptors = descriptors[:-1] # Remove ending ')' 56 | descriptors = [d.strip() for d in descriptors.split(',')] 57 | label = 'description' 58 | p = f.next('*') 59 | while p and p[0].tag != 'h2': 60 | attrname = p.children('b') 61 | if attrname: 62 | label = normalize_attribute(attrname.html()) 63 | attrname.remove() 64 | html = p.outerHtml() 65 | if label in ('description', 'prerequisite'): 66 | if p[0].tag in ('p',): 67 | html = p.html() 68 | else: 69 | sys.stderr.write(u"Skipping tag <%s> in %s['%s']\n" % (p[0].tag, title, label)) 70 | html = u'' 71 | attributes[label] = attributes.get(label, u'') + html 72 | p = p.next('*') 73 | result.append({ 74 | "model": "srd20.feat", 75 | "pk": len(result), 76 | "fields": { 77 | "name": title, 78 | "altname": slug, 79 | "type": ', '.join(descriptors), 80 | "multiple": False, # info not parseable 81 | "stack": False, # info not parseable 82 | "choice": "", # info not parseable 83 | "prerequisite": attributes.get('prerequisite', ''), 84 | "benefit": attributes.get('benefit', ''), 85 | "normal": attributes.get('normal', ''), 86 | "special": attributes.get('special', ''), 87 | "reference": filename, 88 | "description": attributes.get('description', ''), 89 | } 90 | }) 91 | 92 | print json.dumps(result, ensure_ascii=False, indent=4).encode('utf-8') 93 | 94 | -------------------------------------------------------------------------------- /srd20/migrations/0006_auto__del_field_spell_full_text.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Deleting field 'Spell.full_text' 12 | db.delete_column('spell', 'full_text') 13 | 14 | 15 | def backwards(self, orm): 16 | 17 | # Adding field 'Spell.full_text' 18 | db.add_column('spell', 'full_text', self.gf('django.db.models.fields.TextField')(default='No full text'), keep_default=False) 19 | 20 | 21 | models = { 22 | 'srd20.spell': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 25 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 26 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 27 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 28 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 29 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 30 | 'components': ('django.db.models.fields.TextField', [], {}), 31 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 32 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 33 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 34 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 35 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 36 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 37 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 38 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 39 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 40 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 41 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 42 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 43 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 44 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 45 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 46 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 47 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 49 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 51 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 52 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 53 | } 54 | } 55 | 56 | complete_apps = ['srd20'] 57 | -------------------------------------------------------------------------------- /srd20/migrations/0007_auto__chg_field_spell_components.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Spell.components' 12 | db.alter_column('spell', 'components', self.gf('django.db.models.fields.CharField')(max_length=64)) 13 | 14 | 15 | def backwards(self, orm): 16 | 17 | # Changing field 'Spell.components' 18 | db.alter_column('spell', 'components', self.gf('django.db.models.fields.TextField')()) 19 | 20 | 21 | models = { 22 | 'srd20.spell': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 25 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 26 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 27 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 28 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 29 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 30 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 31 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 32 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 33 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 34 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 35 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 36 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 37 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 38 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 39 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 40 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 41 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 42 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 43 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 44 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 45 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 46 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 47 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 49 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 51 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 52 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 53 | } 54 | } 55 | 56 | complete_apps = ['srd20'] 57 | -------------------------------------------------------------------------------- /srd20/migrations/0005_auto__chg_field_spell_altname.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Spell.altname' 12 | db.alter_column('spell', 'altname', self.gf('django.db.models.fields.SlugField')(max_length=64)) 13 | 14 | # Adding index on 'Spell', fields ['altname'] 15 | db.create_index('spell', ['altname']) 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Removing index on 'Spell', fields ['altname'] 21 | db.delete_index('spell', ['altname']) 22 | 23 | # Changing field 'Spell.altname' 24 | db.alter_column('spell', 'altname', self.gf('django.db.models.fields.CharField')(max_length=64)) 25 | 26 | 27 | models = { 28 | 'srd20.spell': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 30 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 31 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 32 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 33 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 34 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 35 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 36 | 'components': ('django.db.models.fields.TextField', [], {}), 37 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 38 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 39 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 40 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 41 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 42 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 43 | 'full_text': ('django.db.models.fields.TextField', [], {}), 44 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 45 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 46 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 47 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 48 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 49 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 50 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 51 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 52 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 53 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 54 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 55 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 56 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'to_develop': ('django.db.models.fields.TextField', [], {}), 58 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 60 | } 61 | } 62 | 63 | complete_apps = ['srd20'] 64 | -------------------------------------------------------------------------------- /srd20/migrations/0004_altname_to_slug.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import DataMigration 5 | from django.db import models 6 | 7 | class Migration(DataMigration): 8 | 9 | def forwards(self, orm): 10 | def charmap(ch): 11 | if ch in ' /': return '-' 12 | if ch.isalnum(): return ch 13 | return '' 14 | for s in orm.Spell.objects.all(): 15 | s.altname = ''.join(charmap(ch) for ch in s.altname) 16 | s.save() 17 | 18 | 19 | def backwards(self, orm): 20 | for s in orm.Spell.objects.all(): 21 | # Generate altname from name 22 | name = s.name 23 | if ', ' in name: 24 | # Lesser Vigor, Mass -> mass lesser vigor 25 | base, modifier = name.split(', ', 1) 26 | name = "%s %s" % (modifier, base) 27 | s.altname = name.lower() 28 | s.save() 29 | 30 | models = { 31 | 'srd20.spell': { 32 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 33 | 'altname': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 34 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 35 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 36 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 37 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 38 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 39 | 'components': ('django.db.models.fields.TextField', [], {}), 40 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 42 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 44 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 46 | 'full_text': ('django.db.models.fields.TextField', [], {}), 47 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 48 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 49 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 50 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 51 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 52 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 53 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 54 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 55 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 56 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 57 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 58 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 59 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 60 | 'to_develop': ('django.db.models.fields.TextField', [], {}), 61 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 62 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 63 | } 64 | } 65 | 66 | complete_apps = ['srd20'] 67 | -------------------------------------------------------------------------------- /srd20/migrations/0003_auto__del_field_spell_sorcerer_focus__del_field_spell_wizard_focus__de.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Deleting field 'Spell.sorcerer_focus' 12 | db.delete_column('spell', 'sorcerer_focus') 13 | 14 | # Deleting field 'Spell.wizard_focus' 15 | db.delete_column('spell', 'wizard_focus') 16 | 17 | # Deleting field 'Spell.bard_focus' 18 | db.delete_column('spell', 'bard_focus') 19 | 20 | 21 | def backwards(self, orm): 22 | 23 | # Adding field 'Spell.sorcerer_focus' 24 | db.add_column('spell', 'sorcerer_focus', self.gf('django.db.models.fields.CharField')(default='', max_length=256, blank=True), keep_default=False) 25 | 26 | # Adding field 'Spell.wizard_focus' 27 | db.add_column('spell', 'wizard_focus', self.gf('django.db.models.fields.CharField')(default='', max_length=256, blank=True), keep_default=False) 28 | 29 | # Adding field 'Spell.bard_focus' 30 | db.add_column('spell', 'bard_focus', self.gf('django.db.models.fields.CharField')(default='', max_length=256, blank=True), keep_default=False) 31 | 32 | 33 | models = { 34 | 'srd20.spell': { 35 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 36 | 'altname': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 37 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 38 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 39 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 40 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 41 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 42 | 'components': ('django.db.models.fields.TextField', [], {}), 43 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 44 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 45 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 46 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 47 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 48 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 49 | 'full_text': ('django.db.models.fields.TextField', [], {}), 50 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 51 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 52 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 53 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 54 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 55 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 56 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 57 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 58 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 59 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 60 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 61 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 62 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 63 | 'to_develop': ('django.db.models.fields.TextField', [], {}), 64 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 66 | } 67 | } 68 | 69 | complete_apps = ['srd20'] 70 | -------------------------------------------------------------------------------- /srd20/migrations/0002_update_arcane_focus.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import DataMigration 5 | from django.db import models 6 | 7 | from srd20.models import Spell 8 | 9 | class Migration(DataMigration): 10 | 11 | def forwards(self, orm): 12 | for s in orm.Spell.objects.exclude(wizard_focus=''): 13 | assert s.wizard_focus == s.sorcerer_focus 14 | assert s.wizard_focus == s.bard_focus 15 | s.arcane_focus = s.wizard_focus 16 | s.wizard_focus = '' 17 | s.sorcerer_focus = '' 18 | s.bard_focus = '' 19 | s.save() 20 | assert not orm.Spell.objects.exclude(wizard_focus='') 21 | assert not orm.Spell.objects.exclude(sorcerer_focus='') 22 | assert not orm.Spell.objects.exclude(bard_focus='') 23 | 24 | def backwards(self, orm): 25 | pass 26 | # This could copy the arcane field to wizard/sorcerer/bard _focus 27 | # on the scrying spells. But I can't find the reason to revert this 28 | # migration 29 | 30 | 31 | models = { 32 | 'srd20.spell': { 33 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 34 | 'altname': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 35 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 36 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 37 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 38 | 'bard_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 39 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 40 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 41 | 'components': ('django.db.models.fields.TextField', [], {}), 42 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 43 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 44 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 46 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 47 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 48 | 'full_text': ('django.db.models.fields.TextField', [], {}), 49 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 50 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 51 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 52 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 53 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 54 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 55 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 56 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 57 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 58 | 'sorcerer_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 60 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 61 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 62 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 63 | 'to_develop': ('django.db.models.fields.TextField', [], {}), 64 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'wizard_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 66 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 67 | } 68 | } 69 | 70 | complete_apps = ['srd20'] 71 | -------------------------------------------------------------------------------- /settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for django_srd20 project. 2 | 3 | import os, os.path 4 | 5 | DEBUG = True 6 | TEMPLATE_DEBUG = DEBUG 7 | 8 | ADMINS = ( 9 | ('Daniel F Moisset', 'dmoisset@machinalis.com'), 10 | ) 11 | 12 | MANAGERS = ADMINS 13 | 14 | DATABASES = { 15 | 'default': { 16 | 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 17 | 'NAME': 'dnd35.db', # Or path to database file if using sqlite3. 18 | 'USER': '', # Not used with sqlite3. 19 | 'PASSWORD': '', # Not used with sqlite3. 20 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 21 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 22 | } 23 | } 24 | 25 | # Local time zone for this installation. Choices can be found here: 26 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 27 | # although not all choices may be available on all operating systems. 28 | # On Unix systems, a value of None will cause Django to use the same 29 | # timezone as the operating system. 30 | # If running in a Windows environment this must be set to the same as your 31 | # system time zone. 32 | TIME_ZONE = 'America/Chicago' 33 | 34 | # Language code for this installation. All choices can be found here: 35 | # http://www.i18nguy.com/unicode/language-identifiers.html 36 | LANGUAGE_CODE = 'en-us' 37 | 38 | SITE_ID = 1 39 | 40 | # If you set this to False, Django will make some optimizations so as not 41 | # to load the internationalization machinery. 42 | USE_I18N = True 43 | 44 | # If you set this to False, Django will not format dates, numbers and 45 | # calendars according to the current locale 46 | USE_L10N = True 47 | 48 | # Absolute filesystem path to the directory that will hold user-uploaded files. 49 | # Example: "/home/media/media.lawrence.com/" 50 | MEDIA_ROOT = '' 51 | 52 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 53 | # trailing slash if there is a path component (optional in other cases). 54 | # Examples: "http://media.lawrence.com", "http://example.com/media/" 55 | MEDIA_URL = '' 56 | 57 | PROJECT_ROOT = os.path.dirname(__file__) 58 | STATIC_URL = '/static/' 59 | STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static') 60 | STATICFILES_FINDERS = ( 61 | 'django.contrib.staticfiles.finders.FileSystemFinder', 62 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 63 | ) 64 | 65 | # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 66 | # trailing slash. 67 | # Examples: "http://foo.com/media/", "/media/". 68 | ADMIN_MEDIA_PREFIX = '/static/admin/' 69 | 70 | # Make this unique, and don't share it with anybody. 71 | SECRET_KEY = 'j%k#s%ujh58ilj*#v+ks15(&v=b9hgl3yk4fgs!+&mll@e7n+p' 72 | 73 | # List of callables that know how to import templates from various sources. 74 | TEMPLATE_LOADERS = ( 75 | 'django.template.loaders.filesystem.Loader', 76 | 'django.template.loaders.app_directories.Loader', 77 | # 'django.template.loaders.eggs.Loader', 78 | ) 79 | 80 | MIDDLEWARE_CLASSES = ( 81 | 'django.middleware.common.CommonMiddleware', 82 | 'django.contrib.sessions.middleware.SessionMiddleware', 83 | 'django.middleware.csrf.CsrfViewMiddleware', 84 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 85 | 'django.contrib.messages.middleware.MessageMiddleware', 86 | ) 87 | 88 | ROOT_URLCONF = 'django_srd20.urls' 89 | 90 | TEMPLATE_DIRS = ( 91 | os.path.join(os.path.dirname(__file__), 'templates'), 92 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 93 | # Always use forward slashes, even on Windows. 94 | # Don't forget to use absolute paths, not relative paths. 95 | ) 96 | 97 | LOGIN_REDIRECT_URL = '/' 98 | 99 | PHILEO_LIKABLE_MODELS = [ 100 | "srd20.Spell", 101 | "srd20.Feat", 102 | "srd20.Monster", 103 | ] 104 | INSTALLED_APPS = ( 105 | 'django.contrib.auth', 106 | 'django.contrib.contenttypes', 107 | 'django.contrib.sessions', 108 | 'django.contrib.sites', 109 | 'django.contrib.messages', 110 | 'django.contrib.staticfiles', 111 | 'django.contrib.admin', 112 | 113 | 'south', 114 | 'registration', 115 | 'phileo', 116 | 'django_search_views', 117 | 118 | 'srd20', 119 | 'search', 120 | 'browse', 121 | 'encounter', 122 | ) 123 | 124 | try: 125 | from local_settings import * 126 | except: 127 | pass 128 | 129 | -------------------------------------------------------------------------------- /browse/templates/browse/spell.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load phileo_tags %} 4 | 5 | {% block extrastyle %} 6 | {{ block.super }} 7 | {% phileo_css %} 8 | 9 | {% endblock %} 10 | {% block extrahead %} 11 | {{ block.super }} 12 | 13 | {% phileo_js %} 14 | {% endblock %} 15 | 16 | {% block title %}{{ spell.name }} | Spell description{% endblock %} 17 | 18 | {% block bodyclass %}flex{% endblock %} 19 | 20 | {% block breadcrumbs %} 21 | 25 | {% endblock %} 26 | 27 | {% block content_title %}

{{ spell }} {% phileo_widget user spell %}

{% endblock %} 28 | 29 | {% block content %} 30 |
31 | 32 | {% phileo_widget_js user spell %} 33 | 34 | {% if editable %} 35 |

36 | [edit] 37 |

38 | {% endif %} 39 | 40 |

{{ spell.school }} 41 | {% if spell.subschool %}({{ spell.subschool }}){% endif %} 42 | {% if spell.descriptor %}[{{spell.descriptor}}]{% endif %}

43 | 44 | 45 | 46 | {% if spell.spellcraft_dc %} 47 | 48 | 49 | 50 | 51 | {% endif %} 52 | {% if spell.to_develop %} 53 | 54 | 55 | 56 | 57 | {% endif %} 58 |
Spellcraft DC:{{ spell.spellcraft_dc }}
To Develop:{{ spell.to_develop }}
59 | 60 | {{ spell.description|safe }} 61 | 62 | {% if spell.verbal_components %} 63 |

Verbal Components: {{ spell.verbal_components }}

64 | {% endif %} 65 | {% if spell.material_components %} 66 |

Material Component: {{ spell.material_components }}

67 | {% endif %} 68 | {% if spell.arcane_material_components %} 69 |

Arcane Material Component: {{ spell.arcane_material_components }}

70 | {% endif %} 71 | {% if spell.focus %} 72 |

Focus: {{ spell.focus }}

73 | {% endif %} 74 | {% if spell.arcane_focus %} 75 |

Arcane Focus: {{ spell.arcane_focus }}

76 | {% endif %} 77 | {% if spell.cleric_focus %} 78 |

Cleric Focus: {{ spell.cleric_focus }}

79 | {% endif %} 80 | {% if spell.druid_focus %} 81 |

Druid Focus: {{ spell.druid_focus }}

82 | {% endif %} 83 | {% if spell.xp_cost %} 84 |

XP Cost: {{ spell.xp_cost }}

85 | {% endif %} 86 |
87 | {% endblock %} 88 | 89 | {% block sidebar %} 90 | 145 | {% endblock %} 146 | -------------------------------------------------------------------------------- /srd20/migrations/0010_auto__del_field_feat_full_text.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Deleting field 'Feat.full_text' 12 | db.delete_column('feat', 'full_text') 13 | 14 | 15 | def backwards(self, orm): 16 | 17 | # Adding field 'Feat.full_text' 18 | db.add_column('feat', 'full_text', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) 19 | 20 | 21 | models = { 22 | 'srd20.feat': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}), 25 | 'benefit': ('django.db.models.fields.TextField', [], {}), 26 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 27 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 28 | 'multiple': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 29 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 30 | 'normal': ('django.db.models.fields.TextField', [], {}), 31 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512'}), 32 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 33 | 'special': ('django.db.models.fields.TextField', [], {}), 34 | 'stack': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 35 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 36 | }, 37 | 'srd20.spell': { 38 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 39 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 40 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 41 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 42 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 44 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 46 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 47 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 49 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 50 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 52 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 53 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 54 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 56 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 57 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 58 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 59 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 60 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 61 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 62 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 63 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 64 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 66 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 67 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 68 | } 69 | } 70 | 71 | complete_apps = ['srd20'] 72 | -------------------------------------------------------------------------------- /srd20/migrations/0009_set_feat_altnames.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import DataMigration 5 | from django.db import models 6 | 7 | class Migration(DataMigration): 8 | 9 | def forwards(self, orm): 10 | def charmap(ch): 11 | if ch in ' /': return '-' 12 | if ch.isalnum(): return ch.lower() 13 | return '' 14 | for f in orm.Feat.objects.all(): 15 | f.altname = ''.join(charmap(ch) for ch in f.name) 16 | f.save() 17 | 18 | def backwards(self, orm): 19 | pass # Nothing to do here 20 | 21 | models = { 22 | 'srd20.feat': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}), 25 | 'benefit': ('django.db.models.fields.TextField', [], {}), 26 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 27 | 'full_text': ('django.db.models.fields.TextField', [], {}), 28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 29 | 'multiple': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 30 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 31 | 'normal': ('django.db.models.fields.TextField', [], {}), 32 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512'}), 33 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 34 | 'special': ('django.db.models.fields.TextField', [], {}), 35 | 'stack': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 36 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 37 | }, 38 | 'srd20.spell': { 39 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 40 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 41 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 42 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 44 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 45 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 46 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 47 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 48 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 49 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 51 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 52 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 53 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 54 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 55 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 56 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 57 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 58 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 59 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 60 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 61 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 62 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 63 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 64 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 65 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 66 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 67 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 68 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 69 | } 70 | } 71 | 72 | complete_apps = ['srd20'] 73 | -------------------------------------------------------------------------------- /srd20/migrations/0016_auto__chg_field_feat_altname.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Feat.altname' 12 | db.alter_column('feat', 'altname', self.gf('django.db.models.fields.SlugField')(default='', max_length=64)) 13 | 14 | 15 | def backwards(self, orm): 16 | 17 | # Changing field 'Feat.altname' 18 | db.alter_column('feat', 'altname', self.gf('django.db.models.fields.SlugField')(max_length=64, null=True)) 19 | 20 | 21 | models = { 22 | 'srd20.feat': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 25 | 'benefit': ('django.db.models.fields.TextField', [], {}), 26 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 27 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 28 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 29 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 30 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 31 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 32 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 33 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 34 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 35 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 36 | }, 37 | 'srd20.spell': { 38 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 39 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 40 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 41 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 42 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 44 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 46 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 47 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 49 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 50 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 52 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 53 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 54 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 56 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 57 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 58 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 59 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 60 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 61 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 62 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 63 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 64 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 66 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 67 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 68 | } 69 | } 70 | 71 | complete_apps = ['srd20'] 72 | -------------------------------------------------------------------------------- /srd20/migrations/0012_backup_multiple_and_stack.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import DataMigration 5 | from django.db import models 6 | 7 | class Migration(DataMigration): 8 | 9 | def forwards(self, orm): 10 | for f in orm.Feat.objects.all(): 11 | f.multiple_copy = f.multiple 12 | f.stack_copy = f.stack 13 | f.save() 14 | 15 | def backwards(self, orm): 16 | for f in orm.Feat.objects.all(): 17 | f.multiple = f.multiple_copy 18 | f.stack = f.stack_copy 19 | f.save() 20 | 21 | models = { 22 | 'srd20.feat': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), 25 | 'benefit': ('django.db.models.fields.TextField', [], {}), 26 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 27 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 28 | 'multiple': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 29 | 'multiple_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 30 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 31 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 32 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 33 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 34 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 35 | 'stack': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 36 | 'stack_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 37 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 38 | }, 39 | 'srd20.spell': { 40 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 41 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 42 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 44 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 46 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 47 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 48 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 49 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 50 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 52 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 53 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 54 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 55 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 56 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 57 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 58 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 59 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 60 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 61 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 62 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 63 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 64 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 65 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 66 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 67 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 68 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 69 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 70 | } 71 | } 72 | 73 | complete_apps = ['srd20'] 74 | -------------------------------------------------------------------------------- /srd20/migrations/0014_convert_multiple_and_stack.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import DataMigration 5 | from django.db import models 6 | 7 | class Migration(DataMigration): 8 | 9 | def forwards(self, orm): 10 | for f in orm.Feat.objects.all(): 11 | f.multiple = f.multiple_copy == 'Yes' 12 | f.stack = f.stack_copy =='Yes' 13 | f.save() 14 | 15 | def backwards(self, orm): 16 | for f in orm.Feat.objects.all(): 17 | f.multiple_copy = ('No', 'Yes')[f.multiple] # This needs to run in python 2.5, so no if/else expressions 18 | f.stack_copy = ('No', 'Yes')[f.stack] 19 | f.save() 20 | 21 | models = { 22 | 'srd20.feat': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 24 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), 25 | 'benefit': ('django.db.models.fields.TextField', [], {}), 26 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 27 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 28 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 29 | 'multiple_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 30 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 31 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 32 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 33 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 34 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 35 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 36 | 'stack_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 37 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 38 | }, 39 | 'srd20.spell': { 40 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 41 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 42 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 43 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 44 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 45 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 46 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 47 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 48 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 49 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 50 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 52 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 53 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 54 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 55 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 56 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 57 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 58 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 59 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 60 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 61 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 62 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 63 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 64 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 65 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 66 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 67 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 68 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 69 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 70 | } 71 | } 72 | 73 | complete_apps = ['srd20'] 74 | -------------------------------------------------------------------------------- /srd20/migrations/0015_auto__del_field_feat_multiple_copy__del_field_feat_stack_copy.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Deleting field 'Feat.multiple_copy' 12 | db.delete_column('feat', 'multiple_copy') 13 | 14 | # Deleting field 'Feat.stack_copy' 15 | db.delete_column('feat', 'stack_copy') 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Adding field 'Feat.multiple_copy' 21 | db.add_column('feat', 'multiple_copy', self.gf('django.db.models.fields.CharField')(default='No', max_length=4), keep_default=False) 22 | 23 | # Adding field 'Feat.stack_copy' 24 | db.add_column('feat', 'stack_copy', self.gf('django.db.models.fields.CharField')(default='No', max_length=4), keep_default=False) 25 | 26 | 27 | models = { 28 | 'srd20.feat': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 30 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), 31 | 'benefit': ('django.db.models.fields.TextField', [], {}), 32 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 33 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 34 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 35 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 36 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 37 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 38 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 39 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 40 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 41 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 42 | }, 43 | 'srd20.spell': { 44 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 45 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 46 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 47 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 48 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 49 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 50 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 52 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 53 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 54 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 55 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 56 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 58 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 59 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 60 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 61 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 62 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 63 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 64 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 65 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 66 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 67 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 68 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 69 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 70 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 71 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 72 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 73 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 74 | } 75 | } 76 | 77 | complete_apps = ['srd20'] 78 | -------------------------------------------------------------------------------- /srd20/migrations/0011_auto__add_field_feat_multiple_copy__add_field_feat_stack_copy.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding field 'Feat.multiple_copy' 12 | db.add_column('feat', 'multiple_copy', self.gf('django.db.models.fields.CharField')(default='No', max_length=4), keep_default=False) 13 | 14 | # Adding field 'Feat.stack_copy' 15 | db.add_column('feat', 'stack_copy', self.gf('django.db.models.fields.CharField')(default='No', max_length=4), keep_default=False) 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Deleting field 'Feat.multiple_copy' 21 | db.delete_column('feat', 'multiple_copy') 22 | 23 | # Deleting field 'Feat.stack_copy' 24 | db.delete_column('feat', 'stack_copy') 25 | 26 | 27 | models = { 28 | 'srd20.feat': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 30 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), 31 | 'benefit': ('django.db.models.fields.TextField', [], {}), 32 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 33 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 34 | 'multiple': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 35 | 'multiple_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 36 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 37 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 38 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 39 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 40 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'stack': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 42 | 'stack_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 43 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 44 | }, 45 | 'srd20.spell': { 46 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 47 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 48 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 49 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 52 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 53 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 54 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 56 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 58 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 60 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 61 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 62 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 63 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 64 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 65 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 66 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 67 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 68 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 69 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 70 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 71 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 72 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 73 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 74 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 75 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 76 | } 77 | } 78 | 79 | complete_apps = ['srd20'] 80 | -------------------------------------------------------------------------------- /srd20/migrations/0013_auto__chg_field_feat_multiple__chg_field_feat_stack.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Feat.multiple' 12 | db.alter_column('feat', 'multiple', self.gf('django.db.models.fields.BooleanField')()) 13 | 14 | # Changing field 'Feat.stack' 15 | db.alter_column('feat', 'stack', self.gf('django.db.models.fields.BooleanField')()) 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Changing field 'Feat.multiple' 21 | db.alter_column('feat', 'multiple', self.gf('django.db.models.fields.CharField')(max_length=4)) 22 | 23 | # Changing field 'Feat.stack' 24 | db.alter_column('feat', 'stack', self.gf('django.db.models.fields.CharField')(max_length=4)) 25 | 26 | 27 | models = { 28 | 'srd20.feat': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 30 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'null': 'True', 'db_index': 'True'}), 31 | 'benefit': ('django.db.models.fields.TextField', [], {}), 32 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 33 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 34 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 35 | 'multiple_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 36 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 37 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 38 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 39 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 40 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 42 | 'stack_copy': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 43 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 44 | }, 45 | 'srd20.spell': { 46 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 47 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 48 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 49 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 52 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 53 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 54 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 56 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 58 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 60 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 61 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 62 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 63 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 64 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 65 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 66 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 67 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 68 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 69 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 70 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 71 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 72 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 73 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 74 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 75 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 76 | } 77 | } 78 | 79 | complete_apps = ['srd20'] 80 | -------------------------------------------------------------------------------- /srd20/migrations/0008_auto__add_feat.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding model 'Feat' 12 | db.create_table('feat', ( 13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=64)), 15 | ('altname', self.gf('django.db.models.fields.SlugField')(db_index=True, max_length=64, null=True, blank=True)), 16 | ('type', self.gf('django.db.models.fields.CharField')(max_length=32)), 17 | ('multiple', self.gf('django.db.models.fields.CharField')(max_length=4)), 18 | ('stack', self.gf('django.db.models.fields.CharField')(max_length=4)), 19 | ('choice', self.gf('django.db.models.fields.CharField')(max_length=256)), 20 | ('prerequisite', self.gf('django.db.models.fields.CharField')(max_length=512)), 21 | ('benefit', self.gf('django.db.models.fields.TextField')()), 22 | ('normal', self.gf('django.db.models.fields.TextField')()), 23 | ('special', self.gf('django.db.models.fields.TextField')()), 24 | ('full_text', self.gf('django.db.models.fields.TextField')()), 25 | ('reference', self.gf('django.db.models.fields.CharField')(max_length=32)), 26 | )) 27 | db.send_create_signal('srd20', ['Feat']) 28 | 29 | 30 | def backwards(self, orm): 31 | 32 | # Deleting model 'Feat' 33 | db.delete_table('feat') 34 | 35 | 36 | models = { 37 | 'srd20.feat': { 38 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 39 | 'altname': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}), 40 | 'benefit': ('django.db.models.fields.TextField', [], {}), 41 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 42 | 'full_text': ('django.db.models.fields.TextField', [], {}), 43 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 44 | 'multiple': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 45 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 46 | 'normal': ('django.db.models.fields.TextField', [], {}), 47 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512'}), 48 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 49 | 'special': ('django.db.models.fields.TextField', [], {}), 50 | 'stack': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 51 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 52 | }, 53 | 'srd20.spell': { 54 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 55 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 56 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 58 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 60 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 61 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 62 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 63 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 64 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 66 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 67 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 68 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 69 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 70 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 71 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 72 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 73 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 74 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 75 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 76 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 77 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 78 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 79 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 80 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 81 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 82 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 83 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 84 | } 85 | } 86 | 87 | complete_apps = ['srd20'] 88 | -------------------------------------------------------------------------------- /srd20/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding model 'Spell' 12 | db.create_table('spell', ( 13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=64)), 15 | ('altname', self.gf('django.db.models.fields.CharField')(max_length=64)), 16 | ('school', self.gf('django.db.models.fields.CharField')(max_length=32)), 17 | ('subschool', self.gf('django.db.models.fields.CharField')(max_length=32)), 18 | ('descriptor', self.gf('django.db.models.fields.CharField')(max_length=64)), 19 | ('spellcraft_dc', self.gf('django.db.models.fields.CharField')(max_length=64)), 20 | ('level', self.gf('django.db.models.fields.CharField')(max_length=128)), 21 | ('components', self.gf('django.db.models.fields.TextField')()), 22 | ('casting_time', self.gf('django.db.models.fields.CharField')(max_length=32)), 23 | ('range', self.gf('django.db.models.fields.CharField')(max_length=64)), 24 | ('target', self.gf('django.db.models.fields.CharField')(max_length=256)), 25 | ('area', self.gf('django.db.models.fields.CharField')(max_length=256)), 26 | ('effect', self.gf('django.db.models.fields.CharField')(max_length=256)), 27 | ('duration', self.gf('django.db.models.fields.CharField')(max_length=128)), 28 | ('saving_throw', self.gf('django.db.models.fields.CharField')(max_length=128)), 29 | ('spell_resistance', self.gf('django.db.models.fields.CharField')(max_length=64)), 30 | ('short_description', self.gf('django.db.models.fields.CharField')(max_length=128)), 31 | ('to_develop', self.gf('django.db.models.fields.TextField')()), 32 | ('material_components', self.gf('django.db.models.fields.TextField')()), 33 | ('arcane_material_components', self.gf('django.db.models.fields.CharField')(max_length=256)), 34 | ('focus', self.gf('django.db.models.fields.TextField')()), 35 | ('description', self.gf('django.db.models.fields.TextField')()), 36 | ('xp_cost', self.gf('django.db.models.fields.TextField')()), 37 | ('arcane_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 38 | ('wizard_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 39 | ('verbal_components', self.gf('django.db.models.fields.CharField')(max_length=256)), 40 | ('sorcerer_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 41 | ('bard_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 42 | ('cleric_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 43 | ('druid_focus', self.gf('django.db.models.fields.CharField')(max_length=256)), 44 | ('full_text', self.gf('django.db.models.fields.TextField')()), 45 | ('reference', self.gf('django.db.models.fields.CharField')(max_length=30)), 46 | )) 47 | db.send_create_signal('srd20', ['Spell']) 48 | 49 | 50 | def backwards(self, orm): 51 | 52 | # Deleting model 'Spell' 53 | db.delete_table('spell') 54 | 55 | 56 | models = { 57 | 'srd20.spell': { 58 | 'Meta': {'object_name': 'Spell', 'db_table': "'spell'"}, 59 | 'altname': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 60 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 61 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 62 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 63 | 'bard_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 64 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 65 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 66 | 'components': ('django.db.models.fields.TextField', [], {}), 67 | 'description': ('django.db.models.fields.TextField', [], {}), 68 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 69 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 70 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 71 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 72 | 'focus': ('django.db.models.fields.TextField', [], {}), 73 | 'full_text': ('django.db.models.fields.TextField', [], {}), 74 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 75 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 76 | 'material_components': ('django.db.models.fields.TextField', [], {}), 77 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 78 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 79 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 80 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 81 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 82 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 83 | 'sorcerer_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 84 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 85 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 86 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 87 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 88 | 'to_develop': ('django.db.models.fields.TextField', [], {}), 89 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 90 | 'wizard_focus': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 91 | 'xp_cost': ('django.db.models.fields.TextField', [], {}) 92 | } 93 | } 94 | 95 | complete_apps = ['srd20'] 96 | -------------------------------------------------------------------------------- /pathfinder/spells.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | import sys, os 5 | import json 6 | import csv 7 | from pyquery import PyQuery as Q 8 | import lxml.etree 9 | 10 | def pqiter(pq): 11 | """ 12 | Iterator on a PyQuery object that produces PyQuery objects, instead 13 | of plain XML elements 14 | """ 15 | index = 0 16 | while index < len(pq): 17 | yield pq.eq(index) 18 | index += 1 19 | 20 | def normalize_attribute(attr): 21 | """ 22 | Normalizes the name of an attribute which is seplled ins lightly different 23 | ways in paizo HTMLs 24 | """ 25 | if attr.find('a'): 26 | attr = attr.find('a').html() # Remove links 27 | else: 28 | attr = attr.html() 29 | attr = attr.strip() 30 | 31 | translation_map = { 32 | 'Targets': 'Target', 33 | 'Component': 'Components', 34 | 'Target or Area': 'Target', 35 | 'Target or Targets': 'Target', 36 | 'Save': 'Saving Throw', 37 | 'Saving': 'Saving Throw', 38 | 'Saving throw': 'Saving Throw', 39 | 'Casting': 'Casting Time', 40 | 'Casting time': 'Casting Time', 41 | 'SR': 'Spell Resistance', 42 | 'Target, Effect, or Area': 'Area', 43 | 'Target, Effect, Area': 'Effect', 44 | 'Target/Effect': 'Effect', 45 | 'Area or Target': 'Area', 46 | } 47 | if attr in translation_map: 48 | attr = translation_map[attr] 49 | assert attr in ('School', 'Level', 'Components', 'Casting Time', 'Range', 50 | 'Effect', 'Duration', 'Saving Throw', 'Spell Resistance', 51 | 'Target', 'Area', 'Preparation Time' 52 | ) 53 | return attr.lower() 54 | 55 | # Load descriptions 56 | descriptions = {} 57 | r = csv.reader(open("descriptions.csv", "r")) 58 | for slug, description in r: 59 | descriptions[slug.decode('utf-8')] = description.decode('utf-8') 60 | 61 | # Iterate over input files 62 | result = [] 63 | for filename in sys.argv[1:]: 64 | spell_html = Q(filename=filename, parser='html') 65 | spells = spell_html("#body .stat-block-title") 66 | 67 | for s in pqiter(spells): 68 | slug = s.attr('id') 69 | fn = os.path.basename(filename) 70 | 71 | if fn == 'icyPrison.html': 72 | # This file has wrong formatting. skip 73 | sys.stderr.write(u"Skipping file %s, known bad formatting\n" % fn) 74 | break 75 | 76 | if slug is None: 77 | if fn in ('fogCloud.html', 'symbolOfStrife.html'): 78 | # the id is missing. autocomplete 79 | basename = os.path.splitext(fn)[0] 80 | for c in 'COS': # letters to un-camelCase 81 | basename = basename.replace(c, '-'+c.lower()) 82 | slug = basename 83 | sys.stderr.write(u"Substituting %s for %s\n" % (fn, slug)) 84 | else: 85 | sys.stderr.write(u"Skipping file %s, no id\n" % fn) 86 | continue 87 | 88 | slug = slug.replace(',', '') # Remove commas in slug 89 | 90 | if slug not in descriptions: 91 | sys.stderr.write('Warning: no short description for %s\n' % slug) 92 | 93 | title = s[0].text_content().strip() 94 | attributes = {} 95 | description = '' 96 | p = s.next('*') 97 | 98 | # Get fields 99 | while p.hasClass('stat-block-1'): 100 | attrname = p.children('b') 101 | for a in pqiter(attrname): 102 | label = normalize_attribute(a) 103 | # Get the rest until the next 104 | elem = a[0] 105 | value = elem.tail or '' 106 | while elem.getnext() is not None and elem.getnext().tag != 'b': 107 | elem = elem.getnext() 108 | value += lxml.etree.tostring(elem) 109 | value = value.strip() 110 | if value.endswith(';'): 111 | value = value[:-1] 112 | attributes[label] = value 113 | p = p.next('*') 114 | 115 | # The rest is description 116 | while p and not p.hasClass('stat-block-title'): 117 | description += p.outerHtml() 118 | p = p.next('*') 119 | 120 | # From the school line get subschool and descriptors 121 | if 'school' in attributes: 122 | school = attributes['school'] 123 | if '[' in school: 124 | position = school.index('[') 125 | descriptors = school[position+1:-1] 126 | school = school[:position-1].strip() 127 | attributes["school"] = school 128 | attributes["descriptor"] = descriptors 129 | if '(' in school: 130 | position = school.index('(') 131 | subschool = school[position+1:-1] 132 | school = school[:position-1].strip() 133 | attributes["school"] = school 134 | attributes["subschool"] = subschool 135 | 136 | # Reference 137 | reference = '/'.join(filename.split('/')[-3:-1]) 138 | 139 | result.append({ 140 | "model": "srd20.spell", 141 | "pk": len(result), 142 | "fields": { 143 | "name": title, 144 | "altname": slug, 145 | "school": attributes.get("school", ""), 146 | "subschool": attributes.get("subschool", ""), 147 | "descriptor": attributes.get("descriptor", ""), 148 | "level": attributes.get("level", ""), 149 | "components": attributes.get("components", ""), 150 | "casting_time": attributes.get("casting time", ""), 151 | "range": attributes.get("range", ""), 152 | "target": attributes.get("target", ""), 153 | "area": attributes.get("area", ""), 154 | "effect": attributes.get("effect", ""), 155 | "duration": attributes.get("duration", ""), 156 | "saving_throw": attributes.get("saving throw", ""), 157 | "spell_resistance": attributes.get("spell resistance", ""), 158 | "reference": reference, 159 | 160 | "description": description, 161 | "short_description": descriptions.get(slug, '') 162 | } 163 | }) 164 | if fn == 'transmutePotionToPoison.html': 165 | # This file has stat-block-title blocks which aren't spells 166 | break 167 | 168 | print json.dumps(result, ensure_ascii=False, indent=4).encode('utf-8') 169 | 170 | -------------------------------------------------------------------------------- /srd20/fixtures/README: -------------------------------------------------------------------------------- 1 | The content in this JSON file is based on the SRD content for Dungeons and 2 | Dragons 3.5,licensed under the Open Gaming License 3 | 4 | The base file for this content was: http://www.andargor.com/files/srd35-db-SQLite-v1.3.zip 5 | 6 | OPEN GAME LICENSE Version 1.0a 7 | 8 | The following text is the property of Wizards of the Coast, Inc. and is Copyright 2000 Wizards of the Coast, Inc ("Wizards"). All Rights Reserved. 9 | 10 | 1. Definitions: 11 | 1. "Contributors" means the copyright and/or trademark owners who have contributed Open Game Content; 12 | 2. "Derivative Material" means copyrighted material including derivative works and translations (including into other computer languages), potation, modification, correction, addition, extension, upgrade, improvement, compilation, abridgment or other form in which an existing work may be recast, transformed or adapted; 13 | 3. "Distribute" means to reproduce, license, rent, lease, sell, broadcast, publicly display, transmit or otherwise distribute; 14 | 4. "Open Game Content" means the game mechanic and includes the methods, procedures, processes and routines to the extent such content does not embody the Product Identity and is an enhancement over the prior art and any additional content clearly identified as Open Game Content by the Contributor, and means any work covered by this License, including translations and derivative works under copyright law, but specifically excludes Product Identity. 15 | 5. "Product Identity" means product and product line names, logos and identifying marks including trade dress; artifacts; creatures characters; stories, storylines, plots, thematic elements, dialogue, incidents, language, artwork, symbols, designs, depictions, likenesses, formats, poses, concepts, themes and graphic, photographic and other visual or audio representations; names and descriptions of characters, spells, enchantments, personalities, teams, personas, likenesses and special abilities; places, locations, environments, creatures, equipment, magical or supernatural abilities or effects, logos, symbols, or graphic designs; and any other trademark or registered trademark clearly identified as Product identity by the owner of the Product Identity, and which specifically excludes the Open Game Content; 16 | 6. "Trademark" means the logos, names, mark, sign, motto, designs that are used by a Contributor to identify itself or its products or the associated products contributed to the Open Game License by the Contributor 17 | 7. "Use", "Used" or "Using" means to use, Distribute, copy, edit, format, modify, translate and otherwise create Derivative Material of Open Game Content. 18 | 8. "You" or "Your" means the licensee in terms of this agreement. 19 | 2. The License: This License applies to any Open Game Content that contains a notice indicating that the Open Game Content may only be Used under and in terms of this License. You must affix such a notice to any Open Game Content that you Use. No terms may be added to or subtracted from this License except as described by the License itself. No other terms or conditions may be applied to any Open Game Content distributed using this License. 20 | 3. Offer and Acceptance: By Using the Open Game Content You indicate Your acceptance of the terms of this License. 21 | 4. Grant and Consideration: In consideration for agreeing to use this License, the Contributors grant You a perpetual, worldwide, royalty-free, non-exclusive license with the exact terms of this License to Use, the Open Game Content. 22 | 5. Representation of Authority to Contribute: If You are contributing original material as Open Game Content, You represent that Your Contributions are Your original creation and/or You have sufficient rights to grant the rights conveyed by this License. 23 | 6. Notice of License Copyright: You must update the COPYRIGHT NOTICE portion of this License to include the exact text of the COPYRIGHT NOTICE of any Open Game Content You are copying, modifying or distributing, and You must add the title, the copyright date, and the copyright holder’s name to the COPYRIGHT NOTICE of any original Open Game Content you Distribute. 24 | 7. Use of Product Identity: You agree not to Use any Product Identity, including as an indication as to compatibility, except as expressly licensed in another, independent Agreement with the owner of each element of that Product Identity. You agree not to indicate compatibility or co-adaptability with any Trademark or Registered Trademark in conjunction with a work containing Open Game Content except as expressly licensed in another, independent Agreement with the owner of such Trademark or Registered Trademark. The use of any Product Identity in Open Game Content does not constitute a challenge to the ownership of that Product Identity. The owner of any Product Identity used in Open Game Content shall retain all rights, title and interest in and to that Product Identity. 25 | 8. Identification: If you distribute Open Game Content You must clearly indicate which portions of the work that you are distributing are Open Game Content. 26 | 9. Updating the License: Wizards or its designated Agents may publish updated versions of this License. You may use any authorized version of this License to copy, modify and distribute any Open Game Content originally distributed under any version of this License. 27 | 10. Copy of this License: You MUST include a copy of this License with every copy of the Open Game Content You Distribute. 28 | 11. Use of Contributor Credits: You may not market or advertise the Open Game Content using the name of any Contributor unless You have written permission from the Contributor to do so. 29 | 12. Inability to Comply: If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Open Game Content due to statute, judicial order, or governmental regulation then You may not Use any Open Game Material so affected. 30 | 13. Termination: This License will terminate automatically if You fail to comply with all terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses shall survive the termination of this License. 31 | 14. Reformation: If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 32 | 15. 33 | COPYRIGHT NOTICE 34 | 35 | Open Game License v 1.0a Copyright 2000, Wizards of the Coast, Inc. 36 | 37 | System Reference Document Copyright 2000-2003, Wizards of the Coast, Inc.; Authors Jonathan Tweet, Monte Cook, Skip Williams, Rich Baker, Andy Collins, David Noonan, Rich Redman, Bruce R. Cordell, John D. Rateliff, Thomas Reid, James Wyatt, based on original material by E. Gary Gygax and Dave Arneson. 38 | 39 | Creature Collection Volume 1 Copyright 2000, Clark Peterson. 40 | 41 | Modern System Reference Document Copyright 2002, Wizards of the Coast, Inc.; Authors Bill Slavicsek, Jeff Grubb, Rich Redman, Charles Ryan, based on material by Jonathan Tweet, Monte Cook, Skip Williams, Richard Baker,Peter Adkison, Bruce R. Cordell, John Tynes, Andy Collins, and JD Wiker 42 | 43 | Monster Manual II Copyright 2002, Wizards of the Coast, Inc. 44 | 45 | Swords of Our Fathers Copyright 2003, The Game Mechanics. 46 | 47 | Mutants & Masterminds Copyright 2002, Green Ronin Publishing. 48 | 49 | Unearthed Arcana Copyright 2004, Wizards of the Coast, Inc.; Andy Collins, Jesse Decker, David Noonan, Rich Redman. 50 | 51 | The Hypertext d20 SRD Copyright 2004, Jans W Carton. 52 | 53 | END OF LICENSE 54 | -------------------------------------------------------------------------------- /srd20/migrations/0018_auto__add_field_feat_description.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding field 'Feat.description' 12 | db.add_column('feat', 'description', self.gf('django.db.models.fields.TextField')(default='', blank=True), keep_default=False) 13 | 14 | 15 | def backwards(self, orm): 16 | 17 | # Deleting field 'Feat.description' 18 | db.delete_column('feat', 'description') 19 | 20 | 21 | models = { 22 | 'srd20.characterclass': { 23 | 'Meta': {'ordering': "('name',)", 'object_name': 'CharacterClass', 'db_table': "'class'"}, 24 | 'alignment': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 25 | 'class_skills': ('django.db.models.fields.TextField', [], {}), 26 | 'epic_feat_base_level': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 27 | 'epic_feat_interval': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 28 | 'epic_feat_list': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 29 | 'epic_full_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 30 | 'full_text': ('django.db.models.fields.TextField', [], {}), 31 | 'hit_die': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 32 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 33 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 34 | 'proficiencies': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 35 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 36 | 'req_base_attack_bonus': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 37 | 'req_epic_feat': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 38 | 'req_feat': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 39 | 'req_languages': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), 40 | 'req_psionics': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 41 | 'req_race': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 42 | 'req_skill': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 43 | 'req_special': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 44 | 'req_spells': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 45 | 'req_weapon_proficiency': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 46 | 'skill_points': ('django.db.models.fields.CharField', [], {'max_length': '1'}), 47 | 'skill_points_ability': ('django.db.models.fields.CharField', [], {'max_length': '3'}), 48 | 'spell_list_1': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 49 | 'spell_list_2': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'spell_list_3': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 51 | 'spell_list_4': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 52 | 'spell_list_5': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 53 | 'spell_stat': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 54 | 'spell_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), 55 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 56 | }, 57 | 'srd20.feat': { 58 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 59 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 60 | 'benefit': ('django.db.models.fields.TextField', [], {}), 61 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 62 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 63 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 64 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 65 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 66 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 67 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 68 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 69 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 70 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 71 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 72 | }, 73 | 'srd20.spell': { 74 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 75 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 76 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 77 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 78 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 79 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 80 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 81 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 82 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 83 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 84 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 85 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 86 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 87 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 88 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 89 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 90 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 91 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 92 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 93 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 94 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 95 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 96 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 97 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 98 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 99 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 100 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 101 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 102 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 103 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 104 | } 105 | } 106 | 107 | complete_apps = ['srd20'] 108 | -------------------------------------------------------------------------------- /srd20/migrations/0021_auto__chg_field_spell_casting_time__chg_field_spell_subschool.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Spell.casting_time' 12 | db.alter_column('spell', 'casting_time', self.gf('django.db.models.fields.CharField')(max_length=64)) 13 | 14 | # Changing field 'Spell.subschool' 15 | db.alter_column('spell', 'subschool', self.gf('django.db.models.fields.CharField')(max_length=128)) 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Changing field 'Spell.casting_time' 21 | db.alter_column('spell', 'casting_time', self.gf('django.db.models.fields.CharField')(max_length=32)) 22 | 23 | # Changing field 'Spell.subschool' 24 | db.alter_column('spell', 'subschool', self.gf('django.db.models.fields.CharField')(max_length=32)) 25 | 26 | 27 | models = { 28 | 'srd20.characterclass': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'CharacterClass', 'db_table': "'class'"}, 30 | 'alignment': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 31 | 'class_skills': ('django.db.models.fields.TextField', [], {}), 32 | 'epic_feat_base_level': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 33 | 'epic_feat_interval': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 34 | 'epic_feat_list': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 35 | 'epic_full_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 36 | 'full_text': ('django.db.models.fields.TextField', [], {}), 37 | 'hit_die': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 38 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 40 | 'proficiencies': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 42 | 'req_base_attack_bonus': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 43 | 'req_epic_feat': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 44 | 'req_feat': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 45 | 'req_languages': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), 46 | 'req_psionics': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 47 | 'req_race': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'req_skill': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 49 | 'req_special': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'req_spells': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 51 | 'req_weapon_proficiency': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 52 | 'skill_points': ('django.db.models.fields.CharField', [], {'max_length': '1'}), 53 | 'skill_points_ability': ('django.db.models.fields.CharField', [], {'max_length': '3'}), 54 | 'spell_list_1': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'spell_list_2': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 56 | 'spell_list_3': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'spell_list_4': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 58 | 'spell_list_5': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'spell_stat': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 60 | 'spell_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), 61 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 62 | }, 63 | 'srd20.feat': { 64 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 65 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 66 | 'benefit': ('django.db.models.fields.TextField', [], {}), 67 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 68 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 69 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 70 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 71 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 72 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 73 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}), 74 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 75 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 76 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 77 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 78 | }, 79 | 'srd20.spell': { 80 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 81 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 82 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 83 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 84 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 85 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 86 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 87 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 88 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 89 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 90 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 91 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 92 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 93 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 94 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 95 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 96 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 97 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 98 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 99 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 100 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 101 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 102 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 103 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 104 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 105 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 106 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 107 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 108 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 109 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 110 | } 111 | } 112 | 113 | complete_apps = ['srd20'] 114 | -------------------------------------------------------------------------------- /srd20/migrations/0020_auto__chg_field_spell_short_description__chg_field_spell_saving_throw.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Spell.short_description' 12 | db.alter_column('spell', 'short_description', self.gf('django.db.models.fields.CharField')(max_length=256)) 13 | 14 | # Changing field 'Spell.saving_throw' 15 | db.alter_column('spell', 'saving_throw', self.gf('django.db.models.fields.CharField')(max_length=256)) 16 | 17 | 18 | def backwards(self, orm): 19 | 20 | # Changing field 'Spell.short_description' 21 | db.alter_column('spell', 'short_description', self.gf('django.db.models.fields.CharField')(max_length=128)) 22 | 23 | # Changing field 'Spell.saving_throw' 24 | db.alter_column('spell', 'saving_throw', self.gf('django.db.models.fields.CharField')(max_length=128)) 25 | 26 | 27 | models = { 28 | 'srd20.characterclass': { 29 | 'Meta': {'ordering': "('name',)", 'object_name': 'CharacterClass', 'db_table': "'class'"}, 30 | 'alignment': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 31 | 'class_skills': ('django.db.models.fields.TextField', [], {}), 32 | 'epic_feat_base_level': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 33 | 'epic_feat_interval': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 34 | 'epic_feat_list': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 35 | 'epic_full_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 36 | 'full_text': ('django.db.models.fields.TextField', [], {}), 37 | 'hit_die': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 38 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 40 | 'proficiencies': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 42 | 'req_base_attack_bonus': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 43 | 'req_epic_feat': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 44 | 'req_feat': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 45 | 'req_languages': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), 46 | 'req_psionics': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 47 | 'req_race': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 48 | 'req_skill': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 49 | 'req_special': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 50 | 'req_spells': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 51 | 'req_weapon_proficiency': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 52 | 'skill_points': ('django.db.models.fields.CharField', [], {'max_length': '1'}), 53 | 'skill_points_ability': ('django.db.models.fields.CharField', [], {'max_length': '3'}), 54 | 'spell_list_1': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 55 | 'spell_list_2': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 56 | 'spell_list_3': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 57 | 'spell_list_4': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 58 | 'spell_list_5': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 59 | 'spell_stat': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 60 | 'spell_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), 61 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 62 | }, 63 | 'srd20.feat': { 64 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 65 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 66 | 'benefit': ('django.db.models.fields.TextField', [], {}), 67 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 68 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 69 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 70 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 71 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 72 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 73 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}), 74 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 75 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 76 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 77 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 78 | }, 79 | 'srd20.spell': { 80 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 81 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 82 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 83 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 84 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 85 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 86 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 87 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 88 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 89 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 90 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 91 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 92 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 93 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 94 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 95 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 96 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 97 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 98 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 99 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 100 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 101 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 102 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 103 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 104 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 105 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 106 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 107 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 108 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 109 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 110 | } 111 | } 112 | 113 | complete_apps = ['srd20'] 114 | -------------------------------------------------------------------------------- /srd20/migrations/0019_auto__chg_field_spell_descriptor__chg_field_spell_components__chg_fiel.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Changing field 'Spell.descriptor' 12 | db.alter_column('spell', 'descriptor', self.gf('django.db.models.fields.CharField')(max_length=256)) 13 | 14 | # Changing field 'Spell.components' 15 | db.alter_column('spell', 'components', self.gf('django.db.models.fields.CharField')(max_length=256)) 16 | 17 | # Changing field 'Feat.prerequisite' 18 | db.alter_column('feat', 'prerequisite', self.gf('django.db.models.fields.CharField')(max_length=1024)) 19 | 20 | 21 | def backwards(self, orm): 22 | 23 | # Changing field 'Spell.descriptor' 24 | db.alter_column('spell', 'descriptor', self.gf('django.db.models.fields.CharField')(max_length=64)) 25 | 26 | # Changing field 'Spell.components' 27 | db.alter_column('spell', 'components', self.gf('django.db.models.fields.CharField')(max_length=64)) 28 | 29 | # Changing field 'Feat.prerequisite' 30 | db.alter_column('feat', 'prerequisite', self.gf('django.db.models.fields.CharField')(max_length=512)) 31 | 32 | 33 | models = { 34 | 'srd20.characterclass': { 35 | 'Meta': {'ordering': "('name',)", 'object_name': 'CharacterClass', 'db_table': "'class'"}, 36 | 'alignment': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 37 | 'class_skills': ('django.db.models.fields.TextField', [], {}), 38 | 'epic_feat_base_level': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 39 | 'epic_feat_interval': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 40 | 'epic_feat_list': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 41 | 'epic_full_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 42 | 'full_text': ('django.db.models.fields.TextField', [], {}), 43 | 'hit_die': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 44 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 45 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 46 | 'proficiencies': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 47 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 48 | 'req_base_attack_bonus': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 49 | 'req_epic_feat': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 50 | 'req_feat': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 51 | 'req_languages': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), 52 | 'req_psionics': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 53 | 'req_race': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 54 | 'req_skill': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 55 | 'req_special': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 56 | 'req_spells': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 57 | 'req_weapon_proficiency': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 58 | 'skill_points': ('django.db.models.fields.CharField', [], {'max_length': '1'}), 59 | 'skill_points_ability': ('django.db.models.fields.CharField', [], {'max_length': '3'}), 60 | 'spell_list_1': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 61 | 'spell_list_2': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 62 | 'spell_list_3': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 63 | 'spell_list_4': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 64 | 'spell_list_5': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 65 | 'spell_stat': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 66 | 'spell_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), 67 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 68 | }, 69 | 'srd20.feat': { 70 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 71 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 72 | 'benefit': ('django.db.models.fields.TextField', [], {}), 73 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 74 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 75 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 76 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 77 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 78 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 79 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}), 80 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 81 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 82 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 83 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 84 | }, 85 | 'srd20.spell': { 86 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 87 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 88 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 89 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 90 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 91 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 92 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 93 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '256'}), 94 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 95 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 96 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 97 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 98 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 99 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 100 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 101 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 102 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 103 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 104 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 105 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 106 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 107 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 108 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 109 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 110 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 111 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 112 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 113 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 114 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 115 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 116 | } 117 | } 118 | 119 | complete_apps = ['srd20'] 120 | -------------------------------------------------------------------------------- /browse/templates/browse/monster.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load phileo_tags %} 4 | 5 | {% block extrastyle %} 6 | {{ block.super }} 7 | {% phileo_css %} 8 | 9 | {% endblock %} 10 | {% block extrahead %} 11 | {{ block.super }} 12 | 13 | 18 | {% phileo_js %} 19 | {% endblock %} 20 | 21 | {% block title %}{{ monster.name }} | Monster description{% endblock %} 22 | 23 | {% block bodyclass %}flex{% endblock %} 24 | 25 | {% block breadcrumbs %} 26 | 30 | {% endblock %} 31 | 32 | {% block content_title %}

{{ monster }} (CR {{ monster.get_cr_display }}){% phileo_widget user monster %}

{% endblock %} 33 | 34 | {% block content %} 35 |
36 | 37 | {% phileo_widget_js user monster %} 38 | 39 | {% if editable %} 40 |

41 | [edit] 42 |

43 | {% endif %} 44 | 45 |

{{ monster.flavor_text }}

46 | 47 |

{{monster.alignment}} {{monster.get_size_display }} {{ monster.type }} 48 | {% if monster.subtypes %}({{ monster.subtypes }}){% endif %} 49 | {% if monster.other_type or monster.class_level %} 50 | / {{ monster.other_type}} {{ monster.name|lower }} {{ monster.class_level }}

51 | {% endif %} 52 | 53 | 54 |
55 |

Defense

56 | 57 | 58 | {% if monster.immunities %} 59 | 60 | 61 | 62 | {% else %} 63 | 64 | {% endif %} 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {% if monster.damage_reduction_amount %} 73 | 74 | {% else %} 75 | 76 | {% endif%} 77 | {% if monster.spell_resistance %} 78 | 79 | {% else %} 80 | 81 | {% endif%} 82 | 83 | 84 | {% if monster.immunities or monster.resistance or monster.defensive_abilities %} 85 | 86 | {% if monster.resistance %} 87 | 88 | 89 | {% else %} 90 | 91 | {% endif %} 92 | {% if monster.weaknesses %} 93 | 94 | {% else %} 95 | 96 | {% endif %} 97 | {% if monster.defensive_abilities %} 98 | 99 | 100 | {% endif %} 101 | 102 | {% endif %} 103 |
HP:{{ monster.hit_points|safe }}Immune:{{ monster.immunities|safe }}HP:{{ monster.hit_points|safe }}Fort:{{ monster.fortitude_save|safe }}
AC:{{ monster.armor_class|safe }}Ref:{{ monster.reflex_save|safe }}
DR:{{ monster.damage_reduction_amount }}/{{ monster.damage_reduction_condition }}SR:{{ monster.spell_resistance }}Will:{{ monster.will_save|safe }}
Resistance:{{ monster.resistance|safe }}Weaknesses:{{ monster.weaknesses|safe }}Defensive Abilities:{{ monster.defensive_abilities|safe }}
104 |
105 | 106 |
107 |

Offense

108 | 109 | 110 | 111 | 112 | 113 | 114 | {% if monster.reach %} 115 | 116 | 117 | {% endif %} 118 | 119 | 120 | 121 | 122 | {% if monster.special_attacks %} 123 | 124 | 125 | {% else %} 126 | 127 | {% endif %} 128 | 129 | {% if monster.ranged or monster.spell_like_abilities %} 130 | 131 | {% if monster.ranged %} 132 | 133 | 134 | {% else %} 135 | 139 | 140 | {% endif %} 141 | 142 | {% endif %} 143 | {% if monster.spells_known %} 144 | 145 | 146 | 147 | 148 | {% endif %} 149 | {% if monster.sorcerer_spells_known %} 150 | 151 | 152 | 153 | 154 | {% endif %} 155 | {% if monster.spells_prepared %} 156 | 157 | 158 | 159 | 160 | {% endif %} 161 | {% if monster.opposition_schools %} 162 | 163 | 164 | 165 | 166 | {% endif %} 167 |
Speed{{ monster.speed|safe }}Space{{ monster.space }} ft.Reach{{ monster.reach }}
Melee{{ monster.melee|safe }}Special Attacks{{ monster.special_attacks|safe }}
Ranged{{ monster.ranged }} 136 | {% endif %} 137 | {% if monster.spell_like_abilities %} 138 | Spell-Like Abilities{{ monster.spell_like_abilities|safe }}
Spells Known:{{ monster.spells_known|safe }}
Sorcerer Spells Known:{{ monster.sorcerer_spells_known|safe }}
Spells Prepared:{{ monster.spells_prepared|safe }}
Opposition Schools:{{ monster.opposition_schools }}
168 |
169 | 170 | {% if monster.monsterability_set.all %} 171 |
172 |

Special abilities

173 | 174 | {% for a in monster.monsterability_set.all %} 175 | 176 | {% endfor %} 177 |
{{ a.name }} ({{ a.kind|capfirst }}){{ a.description|safe }}
178 |
179 | {% endif %} 180 | 181 | {{ monster.description|safe }} 182 | 183 | 184 |
185 | {% endblock %} 186 | 187 | {% block sidebar %} 188 | 290 | {% endblock %} 291 | -------------------------------------------------------------------------------- /srd20/migrations/0017_auto__add_characterclass.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import datetime 3 | from south.db import db 4 | from south.v2 import SchemaMigration 5 | from django.db import models 6 | 7 | class Migration(SchemaMigration): 8 | 9 | def forwards(self, orm): 10 | 11 | # Adding model 'CharacterClass' 12 | db.create_table('class', ( 13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), 14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=32)), 15 | ('type', self.gf('django.db.models.fields.CharField')(max_length=32)), 16 | ('alignment', self.gf('django.db.models.fields.CharField')(max_length=128)), 17 | ('hit_die', self.gf('django.db.models.fields.CharField')(max_length=4)), 18 | ('class_skills', self.gf('django.db.models.fields.TextField')()), 19 | ('skill_points', self.gf('django.db.models.fields.CharField')(max_length=1)), 20 | ('skill_points_ability', self.gf('django.db.models.fields.CharField')(max_length=3)), 21 | ('spell_stat', self.gf('django.db.models.fields.CharField')(max_length=4, blank=True)), 22 | ('proficiencies', self.gf('django.db.models.fields.TextField')(blank=True)), 23 | ('spell_type', self.gf('django.db.models.fields.CharField')(max_length=16)), 24 | ('epic_feat_base_level', self.gf('django.db.models.fields.CharField')(max_length=4)), 25 | ('epic_feat_interval', self.gf('django.db.models.fields.CharField')(max_length=4)), 26 | ('epic_feat_list', self.gf('django.db.models.fields.TextField')(blank=True)), 27 | ('epic_full_text', self.gf('django.db.models.fields.TextField')(blank=True)), 28 | ('req_race', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)), 29 | ('req_weapon_proficiency', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)), 30 | ('req_base_attack_bonus', self.gf('django.db.models.fields.CharField')(max_length=4)), 31 | ('req_skill', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)), 32 | ('req_feat', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)), 33 | ('req_spells', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)), 34 | ('req_languages', self.gf('django.db.models.fields.CharField')(max_length=16, blank=True)), 35 | ('req_psionics', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)), 36 | ('req_epic_feat', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)), 37 | ('req_special', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), 38 | ('spell_list_1', self.gf('django.db.models.fields.TextField')(blank=True)), 39 | ('spell_list_2', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), 40 | ('spell_list_3', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), 41 | ('spell_list_4', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), 42 | ('spell_list_5', self.gf('django.db.models.fields.CharField')(max_length=256, blank=True)), 43 | ('full_text', self.gf('django.db.models.fields.TextField')()), 44 | ('reference', self.gf('django.db.models.fields.CharField')(max_length=32)), 45 | )) 46 | db.send_create_signal('srd20', ['CharacterClass']) 47 | 48 | 49 | def backwards(self, orm): 50 | 51 | # Deleting model 'CharacterClass' 52 | db.delete_table('class') 53 | 54 | 55 | models = { 56 | 'srd20.characterclass': { 57 | 'Meta': {'ordering': "('name',)", 'object_name': 'CharacterClass', 'db_table': "'class'"}, 58 | 'alignment': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 59 | 'class_skills': ('django.db.models.fields.TextField', [], {}), 60 | 'epic_feat_base_level': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 61 | 'epic_feat_interval': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 62 | 'epic_feat_list': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 63 | 'epic_full_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 64 | 'full_text': ('django.db.models.fields.TextField', [], {}), 65 | 'hit_die': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 66 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 67 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 68 | 'proficiencies': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 69 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 70 | 'req_base_attack_bonus': ('django.db.models.fields.CharField', [], {'max_length': '4'}), 71 | 'req_epic_feat': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 72 | 'req_feat': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 73 | 'req_languages': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), 74 | 'req_psionics': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 75 | 'req_race': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 76 | 'req_skill': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 77 | 'req_special': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 78 | 'req_spells': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 79 | 'req_weapon_proficiency': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 80 | 'skill_points': ('django.db.models.fields.CharField', [], {'max_length': '1'}), 81 | 'skill_points_ability': ('django.db.models.fields.CharField', [], {'max_length': '3'}), 82 | 'spell_list_1': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 83 | 'spell_list_2': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 84 | 'spell_list_3': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 85 | 'spell_list_4': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 86 | 'spell_list_5': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 87 | 'spell_stat': ('django.db.models.fields.CharField', [], {'max_length': '4', 'blank': 'True'}), 88 | 'spell_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), 89 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 90 | }, 91 | 'srd20.feat': { 92 | 'Meta': {'ordering': "('name',)", 'object_name': 'Feat', 'db_table': "'feat'"}, 93 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 94 | 'benefit': ('django.db.models.fields.TextField', [], {}), 95 | 'choice': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 96 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 97 | 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 98 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 99 | 'normal': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 100 | 'prerequisite': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}), 101 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 102 | 'special': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 103 | 'stack': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 104 | 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}) 105 | }, 106 | 'srd20.spell': { 107 | 'Meta': {'ordering': "('name',)", 'object_name': 'Spell', 'db_table': "'spell'"}, 108 | 'altname': ('django.db.models.fields.SlugField', [], {'max_length': '64', 'db_index': 'True'}), 109 | 'arcane_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 110 | 'arcane_material_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 111 | 'area': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 112 | 'casting_time': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 113 | 'cleric_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 114 | 'components': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 115 | 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 116 | 'descriptor': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 117 | 'druid_focus': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 118 | 'duration': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 119 | 'effect': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 120 | 'focus': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 121 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 122 | 'level': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), 123 | 'material_components': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 124 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 125 | 'range': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 126 | 'reference': ('django.db.models.fields.CharField', [], {'max_length': '30'}), 127 | 'saving_throw': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 128 | 'school': ('django.db.models.fields.CharField', [], {'max_length': '32'}), 129 | 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 130 | 'spell_resistance': ('django.db.models.fields.CharField', [], {'max_length': '64'}), 131 | 'spellcraft_dc': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), 132 | 'subschool': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), 133 | 'target': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 134 | 'to_develop': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 135 | 'verbal_components': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}), 136 | 'xp_cost': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 137 | } 138 | } 139 | 140 | complete_apps = ['srd20'] 141 | -------------------------------------------------------------------------------- /srd20/models.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | from django.db import models 3 | 4 | class Spell(models.Model): 5 | name = models.CharField(max_length=64, 6 | help_text='Complete spell name. Use proper capitalization, and put the ' 7 | 'base name of the spell at the front, i.e. "Heal, Mass" ' 8 | 'instead of "Mass Heal".') 9 | altname = models.SlugField(max_length=64, 10 | help_text='URL version of the name; use only alphanumeric char, dashes ' 11 | 'and keep the text in lowercase except for roman numerals.') 12 | school = models.CharField(max_length=32, 13 | help_text='School of magic, for example "Illusion"') # Probably a FK to a list 14 | subschool = models.CharField(max_length=128, blank=True, 15 | help_text='Subschool of the magic school, if any. Example: "Figment"') # probably a FK to a list 16 | descriptor = models.CharField(max_length=256, blank=True, 17 | help_text='Descriptor list (comma separated). Example "Fire, Chaos"') # A Many to Many to a table. probably with an attribute (may have all of the descriptors or any of them) 18 | spellcraft_dc = models.CharField(max_length=64, blank=True, 19 | verbose_name='Spellcraft DC', 20 | help_text='DC to cast (epic spells)') # This should be a nullable int, possibly with a flag for see text notes 21 | level = models.CharField(max_length=128, blank=True, 22 | help_text='Comma separated list of Class lvl. Example: "Bard 3, Sor/Wiz 4"') # This should be a many-to-many to class level 23 | components = models.CharField(max_length=256, 24 | help_text='Comma separated list,as shown in spell. Example: "V, S, M/DF, XP"') # This should be a set of flags: V, S, M, F, DF, XP, ... possibly from the nullability of other fields 25 | casting_time = models.CharField(max_length=64) # amount + unit, sometimes with notes 26 | range = models.CharField(max_length=64) # Maybe normalized, but more complex 27 | target = models.CharField(max_length=256, blank=True) 28 | area = models.CharField(max_length=256, blank=True) 29 | effect = models.CharField(max_length=256, blank=True) 30 | duration = models.CharField(max_length=128) 31 | saving_throw = models.CharField(max_length=256) # may be normalized, not sure 32 | spell_resistance = models.CharField(max_length=64) # may be normalized, not sure 33 | short_description = models.CharField(max_length=256, 34 | help_text='Short description shown in spell lists') 35 | to_develop = models.TextField(blank=True, 36 | help_text='Cost to develop epic spell') 37 | material_components = models.TextField(blank=True) 38 | arcane_material_components = models.CharField(max_length=256, blank=True) 39 | focus = models.TextField(blank=True) 40 | description = models.TextField(blank=True) 41 | xp_cost = models.TextField(blank=True) 42 | arcane_focus = models.CharField(max_length=256, blank=True) 43 | verbal_components = models.CharField(max_length=256, blank=True) # only used in 1 spell. Possibly should meld into description 44 | cleric_focus = models.CharField(max_length=256, blank=True) 45 | druid_focus = models.CharField(max_length=256, blank=True) 46 | reference = models.CharField(max_length=30, 47 | help_text='Book containing the spell and pag. Example: "SpC 31"') # Should be a FK 48 | 49 | @models.permalink 50 | def get_absolute_url(self): 51 | return ('spell_detail', [], {'slug': self.altname}) 52 | 53 | def __unicode__(self): 54 | return self.name 55 | 56 | class Meta: 57 | db_table = 'spell' 58 | ordering = ('name',) 59 | 60 | class Feat(models.Model): 61 | name = models.CharField(max_length=64) 62 | altname = models.SlugField(max_length=64) 63 | type = models.CharField(max_length=32) # Should be a Many to many, perhaps with an epic flag 64 | multiple = models.BooleanField() 65 | stack = models.BooleanField() 66 | choice = models.CharField(max_length=256, blank=True) 67 | prerequisite = models.CharField(max_length=1024, blank=True) 68 | benefit = models.TextField() 69 | description = models.TextField(blank=True) 70 | normal = models.TextField(blank=True) 71 | special = models.TextField(blank=True) 72 | reference = models.CharField(max_length=32) 73 | 74 | def short_description(self): 75 | return self.description 76 | 77 | @models.permalink 78 | def get_absolute_url(self): 79 | return ('feat_detail', [], {'slug': self.altname}) 80 | 81 | def __unicode__(self): 82 | return self.name 83 | 84 | class Meta: 85 | db_table = 'feat' 86 | ordering = ('name',) 87 | 88 | 89 | class CharacterClass(models.Model): 90 | name = models.CharField(max_length=32) 91 | type = models.CharField(max_length=32) # should be flags: base/prestige, npc or not, epic or not, psionic or not 92 | alignment = models.CharField(max_length=128) # Should be M2M to alignemnt table 93 | hit_die = models.CharField(max_length=4) # Should be integer field 94 | class_skills = models.TextField() # Maybe a M2M to skill, but there are some special cases 95 | skill_points = models.CharField(max_length=1) # Should be integer field 96 | skill_points_ability = models.CharField(max_length=3) # Always intelligence! remove? 97 | spell_stat = models.CharField(max_length=4, blank=True) # ChoiceField, with empty choice 98 | proficiencies = models.TextField(blank=True) 99 | spell_type = models.CharField(max_length=16) # m2m to Arcane, Divine, Psionic 100 | epic_feat_base_level = models.CharField(max_length=4) # Nullable integer field 101 | epic_feat_interval = models.CharField(max_length=4) # Nullable integer field 102 | epic_feat_list = models.TextField(blank=True) 103 | epic_full_text = models.TextField(blank=True) 104 | req_race = models.CharField(max_length=64, blank=True) 105 | req_weapon_proficiency = models.CharField(max_length=64, blank=True) # Only Eldritch Knight uses this field 106 | req_base_attack_bonus = models.CharField(max_length=4,blank=True) # Nullable integer field 107 | req_skill = models.CharField(max_length=128, blank=True) # May be normalized but has special cases 108 | req_feat = models.CharField(max_length=128, blank=True) # May be normalized but has special cases 109 | req_spells = models.CharField(max_length=128,blank=True) 110 | req_languages = models.CharField(max_length=16, blank=True) # Only Dragon Disciple uses this 111 | req_psionics = models.CharField(max_length=64,blank=True) 112 | req_epic_feat = models.CharField(max_length=64, blank=True) # Probably M2M 113 | req_special = models.CharField(max_length=256, blank=True) 114 | spell_list_1 = models.TextField(blank=True) # M2M 115 | spell_list_2 = models.CharField(max_length=256, blank=True) # M2M 116 | spell_list_3 = models.CharField(max_length=256, blank=True) # M2M 117 | spell_list_4 = models.CharField(max_length=256, blank=True) # M2M 118 | spell_list_5 = models.CharField(max_length=256, blank=True) # M2M 119 | full_text = models.TextField() 120 | reference = models.CharField(max_length=32) 121 | 122 | def __unicode__(self): 123 | return self.name 124 | 125 | class Meta: 126 | db_table = 'class' 127 | ordering = ('name',) 128 | verbose_name_plural = 'character classes' 129 | 130 | class Monster(models.Model): 131 | 132 | SIZE_CHOICES = ( 133 | (-4, 'Fine'), 134 | (-3, 'Diminutive'), 135 | (-2, 'Tiny'), 136 | (-1, 'Small'), 137 | ( 0, 'Medium'), 138 | ( 1, 'Large'), 139 | ( 2, 'Huge'), 140 | ( 3, 'Gargantuan'), 141 | ( 4, 'Colossal'), 142 | ) 143 | 144 | TYPES = [ 145 | 'aberration', 'animal', 'construct', 'dragon', 'fey', 'humanoid', 146 | 'magical beast', 'monstrous humanoid', 'ooze', 'outsider', 'plant', 147 | 'undead', 'vermin' 148 | ] 149 | TYPE_CHOICES = [(t, t.capitalize()) for t in TYPES] 150 | CR_CHOICES = [ 151 | (-4, u'⅛'), 152 | (-3, u'⅙'), 153 | (-2, u'¼'), 154 | (-1, u'⅓'), 155 | (0, u'½'), 156 | ] + [(i, str(i)) for i in range(1,31)] 157 | 158 | name = models.CharField(max_length=64) 159 | altname = models.CharField(max_length=64) 160 | flavor_text = models.TextField() 161 | 162 | # Basic information 163 | cr = models.IntegerField(choices=CR_CHOICES) 164 | xp = models.IntegerField() # This should be a function of cr 165 | alignment = models.CharField(max_length=4) # May be "Any", or a specific alignment coded in the usual style 166 | size = models.IntegerField(choices=SIZE_CHOICES) 167 | type = models.CharField(choices=TYPE_CHOICES, max_length=32) 168 | subtypes = models.CharField(max_length=64, blank=True) 169 | other_type = models.CharField(max_length=64, blank=True) # Other type information (for example base creatur for inherited templates) 170 | class_level = models.CharField(max_length=16, blank=True) 171 | initiative = models.IntegerField() 172 | senses = models.CharField(max_length=512, blank=True) 173 | aura = models.CharField(max_length=256, blank=True) 174 | 175 | # Defense 176 | armor_class = models.CharField(max_length=256) 177 | hit_points = models.CharField(max_length=256) 178 | # The saves are typically integers, but sometimes mention modifiers 179 | fortitude_save = models.CharField(max_length=256) 180 | reflex_save = models.CharField(max_length=128) 181 | will_save = models.CharField(max_length=256) 182 | defensive_abilities = models.CharField(max_length=512, blank=True) 183 | damage_reduction_amount = models.PositiveIntegerField(default=0) 184 | damage_reduction_condition = models.CharField(max_length=128, blank=True) 185 | immunities = models.CharField(max_length=1024, blank=True) 186 | resistance = models.CharField(max_length=256, blank=True) 187 | spell_resistance = models.PositiveIntegerField(default=0) 188 | weaknesses = models.CharField(max_length=256, blank=True) 189 | 190 | # Offense 191 | speed = models.CharField(max_length=128, blank=True) 192 | melee = models.CharField(max_length=512, blank=True) 193 | ranged = models.CharField(max_length=256, blank=True) 194 | space = models.DecimalField(max_digits=6, decimal_places=2, null=True) 195 | reach = models.CharField(max_length=128, blank=True) # Not a decimalfield, usually includes clarifications 196 | special_attacks = models.TextField(blank=True) 197 | spell_like_abilities = models.TextField(blank=True) 198 | spells_known = models.TextField(blank=True) 199 | sorcerer_spells_known = models.TextField(blank=True) 200 | spells_prepared = models.TextField(blank=True) 201 | opposition_schools = models.CharField(max_length=64, blank=True) 202 | # TODO: domains 203 | 204 | # Statistics 205 | strength = models.IntegerField() 206 | dexterity = models.IntegerField() 207 | constitution = models.IntegerField() 208 | intelligence = models.IntegerField() 209 | wisdom = models.IntegerField() 210 | charisma = models.IntegerField() 211 | base_attack_bonus = models.IntegerField() 212 | combat_maneuver_bonus = models.CharField(max_length=64) 213 | combat_maneuver_defense = models.CharField(max_length=64) 214 | feats = models.TextField(blank=True) 215 | skills = models.TextField(blank=True) 216 | racial_modifiers = models.CharField(max_length=512, blank=True) 217 | languages = models.TextField(blank=True) 218 | special_qualities = models.CharField(max_length=512, blank=True) 219 | gear = models.CharField(max_length=128, blank=True) 220 | 221 | # Ecology 222 | environment = models.CharField(max_length=256) 223 | organization = models.TextField() 224 | treasure = models.TextField(blank=True) 225 | 226 | # Other 227 | abilities = models.TextField(blank=True) 228 | description = models.TextField(blank=True) 229 | reference = models.CharField(max_length=64) 230 | 231 | class Meta: 232 | ordering = ['name'] 233 | 234 | def __unicode__(self): 235 | return self.name 236 | 237 | @models.permalink 238 | def get_absolute_url(self): 239 | return ('monster_detail', [], {'slug': self.altname}) 240 | 241 | def short_description(self): 242 | subtypes = "(%s)" % self.subtypes if self.subtypes else "" 243 | cclass = "" 244 | result = "CR%s %s %s %s %s" % (self.get_cr_display(), self.alignment, self.get_size_display(), self.type, subtypes) 245 | return result 246 | 247 | class MonsterAbility(models.Model): 248 | ABILITY_KINDS = ( 249 | ('sp', 'Spell-Like'), 250 | ('su', 'Supernatural'), 251 | ('ex', 'Extraordinary'), 252 | ) 253 | monster = models.ForeignKey(Monster) 254 | name = models.CharField(max_length=128) 255 | kind = models.CharField(max_length=2, choices=ABILITY_KINDS) 256 | description = models.TextField() 257 | 258 | --------------------------------------------------------------------------------