first commit

This commit is contained in:
Lithiil 2020-04-01 20:44:12 +03:00
parent cf3118b9ea
commit 2ee1226137
9 changed files with 221 additions and 0 deletions

3
.env_example Normal file
View file

@ -0,0 +1,3 @@
APITOKEN = "Bearer your_api_key_here"
DATA_PATH = "data/"
API_URL = 'https://kanka.io/api/1.0/'

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.env

158
Generator.py Normal file
View file

@ -0,0 +1,158 @@
import os
import requests
from dotenv import load_dotenv
import json
import sys
import random
class NpcGenerator:
"""
This class is made to create random NPCs into a specific kanka campaign
"""
apiToken = None
apiBaseUrl = None
headers = None
campaign_id = None
dataPath = None
"""
When instancing the class, the variables from the .env files are loaded and the following class variables are set:
apiToken, dataPath, apiBaseUrl and headers
"""
def __init__(self):
load_dotenv()
self.apiToken = os.getenv("APITOKEN")
self.dataPath = os.getenv("DATA_PATH")
self.apiBaseUrl = os.getenv("API_URL")
self.headers = {
'Authorization': self.apiToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
def get_campaigns(self):
"""
This method will get a list of all the campaigns created on the account belonging to the owner of the Token
via a HTTP get request and returns a JSON
:return: JSON
"""
campaigns = requests.get("{}campaigns".format(self.apiBaseUrl), headers=self.headers)
return json.loads(campaigns.content)
def set_campaign_id(self, campaign_name):
"""
This method will parse the JSON generated by get_campaigns and set the campaignId with the id of the campaign
specified in the campaign_name parameter. If no campaign can be found with that name, it will raise an error
:type campaign_name: str
"""
campaigns = self.get_campaigns()
for campaign in campaigns['data']:
if campaign['name'] == campaign_name:
print("Found the campaign that you are looking for with id:{}".format(campaign['id']))
self.campaign_id = campaign['id']
if self.campaign_id is None:
sys.exit("ERROR: No campaign with that name found!")
def load_charater_details(self):
"""
This method will load the three specified files from the location specified in dataPath and returns a dict
containing json objects
@:returns data: dict
"""
appearance_options = json.load(open('{}appearance.json'.format(self.dataPath)))
personality_options = json.load(open('{}personalities.json'.format(self.dataPath)))
title_options = json.load(open('{}titles.json'.format(self.dataPath)))
data = {
'appearance_options': appearance_options,
'personality_options': personality_options,
'title_options': title_options
}
return data
def genrate_npc_name(self, sex):
"""
Will get a name via http request from drycodes.com based on the sex specified
:type sex: str
:return name: str
"""
if sex is "Male":
get_male_name = requests.get(
'http://names.drycodes.com/1?nameOptions=boy_names&format=text&separator=space')
name = get_male_name.text
else:
get_female_name = requests.get(
'http://names.drycodes.com/1?nameOptions=girl_names&format=text&separator=space')
name = get_female_name.text
return name
def generate_npcs(self, times):
"""
Will generate a list of dicts, each dict representing a character. The character details are populated
from the data retrieved by load_character_details. The number of characters is decided by the times parameter
:type times: int
:return npcs: list
"""
npcs = []
data = self.load_charater_details()
for x in range(times):
sex = random.choice(['Male', 'Female'])
name = self.genrate_npc_name(sex)
character = {
'name': name,
'title': random.choice(data['title_options']['data']),
'age': str(random.randrange(14, 100)),
'sex': sex,
'type': 'random_npc',
'is_private': 'true',
'personality_name': ['Goals', 'Fears'],
'personality_entry': [random.choice(data['personality_options']['goals']),
random.choice(data['personality_options']['fears'])],
'appearance_name': ['Hair', 'Eyes', 'Height', 'Marks'],
'appearance_entry': [random.choice(data['appearance_options']['hair_type']),
random.choice(data['appearance_options']['eyes']),
str(round(random.uniform(4.1, 7.5), 1)) + " feet",
random.choice(data['appearance_options']['marks'])]
}
npcs.append(character)
return npcs
def create_npcs(self, campaign_name=str, times=1):
"""
Will search for the specified campaign, generate the npcs and then create then on kanka via http post requests.
Please note that kanka has a limit of 30 calls per minute at this time
:type times: int
:type campaign_name: str
"""
self.set_campaign_id(campaign_name)
npcs = self.generate_npcs(times)
for npc in npcs:
print('Posting character to kanka')
response = requests.post(
"{}campaigns/{}/characters".format(self.apiBaseUrl, self.campaign_id),
data=json.dumps(npc),
headers=self.headers)
if response.status_code is 201:
print("Character named {} was created successfully!".format(npc['name']))
else:
print(
"Character was not created because kanka threw an error, got status code {} with error {} ".format(
response.status_code, response.text))

39
README.md Normal file
View file

@ -0,0 +1,39 @@
# **Kanka Random NPC Creator**
Hi, and thanks for taking the time to checkout this small project!
This mini project basically allows you to create as many random npcs
as you want in your kanka campaign.
# Setup:
1. [Install python 3.x](https://wiki.python.org/moin/BeginnersGuide/Download)
2. `pip install requirement.txt`
3. Create a Personal Access Token on your kanka account as described [here](https://kanka.io/en-US/docs/1.0/setup)
4. Create a .env file based on the .env_example . The only env variable that you will
probably want to modify is the *APITOKEN*
5. Create a python script that uses the Generator class as shown in the example.py
file
Below is an example of how to create 5 random NPCs in the campaign called "My Cool Campaign":
```python
from Generator import NpcGenerator
gen = NpcGenerator()
gen.create_npcs('My Cool Campaign', 5)
```
The characters created by this script have the "random_npc" type. So that
you can filter them out easily.
The names for the NPCs are requested from names.drycodes.com while the
other details are randomly chosen from the JSONs found in the data folder.
Feel free to add stuff to them OR use your own JSONs by pointing the DATA_PATH
env variable to their location (make sure that they are named like the ones
in the data folder tho!).
If by any chance you want to update and/or enrich the existing JSONs, create a PR.
Have a great time!

6
data/appearance.json Normal file
View file

@ -0,0 +1,6 @@
{
"hair_type": ["straight", "wavy", "curly"],
"hair_color": ["brown", "white", "blond", "red", "black"],
"eyes": ["hazel", "blue", "green", "brown"],
"marks": ["Left cheek scar", "None", "Missing middle finger on right hand"]
}

4
data/personalities.json Normal file
View file

@ -0,0 +1,4 @@
{
"goals": ["To become King", "To slay a dragon"],
"fears": ["Cake","Spiders","Blue Eyes"]
}

3
data/titles.json Normal file
View file

@ -0,0 +1,3 @@
{
"data":["The Noble", "The Peasant", "The Great", "The Dark", "The White", "The Strong"]
}

5
example.py Normal file
View file

@ -0,0 +1,5 @@
from Generator import NpcGenerator
gen = NpcGenerator()
gen.create_npcs('Warhammer Fantasy', 5)

2
requirements.txt Normal file
View file

@ -0,0 +1,2 @@
python-dotenv==0.12.0
requests==2.23.0