diff --git a/.coveragerc b/.coveragerc index eff45e0..5cc4f46 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,5 @@ +[run] +branch = True + [report] -omit = /usr/*, env/* +omit = /usr/*, env/*, ~/virtualenv/python*/*, ~/virtualenv/pypy*/*, /opt/python/* diff --git a/.gitignore b/.gitignore index ef225f6..7ce8581 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,17 @@ -.coveralls.yml -data/config.ini +# Deprecated Data files data/*.xml +# compiled python files *.py[cod] env/ -# C extensions -*.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -!lib/README.md -lib64 -__pycache__ +# Secret Config files: +config.py -# Installer logs -pip-log.txt - -# Unit test / coverage reports +# generated files .coverage .tox nosetests.xml -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject +#vim temp files *.swp -static/coverage/ diff --git a/.travis.yml b/.travis.yml index 173574c..dd25b7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,24 @@ language: python +services: + - redis-server python: - "2.7" - "pypy" install: - pip install -r requirements.txt -# command to run tests -script: nosetests +before_script: + - cp config.py.example config.py + - python reimport_data.py +script: nosetests +after_success: + coveralls +notifications: + irc: + channels: "chat.freenode.net#kakow" + on_success: change # default: always + on_failure: change # default: always + use_notice: true + skip_join: true + template: + - "%{repository} (%{commit}) : %{message} " + - "Build details: %{build_url}" diff --git a/.vimrc b/.vimrc index 2dea63c..291ff95 100644 --- a/.vimrc +++ b/.vimrc @@ -1,5 +1,6 @@ " Indent Python in the Google way. +execute pathogen#infect() setlocal indentexpr=GetGooglePythonIndent(v:lnum) let s:maxoff = 50 " maximum number of lines to look backwards. diff --git a/config.py.example b/config.py.example new file mode 100644 index 0000000..55ec625 --- /dev/null +++ b/config.py.example @@ -0,0 +1,24 @@ +class BaseConfiguration(object): + # Statement for enabling the development environment + DEBUG = True + + LOG_PATH='data/logging.json' + + REDIS_URL='redis://127.0.0.1:6379/' + +class ProductionConfiguration(BaseConfiguration): + # Statement for enabling the development environment + DEBUG = False + + LOG_PATH='data/logging.json' + + REDIS_URL='redis://127.0.0.1:6379/' + +class TestConfiguration(BaseConfiguration): + # Statement for enabling the development environment + DEBUG = False + + LOG_PATH='data/logging.json' + + REDIS_URL='redis://127.0.0.1:6379/' + diff --git a/data/config.ini.example b/data/config.ini.example deleted file mode 100644 index f24aee2..0000000 --- a/data/config.ini.example +++ /dev/null @@ -1,6 +0,0 @@ -[main] -debug=false -[redis] -url = redis://127.0.0.1:6379/ -[logging] -path=data/logging.json diff --git a/generators/Artwork.py b/generators/Artwork.py deleted file mode 100644 index de51252..0000000 --- a/generators/Artwork.py +++ /dev/null @@ -1,22 +0,0 @@ - -from generators.Gem import Gem -from generators.Generator import Generator -import logging - -class Artwork(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self,'gem'): - setattr(self,'gem',Gem(self.redis)) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text - - diff --git a/generators/Bond.py b/generators/Bond.py deleted file mode 100644 index 76dee7e..0000000 --- a/generators/Bond.py +++ /dev/null @@ -1,49 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging -import random - -class Bond(Generator): - """Generate a bond between two people 'you' and 'other'.""" - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - - # if self.you and self.other are not set, set them to defaults. - if not hasattr(self,'you'): - self.you='you' - - # a random NPC - if not hasattr(self,'other'): - self.other=NPC(self.redis).name['full'] - - # We put you and other in an array so we can randomly select - # who is the subject and who is the object. - members=[self.you,self.other] - random.shuffle(members) - if not hasattr(self,'either'): - self.either=members[0] - random.shuffle(members) - - # We use partyA/partyB syntax in the templates - if not hasattr(self,'partyA'): - self.partyA=members.pop() - if not hasattr(self,'partyB'): - self.partyB=members.pop() - - # If we don't already have text, we need to render a template - if not hasattr(self,'text'): - #if we have it, we need to add a "when" as well - if hasattr(self,'when'): - self.template=self.when+', '+self.template - self.text=self.render_template(self.template) - - #final sentence is stored as self.text. - # note the need for capitalization of the first character - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text - diff --git a/generators/Business.py b/generators/Business.py deleted file mode 100644 index 920f60a..0000000 --- a/generators/Business.py +++ /dev/null @@ -1,52 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging -import random - -class Business(Generator): - """ Create a business.""" - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - self.generate_features(self.kind) - self.senses=[] - - #originally I was going to move these to a for loop, but the verb - # doesn't match the variable name, so it would require refactoring - # of the dataset and every other damn thing. Meh. - if hasattr(self, 'smell'): - self.smell='you smell '+self.smell - self.senses.append(self.smell) - if hasattr(self, 'sound'): - self.sound='you hear '+self.sound - self.senses.append(self.sound) - if hasattr(self, 'sight'): - self.sight='you see '+self.sight - self.senses.append(self.sight) - - if not hasattr(self, 'owner'): - self.owner=NPC(redis) - - #TODO patrons should be better calculated - if not hasattr(self, 'patroncount'): - self.patroncount=random.randint(1,10); - - # Business is one of the few classes where trailer doesn't start as part of the name - # So we have to add it here. - if hasattr(self, 'trailer'): - self.name['trailer']=self.trailer - self.name['full']=self.name['full'] +' '+self.trailer.title() - - # If maxfloors isn'd designated, set it to 1 - if not hasattr(self, 'maxfloors'): - self.maxfloors=1 - - #don't set floors if it already exists - if not hasattr(self, 'floor'): - self.floor= random.randint(1,int(self.maxfloors)) - - - def __str__(self): - return "%s %s" %(self.name['full'], self.kind) diff --git a/generators/Continent.py b/generators/Continent.py deleted file mode 100644 index 7f0ccf2..0000000 --- a/generators/Continent.py +++ /dev/null @@ -1,23 +0,0 @@ - -from Country import Country -from generators.Generator import Generator -import logging -import random - -class Continent(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - # set a random count - if not hasattr(self, 'countrycount'): - self.countrycount=random.randint(self.countrydetails['mincount'], self.countrydetails['maxcount']) - - def add_countries(self): - """ add countries to the continent""" - if not hasattr(self, 'countries'): - self.countries=[] - for countryid in xrange(self.countrycount): - self.countries.append( Country(self.redis, {'continent':self} ) ) - - def __str__(self): - return "%s with %s countries" %(self.name['full'], self.countrycount) diff --git a/generators/Country.py b/generators/Country.py deleted file mode 100644 index 78eb4a0..0000000 --- a/generators/Country.py +++ /dev/null @@ -1,23 +0,0 @@ - -from generators.Generator import Generator -from generators.Region import Region -import logging -import random - -class Country(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self, 'regioncount'): - self.regioncount=random.randint(self.regiondetails['mincount'], self.regiondetails['maxcount']) - - def add_regions(self): - """ add regions to the country""" - if not hasattr(self, 'regions'): - self.regions=[] - for regionid in xrange(self.regioncount): - self.regions.append( Region(self.redis,{'country':self } ) ) - - def __str__(self): - return "%s with %s regions" %(self.name['full'], self.regioncount) diff --git a/generators/Cuisine.py b/generators/Cuisine.py deleted file mode 100644 index 230a0b0..0000000 --- a/generators/Cuisine.py +++ /dev/null @@ -1,27 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging -import random - -class Cuisine(Generator): - """ What meals are common in your area? """ - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - - # You never know if you'll want a creator for your meal - if not hasattr(self,'creator'): - setattr(self,'creator',NPC(self.redis)) - - # Double parse the template to fill in templated template values. - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - - #remember to capitalize! - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/Currency.py b/generators/Currency.py deleted file mode 100644 index 17596ac..0000000 --- a/generators/Currency.py +++ /dev/null @@ -1,27 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging -import random - -class Currency(Generator): - """ Define a currency to be used in your game """ - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self, 'count'): - self.count=random.randint(self.amount['min'],self.amount['max']) - # Perhaps your currency has a person on it- a king, queen, etc. - if not hasattr(self,'npc'): - setattr(self,'npc',NPC(self.redis)) - self.logger.error('test') - # Double parse the template to fill in templated template values. - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/Event.py b/generators/Event.py deleted file mode 100644 index c0a67c6..0000000 --- a/generators/Event.py +++ /dev/null @@ -1,19 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Event(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - self.generate_features('event'+self.kind ) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - - def __str__(self): - return self.text diff --git a/generators/Flag.py b/generators/Flag.py deleted file mode 100644 index 040e7ff..0000000 --- a/generators/Flag.py +++ /dev/null @@ -1,40 +0,0 @@ - -from generators.Generator import Generator -import json -import logging -import random -import string - -class Flag(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - self.select_colors() - - self.overlay_stripe_countselected=random.randint(0,int(self.overlay_stripe_count)) - if not hasattr(self, 'letter'): - self.letter=random.choice(string.ascii_uppercase) - - def select_colors(self): - colornames=self.redis.lrange('flagcolor',0,-1) - random.shuffle(colornames) - - if not hasattr(self,'colors'): - self.colors=[] - - for i in range(7-len(self.colors)): - colorname=colornames[i] - jsonstring=self.redis.hget('flagcolor_description',colorname) - #FIXME Note this still overwrites - self.colors.append(json.loads(jsonstring)) - - def tojson(self): - data=self.__dict__ - del data['redis'] - del data['pipeline'] - del data['logger'] - return json.dumps(data, skipkeys=True, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=4, separators=(', ', ': '), encoding="utf-8", default=None, sort_keys=False, ) - - return jsonobj diff --git a/generators/Flaw.py b/generators/Flaw.py deleted file mode 100644 index 3c58f12..0000000 --- a/generators/Flaw.py +++ /dev/null @@ -1,22 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging -import random - -class Flaw(Generator): - """ Define a flaw to be used in your game """ - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - # Double parse the template to fill in templated template values. - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text - diff --git a/generators/Gem.py b/generators/Gem.py deleted file mode 100644 index 574cb80..0000000 --- a/generators/Gem.py +++ /dev/null @@ -1,24 +0,0 @@ - -from generators.Generator import Generator -import logging -import random - -class Gem(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self, 'count'): - self.count=random.randint(self.amount['min'],self.amount['max']) - - if not hasattr(self, 'color'): - self.color=random.choice(self.kind_description['color']) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - def __str__(self): - return "%s %s %s, %s" % (self.quality['name'],self.color, self.kind_description['name'], self.value['name']) - diff --git a/generators/Generator.py b/generators/Generator.py deleted file mode 100644 index 007cbac..0000000 --- a/generators/Generator.py +++ /dev/null @@ -1,178 +0,0 @@ - -from jinja2.environment import Environment -from jinja2 import Template -from util import Filters -from util import Seeds -import json -import logging -import random -import redis - -class Generator(object): - """ An abstracted Generator that all generators are based from """ - def __init__(self,redis, features={},namekey=None): - self.logger=logging.getLogger(__name__) - # Redis is the source of all data. - self.redis=redis - self.pipeline=self.redis.pipeline - # We use our class name as a key for redis - if namekey is None: - namekey= self.__class__.__name__.lower() - - # see if we have a seed to use, otherwise generate a new one. - if 'seed' in features: - self.seed=Seeds.set_seed(features['seed']) - else: - self.seed=Seeds.set_seed() - self.logger.info('new generator %s with seed %i', namekey, self.seed) - - # For naming conventions, we use "name"+classname+"stuff" - self.name=self.generate_name('name_'+namekey) - - # For each feature, set it as an attribute for this generator - for feature, value in features.iteritems(): - # This bit of meta code saves soooo much hassle and getters/setters. - # especially with testing. - setattr( self, feature, value) - - - - # This is the guts of the Generator... - self.generate_features(namekey) - - - def generate_features(self,namekey): - """ Given a namekey, add those features to this object.""" - # find all keys matching our namekey - self.logger.info('Generating features for %s with seed %i', namekey, self.seed) - for key in self.redis.keys(namekey+'_*'): - self.generate_feature(namekey, key) - - - def generate_feature(self,namekey,key): - #check to see if your key has a related chance key - if self.redis.exists(key+"_chance"): - # make sure the value is not already set, then grab it. - if not hasattr(self,key+"_chance"): - setattr(self,key+"_chance", int(self.redis.get(key+"_chance")) ) - - # check to see if you have a preset roll; if not, roll 1-100 - if not hasattr(self, key+"_roll"): - setattr( self, key+"_roll", random.randint(1,100) ) - - # if the roll is greater than the chance, you have failed, and don't get to use this stat. - # Go to the next entry in the for loop. - if int(getattr(self,key+"_roll")) > getattr(self,key+"_chance"): - return - - ########################################################################################## - # Provided you had no associated _chance or that you succeeded on the chance roll, you can - # Move on to actually setting the value. - - # Most features don't need the namekey on the front since it's redundant - # so we shorten the name for brevity. - featurename=key.replace(namekey+'_','') - - # Zset means it's a 1-100 stat; - if self.redis.type(key) == 'zset': - setattr( self, featurename, Generator.select_by_roll(self,key) ) - - # string means it's a simple value that plugs right in - elif self.redis.type(key) == 'string': - setattr( self, featurename, self.redis.get(key) ) - - # List gets a bit tricky; select a value, then see if it has an associated description - elif self.redis.type(key) == 'list' : - - # If feature isn't set, grab a rand value from the list. - if not hasattr(self, featurename): - featurevalue=Generator.rand_value(self,key) - setattr( self, featurename, featurevalue ) - # if the description hasn't been set and exists in redis. - if not hasattr( self, featurename+"_description"): - try: - desc_text=self.redis.hmget(key+"_description",getattr(self,featurename) )[0] - if desc_text is not None: - featurevalue=json.loads(desc_text) - setattr( self, featurename+"_description", featurevalue ) - except ValueError as e: - self.logger.critical("JSON parsing error: Couldn't read json %s",rollvalue[0] ) - raise ValueError( "JSON parsing error: Couldn't read json",rollvalue[0]) - - -#################################################### -# needs refactoring below here. - - - - - # FIXME this needs to be integrated with what NPC races use... - def generate_name(self,key): - """ Given a key, query redis and check if all 5 parts of a name exist, then generate a name structure. - This creates the structure "Title PreRootPost Trailer" - Note that in the full name, the title has a trailing space and the trailer has a preceeding space. - Pre, Root and Post have no spaces.""" - name={'full':''} - - if self.redis.exists(key+'title'): - roll=random.randint(1,100) - if (not self.redis.exists(key+'title_chance')) or (roll < int(self.redis.get(key+'title_chance'))): - name['title']=self.rand_value(key+'title') - name['full']=name['title']+' ' - - for part in [ 'pre', 'root', 'post']: - if self.redis.exists(key+part): - if (not self.redis.exists(key+part+'_chance')) or (random.randint(1,100) < int(self.redis.get(key+part+'_chance'))): - name[part]=self.rand_value(key+part) - name['full']+=name[part] - - if self.redis.exists(key+'trailer'): - roll=random.randint(1,100) - if (not self.redis.exists(key+'trailer_chance')) or (roll < int(self.redis.get(key+'trailer_chance'))): - name['trailer']=self.rand_value(key+'trailer') - name['full']+=' '+name['trailer'] - return name - - def rand_value(self,key): - """ Select a Random Value from the list matching the key in redis. """ - try: - total=self.redis.llen(key) - value=self.redis.lindex(key, random.randint(0,total-1 )) - return value - except Exception as e: - raise Exception( "the key (%s) doesn't appear to exist or isn't a list (%s)." % (key, self.redis.type(key) )) - - def select_by_roll(self,key ): - """ Using roll, select the closest matching score from key in Redis. """ - if key+'_roll' not in self.__dict__ : - setattr(self,key+'_roll', random.randint(1,100)) - - roll=max(1,min(getattr(self,key+'_roll'),100)) - - try: - rollvalue= self.redis.zrangebyscore(key, roll, 100, 0, 1) - if rollvalue == None: - raise LookupError - return json.loads(rollvalue[0]) - except IndexError as e: - raise IndexError( "Is %s a valid key?" %( key) ) - except LookupError as e: - raise Exception( "the key (%s) appears to be empty for a roll of %s- This should never happen." % (key, roll)) - except ValueError as e: - raise Exception( "JSON parsing error: Couldn't read json",rollvalue[0]) - except Exception as e: - raise Exception( "the key (%s) doesn't appear to exist or isn't a zset (%s)." % (key, self.redis.type(key))) - - def render_template(self,template): - """ Renders a given template using itself.""" - environment = Environment() - environment.filters['article'] = Filters.select_article - environment.filters['pluralize'] = Filters.select_pluralize - environment.filters['conjunction'] = Filters.select_conjunction - environment.filters['plural_verb'] = Filters.select_plural_verb - environment.filters['plural_adj'] = Filters.select_plural_adj - - template= environment.from_string(template) - - return template.render(params=self) - diff --git a/generators/GeomorphDungeon.py b/generators/GeomorphDungeon.py deleted file mode 100644 index 68656e5..0000000 --- a/generators/GeomorphDungeon.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from generators.Generator import Generator -import json -import logging -import random - -class GeomorphDungeon(Generator): - - # This is a simple translation table - # bits are sorted [ left bottom right top ] - CELL_TYPES={ - '0b0': {'type':'0000', 'rotation':0 }, # No connections - '0b1': {'type':'0001', 'rotation':0 }, # one side - '0b10': {'type':'0001', 'rotation':1 }, # one side - '0b11': {'type':'0010', 'rotation':0 }, # twoside corner - '0b100': {'type':'0001', 'rotation':2 }, # one side - '0b101': {'type':'0011', 'rotation':0 }, # twoside straight - '0b110': {'type':'0010', 'rotation':1 }, # twosided corner - '0b111': {'type':'0100', 'rotation':0 }, #Three sides - '0b1000': {'type':'0001', 'rotation':3 }, # one side - '0b1001': {'type':'0010', 'rotation':3 }, # twosided corner - '0b1010': {'type':'0011', 'rotation':1 }, # twosided straight - '0b1011': {'type':'0100', 'rotation':3 }, # three sides - '0b1100': {'type':'0010', 'rotation':2 }, # twosided corner - '0b1101': {'type':'0100', 'rotation':2 }, # threesided - '0b1110': {'type':'0100', 'rotation':1 }, # three sides - '0b1111': {'type':'0101', 'rotation':0 } # Four connections - } - - def __init__(self, redis, features={}): - """ Generate a Geomorph-like dungeon """ - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - self.generate_features('dungeon') - - self.apply_text_template() #FIXME refactor with RogueDungeon on dungeon names... - self.width=self.gridwidth['tiles'] - self.height=self.gridheight['tiles'] - - self.generate_grid() - self.generate_connections() - self.set_tiletypes() - - def apply_text_template(self): - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text.title() - - - def convert_to_json(self): - resultmatrix=[] - for row in self.spaces: - resultrow=[] - for cell in row: - resultrow.append({ - "path":cell.image, - "rotation":cell.imagerotation, - } ) - resultmatrix.append(resultrow) - return resultmatrix - - - def set_tiletypes(self): - for row in self.spaces: - for cell in row: - #calculate the binary "cell type" - cell.tiletype=bin( (cell.left << 3) + (cell.bottom << 2) + (cell.right<<1) + ( cell.top<<0 )) - - #translate it with the table - cell.imagetype=int(self.CELL_TYPES[cell.tiletype]['type'],2) - - #Using the proper cell type, select an image from redis - tiledata= json.loads( self.rand_value('geomorph_type_'+str(cell.imagetype)) ) - cell.image=str(tiledata['path']) - cell.author=str(tiledata['author']) - cell.tileset=str(tiledata['tileset']) - # Make sure to capture the rotation needed - cell.imagerotation= self.CELL_TYPES[cell.tiletype]['rotation'] - - def generate_grid(self): - - self.spaces = [ [ GeomorphDungeon.Tile(i,j) for i in range(self.width) ] for j in range(self.height) ] - - def generate_connections(self): - alltiles=[] - for row in self.spaces: - for cell in row: - alltiles.append(cell) - - random.shuffle(alltiles) - - for cell in alltiles: - self.calculate_top(cell) - self.calculate_right(cell) - self.calculate_bottom(cell) - self.calculate_left(cell) - - def calculate_top(self, cell): - if cell.y ==0: - cell.top=False - elif self.spaces[cell.y-1][cell.x].bottom != None : - cell.top=self.spaces[cell.y-1][cell.x].bottom - else: - if random.randint(0,self.segmentation['solidchance']) ==0: - cell.top=False - else: - cell.top=True - - def calculate_right(self, cell): - if cell.x == len(self.spaces[0])-1: - cell.right=False - elif self.spaces[cell.y][cell.x+1].left != None : - cell.right=self.spaces[cell.y][cell.x+1].left - else: - if random.randint(0,self.segmentation['solidchance']) ==0: - cell.right=False - else: - cell.right=True - - def calculate_bottom(self, cell): - if cell.y == len(self.spaces)-1: - cell.bottom=False - elif self.spaces[cell.y+1][cell.x].top != None : - cell.bottom=self.spaces[cell.y+1][cell.x].top - else: - if random.randint(0,self.segmentation['solidchance']) ==0: - cell.bottom=False - else: - cell.bottom=True - - def calculate_left(self, cell): - if cell.x == 0: - cell.left=False - elif self.spaces[cell.y][cell.x-1].right != None : - cell.left=self.spaces[cell.y][cell.x-1].right - else: - if random.randint(0,self.segmentation['solidchance']) ==0: - cell.left=False - else: - cell.left=True - - - class Tile(object): - def __init__(self,x,y ): - #def __init__(self, char='#'): - """ test """ - self.left=None - self.right=None - self.top=None - self.bottom=None - self.char='#' - self.x=x - self.y=y - diff --git a/generators/Govt.py b/generators/Govt.py deleted file mode 100644 index b1dc855..0000000 --- a/generators/Govt.py +++ /dev/null @@ -1,16 +0,0 @@ - -from generators.Country import Country -from generators.Generator import Generator -import logging - -class Govt(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - self.generate_features('govt'+self.kind) - - if not hasattr(self, 'body'): - #TODO this should have an if statement on kind and also do cities - self.body=Country(self.redis) diff --git a/generators/JobPosting.py b/generators/JobPosting.py deleted file mode 100644 index b38356c..0000000 --- a/generators/JobPosting.py +++ /dev/null @@ -1,42 +0,0 @@ - -from generators.Business import Business -from generators.Generator import Generator -from generators.NPC import NPC -import logging - -class JobPosting(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - for field in [ 'contact','npc']: - if not hasattr(self,field): - setattr(self,field,NPC(self.redis)) - if not hasattr(self,'business'): - setattr(self,'business',Business(self.redis)) - - - if not hasattr(self,'text'): - - for field in [ 'hook', 'request']: - if hasattr(self,field): - self.template= getattr(self, field) +' '+self.template - - for field in [ 'requirement', 'disclaimer', 'payment']: - if hasattr(self,field): - self.template= self.template+' '+getattr(self, field) - - self.template=self.template+' Contact '+self.contact.name['full'] - self.template=self.template+" at the "+self.business.name['full'] - if hasattr(self, 'detail'): - self.template=self.template+" "+self.detail - - self.template+="." - - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text - diff --git a/generators/Leader.py b/generators/Leader.py deleted file mode 100644 index 52f69d3..0000000 --- a/generators/Leader.py +++ /dev/null @@ -1,29 +0,0 @@ - -from generators.Country import Country -from generators.Generator import Generator -from generators.NPC import NPC -from generators.Sect import Sect -import logging - -class Leader(NPC): - """ Generate a god for your world""" - def __init__(self, redis, features={}): - NPC.__init__(self,redis,features, 'npc') - self.logger=logging.getLogger(__name__) - - self.generate_features('leader') - self.generate_features('leader'+self.kind) - - if self.kind_description['scope'] == 'country': - self.location=Country(self.redis, {'leader':self}) -# elif self.kind_description['scope'] == 'city': -# self.location=City(self.redis, {'leader':self}) - else: -# TODO This should default to organization... - self.location=Country(self.redis, {'leader':self}) - - self.set_title() - - def set_title(self): - self.name['title']=self.leader_description[self.sex['name']] - self.name['fulltitled']=self.name['title'] +" "+self.name['full'] diff --git a/generators/Legend.py b/generators/Legend.py deleted file mode 100644 index 35cf8d3..0000000 --- a/generators/Legend.py +++ /dev/null @@ -1,22 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging - -class Legend(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - for person in ['npc','villain' ]: - if not hasattr(self,person): - setattr(self,person,NPC(self.redis)) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/MagicItem.py b/generators/MagicItem.py deleted file mode 100644 index d8f46b5..0000000 --- a/generators/MagicItem.py +++ /dev/null @@ -1,34 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -from jinja2.environment import Environment -from jinja2 import Template -from util import Filters -import logging - -class MagicItem(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - self.generate_features(self.kind) - - self.npc=NPC(redis) - - self.build_creator() - - text=self.render_template(self.name_template) - self.name=self.render_template(text) - - def build_creator(self): - environment = Environment() - environment.filters['article'] = Filters.select_article - environment.filters['pluralize'] = Filters.select_pluralize - template= environment.from_string(self.creator_template) - - self.creator=template.render(npc=self.npc) - -# TODO needs real testing! - -#TODO move FILTER additions to generator -#TODO same with template rendering diff --git a/generators/Misfire.py b/generators/Misfire.py deleted file mode 100644 index 2ce15fe..0000000 --- a/generators/Misfire.py +++ /dev/null @@ -1,17 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Misfire(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/Moon.py b/generators/Moon.py deleted file mode 100644 index 82fe630..0000000 --- a/generators/Moon.py +++ /dev/null @@ -1,8 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Moon(Generator): - def __init__(self, server, features={}): - Generator.__init__(self,server,features) - self.logger=logging.getLogger(__name__) diff --git a/generators/Motivation.py b/generators/Motivation.py deleted file mode 100644 index a44727f..0000000 --- a/generators/Motivation.py +++ /dev/null @@ -1,19 +0,0 @@ - -from generators.Generator import Generator -import generators -import logging - -class Motivation(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - self.generate_features('motivation'+self.kind) - - if not hasattr(self, 'npc'): - self.npc=generators.NPC.NPC(self.redis, {'motivation':self}) - - self.text=self.render_template(self.text) - def __str__(self): - return self.text diff --git a/generators/MundaneItem.py b/generators/MundaneItem.py deleted file mode 100644 index af8ea72..0000000 --- a/generators/MundaneItem.py +++ /dev/null @@ -1,18 +0,0 @@ - -from generators.Generator import Generator -import logging - -class MundaneItem(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self,'text'): - #TODO move this to the data file - #self.text=self.render_template("{{params.quality['name']|article}} {{params.kind}}, {{params.repair['name']}}") - self.text=self.render_template("{{params.kind}}") - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/NPC.py b/generators/NPC.py deleted file mode 100644 index d6a80c6..0000000 --- a/generators/NPC.py +++ /dev/null @@ -1,55 +0,0 @@ - -from generators.Generator import Generator -import generators -import json -import logging -import random - -class NPC(Generator): - def __init__(self, redis, features={}, namekey=None ): - - Generator.__init__(self,redis,features,namekey) - self.logger=logging.getLogger(__name__) - - if self.race not in self.redis.lrange('npc_race',0,-1): - raise Exception, " %s is not a valid race and has no associated data" % (self.race) - self.generate_features(self.race) - self.generate_features(self.covering) - self.coveringtext=self.render_template(self.covertemplate) - - self.details=json.loads(self.details) - - self.select_names() - - if hasattr(self, 'subrace'): - self.race= self.subrace_description['subrace'].lower() - - if not hasattr(self,'motivation'): - self.motivation=generators.Motivation.Motivation(self.redis, {'npc':self}) - - - def select_names(self): - nameorder= self.redis.zrange(self.race+'_name_order',0,-1) - for namejson in nameorder : - name=json.loads(namejson)['name'] - self.name[name]={} - nameparts=self.redis.hgetall(self.race+"_name_"+name) - for namepart in nameparts : - namepartkey=self.race+"_name_"+name+"_"+namepart - # if random number is less than nape part chance - if random.randint(0,100) <= int( nameparts[namepart]): - self.name[name][namepart] = self.rand_value(namepartkey) - - self.name[name+"name"]="" - for namepart in ['title','pre', 'root', 'post','trailer']: - if namepart in self.name[name]: - if namepart == 'trailer': #space goes before namepart - self.name[name+"name"]+=" " - self.name[name+"name"]+=self.name[name][namepart] - if namepart == 'title': #space goes after namepart - self.name[name+"name"]+=" " - - self.name['full']+=self.name[name+"name"]+" " - self.name['full']=self.name['full'].strip() - - diff --git a/generators/Organization.py b/generators/Organization.py deleted file mode 100644 index 83dc0db..0000000 --- a/generators/Organization.py +++ /dev/null @@ -1,19 +0,0 @@ - -from generators.Generator import Generator -from generators.Leader import Leader -import logging - -class Organization(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self,'leader'): - self.leader=Leader(self.redis) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.oldname=self.name['full'] - self.name['full']=self.text - diff --git a/generators/Resource.py b/generators/Resource.py deleted file mode 100644 index 2f4e958..0000000 --- a/generators/Resource.py +++ /dev/null @@ -1,27 +0,0 @@ - -from generators.Generator import Generator -from generators.Region import Region -import logging - -class Resource(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - del self.name - - if not hasattr(self,'place'): - self.place=Region(self.redis) - - self.subkind=self.kind+'_'+self.rand_value(self.kind+"_kind") - - self.generate_features(self.subkind) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/RogueDungeon.py b/generators/RogueDungeon.py deleted file mode 100644 index 523226d..0000000 --- a/generators/RogueDungeon.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from generators.Generator import Generator -import json -import logging -import random - -class RogueDungeon(Generator): - def __init__(self, redis, features={}): - """ Generate a Rogue-like dungeon """ - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - self.generate_features('dungeon') - - self.apply_text_template() - self.generate_grid() - self.generate_rooms() - self.generate_halls() - - def apply_text_template(self): - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text.title() - - def generate_grid(self): - gridsize=random.randint( self.size['minsize'], self.size['maxsize']) - self.height=gridsize - self.width=int(gridsize*1.8) - - self.spaces = [ [ RogueDungeon.Tile() for i in range(self.width) ] for j in range(self.height) ] - - def convert_to_json(self): - resultmatrix=[] - - for row in self.spaces: - resultrow=[] - for cell in row: - resultrow.append({ - "passable": int(cell.passable), - "doorway": int(cell.isdoorway), - "class":cell.__class__.__name__.lower() - } ) - resultmatrix.append(resultrow) - return resultmatrix - - def create_random_room(self): - - # TODO FIXME w and h is too large, need to make sure it fits in self.width - w =min(self.width-1, random.randint( self.room_size['minsize'], self.room_size['maxsize']) ) - h =min(self.height-1, random.randint( self.room_size['minsize'], self.room_size['maxsize'])) - #random position without going out of the boundaries of the map - - x = random.randint( 0, self.width - w - 1) - y = random.randint( 0, self.height - h - 1) - return RogueDungeon.Room(x, y, w, h) - - - def generate_halls(self): - previous_room=None - rooms=self.rooms - random.shuffle(rooms) - for room in rooms: - if previous_room == None: - room.kind="entrance" - room.kind_description={'name':'entrance', "description":"the way in"} - room.egress=True - else: - self.connect_rooms( room, previous_room ) - room.kind=self.rand_value('roguedungeonroom_kind') - kinddesc=self.redis.hmget("roguedungeonroom_kind_description",room.kind ) - room.kind_description=json.loads(kinddesc[0] ) - previous_room=room - - - def generate_rooms(self): - self.rooms = [] - max_rooms =random.randint( self.room_count['minsize'], self.room_count['maxsize']) - - for r in range(max_rooms): - new_room=self.create_random_room() - - conflict = False - for other_room in self.rooms: - if new_room.intersect(other_room): - conflict = True - break - if not conflict: - self.paint_room(new_room) - self.rooms.append(new_room) - - def connect_rooms(self,new_room,old_room): - pathtype=random.randint(0,3) - ymidpoint=random.randint(min(new_room.center['y'],old_room.center['y']),max(new_room.center['y'],old_room.center['y'])) - xmidpoint=random.randint(min(new_room.center['x'],old_room.center['x']),max(new_room.center['x'],old_room.center['x'])) - - if pathtype == 0: - # startroom new_room - self.paint_h_tunnel(new_room.center['x'], xmidpoint, new_room.center['y']) - self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], xmidpoint) - self.paint_h_tunnel(xmidpoint, old_room.center['x'], old_room.center['y']) - elif pathtype ==1: - # startroom room a - self.paint_v_tunnel(new_room.center['y'], ymidpoint, new_room.center['x']) - self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], ymidpoint) - self.paint_v_tunnel(ymidpoint, old_room.center['y'], old_room.center['x']) - elif pathtype ==2: - # startroom new_room - self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], new_room.center['y']) - self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], old_room.center['x']) - else: - #startroom old_room - self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], new_room.center['x']) - self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], old_room.center['y']) - - - - def paint_room(self,room): - for x in range(room.x1 + 1, room.x2): - for y in range(room.y1 + 1, room.y2): - self.spaces[y][x]=RogueDungeon.RoomTile(room.roomid) - - def paint_h_tunnel(self,x1, x2, y): - lasttile=None - for x in range(min(x1, x2), max(x1, x2) + 1): - if type(self.spaces[y][x]) is RogueDungeon.RoomTile and type(lasttile) is RogueDungeon.HallTile: - # Ignore room tiles, but track that the last tile was a room tile - lasttile.isdoorway=True - elif type(self.spaces[y][x]) is RogueDungeon.Tile: - self.spaces[y][x]=RogueDungeon.HallTile() - if type(lasttile) is RogueDungeon.RoomTile: - self.spaces[y][x].isdoorway=True - lasttile=self.spaces[y][x] - - def paint_v_tunnel(self,y1, y2, x): - lasttile=None - for y in range(min(y1, y2), max(y1, y2) + 1): - if type(self.spaces[y][x]) is RogueDungeon.RoomTile and type(lasttile) is RogueDungeon.HallTile: - # Ignore room tiles, but track that the last tile was a room tile - lasttile.isdoorway=True - elif type(self.spaces[y][x]) is RogueDungeon.Tile: - self.spaces[y][x]=RogueDungeon.HallTile() - if type(lasttile) is RogueDungeon.RoomTile: - self.spaces[y][x].isdoorway=True - lasttile=self.spaces[y][x] - - - - - - - - def printfloor(self): - output="" - for row in self.spaces: - for cell in row: - output+=str(cell)+" " - output+="\n" - return output - - - - class Tile(object): - def __init__(self, char='#'): - #def __init__(self, char='#'): - """ test """ - self.char=char - self.isdoorway=False - self.passable=False - - def __str__(self): - return self.char.encode('utf8') - - class RoomTile(Tile): - def __init__(self, roomid): - """ test """ - self.roomid=roomid - self.char='.' - self.isdoorway=False - self.passable=True - - class HallTile(Tile): - def __init__(self, char='.'): - """ test """ - self.char=char - self.isdoorway=False - self.passable=True - - class Room(object): - roomid=0 - def __init__(self, x, y, w, h): - """ test """ - RogueDungeon.Room.roomid+=1 - self.egress=False - self.roomid=RogueDungeon.Room.roomid - self.x1 = x - self.y1 = y - self.x2 = x + w - self.y2 = y + h - center_x = (self.x1 + self.x2) / 2 - center_y = (self.y1 + self.y2) / 2 - self.center={"x":center_x,"y":center_y} - - - def intersect(self, other): - #returns true if this rectangle intersects with another one - return (self.x1 <= other.x2 and self.x2 >= other.x1 and - self.y1 <= other.y2 and self.y2 >= other.y1) - - - - - -#http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_3 - - - -# Garbage I was playing around with. - -#class UpTile(DungeonTile): -# def __init__(self, char=u'ߡ'): -# """ test """ -# self.char=char -# self.passable=False -# -#class DownTile(DungeonTile): -# def __init__(self, char=u'ߜ'): -# """ test """ -# self.char=char -# self.passable=False -# -#class PortalTile(DungeonTile): -# def __init__(self, char=u'Ω'): -# """ test """ -# self.char=char -# self.passable=False -# -#class WaterTile(DungeonTile): -# def __init__(self, char=u'ω'): -# """ test """ -# self.char=char -# self.passable=False -# -# -#class LavaTile(DungeonTile): -# def __init__(self, char=u'Ж'): -## def __init__(self, char=u'ж'): -# """ test """ -# self.char=char -# self.passable=False diff --git a/generators/Rumor.py b/generators/Rumor.py deleted file mode 100644 index 0fde21e..0000000 --- a/generators/Rumor.py +++ /dev/null @@ -1,22 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging - -class Rumor(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - for person in ['victim', 'culprit', 'source', 'believer' ]: - if not hasattr(self,person): - setattr(self,person,NPC(self.redis).name['full']) - - if not hasattr(self,'text'): - self.text=self.render_template(self.template) - self.text=self.render_template(self.text) - self.text=self.text[0].capitalize()+self.text[1:] - - def __str__(self): - return self.text diff --git a/generators/Sect.py b/generators/Sect.py deleted file mode 100644 index 69f1d4a..0000000 --- a/generators/Sect.py +++ /dev/null @@ -1,22 +0,0 @@ - -from generators.Generator import Generator -import generators -import logging -import random - -class Sect(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - if not hasattr(self, 'deity'): - self.deity=generators.Deity.Deity(redis) - - - if not hasattr(self, 'domain'): - portfolio=self.deity.portfolios - random.shuffle(portfolio) - self.domain=portfolio[0] - -#TODO this should have an __str__; is it using the text->template pattern? diff --git a/generators/Star.py b/generators/Star.py deleted file mode 100644 index 47dc73b..0000000 --- a/generators/Star.py +++ /dev/null @@ -1,8 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Star(Generator): - def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) diff --git a/generators/Street.py b/generators/Street.py deleted file mode 100644 index 881cd3b..0000000 --- a/generators/Street.py +++ /dev/null @@ -1,15 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Street(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - if 'trailer' not in self.name: - self.name['trailer']=self.kind - self.name['full']+=" "+self.kind - - self.name['full']= self.name['full'].title() - diff --git a/generators/Wanted.py b/generators/Wanted.py deleted file mode 100644 index c2d3ecd..0000000 --- a/generators/Wanted.py +++ /dev/null @@ -1,18 +0,0 @@ - -from generators.Generator import Generator -from generators.NPC import NPC -import logging - -class Wanted(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - - for person in ['npc','victim' ]: - if not hasattr(self,person): - setattr(self,person,NPC(self.redis)) - - self.headline=self.render_template(self.headline) - self.lastseen=self.render_template(self.lastseen) - diff --git a/generators/Weather.py b/generators/Weather.py deleted file mode 100644 index 7230ce8..0000000 --- a/generators/Weather.py +++ /dev/null @@ -1,10 +0,0 @@ - -from generators.Generator import Generator -import logging - -class Weather(Generator): - def __init__(self, redis, features={}): - - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) - diff --git a/generators/__init__.py b/generators/__init__.py deleted file mode 100644 index beb6f90..0000000 --- a/generators/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Generators package -""" diff --git a/megacosm.py b/megacosm.py deleted file mode 100644 index 27f570c..0000000 --- a/megacosm.py +++ /dev/null @@ -1,945 +0,0 @@ -"""`main` is the top level module for this application.""" - -# Import the stuffs! -from flask import Flask, render_template, request -from generators import Artwork -from generators import Planet -from generators import NPC -from generators import MagicItem -from generators import Deity -from generators import Bond -from generators import Rumor -from generators import Cuisine -from generators import Continent -from generators import Country -from generators import Sect -from generators import Leader -from generators import Legend -from generators import Business -from generators import Star -from generators import Moon -from generators import Currency -from generators import Misfire -from generators import Region -from generators import Wanted -from generators import Weather -from generators import Govt -from generators import Resource -from generators import Event -from generators import JobPosting -from generators import Gem -from generators import MundaneItem -from generators import Motivation -from generators import RogueDungeon -from generators import GeomorphDungeon -from generators import Street -from generators import Flag -from generators import Flaw -from util.Seeds import set_seed -from generators import Organization -from util import Filters -import logging -import logging.config -import redis -import ConfigParser -import datetime -import json -import re -import traceback - -CONFIG = ConfigParser.RawConfigParser() -CONFIG.read('data/config.ini') - -URL = CONFIG.get('redis', 'url') -server = redis.from_url(URL) - -#logfile= open(CONFIG.get('logging', 'path')) -#logging.config.dictConfig(json.load(logfile)) - -# This thing here.. does stuff. -app = Flask(__name__) - -######################################################################### - -@app.route('/') -def indexpage(): - """This is the first page anyone sees.""" - return render_template('index.html') - -######################################################################### - -@app.route('/magicitem') -def generatemagicitem(): - """Generate a MagicItem""" - - features = feature_filter('magicitem') - magicitem = MagicItem.MagicItem(server, features) - - kind = magicitem.kind - return render_template('magicitem_'+kind+'.html', tempobj=magicitem) - -@app.route('/magicitem_builder') -def magicitem_builder(): - """Build a Magic Item""" - - classname = 'magicitem' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - - -@app.route('/npc') -def generatenpc(): - """Generate an NPC""" - - features = feature_filter('npc') - features['deity'] = Deity.Deity(server) - tempobj = NPC.NPC(server, features) - return render_template('npc.html', tempobj=tempobj) - -@app.route('/npc_builder') -def npc_builder(): - """Build an NPC""" - classname = 'npc' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - -@app.route('/bond') -def generatebond(): - """Generate a bond""" - - features = feature_filter('bond') - titletext = 'The Ties that Bind Us..' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - bonds = [] - for _ in xrange(int(request.args['count'])): - bonds.append(Bond.Bond(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=bonds, oneliner=bonds[0], titletext=titletext, generator='bond') - else: - bond = Bond.Bond(server, features) - return render_template('oneliner.html', oneliner=bond, titletext=titletext, generator='bond') - -@app.route('/bond_builder') -def bond_builder(): - """Build a bond""" - - statinfo = {} - for stat in ['when', 'template']: - statinfo[stat] = [] - for statstring in server.lrange('bond_'+stat, 0, -1): - statinfo[stat].append(statstring) - - return render_template('bond_builder.html', statinfo=statinfo) - -######################################################################### -@app.route('/planet_builder') -def planet_builder(): - """Build a planet""" - classname = 'planet' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -@app.route('/planet') -def generateplanet(): - """Generate a planet""" - features = feature_filter('planet') - planet = Planet.Planet(server, features) - planet.add_continents() - return render_template('planet.html', tempobj=planet) - - -######################################################################### - -@app.route('/resource') -def generateresource(): - """Generate a resource""" - - features = feature_filter('resource') - titletext = 'At Your Disposal...' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - resources = [] - for _ in xrange(int(request.args['count'])): - resources.append(Resource.Resource(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=resources, oneliner=resources[0], titletext=titletext, generator='resource') - else: - resource = Resource.Resource(server, features) - return render_template('oneliner.html', oneliner=resource, titletext=titletext, generator='resource') - - - -@app.route('/resource_builder') -def resource_builder(): - """Build a resource""" - classname = 'resource' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/artwork') -def generateartwork(): - """Generate a artwork""" - features = feature_filter('artwork') - titletext = 'A Work of Art...' - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - artworks = [] - for _ in xrange(int(request.args['count'])): - artworks.append(Artwork.Artwork(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=artworks, oneliner=artworks[0], titletext=titletext, generator='artwork') - else: - artwork = Artwork.Artwork(server, features) - return render_template('oneliner.html', oneliner=artwork, titletext=titletext, generator='artwork') - - - -@app.route('/artwork_builder') -def artwork_builder(): - """Build a a artwork""" - classname = 'artwork' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/rumor') -def generaterumor(): - """Generate a rumor""" - features = feature_filter('rumor') - titletext = 'Did You Hear?' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - rumors = [] - for _ in xrange(int(request.args['count'])): - rumors.append(Rumor.Rumor(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=rumors, oneliner=rumors[0], titletext=titletext, generator='rumor') - else: - rumor = Rumor.Rumor(server, features) - return render_template('oneliner.html', oneliner=rumor, titletext=titletext, generator='rumor') - - - -@app.route('/rumor_builder') -def rumor_builder(): - """Build a a rumor""" - classname = 'rumor' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/misfire') -def generatemisfire(): - """Generate a misfire""" - - features = feature_filter('misfire') - titletext = 'My Spell Misfired!' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - misfires = [] - for _ in xrange(int(request.args['count'])): - misfires.append(Misfire.Misfire(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=misfires, oneliner=misfires[0], titletext=titletext, generator='misfire') - else: - misfire = Misfire.Misfire(server, features) - return render_template('oneliner.html', oneliner=misfire, titletext=titletext, generator='misfire') - - -@app.route('/misfire_builder') -def misfire_builder(): - """Build a a misfire""" - classname = 'misfire' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - - -@app.route('/flaw') -def generateflaw(): - """Generate a flaw""" - features = feature_filter('flaw') - titletext = 'My Greatest Flaw...' - - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - flaws = [] - for _ in xrange(int(request.args['count'])): - flaws.append(Flaw.Flaw(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=flaws, oneliner=flaws[0], titletext=titletext, generator='flaw') - else: - flaw = Flaw.Flaw(server, features) - return render_template('oneliner.html', oneliner=flaw, titletext=titletext, generator='flaw') - - - -@app.route('/flaw_builder') -def flaw_builder(): - """Build a a flaw""" - classname = 'flaw' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - - -@app.route('/currency') -def generatecurrency(): - """Generate a currency""" - features = feature_filter('currency') - titletext = 'Spare Some Change?' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - currencys = [] - for _ in xrange(int(request.args['count'])): - currencys.append(Currency.Currency(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=currencys, oneliner=currencys[0], titletext=titletext, generator='currency') - else: - currency = Currency.Currency(server, features) - return render_template('oneliner.html', oneliner=currency, titletext=titletext, generator='currency') - - - -@app.route('/currency_builder') -def currency_builder(): - """Build a a currency""" - classname = 'currency' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/jobposting') -def generatejobposting(): - """Generate a jobposting""" - - features = feature_filter('jobposting') - titletext = 'Help Wanted!' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - jobpostings = [] - for _ in xrange(int(request.args['count'])): - jobpostings.append(JobPosting.JobPosting(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=jobpostings, oneliner=jobpostings[0], titletext=titletext, generator='jobposting') - else: - jobposting = JobPosting.JobPosting(server, features) - return render_template('oneliner.html', oneliner=jobposting, titletext=titletext, generator='jobposting') - - - -@app.route('/jobposting_builder') -def jobposting_builder(): - """Build a a jobposting""" - classname = 'jobposting' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - - -@app.route('/event') -def generateevent(): - """Generate a event""" - - features = feature_filter('event') - titletext = 'Look over there...' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - events = [] - for _ in xrange(int(request.args['count'])): - events.append(Event.Event(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=events, oneliner=events[0], titletext=titletext, generator='event') - else: - event = Event.Event(server, features) - return render_template('oneliner.html', oneliner=event, titletext=titletext, generator='event') - -@app.route('/event_builder') -def event_builder(): - """Build a a event""" - classname = 'event' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - - -@app.route('/motivation') -def generatemotivation(): - """Generate a motivation""" - features = feature_filter('motivation') - titletext = 'I\'m Motivated...' - features['npc'] = NPC.NPC(server) - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - motivations = [] - for _ in xrange(int(request.args['count'])): - motivations.append(Motivation.Motivation(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=motivations, oneliner=motivations[0], titletext=titletext, generator='motivation') - else: - motivation = Motivation.Motivation(server, features) - return render_template('oneliner.html', oneliner=motivation, titletext=titletext, generator='motivation') - -@app.route('/motivation_builder') -def motivation_builder(): - """Build a a motivation""" - classname = 'motivation' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - - -@app.route('/gem') -def generategem(): - """Generate a gem""" - features = feature_filter('gem') - titletext = 'OOOH, Shiny...' - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - gems = [] - for _ in xrange(int(request.args['count'])): - gems.append(Gem.Gem(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=gems, oneliner=gems[0], titletext=titletext, generator='gem') - else: - gem = Gem.Gem(server, features) - return render_template('oneliner.html', oneliner=gem, titletext=titletext, generator='gem') - -@app.route('/gem_builder') -def gem_builder(): - """Build a a gem""" - classname = 'gem' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/mundaneitem') -def generatemundaneitem(): - """Generate a mundaneitem""" - - features = feature_filter('mundaneitem') - titletext = 'Look what I found!' - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - mundaneitems = [] - for _ in xrange(int(request.args['count'])): - mundaneitems.append(MundaneItem.MundaneItem(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=mundaneitems, oneliner=mundaneitems[0], titletext=titletext, generator='mundaneitem') - else: - mundaneitem = MundaneItem.MundaneItem(server, features) - return render_template('oneliner.html', oneliner=mundaneitem, titletext=titletext, generator='mundaneitem') - -@app.route('/mundaneitem_builder') -def mundaneitem_builder(): - """Build a a mundaneitem""" - classname = 'mundaneitem' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - - -@app.route('/legend') -def generatelegend(): - """Generate a legend""" - features = feature_filter('legend') - titletext = 'Let me tell you a story...' - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - legends = [] - for _ in xrange(int(request.args['count'])): - legends.append(Legend.Legend(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=legends, oneliner=legends[0], titletext=titletext, generator='legend') - else: - legend = Legend.Legend(server, features) - return render_template('oneliner.html', oneliner=legend, titletext=titletext, generator='legend') - -@app.route('/legend_builder') -def legend_builder(): - """Build a a legend""" - classname = 'legend' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/organization') -def GenerateOrganization(): - """Generate a simple organization""" - features = feature_filter('organization') - tempobj = Organization.Organization(server, features) - return render_template('organization.html', tempobj=tempobj) - - -@app.route('/organization_builder') -def Organization_Builder(): - """Generate the basic data about a organization""" - classname = 'organization' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - -@app.route('/business') -def generatebusiness(): - """Generate a business""" - features = feature_filter('business') - business = Business.Business(server, features) - return render_template('business.html', tempobj=business) - - -@app.route('/business_builder') -def business_builder(): - """Build a a business""" - - classname = 'business' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/street') -def generatestreet(): - """Generate a street""" - features = feature_filter('street') - tempobj = Street.Street(server, features) - return render_template('street.html', tempobj=tempobj) - - -@app.route('/street_builder') -def street_builder(): - """Build a a street""" - - classname = 'street' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/moon') -def generatemoon(): - """Generate a moon""" - features = feature_filter('moon') - moon = Moon.Moon(server, features) - return render_template('moon.html', tempobj=moon) - - -@app.route('/moon_builder') -def moon_builder(): - """Build a a moon""" - classname = 'moon' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/star') -def generatestar(): - """Generate a star""" - features = feature_filter('star') - star = Star.Star(server, features) - return render_template('star.html', tempobj=star) - - -@app.route('/star_builder') -def star_builder(): - """Build a a star""" - classname = 'star' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/continent') -def generatecontinent(): - """Generate a continent""" - features = feature_filter('continent') - continent = Continent.Continent(server, features) - continent.add_countries() - return render_template('continent.html', tempobj=continent) - - -@app.route('/continent_builder') -def continent_builder(): - """Build a a continent""" - classname = 'continent' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/region') -def generateregion(): - """Generate a region""" - features = feature_filter('region') - region = Region.Region(server, features) -# region.add_cities() -# region.add_locations()() - return render_template('region.html', tempobj=region) - - -@app.route('/region_builder') -def region_builder(): - """Build a a region""" - classname = 'region' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/sect') -def generatesect(): - """Generate a sect""" - - features = feature_filter('sect') - sect = Sect.Sect(server, features) - return render_template('sect.html', tempobj=sect) - - -@app.route('/sect_builder') -def sect_builder(): - """Build a a sect""" - classname = 'sect' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - -@app.route('/govt') -def generategovt(): - """Generate a govt""" - features = feature_filter('govt') - govt = Govt.Govt(server, features) - return render_template('govt.html', tempobj=govt) - - -@app.route('/govt_builder') -def govt_builder(): - """Build a a govt""" - classname = 'govt' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/weather') -def generateweather(): - """Generate a weather""" - features = feature_filter('weather') - weather = Weather.Weather(server, features) - return render_template('weather.html', tempobj=weather) - - -@app.route('/weather_builder') -def weather_builder(): - """Build a a weather""" - classname = 'weather' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/wanted') -def generatewanted(): - """Generate a wanted""" - features = feature_filter('wanted') - wanted = Wanted.Wanted(server, features) - return render_template('wanted.html', tempobj=wanted) - - -@app.route('/wanted_builder') -def wanted_builder(): - """Build a a wanted""" - classname = 'wanted' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - - -######################################################################### - -@app.route('/geomorphdungeon') -def generategeomorphdungeon(): - """Generate a geomorphdungeon""" - features = feature_filter('geomorphdungeon') - geomorphdungeon = GeomorphDungeon.GeomorphDungeon(server, features) - return render_template('geomorphdungeon.html', tempobj=geomorphdungeon, jsondata=geomorphdungeon.convert_to_json()) - -@app.route('/geomorphdungeon_builder') -def geomorphdungeon_builder(): - """Build a a geomorphdungeon""" - classname = 'geomorphdungeon' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/roguedungeon') -def generateroguedungeon(): - """Generate a dungeon""" - features = feature_filter('roguedungeon') - roguedungeon = RogueDungeon.RogueDungeon(server, features) - return render_template('roguedungeon.html', tempobj=roguedungeon, jsondata=roguedungeon.convert_to_json()) - - -@app.route('/roguedungeon_builder') -def roguedungeon_builder(): - """Build a a dungeon""" - classname = 'roguedungeon' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - - -@app.route('/country') -def generatecountry(): - """Generate a country""" - features = feature_filter('country') - country = Country.Country(server, features) - country.add_regions() - return render_template('country.html', tempobj=country) - - -@app.route('/country_builder') -def country_builder(): - """Build a a country""" - classname = 'country' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### - -@app.route('/cuisine') -def generatecuisine(): - """Generate a cuisine""" - features = feature_filter('cuisine') - features['region'] = Region.Region(server) - titletext = 'What\'s for Dinner?' - if 'count' in request.args and request.args['count'].isdigit() and int(request.args['count']) > 1 and int(request.args['count']) <= 100: - cuisines = [] - for _ in xrange(int(request.args['count'])): - cuisines.append(Cuisine.Cuisine(server, features)) - features['seed'] = set_seed() - return render_template('oneliner.html', oneliners=cuisines, oneliner=cuisines[0], titletext=titletext, generator='cuisine') - else: - cuisine = Cuisine.Cuisine(server, features) - return render_template('oneliner.html', oneliner=cuisine, titletext=titletext, generator='cuisine') - - -@app.route('/cuisine_builder') -def cuisine_builder(): - """Build a a cuisine""" - classname = 'cuisine' - plist, pstring, pset = builder_form_data(classname) - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/deity') -def generatedeity(): - """Generate a deity""" - - features = feature_filter('deity') - deity = Deity.Deity(server, features) - return render_template('deity.html', tempobj=deity) - -@app.route('/deity_builder') -def deity_builder(): - """Build a a deity""" - classname = 'deity' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/leader') -def generateleader(): - """Generate a leader""" - - features = feature_filter('leader') - leader = Leader.Leader(server, features) - return render_template('leader.html', tempobj=leader) - -@app.route('/leader_builder') -def leader_builder(): - """Build a a leader""" - classname = 'leader' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - -######################################################################### - -@app.route('/flag') -def generateflag(): - """Generate a flag""" - - features = feature_filter('flag') - flag = Flag.Flag(server, features) - return render_template('flag.html', tempobj=flag, flagjson=flag.tojson()) - -@app.route('/flag_builder') -def flag_builder(): - """Build a a flag""" - classname = 'flag' - plist, pstring, pset = builder_form_data(classname) - - return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) - - -######################################################################### -######################################################################### -######################################################################### - - - - - -def feature_filter(generator): - """Turn the request string into a feature set.""" - app.seed = set_seed(request.args.get('seed')) - - genregex = re.compile('^'+generator+'_[a-z_]+$') - genrollregex = re.compile('^'+generator+'_[a-z_]+_(roll|chance)$') - - app.logger.info('Request Seed: %i', app.seed) - features = {'seed':app.seed, } - for param in request.args: - if genrollregex.match(param) and isvalidscore(request.args[param]): - features[param] = int(request.args[param]) - elif genregex.match(param) and str(request.args[param]).isdigit(): - fieldname = re.sub(generator+'_', '', param) - features[fieldname] = server.lrange(param, int(request.args[param]), int(request.args[param]))[0] - return features - -def builder_form_data(generator): - """Turn the fields of a generator into fodder for the generic_builder""" - plist = {} - pstring = {} - pset = {} - for key in server.keys(generator+'_*'): - fieldname = key.replace(generator+'_', '') - if server.type(key) == 'list': - plist[fieldname] = server.lrange(key, 0, -1) - elif server.type(key) == 'string': - pstring[fieldname] = server.get(key) - elif server.type(key) == 'zset': - result = server.zrangebyscore(key, 1, 100) - pset[fieldname] = [] - for field in result: - try: - pset[fieldname].append(json.loads(field)) - except ValueError: - raise ValueError("failed to parse %s field %s" % (key, field)) - return plist, pstring, pset - -def isvalidscore(value): - """Verify if a string is a valid score.""" - if value.isdigit() and int(value) >= 0 and int(value) <= 100: - return True - else: - return False - -@app.errorhandler(404) -def page_not_found(error): - """Return a custom 404 error.""" - print " =======================" - print "Exception:", error - time = str(datetime.datetime.now()) - return render_template("400.html", request=request, time=time), 404 - -@app.errorhandler(500) -def page_borked(error): - """Return a custom 500 error. Only hit when debugging is off.""" - print " =======================" - print "problem with ", request.url - time = str(datetime.datetime.now()) - print "on seed", app.seed, "at", time - print "Exception:", error.args[0] - traceback.print_exc() - - return render_template("500.html", seed=app.seed, request=request, e=error, time=time), 500 - -@app.template_filter('article') -def select_article(noun): - """Select the proper article for a noun.""" - return Filters.select_article(noun) - -@app.template_filter('pluralize') -def select_pluralize(verb, count): - """Select the proper verb for a count.""" - return Filters.select_pluralize(verb, count) - -@app.template_filter('conjunction') -def select_conjunction(wordlist): - """Join a list with commas and such.""" - return Filters.select_conjunction(wordlist) - -@app.template_filter('plural_verb') -def select_plural_verb(verb, subject): - """select the proper plural verb.""" - # FIXME is this a duplicate of select_pluralize??? - return Filters.select_plural_verb(verb, subject) - -@app.template_filter('plural_adj') -def select_plural_adj(adj, subject): - """Select the proper version of an adjective.""" - #FIXME is this correct? or is it count-based? - return Filters.select_plural_adj(adj, subject) - -if __name__ == '__main__': - app.debug = True - app.run() - -if CONFIG.has_option('main', 'debug'): - app.debug = CONFIG.getboolean('main', 'debug') - diff --git a/megacosm/__init__.py b/megacosm/__init__.py new file mode 100644 index 0000000..8f5b824 --- /dev/null +++ b/megacosm/__init__.py @@ -0,0 +1,597 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# Import the stuffs! + +"""`main` is the top level module for this application.""" + +from flask import Flask, render_template, request +from megacosm.generators import Business +from megacosm.generators import Continent +from megacosm.generators import Country +from megacosm.generators import Deity +from megacosm.generators import Flag +from megacosm.generators import GeomorphDungeon +from megacosm.generators import Govt +from megacosm.generators import Leader +from megacosm.generators import MagicItem +from megacosm.generators import Moon +from megacosm.generators import NPC +from megacosm.generators import Organization +from megacosm.generators import Planet +from megacosm.generators import Region +from megacosm.generators import RogueDungeon +from megacosm.generators import Sect +from megacosm.generators import Star +from megacosm.generators import Street +from megacosm.generators import Wanted +from megacosm.generators import Weather +from megacosm.util.Seeds import set_seed +from megacosm.util import Filters +import redis +import datetime +import json +import re +import traceback + + +def create_app(config_location='config.BaseConfiguration'): + app = Flask(__name__) + app.config.from_object(config_location) + app.server = redis.from_url(app.config['REDIS_URL']) + return app + + +app = create_app() + + +######################################################################### + +@app.route('/') +def indexpage(): + """This is the first page anyone sees.""" + + return render_template('index.html') + + +######################################################################### + +@app.route('/magicitem') +def generatemagicitem(): + """Generate a MagicItem""" + + features = feature_filter('magicitem') + magicitem = MagicItem(app.server, features) + + kind = magicitem.kind + return render_template('magicitem_' + kind + '.html', tempobj=magicitem) + + +@app.route('/magicitem_builder') +def magicitem_builder(): + """Build a Magic Item""" + + classname = 'magicitem' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/npc') +def generatenpc(): + """Generate an NPC""" + + features = feature_filter('npc') + features['deity'] = Deity(app.server) + tempobj = NPC(app.server, features) + return render_template('npc.html', tempobj=tempobj) + + +@app.route('/npc_builder') +def npc_builder(): + """Build an NPC""" + + classname = 'npc' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/planet_builder') +def planet_builder(): + """Build a planet""" + + classname = 'planet' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +@app.route('/planet') +def generateplanet(): + """Generate a planet""" + + features = feature_filter('planet') + planet = Planet(app.server, features) + planet.add_continents() + return render_template('planet.html', tempobj=planet) + + +######################################################################### + +@app.route('/organization') +def GenerateOrganization(): + """Generate a simple organization""" + + features = feature_filter('organization') + tempobj = Organization(app.server, features) + return render_template('organization.html', tempobj=tempobj) + + +@app.route('/organization_builder') +def Organization_Builder(): + """Generate the basic data about a organization""" + + classname = 'organization' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/business') +def generatebusiness(): + """Generate a business""" + + features = feature_filter('business') + business = Business(app.server, features) + return render_template('business.html', tempobj=business) + + +@app.route('/business_builder') +def business_builder(): + """Build a a business""" + + classname = 'business' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/street') +def generatestreet(): + """Generate a street""" + + features = feature_filter('street') + tempobj = Street(app.server, features) + return render_template('street.html', tempobj=tempobj) + + +@app.route('/street_builder') +def street_builder(): + """Build a a street""" + + classname = 'street' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/moon') +def generatemoon(): + """Generate a moon""" + + features = feature_filter('moon') + moon = Moon(app.server, features) + return render_template('moon.html', tempobj=moon) + + +@app.route('/moon_builder') +def moon_builder(): + """Build a a moon""" + + classname = 'moon' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/star') +def generatestar(): + """Generate a star""" + + features = feature_filter('star') + star = Star(app.server, features) + return render_template('star.html', tempobj=star) + + +@app.route('/star_builder') +def star_builder(): + """Build a a star""" + + classname = 'star' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/continent') +def generatecontinent(): + """Generate a continent""" + + features = feature_filter('continent') + continent = Continent(app.server, features) + continent.add_countries() + return render_template('continent.html', tempobj=continent) + + +@app.route('/continent_builder') +def continent_builder(): + """Build a a continent""" + + classname = 'continent' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/region') +def generateregion(): + """Generate a region""" + + features = feature_filter('region') + region = Region(app.server, features) + +# region.add_cities() +# region.add_locations()() + + return render_template('region.html', tempobj=region) + + +@app.route('/region_builder') +def region_builder(): + """Build a a region""" + + classname = 'region' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/sect') +def generatesect(): + """Generate a sect""" + + features = feature_filter('sect') + sect = Sect(app.server, features) + return render_template('sect.html', tempobj=sect) + + +@app.route('/sect_builder') +def sect_builder(): + """Build a a sect""" + + classname = 'sect' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/govt') +def generategovt(): + """Generate a govt""" + + features = feature_filter('govt') + govt = Govt(app.server, features) + return render_template('govt.html', tempobj=govt) + + +@app.route('/govt_builder') +def govt_builder(): + """Build a a govt""" + + classname = 'govt' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/weather') +def generateweather(): + """Generate a weather""" + + features = feature_filter('weather') + weather = Weather(app.server, features) + return render_template('weather.html', tempobj=weather) + + +@app.route('/weather_builder') +def weather_builder(): + """Build a a weather""" + + classname = 'weather' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/wanted') +def generatewanted(): + """Generate a wanted""" + + features = feature_filter('wanted') + wanted = Wanted(app.server, features) + return render_template('wanted.html', tempobj=wanted) + + +@app.route('/wanted_builder') +def wanted_builder(): + """Build a a wanted""" + + classname = 'wanted' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/geomorphdungeon') +def generategeomorphdungeon(): + """Generate a geomorphdungeon""" + + features = feature_filter('geomorphdungeon') + geomorphdungeon = GeomorphDungeon(app.server, features) + return render_template('geomorphdungeon.html', tempobj=geomorphdungeon, jsondata=geomorphdungeon.convert_to_json()) + + +@app.route('/geomorphdungeon_builder') +def geomorphdungeon_builder(): + """Build a a geomorphdungeon""" + + classname = 'geomorphdungeon' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/roguedungeon') +def generateroguedungeon(): + """Generate a dungeon""" + + features = feature_filter('roguedungeon') + roguedungeon = RogueDungeon(app.server, features) + return render_template('roguedungeon.html', tempobj=roguedungeon, jsondata=roguedungeon.convert_to_json()) + + +@app.route('/roguedungeon_builder') +def roguedungeon_builder(): + """Build a a dungeon""" + + classname = 'roguedungeon' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/country') +def generatecountry(): + """Generate a country""" + + features = feature_filter('country') + country = Country(app.server, features) + country.add_regions() + return render_template('country.html', tempobj=country) + + +@app.route('/country_builder') +def country_builder(): + """Build a a country""" + + classname = 'country' + (plist, pstring, pset) = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/deity') +def generatedeity(): + """Generate a deity""" + + features = feature_filter('deity') + deity = Deity(app.server, features) + return render_template('deity.html', tempobj=deity) + + +@app.route('/deity_builder') +def deity_builder(): + """Build a a deity""" + + classname = 'deity' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/leader') +def generateleader(): + """Generate a leader""" + + features = feature_filter('leader') + leader = Leader(app.server, features) + return render_template('leader.html', tempobj=leader) + + +@app.route('/leader_builder') +def leader_builder(): + """Build a a leader""" + + classname = 'leader' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + +@app.route('/flag') +def generateflag(): + """Generate a flag""" + + features = feature_filter('flag') + app.flag = Flag(app.server, features) + return render_template('flag.html', tempobj=app.flag, flagjson=app.flag.tojson()) + + +@app.route('/flag_builder') +def flag_builder(): + """Build a a flag""" + + classname = 'flag' + (plist, pstring, pset) = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### +######################################################################### +######################################################################### + +def feature_filter(generator): + """Turn the request string into a feature set.""" + + app.seed = set_seed(request.args.get('seed')) + + genregex = re.compile('^' + generator + '_[a-z_]+$') + genrollregex = re.compile('^' + generator + '_[a-z_]+_(roll|chance)$') + + app.logger.info('Request Seed: %i', app.seed) + features = {'seed': app.seed} + for param in request.args: + if genrollregex.match(param) and isvalidscore(request.args[param]): + features[param] = int(request.args[param]) + elif genregex.match(param) and str(request.args[param]).isdigit(): + fieldname = re.sub(generator + '_', '', param) + features[fieldname] = app.server.lrange(param, int(request.args[param]), int(request.args[param]))[0] + return features + + +def builder_form_data(generator): + """Turn the fields of a generator into fodder for the generic_builder""" + + plist = {} + pstring = {} + pset = {} + for key in app.server.keys(generator + '_*'): + fieldname = key.replace(generator + '_', '') + if app.server.type(key) == 'list': + plist[fieldname] = app.server.lrange(key, 0, -1) + elif app.server.type(key) == 'string': + pstring[fieldname] = app.server.get(key) + elif app.server.type(key) == 'zset': + result = app.server.zrangebyscore(key, 1, 100) + pset[fieldname] = [] + for field in result: + try: + pset[fieldname].append(json.loads(field)) + except ValueError: + raise ValueError('failed to parse %s field %s' % (key, field)) + return (plist, pstring, pset) + + +def isvalidscore(value): + """Verify if a string is a valid score.""" + + if value.isdigit() and int(value) >= 0 and int(value) <= 100: + return True + else: + return False + + +@app.errorhandler(404) +def page_not_found(error): + """Return a custom 404 error.""" + + print ' =======================' + print 'Exception:', error + time = str(datetime.datetime.now()) + return (render_template('400.html', request=request, time=time), 404) + + +@app.errorhandler(500) +def page_borked(error): + """Return a custom 500 error. Only hit when debugging is off.""" + + print ' =======================' + print 'problem with ', request.url + time = str(datetime.datetime.now()) + print 'on seed', app.seed, 'at', time + print 'Exception:', error.args[0] + traceback.print_exc() + + return (render_template('500.html', seed=app.seed, request=request, e=error, time=time), 500) + + +@app.template_filter('article') +def select_article(noun): + """Select the proper article for a noun.""" + + return Filters.select_article(noun) + + +@app.template_filter('pluralize') +def select_pluralize(verb, count): + """Select the proper verb for a count.""" + + return Filters.select_pluralize(verb, count) + + +@app.template_filter('conjunction') +def select_conjunction(wordlist): + """Join a list with commas and such.""" + + return Filters.select_conjunction(wordlist) + + +@app.template_filter('plural_verb') +def select_plural_verb(verb, subject): + """select the proper plural verb.""" + + # FIXME is this a duplicate of select_pluralize??? + + return Filters.select_plural_verb(verb, subject) + + +@app.template_filter('plural_adj') +def select_plural_adj(adj, subject): + """Select the proper version of an adjective.""" + + # FIXME is this correct? or is it count-based? + + return Filters.select_plural_adj(adj, subject) + +import oneliners +assert oneliners + +if __name__ == '__main__': + app = create_app + app.run() diff --git a/megacosm/generators/__init__.py b/megacosm/generators/__init__.py new file mode 100644 index 0000000..b807520 --- /dev/null +++ b/megacosm/generators/__init__.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Generators package +""" + +from artwork import Artwork +assert Artwork +from bond import Bond +assert Bond +from business import Business +assert Business +from continent import Continent +assert Continent +from country import Country +assert Country +from cuisine import Cuisine +assert Cuisine +from currency import Currency +assert Currency +from deity import Deity +assert Deity +from event import Event +assert Event +from flag import Flag +assert Flag +from flaw import Flaw +assert Flaw +from gem import Gem +assert Gem +from generator import Generator +assert Generator +from geomorphdungeon import GeomorphDungeon +assert GeomorphDungeon +from govt import Govt +assert Govt +from jobposting import JobPosting +assert JobPosting +from leader import Leader +assert Leader +from legend import Legend +assert Legend +from magicitem import MagicItem +assert MagicItem +from misfire import Misfire +assert Misfire +from moon import Moon +assert Moon +from motivation import Motivation +assert Motivation +from mundaneitem import MundaneItem +assert MundaneItem +from npc import NPC +assert NPC +from organization import Organization +assert Organization +from planet import Planet +assert Planet +from region import Region +assert Region +from resource import Resource +assert Resource +from roguedungeon import RogueDungeon +assert RogueDungeon +from rumor import Rumor +assert Rumor +from sect import Sect +assert Sect +from star import Star +assert Star +from starsystem import StarSystem +assert StarSystem +from street import Street +assert Street +from wanted import Wanted +assert Wanted +from weather import Weather +assert Weather diff --git a/megacosm/generators/artwork.py b/megacosm/generators/artwork.py new file mode 100644 index 0000000..8645243 --- /dev/null +++ b/megacosm/generators/artwork.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from gem import Gem +from generator import Generator +import logging + + +class Artwork(Generator): + + """ """ + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'gem'): + setattr(self, 'gem', Gem(self.redis)) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/bond.py b/megacosm/generators/bond.py new file mode 100644 index 0000000..7e1ce55 --- /dev/null +++ b/megacosm/generators/bond.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import npc +import logging +import random + + +class Bond(Generator): + + """Generate a bond between two people 'you' and 'other'.""" + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + # if self.you and self.other are not set, set them to defaults. + + if not hasattr(self, 'you'): + self.you = 'you' + + # a random NPC + + if not hasattr(self, 'other'): + self.other = npc.NPC(self.redis).name['full'] + + # We put you and other in an array so we can randomly select + # who is the subject and who is the object. + + members = [self.you, self.other] + random.shuffle(members) + if not hasattr(self, 'either'): + self.either = members[0] + random.shuffle(members) + + # We use partyA/partyB syntax in the templates + + if not hasattr(self, 'partyA'): + self.partyA = members.pop() + if not hasattr(self, 'partyB'): + self.partyB = members.pop() + + # If we don't already have text, we need to render a template + + if not hasattr(self, 'text'): + + # if we have it, we need to add a "when" as well + + if hasattr(self, 'when'): + self.template = self.when + ', ' + self.template + self.text = self.render_template(self.template) + + # final sentence is stored as self.text. + # note the need for capitalization of the first character + + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/business.py b/megacosm/generators/business.py new file mode 100644 index 0000000..467b1ac --- /dev/null +++ b/megacosm/generators/business.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging +import random + + +class Business(Generator): + + """ Create a business.""" + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + self.generate_features(self.kind) + self.senses = [] + + # originally I was going to move these to a for loop, but the verb + # doesn't match the variable name, so it would require refactoring + # of the dataset and every other damn thing. Meh. + + if hasattr(self, 'smell'): + self.smell = 'you smell ' + self.smell + self.senses.append(self.smell) + if hasattr(self, 'sound'): + self.sound = 'you hear ' + self.sound + self.senses.append(self.sound) + if hasattr(self, 'sight'): + self.sight = 'you see ' + self.sight + self.senses.append(self.sight) + + if not hasattr(self, 'owner'): + self.owner = NPC(redis) + + # TODO patrons should be better calculated + + if not hasattr(self, 'patroncount'): + self.patroncount = random.randint(1, 10) + + # Business is one of the few classes where trailer doesn't start as part of the name + # So we have to add it here. + + if hasattr(self, 'trailer'): + self.name['trailer'] = self.trailer + self.name['full'] = self.name['full'] + ' ' + self.trailer.title() + + # If maxfloors isn'd designated, set it to 1 + + if not hasattr(self, 'maxfloors'): + self.maxfloors = 1 + + # don't set floors if it already exists + + if not hasattr(self, 'floor'): + self.floor = random.randint(1, int(self.maxfloors)) + + def __str__(self): + return '%s %s' % (self.name['full'], self.kind) diff --git a/megacosm/generators/continent.py b/megacosm/generators/continent.py new file mode 100644 index 0000000..41c04a1 --- /dev/null +++ b/megacosm/generators/continent.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from country import Country +from generator import Generator +import logging +import random + + +class Continent(Generator): + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + # set a random count + + if not hasattr(self, 'countrycount'): + self.countrycount = random.randint(self.countrydetails['mincount'], self.countrydetails['maxcount']) + + def add_countries(self): + """ add countries to the continent""" + + if not hasattr(self, 'countries'): + self.countries = [] + for countryid in xrange(self.countrycount): + self.countries.append(Country(self.redis, {'continent': self})) + + def __str__(self): + return '%s with %s countries' % (self.name['full'], self.countrycount) diff --git a/megacosm/generators/country.py b/megacosm/generators/country.py new file mode 100644 index 0000000..a7d0929 --- /dev/null +++ b/megacosm/generators/country.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from region import Region +import logging +import random + + +class Country(Generator): + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'regioncount'): + self.regioncount = random.randint(self.regiondetails['mincount'], self.regiondetails['maxcount']) + + def add_regions(self): + """ add regions to the country""" + + if not hasattr(self, 'regions'): + self.regions = [] + for regionid in xrange(self.regioncount): + self.regions.append(Region(self.redis, {'country': self})) + + def __str__(self): + return '%s with %s regions' % (self.name['full'], self.regioncount) diff --git a/megacosm/generators/cuisine.py b/megacosm/generators/cuisine.py new file mode 100644 index 0000000..68f67da --- /dev/null +++ b/megacosm/generators/cuisine.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging + + +class Cuisine(Generator): + + """ What meals are common in your area? """ + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + # You never know if you'll want a creator for your meal + + if not hasattr(self, 'creator'): + setattr(self, 'creator', NPC(self.redis)) + + # Double parse the template to fill in templated template values. + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + + # remember to capitalize! + + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/currency.py b/megacosm/generators/currency.py new file mode 100644 index 0000000..a029677 --- /dev/null +++ b/megacosm/generators/currency.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging +import random + + +class Currency(Generator): + + """ Define a currency to be used in your game """ + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'count'): + self.count = random.randint(self.amount['min'], self.amount['max']) + + # Perhaps your currency has a person on it- a king, queen, etc. + + if not hasattr(self, 'npc'): + setattr(self, 'npc', NPC(self.redis)) + self.logger.error('test') + + # Double parse the template to fill in templated template values. + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/generators/Deity.py b/megacosm/generators/deity.py similarity index 59% rename from generators/Deity.py rename to megacosm/generators/deity.py index 43ada81..6a2e0bb 100644 --- a/generators/Deity.py +++ b/megacosm/generators/deity.py @@ -1,84 +1,111 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- -from generators.Generator import Generator -from generators.NPC import NPC -from generators.Sect import Sect +from npc import NPC +from sect import Sect import json import logging import random + class Deity(NPC): + """ Generate a god for your world""" + def __init__(self, redis, features={}): - NPC.__init__(self,redis,features, 'npc') - self.logger=logging.getLogger(__name__) + NPC.__init__(self, redis, features, 'npc') + self.logger = logging.getLogger(__name__) self.generate_features('deity') self.select_portfolio() - def add_sects(self): #TODO make this more like countries for continents + def add_sects(self): # TODO make this more like countries for continents """ each portfolio item except the largest domain can have a sect""" + if not hasattr(self, 'sect'): - self.sects=[] + self.sects = [] # ignore the primary domain and shuffle the rest - sectdomains=self.portfolios[1:] + + sectdomains = self.portfolios[1:] random.shuffle(sectdomains) # Note that the sectchance is inversely proportional to unity- # The more unity, the less chance of fracturing - sectchance=100-self.deity_unity_roll - # give each domain a chance to have a sect, but each success lowers the + + sectchance = 100 - self.deity_unity_roll + + # give each domain a chance to have a sect, but each success lowers the # chance for the next one. A fractured church with many domains could # have many different sects. + for domain in sectdomains: - sectroll=random.randint(1,100) - if sectchance >= sectroll: - sect= Sect(self.redis, {'deity':self,'domain':domain}) + sectroll = random.randint(1, 100) + if sectchance >= sectroll: + sect = Sect(self.redis, {'deity': self, 'domain': domain}) self.sects.append(sect) - sectchance=sectchance/2 - + sectchance = sectchance / 2 + def select_portfolio(self): """ use the deity's importance to determine how many portfolios it has. """ - points=int(self.importance['points']) + points = int(self.importance['points']) # domains are split up by power level; the more valuable, the higher the power # Values currently include: 16, 8, 6, 5, 4, 3, 2, 1 - powerlevels=self.redis.lrange('portfolio_level',0,-1) + + powerlevels = self.redis.lrange('portfolio_level', 0, -1) # Only set this if it's empty. + if not hasattr(self, 'portfolios'): - self.portfolios=[] + self.portfolios = [] # Danger, each assigned domain reduces the point count. - while points>0: + + while points > 0: + # Grab the highest power level available - powerlevel=int(powerlevels.pop()) + + powerlevel = int(powerlevels.pop()) + # Check to make sure this deity has the points to buy at that power level + if powerlevel <= points: + # shuffle the remaining power levels # insert that power level at the back of the list; chances are we won't need it again. + random.shuffle(powerlevels) - powerlevels.insert(0,powerlevel) - + powerlevels.insert(0, powerlevel) + # get all the domains at the current powerlevel - portfolios=self.redis.zrevrangebyscore('portfolio_domain', powerlevel,powerlevel) - #shuffle them in python rather than redis to ensure repeatability. + + portfolios = self.redis.zrevrangebyscore('portfolio_domain', powerlevel, powerlevel) + + # shuffle them in python rather than redis to ensure repeatability. + random.shuffle(portfolios) + # While we can support this power level, lets use it until we can't. - while powerlevel <= points : + + while powerlevel <= points: + # pop a new portfolio off the list. - newdomain=json.loads(portfolios.pop()) + + newdomain = json.loads(portfolios.pop()) # make sure our powerlevel is still what we expect - powerlevel=int(newdomain['score']) #TODO is this still needed?? + + powerlevel = int(newdomain['score']) # TODO is this still needed?? # append the new domain to our deity's list + self.portfolios.append(newdomain) # subtract our new domain's power level from our available points - points=points- powerlevel - #else: - #print "can't support powerlevel",powerlevel,"with",points,"points" + points = points - powerlevel + # else: + # print "can't support powerlevel",powerlevel,"with",points,"points" diff --git a/megacosm/generators/event.py b/megacosm/generators/event.py new file mode 100644 index 0000000..75f8909 --- /dev/null +++ b/megacosm/generators/event.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Event(Generator): + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + self.generate_features('event' + self.kind) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/flag.py b/megacosm/generators/flag.py new file mode 100644 index 0000000..1a40fe9 --- /dev/null +++ b/megacosm/generators/flag.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import json +import logging +import random +import string + + +class Flag(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + self.select_colors() + + self.overlay_stripe_countselected = random.randint(0, int(self.overlay_stripe_count)) + if not hasattr(self, 'letter'): + self.letter = random.choice(string.ascii_uppercase) + + def select_colors(self): + colornames = self.redis.lrange('flagcolor', 0, -1) + random.shuffle(colornames) + + if not hasattr(self, 'colors'): + self.colors = [] + + for i in range(7 - len(self.colors)): + colorname = colornames[i] + jsonstring = self.redis.hget('flagcolor_description', colorname) + + # FIXME Note this still overwrites + + self.colors.append(json.loads(jsonstring)) + + def tojson(self): + data = self.__dict__ + del data['redis'] + del data['pipeline'] + del data['logger'] + return json.dumps( + data, + skipkeys=True, + ensure_ascii=True, + check_circular=True, + allow_nan=True, + cls=None, + indent=4, + separators=(', ', ': '), + encoding='utf-8', + default=None, + sort_keys=False, + ) diff --git a/megacosm/generators/flaw.py b/megacosm/generators/flaw.py new file mode 100644 index 0000000..ef2ee79 --- /dev/null +++ b/megacosm/generators/flaw.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Flaw(Generator): + + """ Define a flaw to be used in your game """ + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + # Double parse the template to fill in templated template values. + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/gem.py b/megacosm/generators/gem.py new file mode 100644 index 0000000..98fbb6a --- /dev/null +++ b/megacosm/generators/gem.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging +import random + + +class Gem(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'count'): + self.count = random.randint(self.amount['min'], self.amount['max']) + + if not hasattr(self, 'color'): + self.color = random.choice(self.kind_description['color']) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return '%s %s %s, %s' % (self.quality['name'], self.color, self.kind_description['name'], self.value['name']) diff --git a/megacosm/generators/generator.py b/megacosm/generators/generator.py new file mode 100644 index 0000000..fc77e94 --- /dev/null +++ b/megacosm/generators/generator.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + Generators package +""" + +from jinja2.environment import Environment +from megacosm.util import Filters +from megacosm.util import Seeds +import json +import logging +import random + + +class Generator(object): + + """ An abstracted Generator that all generators are based from """ + + def __init__(self, redis, features={}, namekey=None): + self.logger = logging.getLogger(__name__) + + # Redis is the source of all data. + + self.redis = redis + self.pipeline = self.redis.pipeline + + # We use our class name as a key for redis + + if namekey is None: + namekey = self.__class__.__name__.lower() + + # see if we have a seed to use, otherwise generate a new one. + + if 'seed' in features: + self.seed = Seeds.set_seed(features['seed']) + else: + self.seed = Seeds.set_seed() + self.logger.info('new generator %s with seed %i', namekey, self.seed) + + # For naming conventions, we use "name"+classname+"stuff" + + self.name = self.generate_name('name_' + namekey) + + # For each feature, set it as an attribute for this generator + + for (feature, value) in features.iteritems(): + + # This bit of meta code saves soooo much hassle and getters/setters. + # especially with testing. + + setattr(self, feature, value) + + # This is the guts of the Generator... + + self.generate_features(namekey) + + def generate_features(self, namekey): + """ Given a namekey, add those features to this object.""" + + # find all keys matching our namekey + + self.logger.info('Generating features for %s with seed %i', namekey, self.seed) + for key in self.redis.keys(namekey + '_*'): + self.generate_feature(namekey, key) + + def generate_feature(self, namekey, key): + + # check to see if your key has a related chance key + + if self.redis.exists(key + '_chance'): + + # make sure the value is not already set, then grab it. + + if not hasattr(self, key + '_chance'): + setattr(self, key + '_chance', int(self.redis.get(key + '_chance'))) + + # check to see if you have a preset roll; if not, roll 1-100 + + if not hasattr(self, key + '_roll'): + setattr(self, key + '_roll', random.randint(1, 100)) + + # if the roll is greater than the chance, you have failed, and don't get to use this stat. + # Go to the next entry in the for loop. + + if int(getattr(self, key + '_roll')) > getattr(self, key + '_chance'): + return + + # ######################################################################################### + # Provided you had no associated _chance or that you succeeded on the chance roll, you can + # Move on to actually setting the value. + + # Most features don't need the namekey on the front since it's redundant + # so we shorten the name for brevity. + + featurename = key.replace(namekey + '_', '') + + # Zset means it's a 1-100 stat; + + if self.redis.type(key) == 'zset': + setattr(self, featurename, Generator.select_by_roll(self, key)) + elif self.redis.type(key) == 'string': + + # string means it's a simple value that plugs right in + setattr(self, featurename, self.redis.get(key)) + elif self.redis.type(key) == 'list': + + # List gets a bit tricky; select a value, then see if it has an associated description + # If feature isn't set, grab a rand value from the list. + + if not hasattr(self, featurename): + featurevalue = Generator.rand_value(self, key) + setattr(self, featurename, featurevalue) + + # if the description hasn't been set and exists in redis. + + if not hasattr(self, featurename + '_description'): + try: + desc_text = self.redis.hmget(key + '_description', getattr(self, featurename))[0] + if desc_text is not None: + featurevalue = json.loads(desc_text) + setattr(self, featurename + '_description', featurevalue) + except ValueError: + self.logger.critical("JSON parsing error: Couldn't read json %s", desc_text) + raise ValueError("JSON parsing error: Couldn't read json", desc_text) + +#################################################### +# needs refactoring below here. + + # FIXME this needs to be integrated with what NPC races use... + + def generate_name(self, key): + """ Given a key, query redis and check if all 5 parts of a name exist, then generate a name structure. + This creates the structure "Title PreRootPost Trailer" + Note that in the full name, the title has a trailing space and the trailer has a preceeding space. + Pre, Root and Post have no spaces.""" + + name = {'full': ''} + + if self.redis.exists(key + 'title'): + roll = random.randint(1, 100) + if not self.redis.exists(key + 'title_chance') or roll < int(self.redis.get(key + 'title_chance')): + name['title'] = self.rand_value(key + 'title') + name['full'] = name['title'] + ' ' + + for part in ['pre', 'root', 'post']: + if self.redis.exists(key + part): + if (not self.redis.exists(key + part + '_chance') or + random.randint(1, 100) < int(self.redis.get(key + part + '_chance'))): + name[part] = self.rand_value(key + part) + name['full'] += name[part] + + if self.redis.exists(key + 'trailer'): + roll = random.randint(1, 100) + if not self.redis.exists(key + 'trailer_chance') or roll < int(self.redis.get(key + 'trailer_chance')): + name['trailer'] = self.rand_value(key + 'trailer') + name['full'] += ' ' + name['trailer'] + return name + + def rand_value(self, key): + """ Select a Random Value from the list matching the key in redis. """ + + try: + total = self.redis.llen(key) + value = self.redis.lindex(key, random.randint(0, total - 1)) + return value + except Exception: + raise Exception("the key (%s) doesn't appear to exist or isn't a list (%s)." % (key, self.redis.type(key))) + + def select_by_roll(self, key): + """ Using roll, select the closest matching score from key in Redis. """ + + if key + '_roll' not in self.__dict__: + setattr(self, key + '_roll', random.randint(1, 100)) + + roll = max(1, min(getattr(self, key + '_roll'), 100)) + + try: + rollvalue = self.redis.zrangebyscore(key, roll, 100, 0, 1) + if rollvalue is None: + raise LookupError + return json.loads(rollvalue[0]) + except IndexError: + raise IndexError('Is %s a valid key?' % key) + except LookupError: + raise Exception('the key (%s) appears to be empty for a roll of %s- This should never happen.' % (key, + roll)) + except ValueError: + raise Exception("JSON parsing error: Couldn't read json", rollvalue[0]) + except Exception: + raise Exception("the key (%s) doesn't appear to exist or isn't a zset (%s)." % (key, self.redis.type(key))) + + def render_template(self, template): + """ Renders a given template using itself.""" + + environment = Environment() + environment.filters['article'] = Filters.select_article + environment.filters['pluralize'] = Filters.select_pluralize + environment.filters['conjunction'] = Filters.select_conjunction + environment.filters['plural_verb'] = Filters.select_plural_verb + environment.filters['plural_adj'] = Filters.select_plural_adj + + template = environment.from_string(template) + + return template.render(params=self) diff --git a/megacosm/generators/geomorphdungeon.py b/megacosm/generators/geomorphdungeon.py new file mode 100644 index 0000000..9fcc16a --- /dev/null +++ b/megacosm/generators/geomorphdungeon.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import json +import logging +import random + + +class GeomorphDungeon(Generator): + + # This is a simple translation table + # bits are sorted [ left bottom right top ] + + CELL_TYPES = { # No connections + # one side + # one side + # twoside corner + # one side + # twoside straight + # twosided corner + # Three sides + # one side + # twosided corner + # twosided straight + # three sides + # twosided corner + # threesided + # three sides + # Four connections + '0b0': {'type': '0000', 'rotation': 0}, + '0b1': {'type': '0001', 'rotation': 0}, + '0b10': {'type': '0001', 'rotation': 1}, + '0b11': {'type': '0010', 'rotation': 0}, + '0b100': {'type': '0001', 'rotation': 2}, + '0b101': {'type': '0011', 'rotation': 0}, + '0b110': {'type': '0010', 'rotation': 1}, + '0b111': {'type': '0100', 'rotation': 0}, + '0b1000': {'type': '0001', 'rotation': 3}, + '0b1001': {'type': '0010', 'rotation': 3}, + '0b1010': {'type': '0011', 'rotation': 1}, + '0b1011': {'type': '0100', 'rotation': 3}, + '0b1100': {'type': '0010', 'rotation': 2}, + '0b1101': {'type': '0100', 'rotation': 2}, + '0b1110': {'type': '0100', 'rotation': 1}, + '0b1111': {'type': '0101', 'rotation': 0}, + } + + def __init__(self, redis, features={}): + """ Generate a Geomorph-like dungeon """ + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + self.generate_features('dungeon') + + self.apply_text_template() # FIXME refactor with RogueDungeon on dungeon names... + self.width = self.gridwidth['tiles'] + self.height = self.gridheight['tiles'] + + self.generate_grid() + self.generate_connections() + self.set_tiletypes() + + def apply_text_template(self): + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text.title() + + def convert_to_json(self): + resultmatrix = [] + for row in self.spaces: + resultrow = [] + for cell in row: + resultrow.append({'path': cell.image, 'rotation': cell.imagerotation}) + resultmatrix.append(resultrow) + return resultmatrix + + def set_tiletypes(self): + for row in self.spaces: + for cell in row: + + # calculate the binary "cell type" + + cell.tiletype = bin((cell.left << 3) + (cell.bottom << 2) + (cell.right << 1) + (cell.top << 0)) + + # translate it with the table + + cell.imagetype = int(self.CELL_TYPES[cell.tiletype]['type'], 2) + + # Using the proper cell type, select an image from redis + + tiledata = json.loads(self.rand_value('geomorph_type_' + str(cell.imagetype))) + cell.image = str(tiledata['path']) + cell.author = str(tiledata['author']) + cell.tileset = str(tiledata['tileset']) + + # Make sure to capture the rotation needed + + cell.imagerotation = self.CELL_TYPES[cell.tiletype]['rotation'] + + def generate_grid(self): + + self.spaces = [[GeomorphDungeon.Tile(i, j) for i in range(self.width)] for j in range(self.height)] + + def generate_connections(self): + alltiles = [] + for row in self.spaces: + for cell in row: + alltiles.append(cell) + + random.shuffle(alltiles) + + for cell in alltiles: + self.calculate_top(cell) + self.calculate_right(cell) + self.calculate_bottom(cell) + self.calculate_left(cell) + + def calculate_top(self, cell): + if cell.y == 0: + cell.top = False + elif self.spaces[cell.y - 1][cell.x].bottom is not None: + cell.top = self.spaces[cell.y - 1][cell.x].bottom + else: + if random.randint(0, self.segmentation['solidchance']) == 0: + cell.top = False + else: + cell.top = True + + def calculate_right(self, cell): + if cell.x == len(self.spaces[0]) - 1: + cell.right = False + elif self.spaces[cell.y][cell.x + 1].left is not None: + cell.right = self.spaces[cell.y][cell.x + 1].left + else: + if random.randint(0, self.segmentation['solidchance']) == 0: + cell.right = False + else: + cell.right = True + + def calculate_bottom(self, cell): + if cell.y == len(self.spaces) - 1: + cell.bottom = False + elif self.spaces[cell.y + 1][cell.x].top is not None: + cell.bottom = self.spaces[cell.y + 1][cell.x].top + else: + if random.randint(0, self.segmentation['solidchance']) == 0: + cell.bottom = False + else: + cell.bottom = True + + def calculate_left(self, cell): + if cell.x == 0: + cell.left = False + elif self.spaces[cell.y][cell.x - 1].right is not None: + cell.left = self.spaces[cell.y][cell.x - 1].right + else: + if random.randint(0, self.segmentation['solidchance']) == 0: + cell.left = False + else: + cell.left = True + + class Tile(object): + + def __init__(self, x, y): + """ test """ + + # def __init__(self, char='#'): + + self.left = None + self.right = None + self.top = None + self.bottom = None + self.char = '#' + self.x = x + self.y = y diff --git a/megacosm/generators/govt.py b/megacosm/generators/govt.py new file mode 100644 index 0000000..f3a8759 --- /dev/null +++ b/megacosm/generators/govt.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from country import Country +from generator import Generator +import logging + + +class Govt(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + self.generate_features('govt' + self.kind) + + if not hasattr(self, 'body'): + + # TODO this should have an if statement on kind and also do cities + + self.body = Country(self.redis) diff --git a/megacosm/generators/jobposting.py b/megacosm/generators/jobposting.py new file mode 100644 index 0000000..fd0e78e --- /dev/null +++ b/megacosm/generators/jobposting.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from business import Business +from generator import Generator +from npc import NPC +import logging + + +class JobPosting(Generator): + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + for field in ['contact', 'npc']: + if not hasattr(self, field): + setattr(self, field, NPC(self.redis)) + if not hasattr(self, 'business'): + setattr(self, 'business', Business(self.redis)) + + if not hasattr(self, 'text'): + + for field in ['hook', 'request']: + if hasattr(self, field): + self.template = getattr(self, field) + ' ' + self.template + + for field in ['requirement', 'disclaimer', 'payment']: + if hasattr(self, field): + self.template = self.template + ' ' + getattr(self, field) + + self.template = self.template + ' Contact ' + self.contact.name['full'] + self.template = self.template + ' at the ' + self.business.name['full'] + if hasattr(self, 'detail'): + self.template = self.template + ' ' + self.detail + + self.template += '.' + + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/leader.py b/megacosm/generators/leader.py new file mode 100644 index 0000000..6a52d1f --- /dev/null +++ b/megacosm/generators/leader.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from country import Country +from npc import NPC +import logging + + +class Leader(NPC): + + """ Generate a god for your world""" + + def __init__(self, redis, features={}): + NPC.__init__(self, redis, features, 'npc') + self.logger = logging.getLogger(__name__) + + self.generate_features('leader') + self.generate_features('leader' + self.kind) + + if self.kind_description['scope'] == 'country': + self.location = Country(self.redis, {'leader': self}) + else: + # elif self.kind_description['scope'] == 'city': + # self.location=City(self.redis, {'leader':self}) + # TODO This should default to organization... + + self.location = Country(self.redis, {'leader': self}) + + self.set_title() + + def set_title(self): + self.name['title'] = self.leader_description[self.sex['name']] + self.name['fulltitled'] = self.name['title'] + ' ' + self.name['full'] diff --git a/megacosm/generators/legend.py b/megacosm/generators/legend.py new file mode 100644 index 0000000..fa19652 --- /dev/null +++ b/megacosm/generators/legend.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging + + +class Legend(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + for person in ['npc', 'villain']: + if not hasattr(self, person): + setattr(self, person, NPC(self.redis)) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/magicitem.py b/megacosm/generators/magicitem.py new file mode 100644 index 0000000..f6eefa2 --- /dev/null +++ b/megacosm/generators/magicitem.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +from jinja2.environment import Environment +from megacosm.util import Filters +import logging + + +class MagicItem(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + self.generate_features(self.kind) + + self.npc = NPC(redis) + + self.build_creator() + + text = self.render_template(self.name_template) + self.name = self.render_template(text) + + def build_creator(self): + environment = Environment() + environment.filters['article'] = Filters.select_article + environment.filters['pluralize'] = Filters.select_pluralize + template = environment.from_string(self.creator_template) + + self.creator = template.render(npc=self.npc) + + +# TODO needs real testing! + +# TODO move FILTER additions to generator +# TODO same with template rendering diff --git a/megacosm/generators/misfire.py b/megacosm/generators/misfire.py new file mode 100644 index 0000000..63f2fb5 --- /dev/null +++ b/megacosm/generators/misfire.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Misfire(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/moon.py b/megacosm/generators/moon.py new file mode 100644 index 0000000..e1d08c3 --- /dev/null +++ b/megacosm/generators/moon.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Moon(Generator): + + def __init__(self, server, features={}): + Generator.__init__(self, server, features) + self.logger = logging.getLogger(__name__) diff --git a/megacosm/generators/motivation.py b/megacosm/generators/motivation.py new file mode 100644 index 0000000..8471d19 --- /dev/null +++ b/megacosm/generators/motivation.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import npc +import logging + + +class Motivation(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + self.generate_features('motivation' + self.kind) + + if not hasattr(self, 'npc'): + self.npc = npc.NPC(self.redis, {'motivation': self}) + + self.text = self.render_template(self.text) + + def __str__(self): + return self.text diff --git a/megacosm/generators/mundaneitem.py b/megacosm/generators/mundaneitem.py new file mode 100644 index 0000000..94a0480 --- /dev/null +++ b/megacosm/generators/mundaneitem.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class MundaneItem(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'text'): + + # TODO move this to the data file + # self.text=self.render_template("{{params.quality['name']|article}} + # {{params.kind}}, {{params.repair['name']}}") + + self.text = self.render_template('{{params.kind}}') + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/npc.py b/megacosm/generators/npc.py new file mode 100644 index 0000000..3c5c7ac --- /dev/null +++ b/megacosm/generators/npc.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import motivation +import json +import logging +import random + + +class NPC(Generator): + + def __init__(self, redis, features={}, namekey=None): + + Generator.__init__(self, redis, features, namekey) + self.logger = logging.getLogger(__name__) + + if self.race not in self.redis.lrange('npc_race', 0, -1): + raise Exception(' %s is not a valid race and has no associated data' % self.race) + self.generate_features(self.race) + self.generate_features(self.covering) + self.coveringtext = self.render_template(self.covertemplate) + + self.details = json.loads(self.details) + + self.select_names() + + if hasattr(self, 'subrace'): + self.race = self.subrace_description['subrace'].lower() + + if not hasattr(self, 'motivation'): + self.motivation = motivation.Motivation(self.redis, {'npc': self}) + + def select_names(self): + nameorder = self.redis.zrange(self.race + '_name_order', 0, -1) + for namejson in nameorder: + name = json.loads(namejson)['name'] + self.name[name] = {} + nameparts = self.redis.hgetall(self.race + '_name_' + name) + for namepart in nameparts: + namepartkey = self.race + '_name_' + name + '_' + namepart + + # if random number is less than nape part chance + + if random.randint(0, 100) <= int(nameparts[namepart]): + self.name[name][namepart] = self.rand_value(namepartkey) + + self.name[name + 'name'] = '' + for namepart in ['title', 'pre', 'root', 'post', 'trailer']: + if namepart in self.name[name]: + if namepart == 'trailer': # space goes before namepart + self.name[name + 'name'] += ' ' + self.name[name + 'name'] += self.name[name][namepart] + if namepart == 'title': # space goes after namepart + self.name[name + 'name'] += ' ' + + self.name['full'] += self.name[name + 'name'] + ' ' + self.name['full'] = self.name['full'].strip() diff --git a/megacosm/generators/organization.py b/megacosm/generators/organization.py new file mode 100644 index 0000000..fa28be1 --- /dev/null +++ b/megacosm/generators/organization.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from leader import Leader +import logging + + +class Organization(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'leader'): + self.leader = Leader(self.redis) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.oldname = self.name['full'] + self.name['full'] = self.text diff --git a/generators/Planet.py b/megacosm/generators/planet.py similarity index 60% rename from generators/Planet.py rename to megacosm/generators/planet.py index 6ed4cc5..7dfce24 100644 --- a/generators/Planet.py +++ b/megacosm/generators/planet.py @@ -1,37 +1,45 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- -from generators.Continent import Continent -from generators.Generator import Generator -from generators.Moon import Moon +from continent import Continent +from generator import Generator +from moon import Moon import logging import random + class Planet(Generator): def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) self.add_moons() def add_continents(self): """ Generate the continents for this planet""" + # Ensure that we have a continents array + if not hasattr(self, 'continents'): - self.continents=[] + self.continents = [] # Ensure that we have a target number of continents + if not hasattr(self, 'continentcount'): - self.continentcount=random.randint(1,5); + self.continentcount = random.randint(1, 5) + # Banzai, er generate continents! - for continentID in xrange(self.continentcount): - self.continents.append( Continent(self.redis, {'planet':self}) ) + for continentID in xrange(self.continentcount): + self.continents.append(Continent(self.redis, {'planet': self})) def add_moons(self): """ Generate a list of moons """ + if not hasattr(self, 'moons'): - self.moons=[] + self.moons = [] # Note that mooncount is a planet stat for moonId in xrange(self.mooncount['count']): - self.moons.append(Moon(self.redis )) + self.moons.append(Moon(self.redis)) diff --git a/generators/Region.py b/megacosm/generators/region.py similarity index 69% rename from generators/Region.py rename to megacosm/generators/region.py index 6cff7d2..23041a1 100644 --- a/generators/Region.py +++ b/megacosm/generators/region.py @@ -1,11 +1,16 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- -from generators.Generator import Generator +from generator import Generator import logging + class Region(Generator): + def __init__(self, redis, features={}): - Generator.__init__(self,redis,features) - self.logger=logging.getLogger(__name__) + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + # TODO start a separate fork for cities and enable this with the new class # def add_cities(self): diff --git a/megacosm/generators/resource.py b/megacosm/generators/resource.py new file mode 100644 index 0000000..fc279ac --- /dev/null +++ b/megacosm/generators/resource.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from region import Region +import logging + + +class Resource(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + del self.name + + if not hasattr(self, 'place'): + self.place = Region(self.redis) + + self.subkind = self.kind + '_' + self.rand_value(self.kind + '_kind') + + self.generate_features(self.subkind) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/roguedungeon.py b/megacosm/generators/roguedungeon.py new file mode 100644 index 0000000..80ae1c4 --- /dev/null +++ b/megacosm/generators/roguedungeon.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import json +import logging +import random + + +class RogueDungeon(Generator): + + def __init__(self, redis, features={}): + """ Generate a Rogue-like dungeon """ + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + self.generate_features('dungeon') + + self.apply_text_template() + self.generate_grid() + self.generate_rooms() + self.generate_halls() + + def apply_text_template(self): + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text.title() + + def generate_grid(self): + gridsize = random.randint(self.size['minsize'], self.size['maxsize']) + self.height = gridsize + self.width = int(gridsize * 1.8) + + self.spaces = [[RogueDungeon.Tile() for i in range(self.width)] for j in range(self.height)] + + def convert_to_json(self): + resultmatrix = [] + + for row in self.spaces: + resultrow = [] + for cell in row: + resultrow.append({'passable': int(cell.passable), 'doorway': int(cell.isdoorway), + 'class': cell.__class__.__name__.lower()}) + resultmatrix.append(resultrow) + return resultmatrix + + def create_random_room(self): + + # TODO FIXME w and h is too large, need to make sure it fits in self.width + + w = min(self.width - 1, random.randint(self.room_size['minsize'], self.room_size['maxsize'])) + h = min(self.height - 1, random.randint(self.room_size['minsize'], self.room_size['maxsize'])) + + # random position without going out of the boundaries of the map + + x = random.randint(0, self.width - w - 1) + y = random.randint(0, self.height - h - 1) + return RogueDungeon.Room(x, y, w, h) + + def generate_halls(self): + previous_room = None + rooms = self.rooms + random.shuffle(rooms) + for room in rooms: + if previous_room is None: + room.kind = 'entrance' + room.kind_description = {'name': 'entrance', 'description': 'the way in'} + room.egress = True + else: + self.connect_rooms(room, previous_room) + room.kind = self.rand_value('roguedungeonroom_kind') + kinddesc = self.redis.hmget('roguedungeonroom_kind_description', room.kind) + room.kind_description = json.loads(kinddesc[0]) + previous_room = room + + def generate_rooms(self): + self.rooms = [] + max_rooms = random.randint(self.room_count['minsize'], self.room_count['maxsize']) + + for r in range(max_rooms): + new_room = self.create_random_room() + + conflict = False + for other_room in self.rooms: + if new_room.intersect(other_room): + conflict = True + break + if not conflict: + self.paint_room(new_room) + self.rooms.append(new_room) + + def connect_rooms(self, new_room, old_room): + pathtype = random.randint(0, 3) + ymidpoint = random.randint(min(new_room.center['y'], old_room.center['y']), max(new_room.center['y'], + old_room.center['y'])) + xmidpoint = random.randint(min(new_room.center['x'], old_room.center['x']), max(new_room.center['x'], + old_room.center['x'])) + + if pathtype == 0: + + # startroom new_room + + self.paint_h_tunnel(new_room.center['x'], xmidpoint, new_room.center['y']) + self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], xmidpoint) + self.paint_h_tunnel(xmidpoint, old_room.center['x'], old_room.center['y']) + elif pathtype == 1: + + # startroom room a + + self.paint_v_tunnel(new_room.center['y'], ymidpoint, new_room.center['x']) + self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], ymidpoint) + self.paint_v_tunnel(ymidpoint, old_room.center['y'], old_room.center['x']) + elif pathtype == 2: + + # startroom new_room + + self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], new_room.center['y']) + self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], old_room.center['x']) + else: + + # startroom old_room + + self.paint_v_tunnel(new_room.center['y'], old_room.center['y'], new_room.center['x']) + self.paint_h_tunnel(new_room.center['x'], old_room.center['x'], old_room.center['y']) + + def paint_room(self, room): + for x in range(room.x1 + 1, room.x2): + for y in range(room.y1 + 1, room.y2): + self.spaces[y][x] = RogueDungeon.RoomTile(room.roomid) + + def paint_h_tunnel(self, x1, x2, y): + lasttile = None + for x in range(min(x1, x2), max(x1, x2) + 1): + if type(self.spaces[y][x]) is RogueDungeon.RoomTile and type(lasttile) is RogueDungeon.HallTile: + + # Ignore room tiles, but track that the last tile was a room tile + + lasttile.isdoorway = True + elif type(self.spaces[y][x]) is RogueDungeon.Tile: + self.spaces[y][x] = RogueDungeon.HallTile() + if type(lasttile) is RogueDungeon.RoomTile: + self.spaces[y][x].isdoorway = True + lasttile = self.spaces[y][x] + + def paint_v_tunnel(self, y1, y2, x): + lasttile = None + for y in range(min(y1, y2), max(y1, y2) + 1): + if type(self.spaces[y][x]) is RogueDungeon.RoomTile and type(lasttile) is RogueDungeon.HallTile: + + # Ignore room tiles, but track that the last tile was a room tile + + lasttile.isdoorway = True + elif type(self.spaces[y][x]) is RogueDungeon.Tile: + self.spaces[y][x] = RogueDungeon.HallTile() + if type(lasttile) is RogueDungeon.RoomTile: + self.spaces[y][x].isdoorway = True + lasttile = self.spaces[y][x] + + def printfloor(self): + output = '' + for row in self.spaces: + for cell in row: + output += str(cell) + ' ' + output += '\n' + return output + + class Tile(object): + + def __init__(self, char='#'): + """ test """ + + # def __init__(self, char='#'): + + self.char = char + self.isdoorway = False + self.passable = False + + def __str__(self): + return self.char.encode('utf8') + + class RoomTile(Tile): + + def __init__(self, roomid): + """ test """ + + self.roomid = roomid + self.char = '.' + self.isdoorway = False + self.passable = True + + class HallTile(Tile): + + def __init__(self, char='.'): + """ test """ + + self.char = char + self.isdoorway = False + self.passable = True + + class Room(object): + + roomid = 0 + + def __init__(self, x, y, w, h): + """ test """ + + RogueDungeon.Room.roomid += 1 + self.egress = False + self.roomid = RogueDungeon.Room.roomid + self.x1 = x + self.y1 = y + self.x2 = x + w + self.y2 = y + h + center_x = (self.x1 + self.x2) / 2 + center_y = (self.y1 + self.y2) / 2 + self.center = {'x': center_x, 'y': center_y} + + def intersect(self, other): + + # returns true if this rectangle intersects with another one + + return self.x1 <= other.x2 and self.x2 >= other.x1 and self.y1 <= other.y2 and self.y2 >= other.y1 + + +# http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod,_part_3 + +# Garbage I was playing around with. + +# class UpTile(DungeonTile): +# def __init__(self, char=u'ߡ'): +# """ test """ +# self.char=char +# self.passable=False +# +# class DownTile(DungeonTile): +# def __init__(self, char=u'ߜ'): +# """ test """ +# self.char=char +# self.passable=False +# +# class PortalTile(DungeonTile): +# def __init__(self, char=u'Ω'): +# """ test """ +# self.char=char +# self.passable=False +# +# class WaterTile(DungeonTile): +# def __init__(self, char=u'ω'): +# """ test """ +# self.char=char +# self.passable=False +# +# +# class LavaTile(DungeonTile): +# def __init__(self, char=u'Ж'): +# #def __init__(self, char=u'ж'): +# """ test """ +# self.char=char +# self.passable=False diff --git a/megacosm/generators/rumor.py b/megacosm/generators/rumor.py new file mode 100644 index 0000000..0bcb3b7 --- /dev/null +++ b/megacosm/generators/rumor.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging + + +class Rumor(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + for person in ['victim', 'culprit', 'source', 'believer']: + if not hasattr(self, person): + setattr(self, person, NPC(self.redis).name['full']) + + if not hasattr(self, 'text'): + self.text = self.render_template(self.template) + self.text = self.render_template(self.text) + self.text = self.text[0].capitalize() + self.text[1:] + + def __str__(self): + return self.text diff --git a/megacosm/generators/sect.py b/megacosm/generators/sect.py new file mode 100644 index 0000000..e36f747 --- /dev/null +++ b/megacosm/generators/sect.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import deity +import logging +import random + + +class Sect(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + if not hasattr(self, 'deity'): + self.deity = deity.Deity(redis) + + if not hasattr(self, 'domain'): + portfolio = self.deity.portfolios + random.shuffle(portfolio) + self.domain = portfolio[0] + + +# TODO this should have an __str__; is it using the text->template pattern? diff --git a/megacosm/generators/star.py b/megacosm/generators/star.py new file mode 100644 index 0000000..6ce8751 --- /dev/null +++ b/megacosm/generators/star.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Star(Generator): + + def __init__(self, redis, features={}): + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) diff --git a/generators/StarSystem.py b/megacosm/generators/starsystem.py similarity index 54% rename from generators/StarSystem.py rename to megacosm/generators/starsystem.py index b2fe96c..b7da367 100644 --- a/generators/StarSystem.py +++ b/megacosm/generators/starsystem.py @@ -1,28 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- -from generators.Generator import Generator -from generators.Planet import Planet -from generators.Star import Star +from generator import Generator +from planet import Planet +from star import Star import json import logging import random + class StarSystem(Generator): + def __init__(self, redis, features={}): - Generator.__init__(self,redis, features) - self.logger=logging.getLogger(__name__) + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) self.generate_stars() self.generate_planet() def generate_stars(self): """ Do stuff""" - self.stars=[] - positions=self.redis.lrange('starposition', 0,-1) + self.stars = [] + + positions = self.redis.lrange('starposition', 0, -1) for starId in xrange(self.starcount['count']): random.shuffle(positions) - self.stars.append(Star(self.redis, {'pos': json.loads(positions.pop(0)) })) + self.stars.append(Star(self.redis, {'pos': json.loads(positions.pop(0))})) def generate_planet(self): """ Do stuff""" - self.planet=Planet(self.redis) + self.planet = Planet(self.redis) diff --git a/megacosm/generators/street.py b/megacosm/generators/street.py new file mode 100644 index 0000000..b408dc7 --- /dev/null +++ b/megacosm/generators/street.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Street(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + if 'trailer' not in self.name: + self.name['trailer'] = self.kind + self.name['full'] += ' ' + self.kind + + self.name['full'] = self.name['full'].title() diff --git a/megacosm/generators/wanted.py b/megacosm/generators/wanted.py new file mode 100644 index 0000000..cebe2ce --- /dev/null +++ b/megacosm/generators/wanted.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +from npc import NPC +import logging + + +class Wanted(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) + + for person in ['npc', 'victim']: + if not hasattr(self, person): + setattr(self, person, NPC(self.redis)) + + self.headline = self.render_template(self.headline) + self.lastseen = self.render_template(self.lastseen) diff --git a/megacosm/generators/weather.py b/megacosm/generators/weather.py new file mode 100644 index 0000000..eec3ed3 --- /dev/null +++ b/megacosm/generators/weather.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from generator import Generator +import logging + + +class Weather(Generator): + + def __init__(self, redis, features={}): + + Generator.__init__(self, redis, features) + self.logger = logging.getLogger(__name__) diff --git a/megacosm/oneliners.py b/megacosm/oneliners.py new file mode 100644 index 0000000..f1cb8f8 --- /dev/null +++ b/megacosm/oneliners.py @@ -0,0 +1,476 @@ +from flask import render_template, request +from megacosm.generators import Artwork +from megacosm.generators import Bond +from megacosm.generators import Resource +from megacosm.generators import Rumor +from megacosm.generators import Flaw +from megacosm.generators import Misfire +from megacosm.generators import Currency +from megacosm.generators import Event +from megacosm.generators import Gem +from megacosm.generators import Motivation +from megacosm.generators import JobPosting +from megacosm.generators import Legend +from megacosm.generators import MundaneItem +from megacosm.generators import Cuisine +from megacosm.generators import NPC +from megacosm.generators import Region + + +from megacosm.util.Seeds import set_seed + +from megacosm import app, feature_filter, builder_form_data + + +######################################################################### + + +@app.route('/bond') +def generatebond(): + """Generate a bond""" + + features = feature_filter('bond') + titletext = 'The Ties that Bind Us..' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + bonds = [] + for _ in xrange(int(request.args['count'])): + bonds.append(Bond(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=bonds, + oneliner=bonds[0], titletext=titletext, generator='bond') + else: + bond = Bond(app.server, features) + return render_template('oneliner.html', oneliner=bond, titletext=titletext, generator='bond') + + +@app.route('/bond_builder') +def bond_builder(): + """Build a bond""" + + statinfo = {} + for stat in ['when', 'template']: + statinfo[stat] = [] + for statstring in app.server.lrange('bond_'+stat, 0, -1): + statinfo[stat].append(statstring) + + return render_template('bond_builder.html', statinfo=statinfo) + +######################################################################### + + +@app.route('/resource') +def generateresource(): + """Generate a resource""" + + features = feature_filter('resource') + titletext = 'At Your Disposal...' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + resources = [] + for _ in xrange(int(request.args['count'])): + resources.append(Resource(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=resources, + oneliner=resources[0], titletext=titletext, generator='resource') + else: + resource = Resource(app.server, features) + return render_template('oneliner.html', oneliner=resource, titletext=titletext, generator='resource') + + +@app.route('/resource_builder') +def resource_builder(): + """Build a resource""" + classname = 'resource' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/artwork') +def generateartwork(): + """Generate a artwork""" + features = feature_filter('artwork') + titletext = 'A Work of Art...' + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + artworks = [] + for _ in xrange(int(request.args['count'])): + artworks.append(Artwork(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=artworks, + oneliner=artworks[0], titletext=titletext, generator='artwork') + else: + artwork = Artwork(app.server, features) + return render_template('oneliner.html', oneliner=artwork, titletext=titletext, generator='artwork') + + +@app.route('/artwork_builder') +def artwork_builder(): + """Build a a artwork""" + classname = 'artwork' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/rumor') +def generaterumor(): + """Generate a rumor""" + features = feature_filter('rumor') + titletext = 'Did You Hear?' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + rumors = [] + for _ in xrange(int(request.args['count'])): + rumors.append(Rumor(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=rumors, + oneliner=rumors[0], titletext=titletext, generator='rumor') + else: + rumor = Rumor(app.server, features) + return render_template('oneliner.html', oneliner=rumor, titletext=titletext, generator='rumor') + + +@app.route('/rumor_builder') +def rumor_builder(): + """Build a a rumor""" + classname = 'rumor' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/misfire') +def generatemisfire(): + """Generate a misfire""" + + features = feature_filter('misfire') + titletext = 'My Spell Misfired!' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + misfires = [] + for _ in xrange(int(request.args['count'])): + misfires.append(Misfire(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=misfires, + oneliner=misfires[0], titletext=titletext, generator='misfire') + else: + misfire = Misfire(app.server, features) + return render_template('oneliner.html', oneliner=misfire, titletext=titletext, generator='misfire') + + +@app.route('/misfire_builder') +def misfire_builder(): + """Build a a misfire""" + classname = 'misfire' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/flaw') +def generateflaw(): + """Generate a flaw""" + features = feature_filter('flaw') + titletext = 'My Greatest Flaw...' + + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + flaws = [] + for _ in xrange(int(request.args['count'])): + flaws.append(Flaw(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=flaws, + oneliner=flaws[0], titletext=titletext, generator='flaw') + else: + flaw = Flaw(app.server, features) + return render_template('oneliner.html', oneliner=flaw, titletext=titletext, generator='flaw') + + +@app.route('/flaw_builder') +def flaw_builder(): + """Build a a flaw""" + classname = 'flaw' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/currency') +def generatecurrency(): + """Generate a currency""" + features = feature_filter('currency') + titletext = 'Spare Some Change?' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + currencys = [] + for _ in xrange(int(request.args['count'])): + currencys.append(Currency(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=currencys, + oneliner=currencys[0], titletext=titletext, generator='currency') + else: + currency = Currency(app.server, features) + return render_template('oneliner.html', oneliner=currency, titletext=titletext, generator='currency') + + +@app.route('/currency_builder') +def currency_builder(): + """Build a a currency""" + classname = 'currency' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/jobposting') +def generatejobposting(): + """Generate a jobposting""" + + features = feature_filter('jobposting') + titletext = 'Help Wanted!' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + jobpostings = [] + for _ in xrange(int(request.args['count'])): + jobpostings.append(JobPosting(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=jobpostings, + oneliner=jobpostings[0], titletext=titletext, generator='jobposting') + else: + jobposting = JobPosting(app.server, features) + return render_template('oneliner.html', oneliner=jobposting, titletext=titletext, generator='jobposting') + + +@app.route('/jobposting_builder') +def jobposting_builder(): + """Build a a jobposting""" + classname = 'jobposting' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + + +######################################################################### + + +@app.route('/event') +def generateevent(): + """Generate a event""" + + features = feature_filter('event') + titletext = 'Look over there...' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + events = [] + for _ in xrange(int(request.args['count'])): + events.append(Event(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=events, + oneliner=events[0], titletext=titletext, generator='event') + else: + event = Event(app.server, features) + return render_template('oneliner.html', oneliner=event, titletext=titletext, generator='event') + + +@app.route('/event_builder') +def event_builder(): + """Build a a event""" + classname = 'event' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/motivation') +def generatemotivation(): + """Generate a motivation""" + features = feature_filter('motivation') + titletext = 'I\'m Motivated...' + features['npc'] = NPC(app.server) + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + motivations = [] + for _ in xrange(int(request.args['count'])): + motivations.append(Motivation(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=motivations, + oneliner=motivations[0], titletext=titletext, generator='motivation') + else: + motivation = Motivation(app.server, features) + return render_template('oneliner.html', oneliner=motivation, titletext=titletext, generator='motivation') + + +@app.route('/motivation_builder') +def motivation_builder(): + """Build a a motivation""" + classname = 'motivation' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/gem') +def generategem(): + """Generate a gem""" + features = feature_filter('gem') + titletext = 'OOOH, Shiny...' + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + gems = [] + for _ in xrange(int(request.args['count'])): + gems.append(Gem(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=gems, oneliner=gems[0], titletext=titletext, generator='gem') + else: + gem = Gem(app.server, features) + return render_template('oneliner.html', oneliner=gem, titletext=titletext, generator='gem') + + +@app.route('/gem_builder') +def gem_builder(): + """Build a a gem""" + classname = 'gem' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/mundaneitem') +def generatemundaneitem(): + """Generate a mundaneitem""" + + features = feature_filter('mundaneitem') + titletext = 'Look what I found!' + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + mundaneitems = [] + for _ in xrange(int(request.args['count'])): + mundaneitems.append(MundaneItem(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=mundaneitems, + oneliner=mundaneitems[0], titletext=titletext, generator='mundaneitem') + else: + mundaneitem = MundaneItem(app.server, features) + return render_template('oneliner.html', oneliner=mundaneitem, titletext=titletext, generator='mundaneitem') + + +@app.route('/mundaneitem_builder') +def mundaneitem_builder(): + """Build a a mundaneitem""" + classname = 'mundaneitem' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/legend') +def generatelegend(): + """Generate a legend""" + features = feature_filter('legend') + titletext = 'Let me tell you a story...' + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + legends = [] + for _ in xrange(int(request.args['count'])): + legends.append(Legend(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=legends, + oneliner=legends[0], titletext=titletext, generator='legend') + else: + legend = Legend(app.server, features) + return render_template('oneliner.html', oneliner=legend, titletext=titletext, generator='legend') + + +@app.route('/legend_builder') +def legend_builder(): + """Build a a legend""" + classname = 'legend' + plist, pstring, pset = builder_form_data(classname) + + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) + +######################################################################### + + +@app.route('/cuisine') +def generatecuisine(): + """Generate a cuisine""" + features = feature_filter('cuisine') + features['region'] = Region(app.server) + titletext = 'What\'s for Dinner?' + if ('count' in request.args and + request.args['count'].isdigit() and + int(request.args['count']) > 1 and + int(request.args['count']) <= 100): + cuisines = [] + for _ in xrange(int(request.args['count'])): + cuisines.append(Cuisine(app.server, features)) + features['seed'] = set_seed() + return render_template('oneliner.html', oneliners=cuisines, + oneliner=cuisines[0], titletext=titletext, generator='cuisine') + else: + cuisine = Cuisine(app.server, features) + return render_template('oneliner.html', oneliner=cuisine, titletext=titletext, generator='cuisine') + + +@app.route('/cuisine_builder') +def cuisine_builder(): + """Build a a cuisine""" + classname = 'cuisine' + plist, pstring, pset = builder_form_data(classname) + return render_template('generic_builder.html', plist=plist, pstring=pstring, pset=pset, name=classname) diff --git a/static/css/sticky-footer.css b/megacosm/static/css/sticky-footer.css similarity index 100% rename from static/css/sticky-footer.css rename to megacosm/static/css/sticky-footer.css diff --git a/static/images/background.png b/megacosm/static/images/background.png similarity index 100% rename from static/images/background.png rename to megacosm/static/images/background.png diff --git a/static/images/background.xcf b/megacosm/static/images/background.xcf similarity index 100% rename from static/images/background.xcf rename to megacosm/static/images/background.xcf diff --git a/static/images/backgrounds/dirt.png b/megacosm/static/images/backgrounds/dirt.png similarity index 100% rename from static/images/backgrounds/dirt.png rename to megacosm/static/images/backgrounds/dirt.png diff --git a/static/images/backgrounds/dirt1.png b/megacosm/static/images/backgrounds/dirt1.png similarity index 100% rename from static/images/backgrounds/dirt1.png rename to megacosm/static/images/backgrounds/dirt1.png diff --git a/static/images/backgrounds/dirt3.png b/megacosm/static/images/backgrounds/dirt3.png similarity index 100% rename from static/images/backgrounds/dirt3.png rename to megacosm/static/images/backgrounds/dirt3.png diff --git a/static/images/backgrounds/dirt4.png b/megacosm/static/images/backgrounds/dirt4.png similarity index 100% rename from static/images/backgrounds/dirt4.png rename to megacosm/static/images/backgrounds/dirt4.png diff --git a/static/images/backgrounds/dirt5.png b/megacosm/static/images/backgrounds/dirt5.png similarity index 100% rename from static/images/backgrounds/dirt5.png rename to megacosm/static/images/backgrounds/dirt5.png diff --git a/static/images/backgrounds/dirt6.png b/megacosm/static/images/backgrounds/dirt6.png similarity index 100% rename from static/images/backgrounds/dirt6.png rename to megacosm/static/images/backgrounds/dirt6.png diff --git a/static/images/backgrounds/granite.png b/megacosm/static/images/backgrounds/granite.png similarity index 100% rename from static/images/backgrounds/granite.png rename to megacosm/static/images/backgrounds/granite.png diff --git a/static/images/backgrounds/granite1.png b/megacosm/static/images/backgrounds/granite1.png similarity index 100% rename from static/images/backgrounds/granite1.png rename to megacosm/static/images/backgrounds/granite1.png diff --git a/static/images/backgrounds/granite2.png b/megacosm/static/images/backgrounds/granite2.png similarity index 100% rename from static/images/backgrounds/granite2.png rename to megacosm/static/images/backgrounds/granite2.png diff --git a/static/images/backgrounds/quartzite.png b/megacosm/static/images/backgrounds/quartzite.png similarity index 100% rename from static/images/backgrounds/quartzite.png rename to megacosm/static/images/backgrounds/quartzite.png diff --git a/static/images/backgrounds/rocks.png b/megacosm/static/images/backgrounds/rocks.png similarity index 100% rename from static/images/backgrounds/rocks.png rename to megacosm/static/images/backgrounds/rocks.png diff --git a/static/images/backgrounds/rocky.png b/megacosm/static/images/backgrounds/rocky.png similarity index 100% rename from static/images/backgrounds/rocky.png rename to megacosm/static/images/backgrounds/rocky.png diff --git a/static/images/backgrounds/sand.png b/megacosm/static/images/backgrounds/sand.png similarity index 100% rename from static/images/backgrounds/sand.png rename to megacosm/static/images/backgrounds/sand.png diff --git a/static/images/backgrounds/sandstone.png b/megacosm/static/images/backgrounds/sandstone.png similarity index 100% rename from static/images/backgrounds/sandstone.png rename to megacosm/static/images/backgrounds/sandstone.png diff --git a/static/images/backgrounds/sandstone1.png b/megacosm/static/images/backgrounds/sandstone1.png similarity index 100% rename from static/images/backgrounds/sandstone1.png rename to megacosm/static/images/backgrounds/sandstone1.png diff --git a/static/images/backgrounds/stone.png b/megacosm/static/images/backgrounds/stone.png similarity index 100% rename from static/images/backgrounds/stone.png rename to megacosm/static/images/backgrounds/stone.png diff --git a/static/images/backgrounds/stone1.png b/megacosm/static/images/backgrounds/stone1.png similarity index 100% rename from static/images/backgrounds/stone1.png rename to megacosm/static/images/backgrounds/stone1.png diff --git a/static/images/clouds.png b/megacosm/static/images/clouds.png similarity index 100% rename from static/images/clouds.png rename to megacosm/static/images/clouds.png diff --git a/static/images/containers.xcf b/megacosm/static/images/containers.xcf similarity index 100% rename from static/images/containers.xcf rename to megacosm/static/images/containers.xcf diff --git a/static/images/decorations/blood.png b/megacosm/static/images/decorations/blood.png similarity index 100% rename from static/images/decorations/blood.png rename to megacosm/static/images/decorations/blood.png diff --git a/static/images/decorations/blood.xcf b/megacosm/static/images/decorations/blood.xcf similarity index 100% rename from static/images/decorations/blood.xcf rename to megacosm/static/images/decorations/blood.xcf diff --git a/static/images/decorations/cavein.png b/megacosm/static/images/decorations/cavein.png similarity index 100% rename from static/images/decorations/cavein.png rename to megacosm/static/images/decorations/cavein.png diff --git a/static/images/decorations/cavein.xcf b/megacosm/static/images/decorations/cavein.xcf similarity index 100% rename from static/images/decorations/cavein.xcf rename to megacosm/static/images/decorations/cavein.xcf diff --git a/static/images/decorations/fog.png b/megacosm/static/images/decorations/fog.png similarity index 100% rename from static/images/decorations/fog.png rename to megacosm/static/images/decorations/fog.png diff --git a/static/images/decorations/fog.xcf b/megacosm/static/images/decorations/fog.xcf similarity index 100% rename from static/images/decorations/fog.xcf rename to megacosm/static/images/decorations/fog.xcf diff --git a/static/images/decorations/lava.xcf b/megacosm/static/images/decorations/lava.xcf similarity index 100% rename from static/images/decorations/lava.xcf rename to megacosm/static/images/decorations/lava.xcf diff --git a/static/images/decorations/lava1.png b/megacosm/static/images/decorations/lava1.png similarity index 100% rename from static/images/decorations/lava1.png rename to megacosm/static/images/decorations/lava1.png diff --git a/static/images/decorations/lava2.png b/megacosm/static/images/decorations/lava2.png similarity index 100% rename from static/images/decorations/lava2.png rename to megacosm/static/images/decorations/lava2.png diff --git a/static/images/decorations/river.png b/megacosm/static/images/decorations/river.png similarity index 100% rename from static/images/decorations/river.png rename to megacosm/static/images/decorations/river.png diff --git a/static/images/decorations/river.xcf b/megacosm/static/images/decorations/river.xcf similarity index 100% rename from static/images/decorations/river.xcf rename to megacosm/static/images/decorations/river.xcf diff --git a/static/images/decorations/shadows.png b/megacosm/static/images/decorations/shadows.png similarity index 100% rename from static/images/decorations/shadows.png rename to megacosm/static/images/decorations/shadows.png diff --git a/static/images/decorations/shadows.xcf b/megacosm/static/images/decorations/shadows.xcf similarity index 100% rename from static/images/decorations/shadows.xcf rename to megacosm/static/images/decorations/shadows.xcf diff --git a/static/images/decorations/slime.png b/megacosm/static/images/decorations/slime.png similarity index 100% rename from static/images/decorations/slime.png rename to megacosm/static/images/decorations/slime.png diff --git a/static/images/decorations/slime.xcf b/megacosm/static/images/decorations/slime.xcf similarity index 100% rename from static/images/decorations/slime.xcf rename to megacosm/static/images/decorations/slime.xcf diff --git a/static/images/decorations/smoke.png b/megacosm/static/images/decorations/smoke.png similarity index 100% rename from static/images/decorations/smoke.png rename to megacosm/static/images/decorations/smoke.png diff --git a/static/images/decorations/spiderwebs.png b/megacosm/static/images/decorations/spiderwebs.png similarity index 100% rename from static/images/decorations/spiderwebs.png rename to megacosm/static/images/decorations/spiderwebs.png diff --git a/static/images/decorations/spiderwebs.xcf b/megacosm/static/images/decorations/spiderwebs.xcf similarity index 100% rename from static/images/decorations/spiderwebs.xcf rename to megacosm/static/images/decorations/spiderwebs.xcf diff --git a/static/images/deity/anchor.png b/megacosm/static/images/deity/anchor.png similarity index 100% rename from static/images/deity/anchor.png rename to megacosm/static/images/deity/anchor.png diff --git a/static/images/deity/anchor.xcf b/megacosm/static/images/deity/anchor.xcf similarity index 100% rename from static/images/deity/anchor.xcf rename to megacosm/static/images/deity/anchor.xcf diff --git a/static/images/deity/anchorbroken.png b/megacosm/static/images/deity/anchorbroken.png similarity index 100% rename from static/images/deity/anchorbroken.png rename to megacosm/static/images/deity/anchorbroken.png diff --git a/static/images/deity/anchorburning.png b/megacosm/static/images/deity/anchorburning.png similarity index 100% rename from static/images/deity/anchorburning.png rename to megacosm/static/images/deity/anchorburning.png diff --git a/static/images/deity/anchorcircled.png b/megacosm/static/images/deity/anchorcircled.png similarity index 100% rename from static/images/deity/anchorcircled.png rename to megacosm/static/images/deity/anchorcircled.png diff --git a/static/images/deity/anchordivided.png b/megacosm/static/images/deity/anchordivided.png similarity index 100% rename from static/images/deity/anchordivided.png rename to megacosm/static/images/deity/anchordivided.png diff --git a/static/images/deity/anchordouble.png b/megacosm/static/images/deity/anchordouble.png similarity index 100% rename from static/images/deity/anchordouble.png rename to megacosm/static/images/deity/anchordouble.png diff --git a/static/images/deity/anchorfragmented.png b/megacosm/static/images/deity/anchorfragmented.png similarity index 100% rename from static/images/deity/anchorfragmented.png rename to megacosm/static/images/deity/anchorfragmented.png diff --git a/static/images/deity/anchorrocking.png b/megacosm/static/images/deity/anchorrocking.png similarity index 100% rename from static/images/deity/anchorrocking.png rename to megacosm/static/images/deity/anchorrocking.png diff --git a/static/images/deity/anchorsideways.png b/megacosm/static/images/deity/anchorsideways.png similarity index 100% rename from static/images/deity/anchorsideways.png rename to megacosm/static/images/deity/anchorsideways.png diff --git a/static/images/deity/anchorswinging.png b/megacosm/static/images/deity/anchorswinging.png similarity index 100% rename from static/images/deity/anchorswinging.png rename to megacosm/static/images/deity/anchorswinging.png diff --git a/static/images/deity/anchortilted.png b/megacosm/static/images/deity/anchortilted.png similarity index 100% rename from static/images/deity/anchortilted.png rename to megacosm/static/images/deity/anchortilted.png diff --git a/static/images/deity/anchortriple.png b/megacosm/static/images/deity/anchortriple.png similarity index 100% rename from static/images/deity/anchortriple.png rename to megacosm/static/images/deity/anchortriple.png diff --git a/static/images/deity/anchorupside-down.png b/megacosm/static/images/deity/anchorupside-down.png similarity index 100% rename from static/images/deity/anchorupside-down.png rename to megacosm/static/images/deity/anchorupside-down.png diff --git a/static/images/deity/ankh.png b/megacosm/static/images/deity/ankh.png similarity index 100% rename from static/images/deity/ankh.png rename to megacosm/static/images/deity/ankh.png diff --git a/static/images/deity/ankh.xcf b/megacosm/static/images/deity/ankh.xcf similarity index 100% rename from static/images/deity/ankh.xcf rename to megacosm/static/images/deity/ankh.xcf diff --git a/static/images/deity/ankhbroken.png b/megacosm/static/images/deity/ankhbroken.png similarity index 100% rename from static/images/deity/ankhbroken.png rename to megacosm/static/images/deity/ankhbroken.png diff --git a/static/images/deity/ankhburning.png b/megacosm/static/images/deity/ankhburning.png similarity index 100% rename from static/images/deity/ankhburning.png rename to megacosm/static/images/deity/ankhburning.png diff --git a/static/images/deity/ankhcircled.png b/megacosm/static/images/deity/ankhcircled.png similarity index 100% rename from static/images/deity/ankhcircled.png rename to megacosm/static/images/deity/ankhcircled.png diff --git a/static/images/deity/ankhdivided.png b/megacosm/static/images/deity/ankhdivided.png similarity index 100% rename from static/images/deity/ankhdivided.png rename to megacosm/static/images/deity/ankhdivided.png diff --git a/static/images/deity/ankhdouble.png b/megacosm/static/images/deity/ankhdouble.png similarity index 100% rename from static/images/deity/ankhdouble.png rename to megacosm/static/images/deity/ankhdouble.png diff --git a/static/images/deity/ankhfragmented.png b/megacosm/static/images/deity/ankhfragmented.png similarity index 100% rename from static/images/deity/ankhfragmented.png rename to megacosm/static/images/deity/ankhfragmented.png diff --git a/static/images/deity/ankhrocking.png b/megacosm/static/images/deity/ankhrocking.png similarity index 100% rename from static/images/deity/ankhrocking.png rename to megacosm/static/images/deity/ankhrocking.png diff --git a/static/images/deity/ankhsideways.png b/megacosm/static/images/deity/ankhsideways.png similarity index 100% rename from static/images/deity/ankhsideways.png rename to megacosm/static/images/deity/ankhsideways.png diff --git a/static/images/deity/ankhswinging.png b/megacosm/static/images/deity/ankhswinging.png similarity index 100% rename from static/images/deity/ankhswinging.png rename to megacosm/static/images/deity/ankhswinging.png diff --git a/static/images/deity/ankhtilted.png b/megacosm/static/images/deity/ankhtilted.png similarity index 100% rename from static/images/deity/ankhtilted.png rename to megacosm/static/images/deity/ankhtilted.png diff --git a/static/images/deity/ankhtriple.png b/megacosm/static/images/deity/ankhtriple.png similarity index 100% rename from static/images/deity/ankhtriple.png rename to megacosm/static/images/deity/ankhtriple.png diff --git a/static/images/deity/ankhupside-down.png b/megacosm/static/images/deity/ankhupside-down.png similarity index 100% rename from static/images/deity/ankhupside-down.png rename to megacosm/static/images/deity/ankhupside-down.png diff --git a/static/images/deity/anvil.png b/megacosm/static/images/deity/anvil.png similarity index 100% rename from static/images/deity/anvil.png rename to megacosm/static/images/deity/anvil.png diff --git a/static/images/deity/anvil.xcf b/megacosm/static/images/deity/anvil.xcf similarity index 100% rename from static/images/deity/anvil.xcf rename to megacosm/static/images/deity/anvil.xcf diff --git a/static/images/deity/anvilbroken.png b/megacosm/static/images/deity/anvilbroken.png similarity index 100% rename from static/images/deity/anvilbroken.png rename to megacosm/static/images/deity/anvilbroken.png diff --git a/static/images/deity/anvilburning.png b/megacosm/static/images/deity/anvilburning.png similarity index 100% rename from static/images/deity/anvilburning.png rename to megacosm/static/images/deity/anvilburning.png diff --git a/static/images/deity/anvilcircled.png b/megacosm/static/images/deity/anvilcircled.png similarity index 100% rename from static/images/deity/anvilcircled.png rename to megacosm/static/images/deity/anvilcircled.png diff --git a/static/images/deity/anvildivided.png b/megacosm/static/images/deity/anvildivided.png similarity index 100% rename from static/images/deity/anvildivided.png rename to megacosm/static/images/deity/anvildivided.png diff --git a/static/images/deity/anvildouble.png b/megacosm/static/images/deity/anvildouble.png similarity index 100% rename from static/images/deity/anvildouble.png rename to megacosm/static/images/deity/anvildouble.png diff --git a/static/images/deity/anvilfragmented.png b/megacosm/static/images/deity/anvilfragmented.png similarity index 100% rename from static/images/deity/anvilfragmented.png rename to megacosm/static/images/deity/anvilfragmented.png diff --git a/static/images/deity/anvilrocking.png b/megacosm/static/images/deity/anvilrocking.png similarity index 100% rename from static/images/deity/anvilrocking.png rename to megacosm/static/images/deity/anvilrocking.png diff --git a/static/images/deity/anvilsideways.png b/megacosm/static/images/deity/anvilsideways.png similarity index 100% rename from static/images/deity/anvilsideways.png rename to megacosm/static/images/deity/anvilsideways.png diff --git a/static/images/deity/anvilswinging.png b/megacosm/static/images/deity/anvilswinging.png similarity index 100% rename from static/images/deity/anvilswinging.png rename to megacosm/static/images/deity/anvilswinging.png diff --git a/static/images/deity/anviltilted.png b/megacosm/static/images/deity/anviltilted.png similarity index 100% rename from static/images/deity/anviltilted.png rename to megacosm/static/images/deity/anviltilted.png diff --git a/static/images/deity/anviltriple.png b/megacosm/static/images/deity/anviltriple.png similarity index 100% rename from static/images/deity/anviltriple.png rename to megacosm/static/images/deity/anviltriple.png diff --git a/static/images/deity/anvilupside-down.png b/megacosm/static/images/deity/anvilupside-down.png similarity index 100% rename from static/images/deity/anvilupside-down.png rename to megacosm/static/images/deity/anvilupside-down.png diff --git a/static/images/deity/apple.png b/megacosm/static/images/deity/apple.png similarity index 100% rename from static/images/deity/apple.png rename to megacosm/static/images/deity/apple.png diff --git a/static/images/deity/apple.xcf b/megacosm/static/images/deity/apple.xcf similarity index 100% rename from static/images/deity/apple.xcf rename to megacosm/static/images/deity/apple.xcf diff --git a/static/images/deity/applebroken.png b/megacosm/static/images/deity/applebroken.png similarity index 100% rename from static/images/deity/applebroken.png rename to megacosm/static/images/deity/applebroken.png diff --git a/static/images/deity/appleburning.png b/megacosm/static/images/deity/appleburning.png similarity index 100% rename from static/images/deity/appleburning.png rename to megacosm/static/images/deity/appleburning.png diff --git a/static/images/deity/applecircled.png b/megacosm/static/images/deity/applecircled.png similarity index 100% rename from static/images/deity/applecircled.png rename to megacosm/static/images/deity/applecircled.png diff --git a/static/images/deity/appledivided.png b/megacosm/static/images/deity/appledivided.png similarity index 100% rename from static/images/deity/appledivided.png rename to megacosm/static/images/deity/appledivided.png diff --git a/static/images/deity/appledouble.png b/megacosm/static/images/deity/appledouble.png similarity index 100% rename from static/images/deity/appledouble.png rename to megacosm/static/images/deity/appledouble.png diff --git a/static/images/deity/applefragmented.png b/megacosm/static/images/deity/applefragmented.png similarity index 100% rename from static/images/deity/applefragmented.png rename to megacosm/static/images/deity/applefragmented.png diff --git a/static/images/deity/applerocking.png b/megacosm/static/images/deity/applerocking.png similarity index 100% rename from static/images/deity/applerocking.png rename to megacosm/static/images/deity/applerocking.png diff --git a/static/images/deity/applesideways.png b/megacosm/static/images/deity/applesideways.png similarity index 100% rename from static/images/deity/applesideways.png rename to megacosm/static/images/deity/applesideways.png diff --git a/static/images/deity/appleswinging.png b/megacosm/static/images/deity/appleswinging.png similarity index 100% rename from static/images/deity/appleswinging.png rename to megacosm/static/images/deity/appleswinging.png diff --git a/static/images/deity/appletilted.png b/megacosm/static/images/deity/appletilted.png similarity index 100% rename from static/images/deity/appletilted.png rename to megacosm/static/images/deity/appletilted.png diff --git a/static/images/deity/appletriple.png b/megacosm/static/images/deity/appletriple.png similarity index 100% rename from static/images/deity/appletriple.png rename to megacosm/static/images/deity/appletriple.png diff --git a/static/images/deity/appleupside-down.png b/megacosm/static/images/deity/appleupside-down.png similarity index 100% rename from static/images/deity/appleupside-down.png rename to megacosm/static/images/deity/appleupside-down.png diff --git a/static/images/deity/axe.png b/megacosm/static/images/deity/axe.png similarity index 100% rename from static/images/deity/axe.png rename to megacosm/static/images/deity/axe.png diff --git a/static/images/deity/axe.xcf b/megacosm/static/images/deity/axe.xcf similarity index 100% rename from static/images/deity/axe.xcf rename to megacosm/static/images/deity/axe.xcf diff --git a/static/images/deity/axebroken.png b/megacosm/static/images/deity/axebroken.png similarity index 100% rename from static/images/deity/axebroken.png rename to megacosm/static/images/deity/axebroken.png diff --git a/static/images/deity/axeburning.png b/megacosm/static/images/deity/axeburning.png similarity index 100% rename from static/images/deity/axeburning.png rename to megacosm/static/images/deity/axeburning.png diff --git a/static/images/deity/axecircled.png b/megacosm/static/images/deity/axecircled.png similarity index 100% rename from static/images/deity/axecircled.png rename to megacosm/static/images/deity/axecircled.png diff --git a/static/images/deity/axedivided.png b/megacosm/static/images/deity/axedivided.png similarity index 100% rename from static/images/deity/axedivided.png rename to megacosm/static/images/deity/axedivided.png diff --git a/static/images/deity/axedouble.png b/megacosm/static/images/deity/axedouble.png similarity index 100% rename from static/images/deity/axedouble.png rename to megacosm/static/images/deity/axedouble.png diff --git a/static/images/deity/axefragmented.png b/megacosm/static/images/deity/axefragmented.png similarity index 100% rename from static/images/deity/axefragmented.png rename to megacosm/static/images/deity/axefragmented.png diff --git a/static/images/deity/axerocking.png b/megacosm/static/images/deity/axerocking.png similarity index 100% rename from static/images/deity/axerocking.png rename to megacosm/static/images/deity/axerocking.png diff --git a/static/images/deity/axesideways.png b/megacosm/static/images/deity/axesideways.png similarity index 100% rename from static/images/deity/axesideways.png rename to megacosm/static/images/deity/axesideways.png diff --git a/static/images/deity/axeswinging.png b/megacosm/static/images/deity/axeswinging.png similarity index 100% rename from static/images/deity/axeswinging.png rename to megacosm/static/images/deity/axeswinging.png diff --git a/static/images/deity/axetilted.png b/megacosm/static/images/deity/axetilted.png similarity index 100% rename from static/images/deity/axetilted.png rename to megacosm/static/images/deity/axetilted.png diff --git a/static/images/deity/axetriple.png b/megacosm/static/images/deity/axetriple.png similarity index 100% rename from static/images/deity/axetriple.png rename to megacosm/static/images/deity/axetriple.png diff --git a/static/images/deity/axeupside-down.png b/megacosm/static/images/deity/axeupside-down.png similarity index 100% rename from static/images/deity/axeupside-down.png rename to megacosm/static/images/deity/axeupside-down.png diff --git a/static/images/deity/bell.png b/megacosm/static/images/deity/bell.png similarity index 100% rename from static/images/deity/bell.png rename to megacosm/static/images/deity/bell.png diff --git a/static/images/deity/bell.xcf b/megacosm/static/images/deity/bell.xcf similarity index 100% rename from static/images/deity/bell.xcf rename to megacosm/static/images/deity/bell.xcf diff --git a/static/images/deity/bellbroken.png b/megacosm/static/images/deity/bellbroken.png similarity index 100% rename from static/images/deity/bellbroken.png rename to megacosm/static/images/deity/bellbroken.png diff --git a/static/images/deity/bellburning.png b/megacosm/static/images/deity/bellburning.png similarity index 100% rename from static/images/deity/bellburning.png rename to megacosm/static/images/deity/bellburning.png diff --git a/static/images/deity/bellcircled.png b/megacosm/static/images/deity/bellcircled.png similarity index 100% rename from static/images/deity/bellcircled.png rename to megacosm/static/images/deity/bellcircled.png diff --git a/static/images/deity/belldivided.png b/megacosm/static/images/deity/belldivided.png similarity index 100% rename from static/images/deity/belldivided.png rename to megacosm/static/images/deity/belldivided.png diff --git a/static/images/deity/belldouble.png b/megacosm/static/images/deity/belldouble.png similarity index 100% rename from static/images/deity/belldouble.png rename to megacosm/static/images/deity/belldouble.png diff --git a/static/images/deity/bellfragmented.png b/megacosm/static/images/deity/bellfragmented.png similarity index 100% rename from static/images/deity/bellfragmented.png rename to megacosm/static/images/deity/bellfragmented.png diff --git a/static/images/deity/bellrocking.png b/megacosm/static/images/deity/bellrocking.png similarity index 100% rename from static/images/deity/bellrocking.png rename to megacosm/static/images/deity/bellrocking.png diff --git a/static/images/deity/bellsideways.png b/megacosm/static/images/deity/bellsideways.png similarity index 100% rename from static/images/deity/bellsideways.png rename to megacosm/static/images/deity/bellsideways.png diff --git a/static/images/deity/bellswinging.png b/megacosm/static/images/deity/bellswinging.png similarity index 100% rename from static/images/deity/bellswinging.png rename to megacosm/static/images/deity/bellswinging.png diff --git a/static/images/deity/belltilted.png b/megacosm/static/images/deity/belltilted.png similarity index 100% rename from static/images/deity/belltilted.png rename to megacosm/static/images/deity/belltilted.png diff --git a/static/images/deity/belltriple.png b/megacosm/static/images/deity/belltriple.png similarity index 100% rename from static/images/deity/belltriple.png rename to megacosm/static/images/deity/belltriple.png diff --git a/static/images/deity/bellupside-down.png b/megacosm/static/images/deity/bellupside-down.png similarity index 100% rename from static/images/deity/bellupside-down.png rename to megacosm/static/images/deity/bellupside-down.png diff --git a/static/images/deity/others.xcf b/megacosm/static/images/deity/others.xcf similarity index 100% rename from static/images/deity/others.xcf rename to megacosm/static/images/deity/others.xcf diff --git a/static/images/dungeon/mini-tiles.xcf b/megacosm/static/images/dungeon/mini-tiles.xcf similarity index 100% rename from static/images/dungeon/mini-tiles.xcf rename to megacosm/static/images/dungeon/mini-tiles.xcf diff --git a/static/images/dungeon/minitiles.png b/megacosm/static/images/dungeon/minitiles.png similarity index 100% rename from static/images/dungeon/minitiles.png rename to megacosm/static/images/dungeon/minitiles.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/a0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/a0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/a0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/a0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/b0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/b0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/b0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/b0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/c0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/c0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/c0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/c0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/d0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/d0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/d0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/d0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/e0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/e0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/e0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/e0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/f0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/f0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/f0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/f0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/g0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/g0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/g0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/g0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/h0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/h0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/h0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/h0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/i0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/i0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/i0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/i0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/j0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/j0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/j0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/j0.png diff --git a/static/images/geomorphs/morgajel/basiccave/0/k0.png b/megacosm/static/images/geomorphs/morgajel/basiccave/0/k0.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/0/k0.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/0/k0.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/a1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/a1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/a1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/a1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/b1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/b1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/b1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/b1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/c1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/c1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/c1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/c1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/d1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/d1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/d1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/d1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/e1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/e1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/e1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/e1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/f1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/f1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/f1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/f1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/g1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/g1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/g1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/g1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/h1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/h1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/h1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/h1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/i1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/i1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/i1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/i1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/j1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/j1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/j1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/j1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/k1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/k1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/k1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/k1.png diff --git a/static/images/geomorphs/morgajel/basiccave/1/l1.png b/megacosm/static/images/geomorphs/morgajel/basiccave/1/l1.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/1/l1.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/1/l1.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/a2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/a2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/a2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/a2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/b2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/b2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/b2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/b2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/c2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/c2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/c2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/c2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/d2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/d2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/d2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/d2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/e2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/e2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/e2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/e2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/f2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/f2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/f2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/f2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/g2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/g2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/g2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/g2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/h2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/h2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/h2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/h2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/i2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/i2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/i2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/i2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/j2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/j2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/j2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/j2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/k2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/k2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/k2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/k2.png diff --git a/static/images/geomorphs/morgajel/basiccave/2/l2.png b/megacosm/static/images/geomorphs/morgajel/basiccave/2/l2.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/2/l2.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/2/l2.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/a3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/a3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/a3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/a3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/b3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/b3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/b3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/b3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/c3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/c3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/c3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/c3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/d3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/d3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/d3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/d3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/e3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/e3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/e3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/e3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/f3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/f3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/f3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/f3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/g3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/g3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/g3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/g3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/h3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/h3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/h3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/h3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/j3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/j3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/j3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/j3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/k3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/k3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/k3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/k3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/l3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/l3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/l3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/l3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/m3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/m3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/m3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/m3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/n3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/n3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/n3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/n3.png diff --git a/static/images/geomorphs/morgajel/basiccave/3/o3.png b/megacosm/static/images/geomorphs/morgajel/basiccave/3/o3.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/3/o3.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/3/o3.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/a4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/a4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/a4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/a4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/b4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/b4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/b4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/b4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/c4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/c4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/c4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/c4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/d4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/d4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/d4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/d4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/e4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/e4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/e4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/e4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/f4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/f4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/f4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/f4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/g4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/g4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/g4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/g4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/h4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/h4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/h4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/h4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/i4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/i4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/i4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/i4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/j4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/j4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/j4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/j4.png diff --git a/static/images/geomorphs/morgajel/basiccave/4/k4.png b/megacosm/static/images/geomorphs/morgajel/basiccave/4/k4.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/4/k4.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/4/k4.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/a5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/a5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/a5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/a5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/b5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/b5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/b5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/b5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/c5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/c5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/c5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/c5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/d5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/d5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/d5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/d5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/e5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/e5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/e5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/e5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/f5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/f5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/f5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/f5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/g5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/g5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/g5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/g5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/h5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/h5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/h5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/h5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/i5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/i5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/i5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/i5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/j5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/j5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/j5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/j5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/k5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/k5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/k5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/k5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/l5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/l5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/l5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/l5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/m5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/m5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/m5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/m5.png diff --git a/static/images/geomorphs/morgajel/basiccave/5/n5.png b/megacosm/static/images/geomorphs/morgajel/basiccave/5/n5.png similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/5/n5.png rename to megacosm/static/images/geomorphs/morgajel/basiccave/5/n5.png diff --git a/static/images/geomorphs/morgajel/basiccave/basiccave.xcf b/megacosm/static/images/geomorphs/morgajel/basiccave/basiccave.xcf similarity index 100% rename from static/images/geomorphs/morgajel/basiccave/basiccave.xcf rename to megacosm/static/images/geomorphs/morgajel/basiccave/basiccave.xcf diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/a0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/a0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/a0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/a0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/b0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/b0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/b0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/b0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/c0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/c0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/c0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/c0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/d0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/d0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/d0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/d0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/e0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/e0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/e0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/e0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/0/f0.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/0/f0.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/0/f0.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/0/f0.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/a1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/a1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/a1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/a1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/b1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/b1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/b1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/b1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/c1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/c1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/c1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/c1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/d1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/d1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/d1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/d1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/e1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/e1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/e1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/e1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/f1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/f1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/f1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/f1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/g1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/g1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/g1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/g1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/h1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/h1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/h1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/h1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/i1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/i1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/i1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/i1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/j1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/j1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/j1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/j1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/k1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/k1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/k1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/k1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/1/l1.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/1/l1.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/1/l1.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/1/l1.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/a2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/a2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/a2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/a2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/b2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/b2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/b2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/b2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/c2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/c2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/c2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/c2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/d2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/d2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/d2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/d2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/e2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/e2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/e2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/e2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/f2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/f2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/f2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/f2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/g2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/g2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/g2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/g2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/h2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/h2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/h2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/h2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/i2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/i2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/i2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/i2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/j2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/j2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/j2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/j2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/k2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/k2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/k2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/k2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/l2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/l2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/l2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/l2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/2/m2.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/2/m2.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/2/m2.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/2/m2.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/a3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/a3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/a3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/a3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/b3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/b3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/b3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/b3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/c3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/c3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/c3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/c3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/d3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/d3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/d3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/d3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/e3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/e3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/e3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/e3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/f3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/f3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/f3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/f3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/g3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/g3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/g3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/g3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/h3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/h3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/h3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/h3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/i3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/i3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/i3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/i3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/j3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/j3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/j3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/j3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/k3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/k3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/k3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/k3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/l3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/l3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/l3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/l3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/3/m3.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/3/m3.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/3/m3.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/3/m3.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/a4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/a4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/a4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/a4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/b4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/b4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/b4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/b4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/c4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/c4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/c4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/c4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/d4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/d4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/d4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/d4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/e4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/e4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/e4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/e4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/f4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/f4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/f4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/f4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/g4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/g4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/g4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/g4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/h4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/h4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/h4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/h4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/i4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/i4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/i4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/i4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/j4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/j4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/j4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/j4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/k4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/k4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/k4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/k4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/l4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/l4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/l4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/l4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/m4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/m4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/m4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/m4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/n4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/n4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/n4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/n4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/4/o4.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/4/o4.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/4/o4.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/4/o4.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/a5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/a5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/a5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/a5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/b5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/b5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/b5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/b5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/c5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/c5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/c5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/c5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/d5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/d5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/d5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/d5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/e5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/e5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/e5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/e5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/f5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/f5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/f5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/f5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/g5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/g5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/g5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/g5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/h5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/h5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/h5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/h5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/i5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/i5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/i5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/i5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/j5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/j5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/j5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/j5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/5/k5.png b/megacosm/static/images/geomorphs/morgajel/basicdungeon/5/k5.png similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/5/k5.png rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/5/k5.png diff --git a/static/images/geomorphs/morgajel/basicdungeon/basicdungeon.xcf b/megacosm/static/images/geomorphs/morgajel/basicdungeon/basicdungeon.xcf similarity index 100% rename from static/images/geomorphs/morgajel/basicdungeon/basicdungeon.xcf rename to megacosm/static/images/geomorphs/morgajel/basicdungeon/basicdungeon.xcf diff --git a/static/images/geomorphs/samplegeomorphs.xcf b/megacosm/static/images/geomorphs/samplegeomorphs.xcf similarity index 100% rename from static/images/geomorphs/samplegeomorphs.xcf rename to megacosm/static/images/geomorphs/samplegeomorphs.xcf diff --git a/static/images/megacosm_icon.xcf b/megacosm/static/images/megacosm_icon.xcf similarity index 100% rename from static/images/megacosm_icon.xcf rename to megacosm/static/images/megacosm_icon.xcf diff --git a/static/images/megacosm_icon_256.png b/megacosm/static/images/megacosm_icon_256.png similarity index 100% rename from static/images/megacosm_icon_256.png rename to megacosm/static/images/megacosm_icon_256.png diff --git a/static/images/megacosm_icon_32.png b/megacosm/static/images/megacosm_icon_32.png similarity index 100% rename from static/images/megacosm_icon_32.png rename to megacosm/static/images/megacosm_icon_32.png diff --git a/static/images/megacosm_icon_64.png b/megacosm/static/images/megacosm_icon_64.png similarity index 100% rename from static/images/megacosm_icon_64.png rename to megacosm/static/images/megacosm_icon_64.png diff --git a/static/images/moon.png b/megacosm/static/images/moon.png similarity index 100% rename from static/images/moon.png rename to megacosm/static/images/moon.png diff --git a/static/images/potion.png b/megacosm/static/images/potion.png similarity index 100% rename from static/images/potion.png rename to megacosm/static/images/potion.png diff --git a/static/images/star.png b/megacosm/static/images/star.png similarity index 100% rename from static/images/star.png rename to megacosm/static/images/star.png diff --git a/static/js/Detector.js b/megacosm/static/js/Detector.js similarity index 100% rename from static/js/Detector.js rename to megacosm/static/js/Detector.js diff --git a/static/js/background.js b/megacosm/static/js/background.js similarity index 100% rename from static/js/background.js rename to megacosm/static/js/background.js diff --git a/static/js/dungeon.js b/megacosm/static/js/dungeon.js similarity index 100% rename from static/js/dungeon.js rename to megacosm/static/js/dungeon.js diff --git a/static/js/flag.js b/megacosm/static/js/flag.js similarity index 100% rename from static/js/flag.js rename to megacosm/static/js/flag.js diff --git a/static/js/flagborder.js b/megacosm/static/js/flagborder.js similarity index 100% rename from static/js/flagborder.js rename to megacosm/static/js/flagborder.js diff --git a/static/js/flagdivision.js b/megacosm/static/js/flagdivision.js similarity index 100% rename from static/js/flagdivision.js rename to megacosm/static/js/flagdivision.js diff --git a/static/js/flagoverlay.js b/megacosm/static/js/flagoverlay.js similarity index 100% rename from static/js/flagoverlay.js rename to megacosm/static/js/flagoverlay.js diff --git a/static/js/flagshape.js b/megacosm/static/js/flagshape.js similarity index 100% rename from static/js/flagshape.js rename to megacosm/static/js/flagshape.js diff --git a/static/js/flagsymbol.js b/megacosm/static/js/flagsymbol.js similarity index 100% rename from static/js/flagsymbol.js rename to megacosm/static/js/flagsymbol.js diff --git a/static/js/flagutils.js b/megacosm/static/js/flagutils.js similarity index 100% rename from static/js/flagutils.js rename to megacosm/static/js/flagutils.js diff --git a/static/js/geomorphdungeon.js b/megacosm/static/js/geomorphdungeon.js similarity index 100% rename from static/js/geomorphdungeon.js rename to megacosm/static/js/geomorphdungeon.js diff --git a/static/js/moon.js b/megacosm/static/js/moon.js similarity index 100% rename from static/js/moon.js rename to megacosm/static/js/moon.js diff --git a/static/js/planet.js b/megacosm/static/js/planet.js similarity index 100% rename from static/js/planet.js rename to megacosm/static/js/planet.js diff --git a/static/js/star.js b/megacosm/static/js/star.js similarity index 100% rename from static/js/star.js rename to megacosm/static/js/star.js diff --git a/templates/400.html b/megacosm/templates/400.html similarity index 100% rename from templates/400.html rename to megacosm/templates/400.html diff --git a/templates/500.html b/megacosm/templates/500.html similarity index 100% rename from templates/500.html rename to megacosm/templates/500.html diff --git a/templates/base.html b/megacosm/templates/base.html similarity index 100% rename from templates/base.html rename to megacosm/templates/base.html diff --git a/templates/bond_builder.html b/megacosm/templates/bond_builder.html similarity index 100% rename from templates/bond_builder.html rename to megacosm/templates/bond_builder.html diff --git a/templates/business.html b/megacosm/templates/business.html similarity index 100% rename from templates/business.html rename to megacosm/templates/business.html diff --git a/templates/continent.html b/megacosm/templates/continent.html similarity index 100% rename from templates/continent.html rename to megacosm/templates/continent.html diff --git a/templates/country.html b/megacosm/templates/country.html similarity index 100% rename from templates/country.html rename to megacosm/templates/country.html diff --git a/templates/debug.html b/megacosm/templates/debug.html similarity index 100% rename from templates/debug.html rename to megacosm/templates/debug.html diff --git a/templates/deity.html b/megacosm/templates/deity.html similarity index 100% rename from templates/deity.html rename to megacosm/templates/deity.html diff --git a/templates/flag.html b/megacosm/templates/flag.html similarity index 100% rename from templates/flag.html rename to megacosm/templates/flag.html diff --git a/templates/generic_builder.html b/megacosm/templates/generic_builder.html similarity index 100% rename from templates/generic_builder.html rename to megacosm/templates/generic_builder.html diff --git a/templates/geomorphdungeon.html b/megacosm/templates/geomorphdungeon.html similarity index 100% rename from templates/geomorphdungeon.html rename to megacosm/templates/geomorphdungeon.html diff --git a/templates/govt.html b/megacosm/templates/govt.html similarity index 100% rename from templates/govt.html rename to megacosm/templates/govt.html diff --git a/templates/index.html b/megacosm/templates/index.html similarity index 100% rename from templates/index.html rename to megacosm/templates/index.html diff --git a/templates/leader.html b/megacosm/templates/leader.html similarity index 100% rename from templates/leader.html rename to megacosm/templates/leader.html diff --git a/templates/magicitem_armor.html b/megacosm/templates/magicitem_armor.html similarity index 100% rename from templates/magicitem_armor.html rename to megacosm/templates/magicitem_armor.html diff --git a/templates/magicitem_builder.html b/megacosm/templates/magicitem_builder.html similarity index 100% rename from templates/magicitem_builder.html rename to megacosm/templates/magicitem_builder.html diff --git a/templates/magicitem_potion.html b/megacosm/templates/magicitem_potion.html similarity index 100% rename from templates/magicitem_potion.html rename to megacosm/templates/magicitem_potion.html diff --git a/templates/magicitem_scroll.html b/megacosm/templates/magicitem_scroll.html similarity index 100% rename from templates/magicitem_scroll.html rename to megacosm/templates/magicitem_scroll.html diff --git a/templates/magicitem_weapon.html b/megacosm/templates/magicitem_weapon.html similarity index 100% rename from templates/magicitem_weapon.html rename to megacosm/templates/magicitem_weapon.html diff --git a/templates/map.html b/megacosm/templates/map.html similarity index 100% rename from templates/map.html rename to megacosm/templates/map.html diff --git a/templates/moon.html b/megacosm/templates/moon.html similarity index 100% rename from templates/moon.html rename to megacosm/templates/moon.html diff --git a/templates/npc.html b/megacosm/templates/npc.html similarity index 100% rename from templates/npc.html rename to megacosm/templates/npc.html diff --git a/templates/npc_builder.html b/megacosm/templates/npc_builder.html similarity index 100% rename from templates/npc_builder.html rename to megacosm/templates/npc_builder.html diff --git a/templates/oneliner.html b/megacosm/templates/oneliner.html similarity index 100% rename from templates/oneliner.html rename to megacosm/templates/oneliner.html diff --git a/templates/organization.html b/megacosm/templates/organization.html similarity index 100% rename from templates/organization.html rename to megacosm/templates/organization.html diff --git a/templates/planet.html b/megacosm/templates/planet.html similarity index 100% rename from templates/planet.html rename to megacosm/templates/planet.html diff --git a/templates/planet_builder.html b/megacosm/templates/planet_builder.html similarity index 100% rename from templates/planet_builder.html rename to megacosm/templates/planet_builder.html diff --git a/templates/region.html b/megacosm/templates/region.html similarity index 100% rename from templates/region.html rename to megacosm/templates/region.html diff --git a/templates/roguedungeon.html b/megacosm/templates/roguedungeon.html similarity index 100% rename from templates/roguedungeon.html rename to megacosm/templates/roguedungeon.html diff --git a/templates/sect.html b/megacosm/templates/sect.html similarity index 100% rename from templates/sect.html rename to megacosm/templates/sect.html diff --git a/templates/star.html b/megacosm/templates/star.html similarity index 100% rename from templates/star.html rename to megacosm/templates/star.html diff --git a/templates/street.html b/megacosm/templates/street.html similarity index 100% rename from templates/street.html rename to megacosm/templates/street.html diff --git a/templates/wanted.html b/megacosm/templates/wanted.html similarity index 100% rename from templates/wanted.html rename to megacosm/templates/wanted.html diff --git a/templates/weather.html b/megacosm/templates/weather.html similarity index 100% rename from templates/weather.html rename to megacosm/templates/weather.html diff --git a/util/Filters.py b/megacosm/util/Filters.py similarity index 62% rename from util/Filters.py rename to megacosm/util/Filters.py index 387b1b9..4f0d24f 100644 --- a/util/Filters.py +++ b/megacosm/util/Filters.py @@ -4,17 +4,22 @@ p = inflect.engine() + def select_article(s): return p.an(s) + def select_pluralize(subject, count): return p.plural(subject, count) -def select_plural_verb(verb,subject ): - return p.plural_verb(verb,subject) -def select_plural_adj(adj,subject ): - return p.plural_adj(adj,subject) +def select_plural_verb(verb, subject): + return p.plural_verb(verb, subject) + + +def select_plural_adj(adj, subject): + return p.plural_adj(adj, subject) + def select_conjunction(wordlist): """Join a list with commas and such.""" diff --git a/megacosm/util/Seeds.py b/megacosm/util/Seeds.py new file mode 100644 index 0000000..a00591c --- /dev/null +++ b/megacosm/util/Seeds.py @@ -0,0 +1,19 @@ +import random + + +def set_seed(seed=None): + + # Make sure it's an Integer + + # What if the seed is empty? Lets make a new one! + MAXSEED = 10000000 + MINSEED = 1 + + if (type(seed) == str or type(seed) == unicode) and seed.isdigit(): + seed = int(seed) + + if type(seed) != int or seed < MINSEED or seed > MAXSEED: + seed = random.randint(MINSEED, MAXSEED) + + random.seed(float(seed)) + return seed diff --git a/util/__init__.py b/megacosm/util/__init__.py similarity index 100% rename from util/__init__.py rename to megacosm/util/__init__.py diff --git a/pylintrc b/pylintrc new file mode 100644 index 0000000..49d85e4 --- /dev/null +++ b/pylintrc @@ -0,0 +1,6 @@ + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=120 + diff --git a/reimport_data.py b/reimport_data.py new file mode 100644 index 0000000..a985d4a --- /dev/null +++ b/reimport_data.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import redis +import glob +import sys +import json +from config import BaseConfiguration +import re + +COMMANDCOUNT = 0 + + +def parse_file(pipe, filename): + linenumber = 0 + global COMMANDCOUNT + raw_data = open(filename) + for line in raw_data: + linenumber += 1 + line = line.rstrip() + if line: + + # print line + + if line.startswith('#'): + continue + else: + COMMANDCOUNT += 1 + (command, args) = line.split(' ', 1) + command = command.upper() + try: + if command == 'SET': + (key, value) = args.split(None, 1) + pipe.set(key, value) + elif command == 'LPUSH': + + # print "setting", key, "to", value + + (key, value) = args.split(' ', 1) + pipe.lpush(key, value) + elif command == 'ZADD': + (key, score, value) = args.split(None, 2) + validate_json(value, filename, linenumber) + pipe.zadd(key, value, score) + elif command == 'HSET': + (name, key, value) = args.split(None, 2) + validate_json(value, filename, linenumber) + pipe.hset(name, key, value) + elif command == 'DEL': + pipe.delete(args) + else: + + # print "I have no idea what ", line, "is." + + raise Exception('line #%s in %s: %s is an unsupported command.' % (linenumber, filename, + command)) + except ValueError: + print 'There was a problem reading', filename, 'near line', linenumber, '' + raw_data.close() + + +JSONVALIDATE = 0 + + +def validate_json(value, filename, linenumber): + global JSONVALIDATE + try: + json.loads(value) + JSONVALIDATE += 1 + except Exception: + print 'ERROR: The following value is not proper JSON:' + print filename, 'near line', linenumber, ':' + print value + sys.exit(1) + + +server = redis.from_url(BaseConfiguration.REDIS_URL) +pipe = server.pipeline() + +pipe.flushall() + +for filename in sorted(glob.glob('data/*.data')): + parse_file(pipe, filename) + +for filename in sorted(glob.glob('data/*/*.data')): + parse_file(pipe, filename) + +IMAGECOUNT = 0 + + +def create_geomorphimage_record(pipe, image): + m = re.search('geomorphs/(.*)/(.*)/([0-5])/.*\.png', image) + global IMAGECOUNT + if m: + author = m.group(1) + tileset = m.group(2) + imagetype = m.group(3) + pipe.lpush('geomorph_type_' + imagetype, ' { "path":"/%s", "author":"%s", "tileset":"%s" }' % (image, author, + tileset)) + IMAGECOUNT += 1 + else: + print 'WARNING, ', image, 'is not in the right format.' + + +# static/images/geomorphs/1/basic2.png + +for image in glob.glob('megacosm/static/images/geomorphs/*/*/*/*.png'): + image = image[9:] + create_geomorphimage_record(pipe, image) + + +def create_dungeonbackground_record(pipe, image): + m = re.search('backgrounds/(.*)\.png', image) + global IMAGECOUNT + if m: + tilename = m.group(1) + pipe.lpush('geomorphdungeon_background', tilename) + IMAGECOUNT += 1 + else: + print 'WARNING, ', image, 'is not in the right format.' + + +for image in sorted(glob.glob('megacosm/static/images/backgrounds/*.png')): + image = image[9:] + create_dungeonbackground_record(pipe, image) + +pipe.set('geomorphdungeon_decoration_chance', 30) + + +def create_dungeondecoration_record(pipe, image): + image = image[9:] + m = re.search('decorations/(.*)\.png', image) + global IMAGECOUNT + if m: + tilename = m.group(1) + pipe.lpush('geomorphdungeon_decoration', tilename) + IMAGECOUNT += 1 + else: + print 'WARNING, ', image, 'is not in the right format.' + + +for image in sorted(glob.glob('megacosm/static/images/decorations/*.png')): + image = image[9:] + create_dungeondecoration_record(pipe, image) + +pipe.execute() + +print COMMANDCOUNT, 'Commands were run.' +print IMAGECOUNT, 'geomorphs documented.' +print JSONVALIDATE, 'JSON strings validated.' diff --git a/requirements.txt b/requirements.txt index 6914a13..0666665 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,24 +1,21 @@ -blinker==1.3 -coverage==3.7.1 -Flask==0.10.1 -Flask-Testing==0.4 -itsdangerous==0.23 -Jinja2==2.7.2 -MarkupSafe==0.18 -nose==1.3.0 -PyPng==0.0.16 -python-termstyle==0.1.10 -Rednose==0.4.1 -twill>=0.9 -unittest2==0.5.1 -Werkzeug==0.9.4 -wsgiref==0.1.2 -redis==2.9.1 -mock>=1.0.1 -gunicorn>=18.0 -inflect>=0.2.4 +blinker +coverage coveralls +fixture +flake8 +Flask +Flask-Assets +Flask-Testing +Flask-WTF +gunicorn +inflect +jsmin +mock +nose pylint -pyflakes -flakeplus - +pytest +pytest-cov +redis +rednose +twill +unittest2 diff --git a/run.py b/run.py new file mode 100755 index 0000000..3b98e68 --- /dev/null +++ b/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +import megacosm + +megacosm.app.config.from_object('config.TestConfiguration') + + +megacosm.app.run(host='0.0.0.0', port=8000) diff --git a/scripts/reimport_data.py b/scripts/reimport_data.py deleted file mode 100755 index 54c414b..0000000 --- a/scripts/reimport_data.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python - -import redis -import ConfigParser, os -import glob -import sys -import json -from pprint import pprint -import re - - -COMMANDCOUNT=0 - -def parse_file(pipe, filename): - linenumber=0 - global COMMANDCOUNT - raw_data=open(filename) - for line in raw_data: - linenumber+=1 - line=line.rstrip() - if line: - #print line - if line.startswith('#'): - continue; - else: - COMMANDCOUNT+=1 - command, args = line.split(' ',1) - command=command.upper() - try: - if command == 'SET': - key,value=args.split(None,1) - pipe.set(key,value) - #print "setting",key,"to",value - elif command == "LPUSH": - key,value=args.split(' ',1) - pipe.lpush(key,value) - elif command == "ZADD": - key,score,value=args.split(None,2) - validate_json(value, filename, linenumber) - pipe.zadd(key,value,score) - elif command == "HSET": - name,key,value=args.split(None,2) - validate_json(value, filename, linenumber) - pipe.hset(name,key,value) - elif command == "DEL": - pipe.delete(args) - else: - #print "I have no idea what ",line,"is." - raise Exception("line #%s in %s: %s is an unsupported command." % (linenumber, filename, command) ) - except ValueError: - print "There was a problem reading",filename,"near line",linenumber,"" - raw_data.close() - - -JSONVALIDATE=0 -def validate_json(value, filename, linenumber): - global JSONVALIDATE - try: - json.loads(value) - JSONVALIDATE+=1 - except Exception: - print "ERROR: The following value is not proper JSON:" - print filename,"near line",linenumber,":" - print value - sys.exit(1) - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') - -url = config.get('redis', 'url') - -server=redis.from_url(url) -pipe=server.pipeline() - -pipe.flushall() - -for filename in sorted(glob.glob("data/*.data")) : - parse_file(pipe, filename) - -for filename in sorted(glob.glob("data/*/*.data")) : - parse_file(pipe, filename) - - -IMAGECOUNT=0 -def create_geomorphimage_record(pipe, image): - m = re.search('geomorphs/(.*)/(.*)/([0-5])/.*\.png', image) - global IMAGECOUNT - if m: - author = m.group(1) - tileset = m.group(2) - imagetype = m.group(3) - pipe.lpush('geomorph_type_'+imagetype,' { "path":"/%s", "author":"%s", "tileset":"%s" }' % (image, author,tileset ) ) - IMAGECOUNT+=1 - else: - print "WARNING,",image,"is not in the right format." -#static/images/geomorphs/1/basic2.png - -for image in glob.glob("static/images/geomorphs/*/*/*/*.png") : - create_geomorphimage_record(pipe, image); - - - - - - -def create_dungeonbackground_record(pipe, image): - m = re.search('backgrounds/(.*)\.png', image) - global IMAGECOUNT - if m: - tilename = m.group(1) - pipe.lpush('geomorphdungeon_background' ,tilename ) - IMAGECOUNT+=1 - else: - print "WARNING,",image,"is not in the right format." - -for image in sorted(glob.glob("static/images/backgrounds/*.png")) : - create_dungeonbackground_record(pipe, image); - - - -pipe.set("geomorphdungeon_decoration_chance",30); -def create_dungeondecoration_record(pipe, image): - m = re.search('decorations/(.*)\.png', image) - global IMAGECOUNT - if m: - tilename = m.group(1) - pipe.lpush('geomorphdungeon_decoration' ,tilename ) - IMAGECOUNT+=1 - else: - print "WARNING,",image,"is not in the right format." - -for image in sorted(glob.glob("static/images/decorations/*.png")) : - create_dungeondecoration_record(pipe, image); - - - - - - -pipe.execute() - -print COMMANDCOUNT, "Commands were run." -print IMAGECOUNT, "geomorphs documented." -print JSONVALIDATE, "JSON strings validated." - - diff --git a/setup.cfg b/setup.cfg index 462dfeb..bea7205 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,20 @@ -[nosetests] -rednose=1 +[pytest] +addopts = --cov megacosm/ +norecursedirs=env +python_files=test_*.py megacosm/* +python_classes=Test +python_functions=test_ +[nosetests] +rednose=true +with-coverage=true +logging-clear-handlers=true +cover-erase=true +cover-inclusive=true +cover-branches=true +no-byte-compile=true +[flake8] +max-line-length = 120 +exclude = env/* diff --git a/tests/bond_tests.py b/tests/bond_tests.py deleted file mode 100644 index 26a0d97..0000000 --- a/tests/bond_tests.py +++ /dev/null @@ -1,38 +0,0 @@ - -from generators.Bond import Bond -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestBond(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( "3" ) - - def test_random_bond(self): - """ """ - bond = Bond(self.redis ) -# self.assertEqual(bond.text,'you') - - def test_bond_features(self): - """ """ - bond = Bond(self.redis, {'you':'Jesse', 'other':'Will', 'either':'Tony', 'partyA':'Shaun', 'partyB':'Rich', 'template':"{{params.you}} {{params.other}} {{params.either}} {{params.partyA}} {{params.partyB}}", 'bond_when_roll':5, 'when':'Bob' }) - - self.assertEqual(bond.text,'Bob, Jesse Will Tony Shaun Rich') - - - - - diff --git a/tests/business_tests.py b/tests/business_tests.py deleted file mode 100644 index 739ae0e..0000000 --- a/tests/business_tests.py +++ /dev/null @@ -1,33 +0,0 @@ - -from generators.Business import Business -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestBusiness(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( '3' ) - - def test_business(self): - """ """ - business = Business(self.redis ) - - def test_senses(self): - """ """ - business = Business(self.redis, {'smell': 'stank', 'sight':'ugly blinds', 'sound': 'cries for help'} ) - self.assertNotEqual("%s"% (business), "" ) - - diff --git a/tests/continent_tests.py b/tests/continent_tests.py deleted file mode 100644 index 71ac3f5..0000000 --- a/tests/continent_tests.py +++ /dev/null @@ -1,37 +0,0 @@ - -from generators.Continent import Continent -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestContinent(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( "3" ) - - def test_random_continent(self): - """ """ - continent = Continent(self.redis ) - continent.add_countries() - self.assertGreaterEqual(len(continent.countries),0) - - - def test_continent_country(self): - """ """ - continent = Continent(self.redis, {'countrycount':25}) - continent.add_countries() - self.assertEqual(len(continent.countries),25) - print continent.__dict__ - - diff --git a/tests/country_tests.py b/tests/country_tests.py deleted file mode 100644 index ec4c91f..0000000 --- a/tests/country_tests.py +++ /dev/null @@ -1,41 +0,0 @@ - -from generators.Country import Country -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestCountry(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( "3" ) - - def test_random_country(self): - """ """ - country = Country(self.redis ) -# country.add_regions() -# self.assertEqual(1,len(country.regions)) - - - def test_country_region(self): - """ """ - country = Country(self.redis, {'regioncount':25}) -# country.add_regions() -# self.assertEqual(25,len(country.regions)) -# print country.__dict__ - - - - - - diff --git a/tests/cuisine_tests.py b/tests/cuisine_tests.py deleted file mode 100644 index 9b2b63e..0000000 --- a/tests/cuisine_tests.py +++ /dev/null @@ -1,36 +0,0 @@ - -from generators.Cuisine import Cuisine -from generators.Motivation import Motivation -from generators.Region import Region -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestCuisine(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.region=Region(self.redis) -# self.seed=set_seed( "3" ) - - def test_random_cuisine(self): - """ """ - cuisine = Cuisine(self.redis, {'region':self.region} ) - print cuisine.text - self.assertNotEqual(cuisine.text,'') - - - - - - diff --git a/tests/currency_tests.py b/tests/currency_tests.py deleted file mode 100644 index 3c91d80..0000000 --- a/tests/currency_tests.py +++ /dev/null @@ -1,30 +0,0 @@ - -from generators.Currency import Currency -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestCurrency(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_currency(self): - """ """ - currency = Currency(self.redis ) - print currency.text - - - diff --git a/tests/deity_tests.py b/tests/deity_tests.py deleted file mode 100644 index f8443d5..0000000 --- a/tests/deity_tests.py +++ /dev/null @@ -1,38 +0,0 @@ - -from generators.Deity import Deity -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestDeity(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( '3' ) - - def test_deity(self): - """ """ - deity = Deity(self.redis ) - - def test_deity_sects(self): - """ """ - deity = Deity(self.redis, {'deity_unity_roll': 100, 'deity_importance_roll':100} ) - deity.add_sects() - self.assertEqual(len(deity.sects),0) - - deity = Deity(self.redis, {'deity_unity_roll': 0, 'deity_importance_roll':100} ) - deity.add_sects() - self.assertGreaterEqual(len(deity.sects),1) - - diff --git a/tests/filter_tests.py b/tests/filter_tests.py deleted file mode 100644 index 5c815ec..0000000 --- a/tests/filter_tests.py +++ /dev/null @@ -1,49 +0,0 @@ -# -import unittest2 as unittest -from util.Filters import * - -class TestFilter(unittest.TestCase): - -# - -################################################################ - def test_select_article(self): - self.assertEquals( 'a dog', select_article('dog') ) - self.assertEquals( 'an apple', select_article('apple') ) - self.assertEquals( 'an hour', select_article('hour') ) -################################################################ - def test_select_pluralize(self): - self.assertEquals( 'dogs', select_pluralize('dog',0) ) - self.assertEquals( 'dog', select_pluralize('dog',1) ) - self.assertEquals( 'dogs', select_pluralize('dog',2) ) - self.assertEquals( 'classes', select_pluralize('class',0) ) - self.assertEquals( 'class', select_pluralize('class',1) ) - self.assertEquals( 'classes', select_pluralize('class',2) ) -################################################################ - def test_select_conjunction(self): - self.assertEquals( "a", select_conjunction(['a']) ) - self.assertEquals( "a and b", select_conjunction(['a','b']) ) - self.assertEquals( "a, b, and c", select_conjunction(['a','b','c']) ) - self.assertEquals( "a, b, c, and d", select_conjunction(['a','b','c','d']) ) -################################################################ - def test_select_plural_verb(self): - self.assertEquals( "were", select_plural_verb('was',0) ) - self.assertEquals( "was", select_plural_verb('was',1) ) - self.assertEquals( "were", select_plural_verb('was',2) ) -################################################################ - def test_select_plural_verb(self): - self.assertEquals( "some", select_plural_adj('a',0) ) - self.assertEquals( "a", select_plural_adj('a',1) ) - self.assertEquals( "some", select_plural_adj('a',2) ) - - self.assertEquals( "these", select_plural_adj('this',0) ) - self.assertEquals( "this", select_plural_adj('this',1) ) - self.assertEquals( "these", select_plural_adj('this',2) ) - - self.assertEquals( "those", select_plural_adj('that',0) ) - self.assertEquals( "that", select_plural_adj('that',1) ) - self.assertEquals( "those", select_plural_adj('that',2) ) - - self.assertEquals( "our", select_plural_adj('my',0) ) - self.assertEquals( "my", select_plural_adj('my',1) ) - self.assertEquals( "our", select_plural_adj('my',2) ) diff --git a/tests/flaw_tests.py b/tests/flaw_tests.py deleted file mode 100644 index 3af87c5..0000000 --- a/tests/flaw_tests.py +++ /dev/null @@ -1,31 +0,0 @@ - -from generators.Flaw import Flaw -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestFlaw(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_flaw(self): - """ """ - flaw = Flaw(self.redis ) - print flaw.text - - - - diff --git a/tests/generator_tests.py b/tests/generator_tests.py deleted file mode 100644 index 5d9aee7..0000000 --- a/tests/generator_tests.py +++ /dev/null @@ -1,65 +0,0 @@ - -from generators.Generator import Generator -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - - -class TestGenerator(unittest.TestCase): - - def setUp(self): - """ """ - self.redis=redis.from_url(url) - - def test_creation(self): - """ """ - generator = Generator(self.redis, {'seed':1007}) - self.assertEqual(generator.seed,1007) - with self.assertRaises(AttributeError) as context: - generator.missingfeature - - def test_randomseed(self): - generator = Generator(self.redis) - self.assertIs(type(generator.seed), int) - - def test_select_by_roll(self): - generator = Generator(self.redis, {'seed':1007, 'star_size_roll':37}) - self.assertEquals({'name':'average', 'multiplier':1.0, u'score': 65}, generator.select_by_roll('star_size')) - - def test_select_by_roll_key_doesnt_exist(self): - generator = Generator(self.redis, {'seed':1007}) - with self.assertRaisesRegexp(IndexError, 'Is funion a valid key?') as context: - generator.select_by_roll('funion') - - def test_select_by_roll_highmin(self): - generator = Generator(self.redis, {'seed':1007, "starsystem_starcount_roll":1037}) - self.assertEquals({u'count': 3, u'name': u'trinary star',u'score': 100},generator.select_by_roll('starsystem_starcount')) - generator = Generator(self.redis, {'seed':1007, "starsystem_starcount_roll":-1037}) - self.assertEquals({u'count': 1, u'name': u'single star',u'score': 70},generator.select_by_roll('starsystem_starcount')) - - def test_select_by_roll_key_wrong_type(self): - generator = Generator(self.redis, {'seed':1007, 'star_size_roll':37}) - with self.assertRaisesRegexp(Exception, "the key \(name_starpre\) doesn't appear to exist or isn't a zset \(list\).") as context: - generator.select_by_roll('name_starpre') - - def test_rand_value(self): - generator = Generator(self.redis, {'seed':1007}) - self.assertIs(str, type(generator.rand_value('name_starpre'))) - - def test_rand_value_key_wrong_type(self): - generator = Generator(self.redis, {'seed':1007}) - with self.assertRaisesRegexp(Exception, "the key \(star_size\) doesn't appear to exist or isn't a list \(zset\).") as context: - generator.rand_value('star_size') - - def test_rand_value_key_doesnt_exist(self): - generator = Generator(self.redis, {'seed':1007}) - with self.assertRaisesRegexp(Exception, "the key \(somekey\) doesn't appear to exist or isn't a list") as context: - generator.rand_value('somekey') - - diff --git a/tests/legend_tests.py b/tests/legend_tests.py deleted file mode 100644 index b46a006..0000000 --- a/tests/legend_tests.py +++ /dev/null @@ -1,34 +0,0 @@ - -from generators.Legend import Legend -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestLegend(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_legend(self): - """ """ - legend = Legend(self.redis ) - print legend.text - self.assertNotEqual(legend.text,'') - - - - - - diff --git a/tests/misfire_tests.py b/tests/misfire_tests.py deleted file mode 100644 index 99259c8..0000000 --- a/tests/misfire_tests.py +++ /dev/null @@ -1,30 +0,0 @@ - -from generators.Misfire import Misfire -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestMisfire(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_misfire(self): - """ """ - misfire = Misfire(self.redis ) - print misfire.text - self.assertNotEqual(misfire.text,'') - self.assertEqual("%s" % (misfire), misfire.text) - - diff --git a/tests/moon_tests.py b/tests/moon_tests.py deleted file mode 100644 index ae11545..0000000 --- a/tests/moon_tests.py +++ /dev/null @@ -1,29 +0,0 @@ - -from generators.Moon import Moon -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestMoon(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_moon(self): - """ """ - moon = Moon(self.redis ) - self.assertNotEqual(moon.color,'') - self.assertNotEqual(moon.size,'') - - diff --git a/tests/motivation_tests.py b/tests/motivation_tests.py deleted file mode 100644 index 58a687e..0000000 --- a/tests/motivation_tests.py +++ /dev/null @@ -1,36 +0,0 @@ - -from generators.Motivation import Motivation -from generators.NPC import NPC -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestMotivation(unittest.TestCase): - - def setUp(self): - """ """ - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_motivation(self): - """ """ - motivation = Motivation(self.redis ) - self.assertNotEqual(motivation.text,'') - - def test_motivation_w_npc(self): - """ """ - npc=NPC(self.redis) - motivation = Motivation(self.redis, { 'npc':npc } ) - self.assertNotEqual(motivation.text,'') - self.assertEqual(motivation.npc,npc) - self.assertNotEqual("%s" % (motivation),'') - - diff --git a/tests/npc_tests.py b/tests/npc_tests.py deleted file mode 100644 index 7fa20b8..0000000 --- a/tests/npc_tests.py +++ /dev/null @@ -1,49 +0,0 @@ - -from generators.NPC import NPC -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * -import re - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestNPC(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( '3' ) - - def test_races(self): - """ """ - npc = NPC(self.redis ) - #FIXME: subraces broke this assertion - #self.assertIn(npc.race, self.redis.lrange('npc_race',0,-1)) - - with self.assertRaisesRegexp(Exception, "turkeys is not a valid race and has no associated data") as context: - npc = NPC(self.redis, {'race':'turkeys'} ) - - npc = NPC(self.redis, { 'race':'human'}) - self.assertEqual(npc.race,'human') - - def test_race_details(self): - """ """ - npc = NPC(self.redis, { 'race':'human'}) - self.assertEqual(npc.race,'human') - - self.assertEqual(npc.details['name'],'Human') - self.assertEqual(npc.details['size'],'medium') - self.assertEqual(npc.details['description'],'quick growth and adaptability') - def test_names(self): - """ """ - npc = NPC(self.redis, { 'race':'human'}) - self.assertEqual(npc.race,'human') - self.assertRegexpMatches(npc.name['full'], '.+ .+') - diff --git a/tests/planet_tests.py b/tests/planet_tests.py deleted file mode 100644 index 8d05afe..0000000 --- a/tests/planet_tests.py +++ /dev/null @@ -1,27 +0,0 @@ - -from generators.Planet import Planet -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - - -class TestPlanet(unittest.TestCase): - - def setUp(self): - """ """ - self.redis=redis.from_url(url) - - def test_creation(self): - """ """ - planet = Planet(self.redis, {'seed':1007}) - - def test_randomseed(self): - planet = Planet(self.redis) - - diff --git a/tests/rumor_tests.py b/tests/rumor_tests.py deleted file mode 100644 index 4a6c273..0000000 --- a/tests/rumor_tests.py +++ /dev/null @@ -1,27 +0,0 @@ - -from generators.Rumor import Rumor -from generators.Motivation import Motivation -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestRumor(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) - self.seed=set_seed( "3" ) - - def test_random_rumor(self): - """ """ - rumor = Rumor(self.redis ) - diff --git a/tests/sect_tests.py b/tests/sect_tests.py deleted file mode 100644 index 2c5215d..0000000 --- a/tests/sect_tests.py +++ /dev/null @@ -1,28 +0,0 @@ - -from generators.Sect import Sect -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestSect(unittest.TestCase): - - def setUp(self): - """ """ - - self.redis=redis.from_url(url) -# self.seed=set_seed( "3" ) - - def test_random_sect(self): - """ """ - sect = Sect(self.redis ) - self.assertNotEqual(sect.domain,'') - - diff --git a/tests/seeds_tests.py b/tests/seeds_tests.py deleted file mode 100644 index bc6f7aa..0000000 --- a/tests/seeds_tests.py +++ /dev/null @@ -1,72 +0,0 @@ - -from util.Seeds import * -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os -from util.Seeds import * - - -class TestSeeds(unittest.TestCase): - - def setUp(self): - """ """ - - def test_int_seeds(self): - """ """ - seeds = set_seed( 17) - self.assertEquals(17,seeds) - - - def test_str_seeds(self): - """ """ - seeds = set_seed( "22") - self.assertEquals(22,seeds) - - def test_unicode_seeds(self): - """ """ - seeds = set_seed( u"22") - self.assertEquals(22,seeds) - - def test_int_invalid_high(self): - """ """ - seeds = set_seed( 10000000000000) - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - def test_int_invalid_low(self): - """ """ - seeds = set_seed( -2) - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - - - def test_string_invalid_high(self): - """ """ - seeds = set_seed( '100000000000000000') - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - def test_string_invalid_low(self): - """ """ - seeds = set_seed( '-2') - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - - def test_string_invalid_value(self): - """ """ - seeds = set_seed( 'herpderp') - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - def test_none(self): - """ """ - seeds = set_seed( None) - self.assertLessEqual(1,seeds) - self.assertGreaterEqual(10000000,seeds) - - - diff --git a/tests/star_tests.py b/tests/star_tests.py deleted file mode 100644 index c2c3eb8..0000000 --- a/tests/star_tests.py +++ /dev/null @@ -1,25 +0,0 @@ - -from generators.Star import Star -import unittest2 as unittest -from mock import MagicMock - - -import redis -import ConfigParser, os - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - -class TestStar(unittest.TestCase): - - def setUp(self): - """ """ - self.redis=redis.from_url(url) - - - def test_creation(self): - """ """ - star = Star(self.redis); - - diff --git a/tests/starsystem_tests.py b/tests/starsystem_tests.py deleted file mode 100644 index 6e221f3..0000000 --- a/tests/starsystem_tests.py +++ /dev/null @@ -1,30 +0,0 @@ - -from generators.StarSystem import StarSystem -import unittest2 as unittest -from mock import MagicMock - -import redis -import ConfigParser, os - -config = ConfigParser.RawConfigParser() -config.read('data/config.ini') -url = config.get('redis', 'url') - - -class TestStarSystem(unittest.TestCase): - - def setUp(self): - """ """ - self.redis=redis.from_url(url) - - def test_creation(self): - """ """ - star = StarSystem(self.redis, {'seed':1007}) - - def test_starcount(self): - """ """ - stars = StarSystem(self.redis,{'seed':1,'starsystem_starcount_roll':100}) - self.assertEqual(stars.seed,1) - self.assertEqual(len(stars.stars),3) - - diff --git a/tests/test_bond.py b/tests/test_bond.py new file mode 100644 index 0000000..262a5d9 --- /dev/null +++ b/tests/test_bond.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Bond +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestBond(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_bond(self): + """ """ + bond = Bond(self.redis) + self.assertNotEqual('', bond.text) + + def test_bond_features(self): + """ """ + bond = Bond(self.redis, { + 'you': 'Jesse', + 'other': 'Will', + 'either': 'Tony', + 'partyA': 'Shaun', + 'partyB': 'Rich', + 'template': '{{params.you}} {{params.other}} {{params.either}} {{params.partyA}} {{params.partyB}}', + 'bond_when_roll': 5, + 'when': 'Bob', + }) + self.assertEqual(bond.text, 'Bob, Jesse Will Tony Shaun Rich') diff --git a/tests/test_business.py b/tests/test_business.py new file mode 100644 index 0000000..e859abe --- /dev/null +++ b/tests/test_business.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Business +import unittest2 as unittest + +import redis +from megacosm.util.Seeds import set_seed + +from config import TestConfiguration + + +class TestBusiness(unittest.TestCase): + + def setUp(self): + """ """ + + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + self.seed = set_seed('3') + + def test_business(self): + """ """ + business = Business(self.redis) + self.assertNotEqual('', business.name) + + def test_senses(self): + """ """ + + business = Business(self.redis, {'smell': 'stank', 'sight': 'ugly blinds', 'sound': 'cries for help'}) + self.assertNotEqual('%s' % business, '') diff --git a/tests/test_continent.py b/tests/test_continent.py new file mode 100644 index 0000000..792751a --- /dev/null +++ b/tests/test_continent.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Continent +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestContinent(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_continent(self): + """ """ + continent = Continent(self.redis) + continent.add_countries() + self.assertGreaterEqual(len(continent.countries), 0) + + def test_continent_country(self): + """ """ + continent = Continent(self.redis, {'countrycount': 25}) + continent.add_countries() + self.assertEqual(len(continent.countries), 25) diff --git a/tests/test_country.py b/tests/test_country.py new file mode 100644 index 0000000..1714a2e --- /dev/null +++ b/tests/test_country.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Country +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestCountry(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_country(self): + """ """ + country = Country(self.redis) + self.assertNotEqual('', country.name) + + def test_country_region(self): + """ """ + + country = Country(self.redis, {'regioncount': 25}) + country.add_regions() + self.assertNotEqual('', country.name) + + self.assertEqual(25, len(country.regions)) diff --git a/tests/test_cuisine.py b/tests/test_cuisine.py new file mode 100644 index 0000000..9487eb9 --- /dev/null +++ b/tests/test_cuisine.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Cuisine +from megacosm.generators import Region +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestCuisine(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + self.region = Region(self.redis) + + def test_random_cuisine(self): + """ """ + + cuisine = Cuisine(self.redis, {'region': self.region}) + print cuisine.text + self.assertNotEqual('', cuisine.text) diff --git a/tests/test_currency.py b/tests/test_currency.py new file mode 100644 index 0000000..653e9ad --- /dev/null +++ b/tests/test_currency.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Currency +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestCurrency(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_currency(self): + """ """ + + currency = Currency(self.redis) + self.assertNotEquals('', currency.name) diff --git a/tests/test_deity.py b/tests/test_deity.py new file mode 100644 index 0000000..94ee4a2 --- /dev/null +++ b/tests/test_deity.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Deity +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestDeity(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_deity(self): + """ """ + deity = Deity(self.redis) + self.assertNotEqual('', deity.name) + + def test_deity_sects(self): + """ """ + + deity = Deity(self.redis, {'deity_unity_roll': 100, 'deity_importance_roll': 100}) + deity.add_sects() + self.assertEqual(len(deity.sects), 0) + + deity = Deity(self.redis, {'deity_unity_roll': 0, 'deity_importance_roll': 100}) + deity.add_sects() + self.assertGreaterEqual(len(deity.sects), 1) diff --git a/tests/test_filter.py b/tests/test_filter.py new file mode 100644 index 0000000..db3738f --- /dev/null +++ b/tests/test_filter.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + +import unittest2 as unittest +from megacosm import select_article, select_pluralize, select_conjunction +from megacosm import select_plural_verb, select_plural_adj + + +class TestFilter(unittest.TestCase): + + def test_select_article(self): + self.assertEquals('a dog', select_article('dog')) + self.assertEquals('an apple', select_article('apple')) + self.assertEquals('an hour', select_article('hour')) + + def test_select_pluralize(self): + self.assertEquals('dogs', select_pluralize('dog', 0)) + self.assertEquals('dog', select_pluralize('dog', 1)) + self.assertEquals('dogs', select_pluralize('dog', 2)) + self.assertEquals('classes', select_pluralize('class', 0)) + self.assertEquals('class', select_pluralize('class', 1)) + self.assertEquals('classes', select_pluralize('class', 2)) + + def test_select_conjunction(self): + self.assertEquals('a', select_conjunction(['a'])) + self.assertEquals('a and b', select_conjunction(['a', 'b'])) + self.assertEquals('a, b, and c', select_conjunction(['a', 'b', 'c'])) + self.assertEquals('a, b, c, and d', select_conjunction(['a', 'b', 'c', 'd'])) + + def test_select_plural_verb(self): + self.assertEquals('were', select_plural_verb('was', 0)) + self.assertEquals('was', select_plural_verb('was', 1)) + self.assertEquals('were', select_plural_verb('was', 2)) + + def test_select_plural_adj(self): + self.assertEquals('some', select_plural_adj('a', 0)) + self.assertEquals('a', select_plural_adj('a', 1)) + self.assertEquals('some', select_plural_adj('a', 2)) + + self.assertEquals('these', select_plural_adj('this', 0)) + self.assertEquals('this', select_plural_adj('this', 1)) + self.assertEquals('these', select_plural_adj('this', 2)) + + self.assertEquals('those', select_plural_adj('that', 0)) + self.assertEquals('that', select_plural_adj('that', 1)) + self.assertEquals('those', select_plural_adj('that', 2)) + + self.assertEquals('our', select_plural_adj('my', 0)) + self.assertEquals('my', select_plural_adj('my', 1)) + self.assertEquals('our', select_plural_adj('my', 2)) diff --git a/tests/test_flaw.py b/tests/test_flaw.py new file mode 100644 index 0000000..0ccb1aa --- /dev/null +++ b/tests/test_flaw.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Flaw +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestFlaw(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_flaw(self): + """ """ + flaw = Flaw(self.redis) + self.assertNotEquals('', flaw.text) diff --git a/tests/test_generator.py b/tests/test_generator.py new file mode 100644 index 0000000..daecd3e --- /dev/null +++ b/tests/test_generator.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Generator +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestGenerator(unittest.TestCase): + + def setUp(self): + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_creation(self): + """ """ + + generator = Generator(self.redis, {'seed': 1007}) + self.assertEqual(generator.seed, 1007) + with self.assertRaises(AttributeError): + generator.missingfeature + + def test_randomseed(self): + generator = Generator(self.redis) + self.assertIs(type(generator.seed), int) + + def test_select_by_roll(self): + generator = Generator(self.redis, {'seed': 1007, 'star_size_roll': 37}) + self.assertEquals({'name': 'average', 'multiplier': 1.0, u'score': 65}, + generator.select_by_roll('star_size')) + + def test_select_by_roll_key_doesnt_exist(self): + generator = Generator(self.redis, {'seed': 1007}) + with self.assertRaisesRegexp(IndexError, 'Is funion a valid key?'): + generator.select_by_roll('funion') + + def test_select_by_roll_highmin(self): + generator = Generator(self.redis, {'seed': 1007, 'starsystem_starcount_roll': 1037}) + self.assertEquals({u'count': 3, u'name': u'trinary star', u'score': 100}, + generator.select_by_roll('starsystem_starcount')) + generator = Generator(self.redis, {'seed': 1007, 'starsystem_starcount_roll': -1037}) + self.assertEquals({u'count': 1, u'name': u'single star', u'score': 70}, + generator.select_by_roll('starsystem_starcount')) + + def test_select_by_roll_key_wrong_type(self): + generator = Generator(self.redis, {'seed': 1007, 'star_size_roll': 37}) + with self.assertRaisesRegexp(Exception, + "the key \(name_starpre\) doesn't appear to exist or isn't a zset \(list\)."): + generator.select_by_roll('name_starpre') + + def test_rand_value(self): + generator = Generator(self.redis, {'seed': 1007}) + self.assertIs(str, type(generator.rand_value('name_starpre'))) + + def test_rand_value_key_wrong_type(self): + generator = Generator(self.redis, {'seed': 1007}) + with self.assertRaisesRegexp(Exception, + "the key \(star_size\) doesn't appear to exist or isn't a list \(zset\)."): + generator.rand_value('star_size') + + def test_rand_value_key_doesnt_exist(self): + generator = Generator(self.redis, {'seed': 1007}) + with self.assertRaisesRegexp(Exception, "the key \(somekey\) doesn't appear to exist or isn't a list"): + generator.rand_value('somekey') diff --git a/tests/test_legend.py b/tests/test_legend.py new file mode 100644 index 0000000..793ca5f --- /dev/null +++ b/tests/test_legend.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Legend +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestLegend(unittest.TestCase): + + def setUp(self): + """ """ + + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_legend(self): + """ """ + legend = Legend(self.redis) + self.assertNotEqual('', legend.text) diff --git a/tests/megacosm_tests.py b/tests/test_megacosm.py similarity index 55% rename from tests/megacosm_tests.py rename to tests/test_megacosm.py index 97c0f23..d66a394 100644 --- a/tests/megacosm_tests.py +++ b/tests/test_megacosm.py @@ -1,37 +1,43 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- # + import megacosm -import unittest2 as unittest -import flask.ext.testing -from flask import Flask +from flask.ext.testing import TestCase + + +class MegacosmFlaskTestCast(TestCase): -class MegacosmFlaskTestCast(flask.ext.testing.TestCase): -# def create_app(self): - app = Flask(__name__) - app.config['TESTING'] = True + """ """ + app = megacosm.create_app('config.TestConfiguration') return app def setUp(self): self.app = megacosm.app.test_client() + def tearDown(self): self.app = None - megacosm.server.delete('unittestgenerator_list') - megacosm.server.delete('unittestgenerator_list_chance') - megacosm.server.delete('unittestgenerator_range') - megacosm.server.delete('unittestgenerator_list_description') -################################################################ - def test_builder_form_data(self): - megacosm.server.lpush('unittestgenerator_list', 'a','b','c') - megacosm.server.set('unittestgenerator_list_chance', 30) - megacosm.server.zadd('unittestgenerator_range', '{"name":"test1"}', 50) - megacosm.server.zadd('unittestgenerator_range', '{"name":"test2"}', 100) - megacosm.server.hset('unittestgenerator_list_description','foo', '{"name":"test1"}') - megacosm.server.hset('unittestgenerator_list-description','bar', '{"name":"test2"}') - self.assertEquals( megacosm.builder_form_data('unittestgenerator'),({'list': ['c', 'b', 'a']}, {'list_chance': '30'}, {'range': [{u'name': u'test1'}, {u'name': u'test2'}]}) ); + megacosm.app.server.delete('unittestgenerator_list') + megacosm.app.server.delete('unittestgenerator_list_chance') + megacosm.app.server.delete('unittestgenerator_range') + megacosm.app.server.delete('unittestgenerator_list_description') - megacosm.server.zadd('unittestgenerator_range', '{"name":"test2"', 100) +################################################################ - with self.assertRaisesRegexp(ValueError, 'failed to parse unittestgenerator_range field {"name":"test2"') as context: + def test_builder_form_data(self): + megacosm.app.server.lpush('unittestgenerator_list', 'a', 'b', 'c') + megacosm.app.server.set('unittestgenerator_list_chance', 30) + megacosm.app.server.zadd('unittestgenerator_range', '{"name":"test1"}', 50) + megacosm.app.server.zadd('unittestgenerator_range', '{"name":"test2"}', 100) + megacosm.app.server.hset('unittestgenerator_list_description', 'foo', '{"name":"test1"}') + megacosm.app.server.hset('unittestgenerator_list-description', 'bar', '{"name":"test2"}') + self.assertEquals(megacosm.builder_form_data('unittestgenerator'), ({'list': ['c', 'b', 'a']}, + {'list_chance': '30'}, {'range': [{u'name': u'test1'}, {u'name': u'test2'}]})) + + megacosm.app.server.zadd('unittestgenerator_range', '{"name":"test2"', 100) + + with self.assertRaisesRegexp(ValueError, 'failed to parse unittestgenerator_range field {"name":"test2"'): megacosm.builder_form_data('unittestgenerator') # paramlist={} @@ -54,307 +60,379 @@ def test_builder_form_data(self): # return paramlist,paramstring,paramset ################################################################ + def test_isvalidscore(self): - self.assertTrue( megacosm.isvalidscore("100")) - self.assertTrue( megacosm.isvalidscore("50")) - self.assertTrue( megacosm.isvalidscore("0")) - self.assertFalse( megacosm.isvalidscore("-10")) - self.assertFalse( megacosm.isvalidscore("1010")) - self.assertFalse( megacosm.isvalidscore("Fred")) + self.assertTrue(megacosm.isvalidscore('100')) + self.assertTrue(megacosm.isvalidscore('50')) + self.assertTrue(megacosm.isvalidscore('0')) + self.assertFalse(megacosm.isvalidscore('-10')) + self.assertFalse(megacosm.isvalidscore('1010')) + self.assertFalse(megacosm.isvalidscore('Fred')) + ################################################################ + def test_select_article(self): - self.assertEquals( 'a dog', megacosm.select_article('dog') ) - self.assertEquals( 'an apple', megacosm.select_article('apple') ) - self.assertEquals( 'an hour', megacosm.select_article('hour') ) + self.assertEquals('a dog', megacosm.select_article('dog')) + self.assertEquals('an apple', megacosm.select_article('apple')) + self.assertEquals('an hour', megacosm.select_article('hour')) + ################################################################ + def test_select_pluralize(self): - self.assertEquals( 'dogs', megacosm.select_pluralize('dog',0) ) - self.assertEquals( 'dog', megacosm.select_pluralize('dog',1) ) - self.assertEquals( 'dogs', megacosm.select_pluralize('dog',2) ) - self.assertEquals( 'classes', megacosm.select_pluralize('class',0) ) - self.assertEquals( 'class', megacosm.select_pluralize('class',1) ) - self.assertEquals( 'classes', megacosm.select_pluralize('class',2) ) + self.assertEquals('dogs', megacosm.select_pluralize('dog', 0)) + self.assertEquals('dog', megacosm.select_pluralize('dog', 1)) + self.assertEquals('dogs', megacosm.select_pluralize('dog', 2)) + self.assertEquals('classes', megacosm.select_pluralize('class', 0)) + self.assertEquals('class', megacosm.select_pluralize('class', 1)) + self.assertEquals('classes', megacosm.select_pluralize('class', 2)) + ################################################################ + def test_select_conjunction(self): - self.assertEquals( "a", megacosm.select_conjunction(['a']) ) - self.assertEquals( "a and b", megacosm.select_conjunction(['a','b']) ) - self.assertEquals( "a, b, and c", megacosm.select_conjunction(['a','b','c']) ) - self.assertEquals( "a, b, c, and d", megacosm.select_conjunction(['a','b','c','d']) ) + self.assertEquals('a', megacosm.select_conjunction(['a'])) + self.assertEquals('a and b', megacosm.select_conjunction(['a', 'b'])) + self.assertEquals('a, b, and c', megacosm.select_conjunction(['a', 'b', 'c'])) + self.assertEquals('a, b, c, and d', megacosm.select_conjunction(['a', 'b', 'c', 'd'])) + ################################################################ + def test_select_plural_verb(self): - self.assertEquals( "were", megacosm.select_plural_verb('was',0) ) - self.assertEquals( "was", megacosm.select_plural_verb('was',1) ) - self.assertEquals( "were", megacosm.select_plural_verb('was',2) ) + self.assertEquals('were', megacosm.select_plural_verb('was', 0)) + self.assertEquals('was', megacosm.select_plural_verb('was', 1)) + self.assertEquals('were', megacosm.select_plural_verb('was', 2)) + ################################################################ - def test_select_plural_verb(self): - self.assertEquals( "some", megacosm.select_plural_adj('a',0) ) - self.assertEquals( "a", megacosm.select_plural_adj('a',1) ) - self.assertEquals( "some", megacosm.select_plural_adj('a',2) ) - self.assertEquals( "these", megacosm.select_plural_adj('this',0) ) - self.assertEquals( "this", megacosm.select_plural_adj('this',1) ) - self.assertEquals( "these", megacosm.select_plural_adj('this',2) ) + def test_select_plural_adj(self): + self.assertEquals('some', megacosm.select_plural_adj('a', 0)) + self.assertEquals('a', megacosm.select_plural_adj('a', 1)) + self.assertEquals('some', megacosm.select_plural_adj('a', 2)) + + self.assertEquals('these', megacosm.select_plural_adj('this', 0)) + self.assertEquals('this', megacosm.select_plural_adj('this', 1)) + self.assertEquals('these', megacosm.select_plural_adj('this', 2)) + + self.assertEquals('those', megacosm.select_plural_adj('that', 0)) + self.assertEquals('that', megacosm.select_plural_adj('that', 1)) + self.assertEquals('those', megacosm.select_plural_adj('that', 2)) - self.assertEquals( "those", megacosm.select_plural_adj('that',0) ) - self.assertEquals( "that", megacosm.select_plural_adj('that',1) ) - self.assertEquals( "those", megacosm.select_plural_adj('that',2) ) + self.assertEquals('our', megacosm.select_plural_adj('my', 0)) + self.assertEquals('my', megacosm.select_plural_adj('my', 1)) + self.assertEquals('our', megacosm.select_plural_adj('my', 2)) - self.assertEquals( "our", megacosm.select_plural_adj('my',0) ) - self.assertEquals( "my", megacosm.select_plural_adj('my',1) ) - self.assertEquals( "our", megacosm.select_plural_adj('my',2) ) ################################################################ + def test_index_route(self): - response = self.app.get("/") + response = self.app.get('/') self.assertTemplateUsed('index.html') self.assert200(response) + ############################################################### + def test_bond_route(self): - response = self.app.get("/bond") + response = self.app.get('/bond') self.assert200(response) def test_bond_builder_route(self): - response = self.app.get("/bond_builder") + response = self.app.get('/bond_builder') self.assert200(response) + ################################################################ + def test_business_route(self): - response = self.app.get("/business") + response = self.app.get('/business') self.assert200(response) def test_business_builder_route(self): - response = self.app.get("/business_builder") + response = self.app.get('/business_builder') self.assert200(response) + ################################################################ + def test_continent_route(self): - response = self.app.get("/continent") + response = self.app.get('/continent') self.assert200(response) def test_continent_builder_route(self): - response = self.app.get("/continent_builder") + response = self.app.get('/continent_builder') self.assert200(response) + ################################################################ + def test_country_route(self): - response = self.app.get("/country") + response = self.app.get('/country') self.assert200(response) def test_country_builder_route(self): - response = self.app.get("/country_builder") + response = self.app.get('/country_builder') self.assert200(response) + ################################################################ + def test_cuisine_route(self): - response = self.app.get("/cuisine") + response = self.app.get('/cuisine') self.assert200(response) def test_cuisine_builder_route(self): - response = self.app.get("/cuisine_builder") + response = self.app.get('/cuisine_builder') self.assert200(response) + ################################################################ + def test_currency_route(self): - response = self.app.get("/currency") + response = self.app.get('/currency') self.assert200(response) def test_currency_builder_route(self): - response = self.app.get("/currency_builder") + response = self.app.get('/currency_builder') self.assert200(response) + ################################################################ + def test_deity_route(self): - response = self.app.get("/deity") + response = self.app.get('/deity') self.assert200(response) def test_deity_builder_route(self): - response = self.app.get("/deity_builder") + response = self.app.get('/deity_builder') self.assert200(response) + ################################################################ + def test_event_route(self): - response = self.app.get("/event") + response = self.app.get('/event') self.assert200(response) def test_event_builder_route(self): - response = self.app.get("/event_builder") + response = self.app.get('/event_builder') self.assert200(response) + ################################################################ + def test_flag_route(self): - response = self.app.get("/flag") + response = self.app.get('/flag') self.assert200(response) def test_flag_builder_route(self): - response = self.app.get("/flag_builder") + response = self.app.get('/flag_builder') self.assert200(response) + ################################################################ + def test_gem_route(self): - response = self.app.get("/gem") + response = self.app.get('/gem') self.assert200(response) def test_gem_builder_route(self): - response = self.app.get("/gem_builder") + response = self.app.get('/gem_builder') self.assert200(response) + ################################################################ + def test_geomorphdungeon_route(self): - response = self.app.get("/geomorphdungeon") + response = self.app.get('/geomorphdungeon') self.assert200(response) def test_geomorphdungeon_builder_route(self): - response = self.app.get("/geomorphdungeon_builder") + response = self.app.get('/geomorphdungeon_builder') self.assert200(response) + ################################################################ + def test_govt_route(self): - response = self.app.get("/govt") + response = self.app.get('/govt') self.assert200(response) def test_govt_builder_route(self): - response = self.app.get("/govt_builder") + response = self.app.get('/govt_builder') self.assert200(response) + ################################################################ + def test_jobposting_route(self): - response = self.app.get("/jobposting") + response = self.app.get('/jobposting') self.assert200(response) def test_jobposting_builder_route(self): - response = self.app.get("/jobposting_builder") + response = self.app.get('/jobposting_builder') self.assert200(response) + ################################################################ + def test_leader_route(self): - response = self.app.get("/leader") + response = self.app.get('/leader') self.assert200(response) def test_leader_builder_route(self): - response = self.app.get("/leader_builder") + response = self.app.get('/leader_builder') self.assert200(response) + ################################################################ + def test_legend_route(self): - response = self.app.get("/legend") + response = self.app.get('/legend') self.assert200(response) def test_legend_builder_route(self): - response = self.app.get("/legend_builder") + response = self.app.get('/legend_builder') self.assert200(response) + ################################################################ def test_magicitem_route(self): - response = self.app.get("/magicitem") + response = self.app.get('/magicitem') self.assert200(response) def test_magicitem_builder_route(self): - response = self.app.get("/magicitem_builder") + response = self.app.get('/magicitem_builder') self.assert200(response) + ################################################################ + def test_misfire_route(self): - response = self.app.get("/misfire") + response = self.app.get('/misfire') self.assert200(response) def test_misfire_builder_route(self): - response = self.app.get("/misfire_builder") + response = self.app.get('/misfire_builder') self.assert200(response) + ################################################################ + def test_moon_route(self): - response = self.app.get("/moon") + response = self.app.get('/moon') self.assert200(response) def test_moon_builder_route(self): - response = self.app.get("/moon_builder") + response = self.app.get('/moon_builder') self.assert200(response) + ################################################################ + def test_motivation_route(self): - response = self.app.get("/motivation") + response = self.app.get('/motivation') self.assert200(response) def test_motivation_builder_route(self): - response = self.app.get("/motivation_builder") + response = self.app.get('/motivation_builder') self.assert200(response) + ################################################################ + def test_mundaneitem_route(self): - response = self.app.get("/mundaneitem") + response = self.app.get('/mundaneitem') self.assert200(response) def test_mundaneitem_builder_route(self): - response = self.app.get("/mundaneitem_builder") + response = self.app.get('/mundaneitem_builder') self.assert200(response) + ################################################################ + def test_npc_route(self): - response = self.app.get("/npc") + response = self.app.get('/npc') self.assert200(response) def test_npc_builder_route(self): - response = self.app.get("/npc_builder") + response = self.app.get('/npc_builder') self.assert200(response) + ################################################################ + def test_planet_route(self): - response = self.app.get("/planet") + response = self.app.get('/planet') self.assert200(response) def test_planet_builder_route(self): - response = self.app.get("/planet_builder") + response = self.app.get('/planet_builder') self.assert200(response) + ################################################################ + def test_region_route(self): - response = self.app.get("/region") + response = self.app.get('/region') self.assert200(response) def test_region_builder_route(self): - response = self.app.get("/region_builder") + response = self.app.get('/region_builder') self.assert200(response) + ################################################################ + def test_resource_route(self): - response = self.app.get("/resource") + response = self.app.get('/resource') self.assert200(response) def test_resource_builder_route(self): - response = self.app.get("/resource_builder") + response = self.app.get('/resource_builder') self.assert200(response) + ################################################################ + def test_roguedungeon_route(self): - response = self.app.get("/roguedungeon") + response = self.app.get('/roguedungeon') self.assert200(response) def test_roguedungeon_builder_route(self): - response = self.app.get("/roguedungeon_builder") + response = self.app.get('/roguedungeon_builder') self.assert200(response) + ################################################################ + def test_rumor_route(self): - response = self.app.get("/rumor") + response = self.app.get('/rumor') self.assert200(response) def test_rumor_builder_route(self): - response = self.app.get("/rumor_builder") + response = self.app.get('/rumor_builder') self.assert200(response) + ################################################################ + def test_sect_route(self): - response = self.app.get("/sect") + response = self.app.get('/sect') self.assert200(response) def test_sect_builder_route(self): - response = self.app.get("/sect_builder") + response = self.app.get('/sect_builder') self.assert200(response) + ################################################################ + def test_star_route(self): - response = self.app.get("/star") + response = self.app.get('/star') self.assert200(response) def test_star_builder_route(self): - response = self.app.get("/star_builder") + response = self.app.get('/star_builder') self.assert200(response) + ################################################################ + def test_street_route(self): - response = self.app.get("/street") + response = self.app.get('/street') self.assert200(response) def test_street_builder_route(self): - response = self.app.get("/street_builder") + response = self.app.get('/street_builder') self.assert200(response) + ################################################################ + def test_wanted_route(self): - response = self.app.get("/wanted") + response = self.app.get('/wanted') self.assert200(response) def test_wanted_builder_route(self): - response = self.app.get("/wanted_builder") + response = self.app.get('/wanted_builder') self.assert200(response) + ################################################################ + def test_weather_route(self): - response = self.app.get("/weather") + response = self.app.get('/weather') self.assert200(response) def test_weather_builder_route(self): - response = self.app.get("/weather_builder") + response = self.app.get('/weather_builder') self.assert200(response) - - diff --git a/tests/test_misfire.py b/tests/test_misfire.py new file mode 100644 index 0000000..0aa5a36 --- /dev/null +++ b/tests/test_misfire.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Misfire +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestMisfire(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_misfire(self): + """ """ + misfire = Misfire(self.redis) + print misfire.text + self.assertNotEqual(misfire.text, '') + self.assertEqual('%s' % misfire, misfire.text) diff --git a/tests/test_moon.py b/tests/test_moon.py new file mode 100644 index 0000000..fe5e943 --- /dev/null +++ b/tests/test_moon.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Moon +import unittest2 as unittest + +import redis + +from config import TestConfiguration + + +class TestMoon(unittest.TestCase): + + def setUp(self): + """ """ + + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_moon(self): + """ """ + + moon = Moon(self.redis) + self.assertNotEqual(moon.color, '') + self.assertNotEqual(moon.size, '') diff --git a/tests/test_motivation.py b/tests/test_motivation.py new file mode 100644 index 0000000..22ae3b7 --- /dev/null +++ b/tests/test_motivation.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Motivation +from megacosm.generators import NPC +import unittest2 as unittest + +import redis + +from config import TestConfiguration + + +class TestMotivation(unittest.TestCase): + + def setUp(self): + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_random_motivation(self): + """ """ + + motivation = Motivation(self.redis) + self.assertNotEqual(motivation.text, '') + + def test_motivation_w_npc(self): + """ """ + + npc = NPC(self.redis) + motivation = Motivation(self.redis, {'npc': npc}) + self.assertNotEqual(motivation.text, '') + self.assertEqual(motivation.npc, npc) + self.assertNotEqual('%s' % motivation, '') diff --git a/tests/test_npc.py b/tests/test_npc.py new file mode 100644 index 0000000..ee412c9 --- /dev/null +++ b/tests/test_npc.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import NPC +import unittest2 as unittest + +import redis +from megacosm.util.Seeds import set_seed +from config import TestConfiguration + + +class TestNPC(unittest.TestCase): + + def setUp(self): + """ """ + + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + self.seed = set_seed('3') + + def test_races(self): + """ """ + + npc = NPC(self.redis) + + # FIXME: subraces broke this assertion + # self.assertIn(npc.race, self.redis.lrange('npc_race',0,-1)) + + with self.assertRaisesRegexp(Exception, 'turkeys is not a valid race and has no associated data'): + npc = NPC(self.redis, {'race': 'turkeys'}) + + npc = NPC(self.redis, {'race': 'human'}) + self.assertEqual(npc.race, 'human') + + def test_race_details(self): + """ """ + + npc = NPC(self.redis, {'race': 'human'}) + self.assertEqual(npc.race, 'human') + + self.assertEqual(npc.details['name'], 'Human') + self.assertEqual(npc.details['size'], 'medium') + self.assertEqual(npc.details['description'], 'quick growth and adaptability') + + def test_names(self): + """ """ + + npc = NPC(self.redis, {'race': 'human'}) + self.assertEqual(npc.race, 'human') + self.assertRegexpMatches(npc.name['full'], '.+ .+') diff --git a/tests/test_planet.py b/tests/test_planet.py new file mode 100644 index 0000000..e5b44ae --- /dev/null +++ b/tests/test_planet.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Planet +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestPlanet(unittest.TestCase): + + def setUp(self): + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_creation(self): + """ """ + planet = Planet(self.redis, {'seed': 1007}) + self.assertNotEquals('', planet.name) + + def test_randomseed(self): + planet = Planet(self.redis) + self.assertNotEquals('', planet.name) diff --git a/tests/test_rumor.py b/tests/test_rumor.py new file mode 100644 index 0000000..969df41 --- /dev/null +++ b/tests/test_rumor.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Rumor +import unittest2 as unittest + +import redis +from megacosm.util.Seeds import set_seed + +from config import TestConfiguration + + +class TestRumor(unittest.TestCase): + + def setUp(self): + """ """ + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + self.seed = set_seed('3') + + def test_random_rumor(self): + """ """ + rumor = Rumor(self.redis) + self.assertNotEqual('', rumor.text) diff --git a/tests/test_sect.py b/tests/test_sect.py new file mode 100644 index 0000000..a7f7617 --- /dev/null +++ b/tests/test_sect.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Sect +import unittest2 as unittest + +import redis +from megacosm.util.Seeds import set_seed + +from config import TestConfiguration + + +class TestSect(unittest.TestCase): + + def setUp(self): + """ """ + + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + self.seed = set_seed("3") + + def test_random_sect(self): + """ """ + + sect = Sect(self.redis) + self.assertNotEqual(sect.domain, '') diff --git a/tests/test_seeds.py b/tests/test_seeds.py new file mode 100644 index 0000000..f6a2344 --- /dev/null +++ b/tests/test_seeds.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import unittest2 as unittest + +from megacosm.util.Seeds import set_seed + + +class TestSeeds(unittest.TestCase): + + def setUp(self): + """ """ + + def test_int_seeds(self): + """ """ + + seeds = set_seed(17) + self.assertEquals(17, seeds) + + def test_str_seeds(self): + """ """ + + seeds = set_seed('22') + self.assertEquals(22, seeds) + + def test_unicode_seeds(self): + """ """ + + seeds = set_seed(u'22') + self.assertEquals(22, seeds) + + def test_int_invalid_high(self): + """ """ + + seeds = set_seed(10000000000000) + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) + + def test_int_invalid_low(self): + """ """ + + seeds = set_seed(-2) + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) + + def test_string_invalid_high(self): + """ """ + + seeds = set_seed('100000000000000000') + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) + + def test_string_invalid_low(self): + """ """ + + seeds = set_seed('-2') + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) + + def test_string_invalid_value(self): + """ """ + + seeds = set_seed('herpderp') + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) + + def test_none(self): + """ """ + + seeds = set_seed(None) + self.assertLessEqual(1, seeds) + self.assertGreaterEqual(10000000, seeds) diff --git a/tests/test_star.py b/tests/test_star.py new file mode 100644 index 0000000..b0b2901 --- /dev/null +++ b/tests/test_star.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import Star +import unittest2 as unittest + +import redis + +from config import TestConfiguration + + +class TestStar(unittest.TestCase): + + def setUp(self): + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_creation(self): + """ """ + + star = Star(self.redis) + self.assertNotEquals('', star.name) diff --git a/tests/test_starsystem.py b/tests/test_starsystem.py new file mode 100644 index 0000000..ab02d84 --- /dev/null +++ b/tests/test_starsystem.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from megacosm.generators import StarSystem +import unittest2 as unittest + +import redis +from config import TestConfiguration + + +class TestStarSystem(unittest.TestCase): + + def setUp(self): + self.redis = redis.from_url(TestConfiguration.REDIS_URL) + + def test_creation(self): + """ """ + + starsystem = StarSystem(self.redis, {'seed': 1007}) + self.assertTrue(starsystem.planet) + + def test_starcount(self): + """ """ + + stars = StarSystem(self.redis, {'seed': 1, 'starsystem_starcount_roll': 100}) + self.assertEqual(stars.seed, 1) + self.assertEqual(len(stars.stars), 3) diff --git a/util/Seeds.py b/util/Seeds.py deleted file mode 100644 index fea0965..0000000 --- a/util/Seeds.py +++ /dev/null @@ -1,19 +0,0 @@ -import random -import re -def set_seed(seed=None): - - #Make sure it's an Integer - - # What if the seed is empty? Lets make a new one! - MAXSEED=10000000 - MINSEED=1 - - - if ( type(seed) == str or type(seed) == unicode ) and seed.isdigit(): - seed=int(seed) - - if type(seed) != int or seed < MINSEED or seed > MAXSEED : - seed=random.randint(MINSEED,MAXSEED) - - random.seed(float(seed)) - return seed