Resolve "import templates from bottle" #60
@@ -1,129 +0,0 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
@@ -1,2 +0,0 @@
|
||||
# kontor-bottle
|
||||
Kontor with Python Bottle Framework
|
||||
@@ -1,19 +0,0 @@
|
||||
# set base image (host OS)
|
||||
FROM python:3.8
|
||||
|
||||
# set the working directory in the container
|
||||
WORKDIR /code
|
||||
|
||||
# copy the dependencies file to the working directory
|
||||
COPY requirements.txt /code/
|
||||
|
||||
# copy the content of the local src directory to the working directory
|
||||
COPY src/ /code/
|
||||
|
||||
# install dependencies
|
||||
RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
# command to run on container start
|
||||
CMD [ "python", "./kontor.py" ]
|
||||
@@ -1,2 +0,0 @@
|
||||
pymongo
|
||||
bottle
|
||||
@@ -1,193 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import comics.publisherDAO
|
||||
import comics.artistDAO
|
||||
import comics.comicDAO
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.publishers = publisherDAO.PublisherDAO(database)
|
||||
self.artists = artistDAO.ArtistDAO(database)
|
||||
self.comics = comicDAO.ComicDAO(database)
|
||||
self.routing()
|
||||
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/comics/', 'GET', self.comic_index)
|
||||
self.app.route('/comics/comic', 'GET', self.comic_list)
|
||||
self.app.route('/comics/comic/<id>', 'GET', self.comic_details)
|
||||
self.app.route('/comics/comic/create', 'GET', self.get_comic_create)
|
||||
self.app.route('/comics/comic/create', 'POST', self.post_create_comic)
|
||||
self.app.route('/comics/publisher', 'GET', self.publisher_list)
|
||||
self.app.route('/comics/publisher/<id>', 'GET', self.publisher_details)
|
||||
self.app.route('/comics/publisher/create', 'GET', self.get_publisher_create)
|
||||
self.app.route('/comics/publisher/create', 'POST', self.post_create_publisher)
|
||||
self.app.route('/comics/artist', 'GET', self.artist_list)
|
||||
self.app.route('/comics/artist/<id>', 'GET', self.artist_details)
|
||||
self.app.route('/comics/artist/create', 'GET', self.get_artist_create)
|
||||
self.app.route('/comics/artist/create', 'POST', self.post_create_artist)
|
||||
self.app.route('/comics/storyarc', 'GET', self.storyarc_list)
|
||||
self.app.route('/comics/storyarc/<id>', 'GET', self.storyarc_details)
|
||||
self.app.route('/comics/storyarc/create', 'GET', self.get_storyarc_create)
|
||||
self.app.route('/comics/storyarc/create', 'POST', self.post_create_storyarc)
|
||||
|
||||
def comic_index(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template('comic_index', dict(username=username))
|
||||
|
||||
|
||||
def comic_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.comics.get_comics()
|
||||
return bottle.template('comic_list', dict(comics=l, username=username))
|
||||
|
||||
|
||||
def comic_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
comic = self.comics.get_comic(id)
|
||||
errors = ""
|
||||
if comic == None:
|
||||
errors = "Entry not found"
|
||||
return bottle.template('comic_template', dict(title=comic['title'],
|
||||
id=comic['_id'],
|
||||
current_order=comic['current_order'],
|
||||
completed=comic['completed'],
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
|
||||
def get_comic_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("comic_template", dict(title="",
|
||||
id='newentry',
|
||||
current_order=False,
|
||||
completed=False,
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
|
||||
def post_create_comic(self):
|
||||
comic_id = bottle.request.forms.get("id")
|
||||
comic_title = bottle.request.forms.get("title")
|
||||
comic_order = bottle.request.forms.get("current_order")
|
||||
comic_completed = bottle.request.forms.get("completed")
|
||||
if comic_id == "newentry":
|
||||
self.comics.insert_entry(comic_title, None, comic_order, comic_completed)
|
||||
else:
|
||||
self.comics.update_entry(comic_id, comic_title, None, comic_order, comic_completed)
|
||||
bottle.redirect("/comics/comic")
|
||||
|
||||
|
||||
def publisher_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.publishers.get_publishers()
|
||||
return bottle.template('publisher_list', dict(publishers=l, username=username))
|
||||
|
||||
|
||||
def publisher_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
publisher = self.publishers.get_publisher(id)
|
||||
errors = ""
|
||||
if publisher == None:
|
||||
errors= "Entry not found"
|
||||
return bottle.template('publisher_template', dict(name=publisher['name'], id=publisher['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_publisher_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("publisher_template", dict(name="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_publisher(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
publisher_id = bottle.request.forms.get("id")
|
||||
publisher_name = bottle.request.forms.get("name")
|
||||
if publisher_id == "newentry":
|
||||
self.publishers.insert_entry(publisher_name)
|
||||
else:
|
||||
self.publishers.update_entry(publisher_id, publisher_name)
|
||||
bottle.redirect("/comics/publisher")
|
||||
|
||||
|
||||
def artist_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.artists.get_artists()
|
||||
return bottle.template('artist_list', dict(artists=l, username=username))
|
||||
|
||||
|
||||
def artist_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
artist = self.artists.get_artist(id)
|
||||
errors = ""
|
||||
if artist == None:
|
||||
errors= "Entry not found"
|
||||
return bottle.template('artist_template', dict(name=artist['name'], id=artist['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_artist_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("artist_template", dict(name="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_artist(self):
|
||||
artist_id = bottle.request.forms.get("id")
|
||||
artist_name = bottle.request.forms.get("name")
|
||||
if artist_id == "newentry":
|
||||
self.artists.insert_entry(artist_name)
|
||||
else:
|
||||
self.artists.update_entry(artist_id, artist_name)
|
||||
bottle.redirect("/comics/artist")
|
||||
|
||||
|
||||
def storyarc_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.storyarcs.get_storyarcs()
|
||||
return bottle.template('storyarc_list', dict(storyarcs=l, username=username))
|
||||
|
||||
|
||||
def storyarc_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
storyarc = self.storyarcs.get_storyarc(id)
|
||||
errors = ""
|
||||
if storyarc == None:
|
||||
errors = "Entry not found"
|
||||
return bottle.template('storyarc_template', dict(title=storyarc['title'], id=storyarc['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_storyarc_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("storyarc_template", dict(title="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_storyarc(self):
|
||||
storyarc_id = bottle.request.forms.get("id")
|
||||
storyarc_title = bottle.request.forms.get("title")
|
||||
if storyarc_id == "newentry":
|
||||
self.storyarcs.insert_entry(storyarc_title)
|
||||
else:
|
||||
self.storyarcs.update_entry(storyarc_id, storyarc_title)
|
||||
bottle.redirect("/comics/storyarc")
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class ArtistDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.artists = database.artists
|
||||
|
||||
def get_artists(self):
|
||||
cursor = self.artists.find()
|
||||
l = []
|
||||
for artist in cursor:
|
||||
l.append({'name':artist['name'], '_id':artist['_id']})
|
||||
return l
|
||||
|
||||
def get_artist(self, artist_id):
|
||||
artist = self.artists.find_one({"_id": ObjectId(artist_id)})
|
||||
return artist
|
||||
|
||||
def insert_entry(self, artist_name):
|
||||
print("inserting artist entry", artist_name)
|
||||
|
||||
artist = {"name": artist_name}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.artists.insert_one(artist)
|
||||
print("Matching artist: ", result.matched_count)
|
||||
print("Modified artist: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting artist")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
|
||||
def update_entry(self, artist_id, artist_name):
|
||||
print("upserting artist entry", artist_name)
|
||||
|
||||
filter_doc = {"_id": ObjectId(artist_id)}
|
||||
artist = { "$set": {"name": artist_name}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.artists.update_one(filter_doc, artist)
|
||||
print("Modified artist: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting artist")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
@@ -1,52 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class ComicDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.comics = database.comics
|
||||
|
||||
def get_comics(self):
|
||||
cursor = self.comics.find()
|
||||
l = []
|
||||
for comic in cursor:
|
||||
l.append({'title':comic['title'],
|
||||
'_id':comic['_id'],
|
||||
'current_order':comic['current_order'],
|
||||
'completed':comic['completed']})
|
||||
return l
|
||||
|
||||
def get_comic(self, comic_id):
|
||||
comic = self.comics.find_one({"_id": ObjectId(comic_id)})
|
||||
return comic
|
||||
|
||||
def insert_entry(self, comic_title, comic_publisher=None, comic_order=False, comic_completed=False):
|
||||
print("inserting comic entry", comic_title)
|
||||
|
||||
comic = {"title": comic_title, "current_order": comic_order, "completed": comic_completed}
|
||||
|
||||
# now insert the comic
|
||||
try:
|
||||
result = self.comics.insert_one(comic)
|
||||
print("Modified comic: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting comic")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
|
||||
def update_entry(self, comic_id, comic_title, comic_publisher=None, comic_order=False, comic_completed=False):
|
||||
print("upserting comic entry", comic_title)
|
||||
|
||||
filter_doc = {"_id": ObjectId(comic_id)}
|
||||
comic = { "$set": {"title": comic_title, 'current_order': comic_order, 'completed': comic_completed}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.comics.update_one(filter_doc, comic)
|
||||
print("Matching comic: ", result.matched_count)
|
||||
print("Modified comic: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting comic")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
@@ -1,121 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from mongoengine import connect, Document
|
||||
from mongoengine import StringField, BooleanField
|
||||
from mongoengine import ListField, ReferenceField, GenericReferenceField
|
||||
import pprint
|
||||
|
||||
|
||||
class Publisher(Document):
|
||||
name = StringField(required=True)
|
||||
|
||||
def __str__(self):
|
||||
s = "Publisher(%s)" % self.name
|
||||
return s
|
||||
|
||||
|
||||
class Artist(Document):
|
||||
name = StringField(required=True)
|
||||
className = StringField()
|
||||
|
||||
def __str__(self):
|
||||
s = "Artist(%s)" % self.name
|
||||
return s
|
||||
|
||||
|
||||
class Issue(Document):
|
||||
number = StringField()
|
||||
comic = GenericReferenceField()
|
||||
is_read = BooleanField(default=False)
|
||||
is_stock = BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
s = "Issue(%s # %s, %s)" % (self.comic.title, self.number, self.is_read)
|
||||
return s
|
||||
|
||||
|
||||
class StoryArc(Document):
|
||||
name = StringField(required=True)
|
||||
comic = GenericReferenceField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
|
||||
def __str__(self):
|
||||
s = "StoryArc(%s, %s)" % (self.name, self.comic.title)
|
||||
return s
|
||||
|
||||
|
||||
class Volume(Document):
|
||||
name = StringField(required=True)
|
||||
comic = GenericReferenceField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
|
||||
def __str__(self):
|
||||
s = "Volume(%s, %s, %s)" % (self.id, self.name, self.comic.title)
|
||||
return s
|
||||
|
||||
|
||||
class Comic(Document):
|
||||
title = StringField(required=True)
|
||||
publisher = ReferenceField(Publisher)
|
||||
current_order = BooleanField()
|
||||
completed = BooleanField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
stories = ListField(ReferenceField(StoryArc))
|
||||
|
||||
def __str__(self):
|
||||
if self.publisher is None:
|
||||
s = "Comic(%s, %s, %s, %s)" % (self.title, self.publisher, self.current_order, self.completed)
|
||||
return s
|
||||
else:
|
||||
s = "Comic(%s, %s, %s, %s)" % (
|
||||
self.title, self.publisher.name, self.current_order, self.completed)
|
||||
return s
|
||||
|
||||
|
||||
class TradePaperback(Document):
|
||||
comic = ReferenceField(Comic)
|
||||
issue_start = StringField()
|
||||
issue_end = StringField()
|
||||
|
||||
def __str__(self):
|
||||
s = "TPB(%s)" % self.comic.title
|
||||
return s
|
||||
|
||||
|
||||
def get_publisher(name):
|
||||
publisher = Publisher.objects(name=name)
|
||||
if publisher.count() > 0:
|
||||
return publisher[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_comic(title):
|
||||
comic = Comic.objects(title=title)
|
||||
if comic.count() > 0:
|
||||
return comic[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_issue(title, number):
|
||||
comic = get_comic(title)
|
||||
issues = Issue.objects(number=number, comic=comic)
|
||||
if issues.count() > 0:
|
||||
return issues[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
if __name__ == '__main__':
|
||||
connect('comics')
|
||||
for publisher in Publisher.objects:
|
||||
pprint.pprint(publisher)
|
||||
for artist in Artist.objects:
|
||||
pprint.pprint(artist)
|
||||
for comic in Comic.objects:
|
||||
pprint.pprint(comic)
|
||||
for issue in Issue.objects:
|
||||
pprint.pprint(issue)
|
||||
for story in StoryArc.objects:
|
||||
pprint.pprint(story)
|
||||
for tpb in TradePaperback.objects:
|
||||
pprint.pprint(tpb)
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class PublisherDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.publishers = database.publishers
|
||||
|
||||
def get_publishers(self):
|
||||
cursor = self.publishers.find()
|
||||
l = []
|
||||
for publisher in cursor:
|
||||
l.append({'name':publisher['name'], '_id':publisher['_id']})
|
||||
return l
|
||||
|
||||
def get_publisher(self, publisher_id):
|
||||
publisher = self.publishers.find_one({"_id": ObjectId(publisher_id)})
|
||||
return publisher
|
||||
|
||||
def insert_entry(self, publisher_name):
|
||||
print("inserting publisher entry", publisher_name)
|
||||
|
||||
publisher = {"name": publisher_name}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.publishers.insert_one(publisher)
|
||||
print("Matching publisher: ", result.matched_count)
|
||||
print("Modified publisher: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting publisher")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
|
||||
def update_entry(self, publisher_id, publisher_name):
|
||||
print("upserting publisher entry", publisher_name)
|
||||
|
||||
filter_doc = {"_id": ObjectId(publisher_id)}
|
||||
publisher = { "$set": {"name": publisher_name}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.publishers.update_one(filter_doc, publisher)
|
||||
print("Modified publisher: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting publisher")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
|
||||
class StoryArcDAO:
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.storyarcs = database.storyarcs
|
||||
|
||||
def get_storyarcs(self):
|
||||
cursor = self.storyarcs.find()
|
||||
l = []
|
||||
for storyarc in cursor:
|
||||
l.append({'title': storyarc['title'], '_id': storyarc['_id']})
|
||||
return l
|
||||
|
||||
def get_storyarc(self, storyarc_id):
|
||||
storyarc = self.storyarcs.find_one({"_id": ObjectId(storyarc_id)})
|
||||
return storyarc
|
||||
|
||||
def insert_entry(self, storyarc_title):
|
||||
print("inserting publisher entry", storyarc_title)
|
||||
|
||||
storyarc = {"name": storyarc_title}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.storyarcs.insert_one(storyarc)
|
||||
print("Matching storyarc: ", result.matched_count)
|
||||
print("Modified storyarc: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting storyarc")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
|
||||
def update_entry(self, storyarc_id, storyarc_title):
|
||||
print("upserting storyarc entry", storyarc_title)
|
||||
|
||||
filter_doc = {"_id": ObjectId(storyarc_id)}
|
||||
storyarc = {"$set": {"name": storyarc_title}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.storyarcs.update_one(filter_doc, storyarc)
|
||||
print("Modified storyarc: ", result.modified_count)
|
||||
except:
|
||||
print("Error inserting storyarc")
|
||||
print("Unexpected error:", sys.exc_info())
|
||||
@@ -1,89 +0,0 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
color: #333333;
|
||||
padding:4em 0 4em;
|
||||
}
|
||||
body,
|
||||
.wrapper {
|
||||
margin: 10px auto;
|
||||
/*max-width: 60em;*/
|
||||
}
|
||||
|
||||
header, nav, nav a, main, section, footer {
|
||||
border-radius: 0px 0.5em 0.5em;
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
header {
|
||||
position:fixed;
|
||||
top:0px;
|
||||
left:0px;
|
||||
right:0px;
|
||||
text-align:center;
|
||||
padding:10px;
|
||||
background: lightgrey;
|
||||
/*border-bottom: 1px solid #d5d5d5;*/
|
||||
}
|
||||
|
||||
nav {
|
||||
position: fixed;
|
||||
padding-top: 10em;
|
||||
|
||||
font-size: 0.91em;
|
||||
float: left;
|
||||
width: 15em;
|
||||
padding: 0;
|
||||
background: lightskyblue;
|
||||
border-color: skyblue;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
nav a {
|
||||
display: block;
|
||||
padding: 0.2em 10px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
background-color: skyblue;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
nav ul a:hover,
|
||||
nav ul a:active {
|
||||
color: #fffbf0;
|
||||
background-color: #dfac20;
|
||||
}
|
||||
|
||||
main {
|
||||
display: block;
|
||||
background: lightblue;
|
||||
border-color: #8a9da8;
|
||||
margin-left: 15em;
|
||||
min-width: 16em; /* Mindestbreite (der Überschrift) verhindert Anzeigefehler in modernen Browsern */
|
||||
}
|
||||
|
||||
footer {
|
||||
position:fixed;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
bottom:0;
|
||||
left: 0;
|
||||
right:0;
|
||||
background: lightgrey;
|
||||
border-color: grey;
|
||||
}
|
||||
|
||||
footer p {
|
||||
float:right;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pymongo
|
||||
import sessionDAO
|
||||
import userDAO
|
||||
import comics
|
||||
#import library
|
||||
import bottle
|
||||
import cgi
|
||||
import re
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
app = bottle.Bottle()
|
||||
|
||||
|
||||
def index():
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = sessions.get_username(cookie)
|
||||
return bottle.template('kontor', dict(username=username))
|
||||
|
||||
|
||||
def show_signup():
|
||||
return bottle.template("signup", dict(username="",
|
||||
password="",
|
||||
password_error="",
|
||||
email="",
|
||||
username_error="",
|
||||
email_error="",
|
||||
verify_error =""))
|
||||
|
||||
|
||||
def process_signup():
|
||||
email = bottle.request.forms.get("email")
|
||||
username = bottle.request.forms.get("username")
|
||||
password = bottle.request.forms.get("password")
|
||||
verify = bottle.request.forms.get("verify")
|
||||
|
||||
# set these up in case we have an error case
|
||||
errors = {'username': cgi.escape(username), 'email': cgi.escape(email)}
|
||||
if validate_signup(username, password, verify, email, errors):
|
||||
|
||||
if not users.add_user(username, password, email):
|
||||
# this was a duplicate
|
||||
errors['username_error'] = "Username already in use. Please choose another"
|
||||
return bottle.template("signup", errors)
|
||||
|
||||
session_id = sessions.start_session(username)
|
||||
print(session_id)
|
||||
bottle.response.set_cookie("session", session_id)
|
||||
bottle.redirect("/welcome")
|
||||
else:
|
||||
print("user did not validate")
|
||||
return bottle.template("signup", errors)
|
||||
|
||||
|
||||
def show_login():
|
||||
return bottle.template('login', dict(username="", password="", login_error=""))
|
||||
|
||||
def process_login():
|
||||
username = bottle.request.forms.get("username")
|
||||
password = bottle.request.forms.get("password")
|
||||
|
||||
print("user submitted ", username, "pass ", password)
|
||||
|
||||
user_record = users.validate_login(username, password)
|
||||
if user_record:
|
||||
# username is stored in the user collection in the _id key
|
||||
session_id = sessions.start_session(user_record['_id'])
|
||||
|
||||
if session_id is None:
|
||||
bottle.redirect("/internal_error")
|
||||
|
||||
cookie = session_id
|
||||
|
||||
# Warning, if you are running into a problem whereby the cookie being set here is
|
||||
# not getting set on the redirect, you are probably using the experimental version of bottle (.12).
|
||||
# revert to .11 to solve the problem.
|
||||
bottle.response.set_cookie("session", cookie)
|
||||
|
||||
bottle.redirect("/")
|
||||
|
||||
else:
|
||||
return bottle.template("login", dict(username=cgi.escape(username), password="", login_error="Invalid Login"))
|
||||
|
||||
|
||||
def process_logout():
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
sessions.end_session(cookie)
|
||||
bottle.response.set_cookie("session", "")
|
||||
bottle.redirect("/")
|
||||
|
||||
|
||||
def send_stylesheet(filename):
|
||||
return bottle.static_file(filename, root='.', mimetype='text/css')
|
||||
|
||||
|
||||
def setup_routing(app):
|
||||
app.route('/', 'GET', index)
|
||||
app.route('/signup', 'GET', show_signup)
|
||||
app.route('/signup', 'POST', process_signup)
|
||||
app.route('/login', 'GET', show_login)
|
||||
app.route('/login', 'POST', process_login)
|
||||
app.route('/logout', 'GET', process_logout)
|
||||
app.route('/css/<filename:re:.*\.css>', 'GET', send_stylesheet)
|
||||
|
||||
|
||||
# validates that the user information is valid for new signup, return True of False
|
||||
# and fills in the error string if there is an issue
|
||||
def validate_signup(username, password, verify, email, errors):
|
||||
USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
|
||||
PASS_RE = re.compile(r"^.{3,20}$")
|
||||
EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
|
||||
|
||||
errors['username_error'] = ""
|
||||
errors['password_error'] = ""
|
||||
errors['verify_error'] = ""
|
||||
errors['email_error'] = ""
|
||||
|
||||
if not USER_RE.match(username):
|
||||
errors['username_error'] = "invalid username. try just letters and numbers"
|
||||
return False
|
||||
|
||||
if not PASS_RE.match(password):
|
||||
errors['password_error'] = "invalid password."
|
||||
return False
|
||||
if password != verify:
|
||||
errors['verify_error'] = "password must match"
|
||||
return False
|
||||
if email != "":
|
||||
if not EMAIL_RE.match(email):
|
||||
errors['email_error'] = "invalid email address"
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
setup_routing(app)
|
||||
|
||||
connection = pymongo.MongoClient("mongodb://mongodb")
|
||||
database = connection.kontor
|
||||
|
||||
users = userDAO.UserDAO(database)
|
||||
sessions = sessionDAO.SessionDAO(database)
|
||||
|
||||
comics_plugin = comics.Plugin(app, database, sessions)
|
||||
#library_plugin = library.Plugin(app, database, sessions)
|
||||
print("starting app Kontor")
|
||||
bottle.run(app, host="0.0.0.0", port=9000, debug=True)
|
||||
@@ -1,64 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
# The session Data Access Object handles interactions with the sessions collection
|
||||
|
||||
class SessionDAO:
|
||||
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.sessions = database.sessions
|
||||
|
||||
# will start a new session id by adding a new document to the sessions collection
|
||||
# returns the sessionID or None
|
||||
def start_session(self, username):
|
||||
|
||||
session_id = self.get_random_str(32)
|
||||
session = {'username': username, '_id': session_id}
|
||||
|
||||
try:
|
||||
self.sessions.insert_one(session)
|
||||
except:
|
||||
print("Unexpected error on start_session:", sys.exc_info()[0])
|
||||
return None
|
||||
|
||||
return str(session['_id'])
|
||||
|
||||
# will send a new user session by deleting from sessions table
|
||||
def end_session(self, session_id):
|
||||
|
||||
if session_id is None:
|
||||
return
|
||||
|
||||
self.sessions.delete_one({'_id': session_id})
|
||||
|
||||
return
|
||||
|
||||
# if there is a valid session, it is returned
|
||||
def get_session(self, session_id):
|
||||
|
||||
if session_id is None:
|
||||
return None
|
||||
|
||||
session = self.sessions.find_one({'_id': session_id})
|
||||
|
||||
return session
|
||||
|
||||
# get the username of the current session, or None if the session is not valid
|
||||
def get_username(self, session_id):
|
||||
|
||||
session = self.get_session(session_id)
|
||||
if session is None:
|
||||
return None
|
||||
else:
|
||||
return session['username']
|
||||
|
||||
def get_random_str(self, num_chars):
|
||||
random_string = ""
|
||||
for i in range(num_chars):
|
||||
random_string = random_string + random.choice(string.ascii_letters)
|
||||
return random_string
|
||||
@@ -1,74 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
import pymongo
|
||||
|
||||
|
||||
# The User Data Access Object handles all interactions with the User collection.
|
||||
class UserDAO:
|
||||
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
self.users = self.db.users
|
||||
self.SECRET = 'verysecret'
|
||||
|
||||
# makes a little salt
|
||||
def make_salt(self):
|
||||
salt = ""
|
||||
for i in range(5):
|
||||
salt = salt + random.choice(string.ascii_letters)
|
||||
return salt
|
||||
|
||||
# implement the function make_pw_hash(name, pw) that returns a hashed password
|
||||
# of the format:
|
||||
# HASH(pw + salt),salt
|
||||
# use sha256
|
||||
|
||||
def make_pw_hash(self, pw,salt=None):
|
||||
if salt == None:
|
||||
salt = self.make_salt()
|
||||
return hashlib.sha256(pw + salt).hexdigest()+","+ salt
|
||||
|
||||
# Validates a user login. Returns user record or None
|
||||
def validate_login(self, username, password):
|
||||
|
||||
user = None
|
||||
try:
|
||||
user = self.users.find_one({'_id': username})
|
||||
except:
|
||||
print("Unable to query database for user")
|
||||
|
||||
if user is None:
|
||||
print("User not in database")
|
||||
return None
|
||||
|
||||
salt = user['password'].split(',')[1]
|
||||
|
||||
if user['password'] != self.make_pw_hash(password, salt):
|
||||
print("user password is not a match")
|
||||
return None
|
||||
|
||||
# Looks good
|
||||
return user
|
||||
|
||||
|
||||
# creates a new user in the users collection
|
||||
def add_user(self, username, password, email):
|
||||
password_hash = self.make_pw_hash(password)
|
||||
|
||||
user = {'_id': username, 'password': password_hash}
|
||||
if email != "":
|
||||
user['email'] = email
|
||||
|
||||
try:
|
||||
self.users.insert_one(user)
|
||||
except pymongo.errors.OperationFailure:
|
||||
print("oops, mongo error")
|
||||
return False
|
||||
except pymongo.errors.DuplicateKeyError:
|
||||
print("oops, username is already taken")
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for artist in artists:
|
||||
<li><a href="/comics/artist/{{artist['_id']}}">{{artist['name']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/artist/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="name" size="60" value="{{name}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,44 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<table border="1">
|
||||
<tr><td>Title</td><td>Current Order</td><td>Completed</td></tr>
|
||||
<tr>
|
||||
%for comic in comics:
|
||||
<td><a href="/comics/comic/{{comic['_id']}}">{{comic['title']}}</a></td>
|
||||
<td>{{comic['current_order']}}</td>
|
||||
<td>{{comic['completed']}}</td>
|
||||
%end
|
||||
</tr>
|
||||
</table>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,51 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/comic/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="title" size="60" value="{{title}}"><br>
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" name="current_order" size="60" value="{{current_order}}">
|
||||
Current Order
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="completed" size="60" value="{{completed}}">
|
||||
Completed
|
||||
</label>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
</details>
|
||||
</main>
|
||||
%if (username == None):
|
||||
<footer><a href="/login">Login</a><p>Ingenieurbüro Thomas Peetz</p></footer>
|
||||
%end
|
||||
%if (username != None):
|
||||
<footer><a href="/logout">{{username}}</a><p>Ingenieurbüro Thomas Peetz</p></footer>
|
||||
%end
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,52 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form method="POST">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="label">Username</td>
|
||||
<td><input type="text" name="username" value="{{username}}"></td>
|
||||
<td class="error"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">Password</td>
|
||||
<td><input type="password" name="password" value=""></td>
|
||||
<td class="error">{{login_error}}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for publisher in publishers:
|
||||
<li><a href="/comics/publisher/{{publisher['_id']}}">{{publisher['name']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics/comic">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/publisher/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="name" size="60" value="{{name}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<h2>Signup</h2>
|
||||
<form method="post">
|
||||
<table>
|
||||
<tr><td class="label">Username</td>
|
||||
<td><input type="text" name="username" value="{{username}}"></td>
|
||||
<td class="error">{{username_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Password</td>
|
||||
<td><input type="password" name="password" value=""></td>
|
||||
<td class="error">{{password_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Verify Password</td>
|
||||
<td><input type="password" name="verify" value=""></td>
|
||||
<td class="error">{{verify_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Email (optional)</td>
|
||||
<td><input type="text" name="email" value="{{email}}"></td>
|
||||
<td class="error">{{email_error}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics/comic">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
<li><a href="/comics/storyarc">StoryArcs</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for storyarc in storyarcs:
|
||||
<li><a href="/comics/storyarc/{{storyarc['_id']}}">{{storyarc['title']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
<li><a href="/comics/storyarc">StoryArcs</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/storyarc/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="title" size="60" value="{{title}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,31 +0,0 @@
|
||||
services:
|
||||
mongodb:
|
||||
image: mongo
|
||||
restart: always
|
||||
volumes:
|
||||
- db-data:/var/lib/mongo
|
||||
networks:
|
||||
- backend-network
|
||||
app:
|
||||
build: app
|
||||
restart: always
|
||||
ports:
|
||||
- 9000:9000
|
||||
networks:
|
||||
- backend-network
|
||||
- frontend-network
|
||||
nginx:
|
||||
image: nginx
|
||||
restart: always
|
||||
volumes:
|
||||
- ./nginx:/etc/nginx/conf.d
|
||||
- ./front-end:/var/www/front-end
|
||||
ports:
|
||||
- 8070:80
|
||||
networks:
|
||||
- frontend-network
|
||||
volumes:
|
||||
db-data:
|
||||
networks:
|
||||
backend-network:
|
||||
frontend-network:
|
||||
@@ -1,82 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Hello!</title>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
|
||||
<meta content="utf-8" http-equiv="encoding">
|
||||
<style>
|
||||
*, ::after, ::before {
|
||||
box-sizing: inherit;
|
||||
background-color: #9eb5c2;
|
||||
color: rgb(8, 8, 71);
|
||||
}
|
||||
.moby {
|
||||
padding: 2rem 1rem;
|
||||
margin-bottom: 2rem;
|
||||
border-radius: .3rem;
|
||||
border-bottom: 0;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
.moby button {
|
||||
color: #fff;
|
||||
background-color: rgb(6, 105, 138);
|
||||
border-color: rgb(6, 105, 138);
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
.moby .query {
|
||||
text-align: left;
|
||||
border: 3px dotted #e9ecef;
|
||||
padding: 1.5rem 1.2rem;
|
||||
max-width: 800px;
|
||||
min-height: 200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-radius: .3rem;
|
||||
}
|
||||
.moby .query button:hover{
|
||||
cursor: pointer;
|
||||
background-color: #73abff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="moby">
|
||||
<img src="https://www.docker.com/sites/default/files/Whale%20Logo332_5.png" />
|
||||
<h1>Hello there!</h1>
|
||||
<p>Simple DEV environment setup with Docker and Docker Compose</p>
|
||||
<div class="query">
|
||||
<p>Set url path(default is '/'), then query the app service.</p>
|
||||
<div>
|
||||
<button type="submit" onclick="queryServer()">GET</button>
|
||||
<input id="path" type="text">
|
||||
</div>
|
||||
<h3>Server response</h3>
|
||||
<div id="response">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function queryServer() {
|
||||
const Http = new XMLHttpRequest();
|
||||
const path = document.getElementById('path').value;
|
||||
const url = "/";
|
||||
Http.open("GET", url + path);
|
||||
Http.send();
|
||||
|
||||
Http.onreadystatechange = (e) => {
|
||||
document.getElementById('response').innerHTML = Http.responseText;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,14 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /var/www/front-end;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://app:9000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
.idea/
|
||||
__pycache__/
|
||||
bin/
|
||||
include/
|
||||
lib/
|
||||
lib64
|
||||
pip-selfcheck.json
|
||||
*.pyc
|
||||
kontor.properties
|
||||
*.nja
|
||||
dist/
|
||||
kontor_bottle.egg-info/
|
||||
Vendored
-13
@@ -1,13 +0,0 @@
|
||||
node {
|
||||
stage("Checkout") {
|
||||
checkout scm
|
||||
}
|
||||
stage("setup virualenv") {
|
||||
sh "virtualenv ."
|
||||
sh "source bin/activate; pip install bottle pymongo"
|
||||
}
|
||||
stage("build") {
|
||||
sh "source bin/activate; python setup.py sdist"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# Kontor Bottle
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import publisherDAO
|
||||
import artistDAO
|
||||
import comicDAO
|
||||
import storyArcDAO
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.publishers = publisherDAO.PublisherDAO(database)
|
||||
self.artists = artistDAO.ArtistDAO(database)
|
||||
self.comics = comicDAO.ComicDAO(database)
|
||||
self.storyarcs = storyArcDAO.StoryArcDAO(database)
|
||||
self.routing()
|
||||
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/comics', 'GET', self.comic_index)
|
||||
self.app.route('/comics/', 'GET', self.comic_index)
|
||||
self.app.route('/comics/comic', 'GET', self.comic_list)
|
||||
self.app.route('/comics/comic/<id>', 'GET', self.comic_details)
|
||||
self.app.route('/comics/comic/create', 'GET', self.get_comic_create)
|
||||
self.app.route('/comics/comic/create', 'POST', self.post_create_comic)
|
||||
self.app.route('/comics/publisher', 'GET', self.publisher_list)
|
||||
self.app.route('/comics/publisher/<id>', 'GET', self.publisher_details)
|
||||
self.app.route('/comics/publisher/create', 'GET', self.get_publisher_create)
|
||||
self.app.route('/comics/publisher/create', 'POST', self.post_create_publisher)
|
||||
self.app.route('/comics/artist', 'GET', self.artist_list)
|
||||
self.app.route('/comics/artist/<id>', 'GET', self.artist_details)
|
||||
self.app.route('/comics/artist/create', 'GET', self.get_artist_create)
|
||||
self.app.route('/comics/artist/create', 'POST', self.post_create_artist)
|
||||
self.app.route('/comics/storyarc', 'GET', self.storyarc_list)
|
||||
self.app.route('/comics/storyarc/<id>', 'GET', self.storyarc_details)
|
||||
self.app.route('/comics/storyarc/create', 'GET', self.get_storyarc_create)
|
||||
self.app.route('/comics/storyarc/create', 'POST', self.post_create_storyarc)
|
||||
|
||||
def comic_index(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template('comic_index', dict(username=username))
|
||||
|
||||
|
||||
def comic_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.comics.get_comics()
|
||||
return bottle.template('comic_list', dict(comics=l, username=username))
|
||||
|
||||
|
||||
def comic_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
comic = self.comics.get_comic(id)
|
||||
errors = ""
|
||||
if comic == None:
|
||||
errors = "Entry not found"
|
||||
return bottle.template('comic_template', dict(title=comic['title'],
|
||||
id=comic['_id'],
|
||||
current_order=comic['current_order'],
|
||||
completed=comic['completed'],
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
|
||||
def get_comic_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("comic_template", dict(title="",
|
||||
id='newentry',
|
||||
current_order=False,
|
||||
completed=False,
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
|
||||
def post_create_comic(self):
|
||||
comic_id = bottle.request.forms.get("id")
|
||||
comic_title = bottle.request.forms.get("title")
|
||||
comic_order = bottle.request.forms.get("current_order")
|
||||
comic_completed = bottle.request.forms.get("completed")
|
||||
if comic_id == "newentry":
|
||||
self.comics.insert_entry(comic_title, None, comic_order, comic_completed)
|
||||
else:
|
||||
self.comics.update_entry(comic_id, comic_title, None, comic_order, comic_completed)
|
||||
bottle.redirect("/comics/comic")
|
||||
|
||||
|
||||
def publisher_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.publishers.get_publishers()
|
||||
return bottle.template('publisher_list', dict(publishers=l, username=username))
|
||||
|
||||
|
||||
def publisher_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
publisher = self.publishers.get_publisher(id)
|
||||
errors = ""
|
||||
if publisher == None:
|
||||
errors= "Entry not found"
|
||||
return bottle.template('publisher_template', dict(name=publisher['name'], id=publisher['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_publisher_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("publisher_template", dict(name="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_publisher(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
publisher_id = bottle.request.forms.get("id")
|
||||
publisher_name = bottle.request.forms.get("name")
|
||||
if publisher_id == "newentry":
|
||||
self.publishers.insert_entry(publisher_name)
|
||||
else:
|
||||
self.publishers.update_entry(publisher_id, publisher_name)
|
||||
bottle.redirect("/comics/publisher")
|
||||
|
||||
|
||||
def artist_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.artists.get_artists()
|
||||
return bottle.template('artist_list', dict(artists=l, username=username))
|
||||
|
||||
|
||||
def artist_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
artist = self.artists.get_artist(id)
|
||||
errors = ""
|
||||
if artist == None:
|
||||
errors= "Entry not found"
|
||||
return bottle.template('artist_template', dict(name=artist['name'], id=artist['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_artist_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("artist_template", dict(name="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_artist(self):
|
||||
artist_id = bottle.request.forms.get("id")
|
||||
artist_name = bottle.request.forms.get("name")
|
||||
if artist_id == "newentry":
|
||||
self.artists.insert_entry(artist_name)
|
||||
else:
|
||||
self.artists.update_entry(artist_id, artist_name)
|
||||
bottle.redirect("/comics/artist")
|
||||
|
||||
|
||||
def storyarc_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.storyarcs.get_storyarcs()
|
||||
return bottle.template('storyarc_list', dict(storyarcs=l, username=username))
|
||||
|
||||
|
||||
def storyarc_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
storyarc = self.storyarcs.get_storyarc(id)
|
||||
errors = ""
|
||||
if storyarc == None:
|
||||
errors = "Entry not found"
|
||||
return bottle.template('storyarc_template', dict(title=storyarc['title'], id=storyarc['_id'], errors="", username=username))
|
||||
|
||||
|
||||
def get_storyarc_create(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("storyarc_template", dict(title="", id='newentry', errors="", username=username))
|
||||
|
||||
|
||||
def post_create_storyarc(self):
|
||||
storyarc_id = bottle.request.forms.get("id")
|
||||
storyarc_title = bottle.request.forms.get("title")
|
||||
if storyarc_id == "newentry":
|
||||
self.storyarcs.insert_entry(storyarc_title)
|
||||
else:
|
||||
self.storyarcs.update_entry(storyarc_id, storyarc_title)
|
||||
bottle.redirect("/comics/storyarc")
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class ArtistDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.artists = database.artists
|
||||
|
||||
def get_artists(self):
|
||||
cursor = self.artists.find()
|
||||
l = []
|
||||
for artist in cursor:
|
||||
l.append({'name':artist['name'], '_id':artist['_id']})
|
||||
return l
|
||||
|
||||
def get_artist(self, artist_id):
|
||||
artist = self.artists.find_one({"_id": ObjectId(artist_id)})
|
||||
return artist
|
||||
|
||||
def insert_entry(self, artist_name):
|
||||
print "inserting artist entry", artist_name
|
||||
|
||||
artist = {"name": artist_name}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.artists.insert_one(artist)
|
||||
print "Matching artist: ", result.matched_count
|
||||
print "Modified artist: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting artist"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
def update_entry(self, artist_id, artist_name):
|
||||
print "upserting artist entry", artist_name
|
||||
|
||||
filter_doc = {"_id": ObjectId(artist_id)}
|
||||
artist = { "$set": {"name": artist_name}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.artists.update_one(filter_doc, artist)
|
||||
print "Modified artist: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting artist"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class ComicDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.comics = database.comics
|
||||
|
||||
def get_comics(self):
|
||||
cursor = self.comics.find()
|
||||
l = []
|
||||
for comic in cursor:
|
||||
l.append({'title':comic['title'],
|
||||
'_id':comic['_id'],
|
||||
'current_order':comic['current_order'],
|
||||
'completed':comic['completed']})
|
||||
return l
|
||||
|
||||
def get_comic(self, comic_id):
|
||||
comic = self.comics.find_one({"_id": ObjectId(comic_id)})
|
||||
return comic
|
||||
|
||||
def insert_entry(self, comic_title, comic_publisher=None, comic_order=False, comic_completed=False):
|
||||
print "inserting comic entry", comic_title
|
||||
|
||||
comic = {"title": comic_title, "current_order": comic_order, "completed": comic_completed}
|
||||
|
||||
# now insert the comic
|
||||
try:
|
||||
result = self.comics.insert_one(comic)
|
||||
print "Modified comic: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting comic"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
def update_entry(self, comic_id, comic_title, comic_publisher=None, comic_order=False, comic_completed=False):
|
||||
print "upserting comic entry", comic_title
|
||||
|
||||
filter_doc = {"_id": ObjectId(comic_id)}
|
||||
comic = { "$set": {"title": comic_title, 'current_order': comic_order, 'completed': comic_completed}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.comics.update_one(filter_doc, comic)
|
||||
print "Matching comic: ", result.matched_count
|
||||
print "Modified comic: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting comic"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from mongoengine import connect, Document
|
||||
from mongoengine import StringField, BooleanField
|
||||
from mongoengine import ListField, ReferenceField, GenericReferenceField
|
||||
import pprint
|
||||
|
||||
|
||||
class Publisher(Document):
|
||||
name = StringField(required=True)
|
||||
|
||||
def __str__(self):
|
||||
s = "Publisher(%s)" % self.name
|
||||
return s
|
||||
|
||||
|
||||
class Artist(Document):
|
||||
name = StringField(required=True)
|
||||
className = StringField()
|
||||
|
||||
def __str__(self):
|
||||
s = "Artist(%s)" % self.name
|
||||
return s
|
||||
|
||||
|
||||
class Issue(Document):
|
||||
number = StringField()
|
||||
comic = GenericReferenceField()
|
||||
is_read = BooleanField(default=False)
|
||||
is_stock = BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
s = "Issue(%s # %s, %s)" % (self.comic.title, self.number, self.is_read)
|
||||
return s
|
||||
|
||||
|
||||
class StoryArc(Document):
|
||||
name = StringField(required=True)
|
||||
comic = GenericReferenceField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
|
||||
def __str__(self):
|
||||
s = "StoryArc(%s, %s)" % (self.name, self.comic.title)
|
||||
return s
|
||||
|
||||
|
||||
class Volume(Document):
|
||||
name = StringField(required=True)
|
||||
comic = GenericReferenceField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
|
||||
def __str__(self):
|
||||
s = "Volume(%s, %s, %s)" % (self.id, self.name, self.comic.title)
|
||||
return s
|
||||
|
||||
|
||||
class Comic(Document):
|
||||
title = StringField(required=True)
|
||||
publisher = ReferenceField(Publisher)
|
||||
current_order = BooleanField()
|
||||
completed = BooleanField()
|
||||
issues = ListField(ReferenceField(Issue))
|
||||
stories = ListField(ReferenceField(StoryArc))
|
||||
|
||||
def __str__(self):
|
||||
if self.publisher is None:
|
||||
s = "Comic(%s, %s, %s, %s)" % (self.title, self.publisher, self.current_order, self.completed)
|
||||
return s
|
||||
else:
|
||||
s = "Comic(%s, %s, %s, %s)" % (
|
||||
self.title, self.publisher.name, self.current_order, self.completed)
|
||||
return s
|
||||
|
||||
|
||||
class TradePaperback(Document):
|
||||
comic = ReferenceField(Comic)
|
||||
issue_start = StringField()
|
||||
issue_end = StringField()
|
||||
|
||||
def __str__(self):
|
||||
s = "TPB(%s)" % self.comic.title
|
||||
return s
|
||||
|
||||
|
||||
def get_publisher(name):
|
||||
publisher = Publisher.objects(name=name)
|
||||
if publisher.count() > 0:
|
||||
return publisher[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_comic(title):
|
||||
comic = Comic.objects(title=title)
|
||||
if comic.count() > 0:
|
||||
return comic[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_issue(title, number):
|
||||
comic = get_comic(title)
|
||||
issues = Issue.objects(number=number, comic=comic)
|
||||
if issues.count() > 0:
|
||||
return issues[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
if __name__ == '__main__':
|
||||
connect('comics')
|
||||
for publisher in Publisher.objects:
|
||||
pprint.pprint(publisher)
|
||||
for artist in Artist.objects:
|
||||
pprint.pprint(artist)
|
||||
for comic in Comic.objects:
|
||||
pprint.pprint(comic)
|
||||
for issue in Issue.objects:
|
||||
pprint.pprint(issue)
|
||||
for story in StoryArc.objects:
|
||||
pprint.pprint(story)
|
||||
for tpb in TradePaperback.objects:
|
||||
pprint.pprint(tpb)
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class PublisherDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.publishers = database.publishers
|
||||
|
||||
def get_publishers(self):
|
||||
cursor = self.publishers.find()
|
||||
l = []
|
||||
for publisher in cursor:
|
||||
l.append({'name':publisher['name'], '_id':publisher['_id']})
|
||||
return l
|
||||
|
||||
def get_publisher(self, publisher_id):
|
||||
publisher = self.publishers.find_one({"_id": ObjectId(publisher_id)})
|
||||
return publisher
|
||||
|
||||
def insert_entry(self, publisher_name):
|
||||
print "inserting publisher entry", publisher_name
|
||||
|
||||
publisher = {"name": publisher_name}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.publishers.insert_one(publisher)
|
||||
print "Matching publisher: ", result.matched_count
|
||||
print "Modified publisher: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting publisher"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
def update_entry(self, publisher_id, publisher_name):
|
||||
print "upserting publisher entry", publisher_name
|
||||
|
||||
filter_doc = {"_id": ObjectId(publisher_id)}
|
||||
publisher = { "$set": {"name": publisher_name}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.publishers.update_one(filter_doc, publisher)
|
||||
print "Modified publisher: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting publisher"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
|
||||
class StoryArcDAO:
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.storyarcs = database.storyarcs
|
||||
|
||||
def get_storyarcs(self):
|
||||
cursor = self.storyarcs.find()
|
||||
l = []
|
||||
for storyarc in cursor:
|
||||
l.append({'title': storyarc['title'], '_id': storyarc['_id']})
|
||||
return l
|
||||
|
||||
def get_storyarc(self, storyarc_id):
|
||||
storyarc = self.storyarcs.find_one({"_id": ObjectId(storyarc_id)})
|
||||
return storyarc
|
||||
|
||||
def insert_entry(self, storyarc_title):
|
||||
print "inserting publisher entry", storyarc_title
|
||||
|
||||
storyarc = {"name": storyarc_title}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.storyarcs.insert_one(storyarc)
|
||||
print "Matching storyarc: ", result.matched_count
|
||||
print "Modified storyarc: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting storyarc"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
def update_entry(self, storyarc_id, storyarc_title):
|
||||
print "upserting storyarc entry", storyarc_title
|
||||
|
||||
filter_doc = {"_id": ObjectId(storyarc_id)}
|
||||
storyarc = {"$set": {"name": storyarc_title}}
|
||||
|
||||
# now insert the post
|
||||
try:
|
||||
result = self.storyarcs.update_one(filter_doc, storyarc)
|
||||
print "Modified storyarc: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting storyarc"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.routing()
|
||||
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/office', 'GET', self.office_index)
|
||||
self.app.route('/office/travel', 'GET', self.office_index)
|
||||
|
||||
|
||||
def office_index(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template('office_index', dict(username=username))
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
color: #333333;
|
||||
padding: 3em 0 4em;
|
||||
}
|
||||
|
||||
body,
|
||||
.wrapper {
|
||||
margin: 10px auto;
|
||||
/*max-width: 60em;*/
|
||||
}
|
||||
|
||||
header, main, section, footer {
|
||||
border-radius: 0px 0.5em 0.5em;
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
header {
|
||||
position:fixed;
|
||||
top:0px;
|
||||
left:0px;
|
||||
right:0px;
|
||||
text-align:center;
|
||||
padding: 10px;
|
||||
background: lightgrey;
|
||||
/*border-bottom: 1px solid #d5d5d5;*/
|
||||
}
|
||||
|
||||
nav {
|
||||
/*position: fixed;*/
|
||||
/*padding-top: 10em; */
|
||||
|
||||
border-radius: 0px 0.5em 0.5em;
|
||||
border: 1px solid;
|
||||
|
||||
padding: 0;
|
||||
margin: 10px;
|
||||
|
||||
font-size: 0.91em;
|
||||
float: left;
|
||||
width: 15em;
|
||||
background: lightskyblue;
|
||||
border-color: skyblue;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav li {
|
||||
list-style: none;
|
||||
margin: 0.4em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav ul ul {
|
||||
margin: 0 0 0 2em;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
nav ul ul li {
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
|
||||
nav a {
|
||||
display: block;
|
||||
padding: 0.4em;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border: 1px solid blue;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 5px 10px white inset;
|
||||
background-color: skyblue;
|
||||
color: #333;
|
||||
|
||||
}
|
||||
|
||||
nav a:focus,
|
||||
nav a:hover {
|
||||
color: royalblue;
|
||||
background-color: gold;
|
||||
}
|
||||
|
||||
main {
|
||||
display: block;
|
||||
background: lightblue;
|
||||
border-color: #8a9da8;
|
||||
margin-left: 15em;
|
||||
min-width: 16em; /* Mindestbreite (der Überschrift) verhindert Anzeigefehler in modernen Browsern */
|
||||
}
|
||||
|
||||
footer {
|
||||
position:fixed;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
bottom:0;
|
||||
left: 0;
|
||||
right:0;
|
||||
background: lightgrey;
|
||||
border-color: grey;
|
||||
}
|
||||
|
||||
footer p {
|
||||
float:right;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pymongo
|
||||
import sessionDAO
|
||||
import userDAO
|
||||
import homeoffice
|
||||
import comics
|
||||
import library
|
||||
import medien
|
||||
import tradingcards
|
||||
import ConfigParser
|
||||
import bottle
|
||||
import cgi
|
||||
import re
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
app = bottle.Bottle()
|
||||
|
||||
|
||||
def index():
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = sessions.get_username(cookie)
|
||||
return bottle.template('kontor', dict(username=username))
|
||||
|
||||
|
||||
def show_signup():
|
||||
return bottle.template("signup", dict(username="",
|
||||
password="",
|
||||
password_error="",
|
||||
email="",
|
||||
username_error="",
|
||||
email_error="",
|
||||
verify_error =""))
|
||||
|
||||
|
||||
def process_signup():
|
||||
email = bottle.request.forms.get("email")
|
||||
username = bottle.request.forms.get("username")
|
||||
password = bottle.request.forms.get("password")
|
||||
verify = bottle.request.forms.get("verify")
|
||||
|
||||
# set these up in case we have an error case
|
||||
errors = {'username': cgi.escape(username), 'email': cgi.escape(email)}
|
||||
if validate_signup(username, password, verify, email, errors):
|
||||
|
||||
if not users.add_user(username, password, email):
|
||||
# this was a duplicate
|
||||
errors['username_error'] = "Username already in use. Please choose another"
|
||||
return bottle.template("signup", errors)
|
||||
|
||||
session_id = sessions.start_session(username)
|
||||
print session_id
|
||||
bottle.response.set_cookie("session", session_id)
|
||||
bottle.redirect("/welcome")
|
||||
else:
|
||||
print "user did not validate"
|
||||
return bottle.template("signup", errors)
|
||||
|
||||
|
||||
def show_login():
|
||||
return bottle.template('login', dict(username="", password="", login_error=""))
|
||||
|
||||
def process_login():
|
||||
username = bottle.request.forms.get("username")
|
||||
password = bottle.request.forms.get("password")
|
||||
|
||||
print "user submitted ", username, "pass ", password
|
||||
|
||||
user_record = users.validate_login(username, password)
|
||||
if user_record:
|
||||
# username is stored in the user collection in the _id key
|
||||
session_id = sessions.start_session(user_record['_id'])
|
||||
|
||||
if session_id is None:
|
||||
bottle.redirect("/internal_error")
|
||||
|
||||
cookie = session_id
|
||||
|
||||
# Warning, if you are running into a problem whereby the cookie being set here is
|
||||
# not getting set on the redirect, you are probably using the experimental version of bottle (.12).
|
||||
# revert to .11 to solve the problem.
|
||||
bottle.response.set_cookie("session", cookie)
|
||||
|
||||
bottle.redirect("/")
|
||||
|
||||
else:
|
||||
return bottle.template("login", dict(username=cgi.escape(username), password="", login_error="Invalid Login"))
|
||||
|
||||
|
||||
def process_logout():
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
sessions.end_session(cookie)
|
||||
bottle.response.set_cookie("session", "")
|
||||
bottle.redirect("/")
|
||||
|
||||
|
||||
def send_stylesheet(filename):
|
||||
return bottle.static_file(filename, root='.', mimetype='text/css')
|
||||
|
||||
|
||||
def setup_routing(app):
|
||||
app.route('/', 'GET', index)
|
||||
app.route('/signup', 'GET', show_signup)
|
||||
app.route('/signup', 'POST', process_signup)
|
||||
app.route('/login', 'GET', show_login)
|
||||
app.route('/login', 'POST', process_login)
|
||||
app.route('/logout', 'GET', process_logout)
|
||||
app.route('/css/<filename:re:.*\.css>', 'GET', send_stylesheet)
|
||||
|
||||
|
||||
# validates that the user information is valid for new signup, return True of False
|
||||
# and fills in the error string if there is an issue
|
||||
def validate_signup(username, password, verify, email, errors):
|
||||
USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
|
||||
PASS_RE = re.compile(r"^.{3,20}$")
|
||||
EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
|
||||
|
||||
errors['username_error'] = ""
|
||||
errors['password_error'] = ""
|
||||
errors['verify_error'] = ""
|
||||
errors['email_error'] = ""
|
||||
|
||||
if not USER_RE.match(username):
|
||||
errors['username_error'] = "invalid username. try just letters and numbers"
|
||||
return False
|
||||
|
||||
if not PASS_RE.match(password):
|
||||
errors['password_error'] = "invalid password."
|
||||
return False
|
||||
if password != verify:
|
||||
errors['verify_error'] = "password must match"
|
||||
return False
|
||||
if email != "":
|
||||
if not EMAIL_RE.match(email):
|
||||
errors['email_error'] = "invalid email address"
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
setup_routing(app)
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read('kontor.properties')
|
||||
server = config.get('host', 'server')
|
||||
port = config.get('host', 'port')
|
||||
|
||||
db_server = config.get('database', 'server')
|
||||
db_port = config.get('database', 'port')
|
||||
db_admin = config.get('database', 'adminDB')
|
||||
db_user = config.get('database', 'user')
|
||||
db_password = config.get('database', 'password')
|
||||
connection_string = "mongodb://"
|
||||
if db_admin:
|
||||
connection_string += db_user
|
||||
connection_string += ':'
|
||||
connection_string += db_password
|
||||
connection_string += '@'
|
||||
connection_string += db_server
|
||||
connection_string += '?/authsource='
|
||||
connection_string += db_admin
|
||||
else:
|
||||
connection_string += db_server
|
||||
connection = pymongo.MongoClient(connection_string)
|
||||
database = connection.kontor
|
||||
|
||||
users = userDAO.UserDAO(database)
|
||||
sessions = sessionDAO.SessionDAO(database)
|
||||
|
||||
office_plugin = homeoffice.Plugin(app, database, sessions)
|
||||
comics_plugin = comics.Plugin(app, database, sessions)
|
||||
library_plugin = library.Plugin(app, database, sessions)
|
||||
medien_plugin = medien.Plugin(app, database, sessions)
|
||||
tradingcards_plugin = tradingcards.Plugin(app, database, sessions)
|
||||
|
||||
bottle.run(app, host=server, port=port, debug=True, reloader=True)
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import bookDAO
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.books = bookDAO.BookDAO(database)
|
||||
self.routing()
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/library', 'GET', self.book_list)
|
||||
self.app.route('/library/book', 'GET', self.book_list)
|
||||
self.app.route('/library/book/<id>', 'GET', self.book_details)
|
||||
self.app.route('/library/book/create', 'GET', self.get_book_create)
|
||||
self.app.route('/library/book/create', 'POST', self.post_create_book)
|
||||
|
||||
def book_list(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
l = self.books.get_books()
|
||||
return bottle.template('book_list', dict(books=l, username=username))
|
||||
|
||||
def book_details(self, id):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
book = self.books.get_book(id)
|
||||
errors = ""
|
||||
if book == None:
|
||||
errors = "Entry not found"
|
||||
return bottle.template('book_template', dict(title=book['title'],
|
||||
id=book['_id'],
|
||||
current_order=book['current_order'],
|
||||
completed=book['completed'],
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
def get_book_create(self):
|
||||
cookie = bottle.rddequest.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template("book_template", dict(title="",
|
||||
id='newentry',
|
||||
current_order=False,
|
||||
completed=False,
|
||||
errors="",
|
||||
username=username))
|
||||
|
||||
def post_create_book(self):
|
||||
book_id = bottle.request.forms.get("id")
|
||||
book_title = bottle.request.forms.get("title")
|
||||
book_order = bottle.request.forms.get("current_order")
|
||||
book_completed = bottle.request.forms.get("completed")
|
||||
if book_id == "newentry":
|
||||
self.books.insert_entry(book_title, None, book_order, book_completed)
|
||||
else:
|
||||
self.comics.update_entry(book_id, book_title, None, book_order, book_completed)
|
||||
bottle.redirect("/comics/comic")
|
||||
@@ -1,56 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from bson.objectid import ObjectId
|
||||
import sys
|
||||
|
||||
class BookDAO:
|
||||
|
||||
# constructor for the class
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.books = database.books
|
||||
|
||||
def get_books(self):
|
||||
cursor = self.books.find()
|
||||
l = []
|
||||
for book in cursor:
|
||||
l.append(
|
||||
{'title':book['title'],
|
||||
'_id':book['_id'],
|
||||
'publisher':book['publisher'],
|
||||
'isbn':book['isbn'],
|
||||
'author':book['author']}
|
||||
)
|
||||
return l
|
||||
|
||||
def get_book(self, book_id):
|
||||
book = self.books.find_one({"_id": ObjectId(book_id)})
|
||||
return book
|
||||
|
||||
def insert_entry(self, book_title):
|
||||
print "inserting book entry", book_title
|
||||
|
||||
book = {"title": book_title}
|
||||
|
||||
# now insert the book
|
||||
try:
|
||||
result = self.books.insert_one(book)
|
||||
print "Matching book: ", result.matched_count
|
||||
print "Modified book: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting book"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
def update_entry(self, book_id, book_title):
|
||||
print "updating book entry", book_title
|
||||
|
||||
filter_doc = {"_id": ObjectId(book_id)}
|
||||
book = { "$set": {"name": book_title}}
|
||||
|
||||
# now insert the book
|
||||
try:
|
||||
result = self.books.update_one(filter_doc, book)
|
||||
print "Modified book: ", result.modified_count
|
||||
except:
|
||||
print "Error inserting book"
|
||||
print "Unexpected error:", sys.exc_info()
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.routing()
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/medien', 'GET', self.media_index)
|
||||
|
||||
def media_index(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template('media_index', dict(username=username))
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
# The session Data Access Object handles interactions with the sessions collection
|
||||
|
||||
class SessionDAO:
|
||||
|
||||
def __init__(self, database):
|
||||
self.db = database
|
||||
self.sessions = database.sessions
|
||||
|
||||
# will start a new session id by adding a new document to the sessions collection
|
||||
# returns the sessionID or None
|
||||
def start_session(self, username):
|
||||
|
||||
session_id = self.get_random_str(32)
|
||||
session = {'username': username, '_id': session_id}
|
||||
|
||||
try:
|
||||
self.sessions.insert_one(session)
|
||||
except:
|
||||
print "Unexpected error on start_session:", sys.exc_info()[0]
|
||||
return None
|
||||
|
||||
return str(session['_id'])
|
||||
|
||||
# will send a new user session by deleting from sessions table
|
||||
def end_session(self, session_id):
|
||||
|
||||
if session_id is None:
|
||||
return
|
||||
|
||||
self.sessions.delete_one({'_id': session_id})
|
||||
|
||||
return
|
||||
|
||||
# if there is a valid session, it is returned
|
||||
def get_session(self, session_id):
|
||||
|
||||
if session_id is None:
|
||||
return None
|
||||
|
||||
session = self.sessions.find_one({'_id': session_id})
|
||||
|
||||
return session
|
||||
|
||||
# get the username of the current session, or None if the session is not valid
|
||||
def get_username(self, session_id):
|
||||
|
||||
session = self.get_session(session_id)
|
||||
if session is None:
|
||||
return None
|
||||
else:
|
||||
return session['username']
|
||||
|
||||
def get_random_str(self, num_chars):
|
||||
random_string = ""
|
||||
for i in range(num_chars):
|
||||
random_string = random_string + random.choice(string.ascii_letters)
|
||||
return random_string
|
||||
@@ -1,11 +0,0 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='kontor-bottle',
|
||||
packages=['comics', 'homeoffice', 'library', 'medien'],
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'bottle',
|
||||
'pymongo'
|
||||
],
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
import pymongo
|
||||
import bottle
|
||||
import cgi
|
||||
|
||||
|
||||
__author__ = 'tpeetz'
|
||||
|
||||
|
||||
class Plugin:
|
||||
|
||||
def __init__(self, app, database, sessions):
|
||||
self.app = app
|
||||
self.db = database
|
||||
self.sessions = sessions
|
||||
self.routing()
|
||||
|
||||
def routing(self):
|
||||
self.app.route('/tradingcards', 'GET', self.tradingcards_index)
|
||||
|
||||
def tradingcards_index(self):
|
||||
cookie = bottle.request.get_cookie("session")
|
||||
username = self.sessions.get_username(cookie)
|
||||
return bottle.template('tradingcards_index', dict(username=username))
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import hmac
|
||||
import random
|
||||
import string
|
||||
import hashlib
|
||||
import pymongo
|
||||
|
||||
|
||||
# The User Data Access Object handles all interactions with the User collection.
|
||||
class UserDAO:
|
||||
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
self.users = self.db.users
|
||||
self.SECRET = 'verysecret'
|
||||
|
||||
# makes a little salt
|
||||
def make_salt(self):
|
||||
salt = ""
|
||||
for i in range(5):
|
||||
salt = salt + random.choice(string.ascii_letters)
|
||||
return salt
|
||||
|
||||
# implement the function make_pw_hash(name, pw) that returns a hashed password
|
||||
# of the format:
|
||||
# HASH(pw + salt),salt
|
||||
# use sha256
|
||||
|
||||
def make_pw_hash(self, pw,salt=None):
|
||||
if salt == None:
|
||||
salt = self.make_salt();
|
||||
return hashlib.sha256(pw + salt).hexdigest()+","+ salt
|
||||
|
||||
# Validates a user login. Returns user record or None
|
||||
def validate_login(self, username, password):
|
||||
|
||||
user = None
|
||||
try:
|
||||
user = self.users.find_one({'_id': username})
|
||||
except:
|
||||
print "Unable to query database for user"
|
||||
|
||||
if user is None:
|
||||
print "User not in database"
|
||||
return None
|
||||
|
||||
salt = user['password'].split(',')[1]
|
||||
|
||||
if user['password'] != self.make_pw_hash(password, salt):
|
||||
print "user password is not a match"
|
||||
return None
|
||||
|
||||
# Looks good
|
||||
return user
|
||||
|
||||
|
||||
# creates a new user in the users collection
|
||||
def add_user(self, username, password, email):
|
||||
password_hash = self.make_pw_hash(password)
|
||||
|
||||
user = {'_id': username, 'password': password_hash}
|
||||
if email != "":
|
||||
user['email'] = email
|
||||
|
||||
try:
|
||||
self.users.insert_one(user)
|
||||
except pymongo.errors.OperationFailure:
|
||||
print "oops, mongo error"
|
||||
return False
|
||||
except pymongo.errors.DuplicateKeyError as e:
|
||||
print "oops, username is already taken"
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for artist in artists:
|
||||
<li><a href="/comics/artist/{{artist['_id']}}">{{artist['name']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/artist/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="name" size="60" value="{{name}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<table border="1">
|
||||
<tr><td>Title</td><td>Current Order</td><td>Completed</td></tr>
|
||||
<tr>
|
||||
%for book in books:
|
||||
<td><a href="/library/book/{{book['_id']}}">{{book['title']}}</a></td>
|
||||
<td>{{book['current_order']}}</td>
|
||||
<td>{{book['completed']}}</td>
|
||||
%end
|
||||
</tr>
|
||||
</table>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,44 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<table border="1">
|
||||
<tr><td>Title</td><td>Current Order</td><td>Completed</td></tr>
|
||||
<tr>
|
||||
%for comic in comics:
|
||||
<td><a href="/comics/comic/{{comic['_id']}}">{{comic['title']}}</a></td>
|
||||
<td>{{comic['current_order']}}</td>
|
||||
<td>{{comic['completed']}}</td>
|
||||
%end
|
||||
</tr>
|
||||
</table>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,51 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/comic/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="title" size="60" value="{{title}}"><br>
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" name="current_order" size="60" value="{{current_order}}">
|
||||
Current Order
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="completed" size="60" value="{{completed}}">
|
||||
Completed
|
||||
</label>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/office">HomeOffice</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
</details>
|
||||
</main>
|
||||
%if (username == None):
|
||||
<footer><a href="/login">Login</a><p>Ingenieurbüro Thomas Peetz</p></footer>
|
||||
%end
|
||||
%if (username != None):
|
||||
<footer><a href="/logout">{{username}}</a><p>Ingenieurbüro Thomas Peetz</p></footer>
|
||||
%end
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,52 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form method="POST">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="label">Username</td>
|
||||
<td><input type="text" name="username" value="{{username}}"></td>
|
||||
<td class="error"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">Password</td>
|
||||
<td><input type="password" name="password" value=""></td>
|
||||
<td class="error">{{login_error}}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/office">HomeOffice</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<h2>Medien</h2>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/office">HomeOffice</a></li>
|
||||
<ul>
|
||||
<li><a href="/office/travel">Dienstreise</a></li>
|
||||
</ul>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<h2>HomeOffice</h2>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for publisher in publishers:
|
||||
<li><a href="/comics/publisher/{{publisher['_id']}}">{{publisher['name']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics/comic">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/publisher/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="name" size="60" value="{{name}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<h2>Signup</h2>
|
||||
<form method="post">
|
||||
<table>
|
||||
<tr><td class="label">Username</td>
|
||||
<td><input type="text" name="username" value="{{username}}"></td>
|
||||
<td class="error">{{username_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Password</td>
|
||||
<td><input type="password" name="password" value=""></td>
|
||||
<td class="error">{{password_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Verify Password</td>
|
||||
<td><input type="password" name="verify" value=""></td>
|
||||
<td class="error">{{verify_error}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Email (optional)</td>
|
||||
<td><input type="text" name="email" value="{{email}}"></td>
|
||||
<td class="error">{{email_error}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics/comic">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
<li><a href="/comics/storyarc">StoryArcs</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<ul>
|
||||
%for storyarc in storyarcs:
|
||||
<li><a href="/comics/storyarc/{{storyarc['_id']}}">{{storyarc['title']}}</a></li>
|
||||
%end
|
||||
</ul>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="/comics/artist">Artists</a></li>
|
||||
<li><a href="/comics/publisher">Publishers</a></li>
|
||||
<li><a href="/comics/storyarc">StoryArcs</a></li>
|
||||
</ul>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<form action="/comics/storyarc/create" method="POST">
|
||||
{{errors}}
|
||||
<h2>Title</h2>
|
||||
<input type="hidden" name="id", value="{{id}}">
|
||||
<input type="text" name="title" size="60" value="{{title}}"><br>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kontor</title>
|
||||
<link rel="stylesheet" href="/css/kontor.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Kontor</header>
|
||||
<nav><ul>
|
||||
<li><a href="/">Kontor</a></li>
|
||||
<li><a href="/office">HomeOffice</a></li>
|
||||
<li><a href="/comics">Comics</a></li>
|
||||
<li><a href="/library">Bücher</a></li>
|
||||
<li><a href="/medien">Medien</a></li>
|
||||
<li><a href="/tradingcards">Trading Cards</a></li>
|
||||
</ul></nav>
|
||||
<main role="main">
|
||||
<details>
|
||||
<h2>Trading Cards</h2>
|
||||
</details>
|
||||
</main>
|
||||
<footer>
|
||||
%if (username == None):
|
||||
<a href="/login">Login</a>
|
||||
%end
|
||||
%if (username != None):
|
||||
<a href="/logout">{{username}}</a>
|
||||
%end
|
||||
<p>Ingenieurbüro Thomas Peetz</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
bin/
|
||||
include/
|
||||
lib/
|
||||
lib64/
|
||||
lib64
|
||||
pip-selfcheck.json
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
*.pyc
|
||||
kontor/db.sqlite3
|
||||
.idea/
|
||||
=======
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
*.pyc
|
||||
>>>>>>> ignore compiled scripts
|
||||
Vendored
-13
@@ -1,13 +0,0 @@
|
||||
node {
|
||||
stage "Checkout"
|
||||
checkout scm
|
||||
stage "make migrations"
|
||||
sh "python kontor/manage.py makemigrations"
|
||||
stage "execute tests"
|
||||
<<<<<<< HEAD
|
||||
sh "python kontor/manage.py test comics library medien tradingcards homeoffice"
|
||||
=======
|
||||
sh "python kontor/manage.py test commics library medien tradingcards homeoffice"
|
||||
>>>>>>> add tests
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
# Kontor Django
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> add Comic models
|
||||
from .models import Publisher
|
||||
from .models import Artist
|
||||
from .models import Issue
|
||||
from .models import StoryArc
|
||||
from .models import Comic
|
||||
from .models import TradePaperback
|
||||
from .models import Volume
|
||||
|
||||
<<<<<<< HEAD
|
||||
# Register your models here.
|
||||
|
||||
|
||||
class IssueInline(admin.StackedInline):
|
||||
model = Issue
|
||||
extra = 1
|
||||
|
||||
|
||||
class IssueAdmin(admin.ModelAdmin):
|
||||
fields = ['comic', 'number', 'is_read', 'in_stock']
|
||||
|
||||
|
||||
class ComicAdmin(admin.ModelAdmin):
|
||||
fields = ['title', 'publisher', 'writer', 'current_order', 'completed']
|
||||
inlines = [IssueInline]
|
||||
|
||||
|
||||
class ComicInline(admin.StackedInline):
|
||||
model = Comic
|
||||
extra = 1
|
||||
|
||||
|
||||
class PublisherAdmin(admin.ModelAdmin):
|
||||
inlines = [ComicInline]
|
||||
|
||||
|
||||
admin.site.register(Publisher, PublisherAdmin)
|
||||
admin.site.register(Artist)
|
||||
admin.site.register(Issue, IssueAdmin)
|
||||
admin.site.register(Volume)
|
||||
admin.site.register(StoryArc)
|
||||
admin.site.register(Comic, ComicAdmin)
|
||||
admin.site.register(TradePaperback)
|
||||
=======
|
||||
# Register your models here.
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
# Register your models here.
|
||||
|
||||
|
||||
class IssueInline(admin.StackedInline):
|
||||
model = Issue
|
||||
extra = 1
|
||||
|
||||
|
||||
class IssueAdmin(admin.ModelAdmin):
|
||||
fields = ['comic', 'number', 'is_read', 'in_stock']
|
||||
|
||||
|
||||
class ComicAdmin(admin.ModelAdmin):
|
||||
fields = ['title', 'publisher', 'writer', 'artist', 'current_order', 'completed']
|
||||
inlines = [IssueInline]
|
||||
|
||||
|
||||
class ComicInline(admin.StackedInline):
|
||||
model = Comic
|
||||
extra = 1
|
||||
|
||||
|
||||
class PublisherAdmin(admin.ModelAdmin):
|
||||
inlines = [ComicInline]
|
||||
|
||||
|
||||
admin.site.register(Publisher, PublisherAdmin)
|
||||
admin.site.register(Artist)
|
||||
admin.site.register(Issue, IssueAdmin)
|
||||
admin.site.register(Volume)
|
||||
admin.site.register(StoryArc)
|
||||
admin.site.register(Comic, ComicAdmin)
|
||||
admin.site.register(TradePaperback)
|
||||
>>>>>>> add Comic models
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ComicsConfig(AppConfig):
|
||||
name = 'comics'
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,105 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
<<<<<<< HEAD
|
||||
# Generated by Django 1.9.6 on 2016-06-13 15:33
|
||||
=======
|
||||
# Generated by Django 1.9.5 on 2016-04-10 20:23
|
||||
>>>>>>> ignore compiled scripts
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Artist',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Comic',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=40)),
|
||||
('current_order', models.BooleanField()),
|
||||
('completed', models.BooleanField()),
|
||||
<<<<<<< HEAD
|
||||
('artist', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='artist', to='comics.Artist')),
|
||||
=======
|
||||
>>>>>>> ignore compiled scripts
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Issue',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('number', models.CharField(max_length=4)),
|
||||
('is_read', models.BooleanField(default=False)),
|
||||
('in_stock', models.BooleanField(default=False)),
|
||||
('comic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='comics.Comic')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Publisher',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='StoryArc',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('comic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='comics.Comic')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TradePaperback',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
('issue_start', models.IntegerField()),
|
||||
('issue_end', models.IntegerField()),
|
||||
('comic', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='comics.Comic')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Volume',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
('comic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='comics.Comic')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
<<<<<<< HEAD
|
||||
model_name='issue',
|
||||
name='volume',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='comics.Volume'),
|
||||
),
|
||||
migrations.AddField(
|
||||
=======
|
||||
>>>>>>> ignore compiled scripts
|
||||
model_name='comic',
|
||||
name='publisher',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='comics.Publisher'),
|
||||
),
|
||||
<<<<<<< HEAD
|
||||
migrations.AddField(
|
||||
model_name='comic',
|
||||
name='writer',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='writer', to='comics.Artist'),
|
||||
),
|
||||
=======
|
||||
>>>>>>> ignore compiled scripts
|
||||
]
|
||||
@@ -1,26 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-20 14:05
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('comics', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='comic',
|
||||
name='artist',
|
||||
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='artist', to='comics.Artist'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comic',
|
||||
name='writer',
|
||||
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='writer', to='comics.Artist'),
|
||||
),
|
||||
]
|
||||
@@ -1,26 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-20 14:10
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('comics', '0002_auto_20160620_1405'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='comic',
|
||||
name='artist',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='artist', to='comics.Artist'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comic',
|
||||
name='writer',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='writer', to='comics.Artist'),
|
||||
),
|
||||
]
|
||||
@@ -1,21 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-22 11:22
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('comics', '0003_auto_20160620_1410'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='issue',
|
||||
name='volume',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comics.Volume'),
|
||||
),
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-22 11:46
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('comics', '0004_auto_20160622_1122'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='comic',
|
||||
name='title',
|
||||
field=models.CharField(max_length=60),
|
||||
),
|
||||
]
|
||||
@@ -1,101 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
>>>>>>> add Comic models
|
||||
|
||||
|
||||
class Publisher(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Artist(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Comic(models.Model):
|
||||
<<<<<<< HEAD
|
||||
title = models.CharField(max_length=60)
|
||||
publisher = models.ForeignKey(Publisher)
|
||||
current_order = models.BooleanField()
|
||||
completed = models.BooleanField()
|
||||
writer = models.ForeignKey(Artist, blank=True, null=True, related_name='writer')
|
||||
artist = models.ForeignKey(Artist, blank=True, null=True, related_name='artist')
|
||||
=======
|
||||
title = models.CharField(max_length=40)
|
||||
publisher = models.ForeignKey(Publisher)
|
||||
current_order = models.BooleanField()
|
||||
completed = models.BooleanField()
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> add Comic models
|
||||
=======
|
||||
writer = models.ForeignKey(Artist, null=True, related_name='writer')
|
||||
artist = models.ForeignKey(Artist, null=True, related_name='artist')
|
||||
>>>>>>> backup
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class Volume(models.Model):
|
||||
name = models.CharField(max_length=40)
|
||||
comic = models.ForeignKey(Comic)
|
||||
|
||||
def __str__(self):
|
||||
return self.comic.title + ' ' + self.name
|
||||
|
||||
|
||||
class Issue(models.Model):
|
||||
number = models.CharField(max_length=4)
|
||||
is_read = models.BooleanField(default=False)
|
||||
in_stock = models.BooleanField(default=False)
|
||||
comic = models.ForeignKey(Comic, null=True)
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
volume = models.ForeignKey(Volume, blank=True, null=True)
|
||||
=======
|
||||
>>>>>>> add Comic models
|
||||
=======
|
||||
volume = models.ForeignKey(Volume, null=True)
|
||||
>>>>>>> backup
|
||||
|
||||
def __str__(self):
|
||||
return self.comic.title + ' #' + self.number
|
||||
|
||||
|
||||
class StoryArc(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
comic = models.ForeignKey(Comic, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class TradePaperback(models.Model):
|
||||
name = models.CharField(max_length=40)
|
||||
comic = models.ForeignKey(Comic, null=True)
|
||||
issue_start = models.IntegerField()
|
||||
issue_end = models.IntegerField()
|
||||
|
||||
def __str__(self):
|
||||
<<<<<<< HEAD
|
||||
return self.comic.title + ' TP ' + self.name
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
>>>>>>> add Comic models
|
||||
=======
|
||||
return self.comic.title + ' TP ' + self.name
|
||||
>>>>>>> backup
|
||||
@@ -1,6 +0,0 @@
|
||||
li a {
|
||||
color: green;
|
||||
}
|
||||
td a {
|
||||
color: green;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<<<<<<< HEAD
|
||||
{% extends "kontor/base.html" %}
|
||||
{% block title %}Comic Details{% endblock %}
|
||||
{% block content %}
|
||||
=======
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Comic Details</title>
|
||||
</head>
|
||||
<body>
|
||||
>>>>>>> backup
|
||||
<table>
|
||||
<thead><td>Name</td><td>current Order</td><td>completed</td></thead>
|
||||
<tr>
|
||||
<td>{{ comic.title }}</td>
|
||||
<td>{{ comic.current_order }}</td>
|
||||
<td>{{ comic.completed }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<<<<<<< HEAD
|
||||
{% endblock %}
|
||||
=======
|
||||
|
||||
</body>
|
||||
</html>
|
||||
>>>>>>> backup
|
||||
@@ -1,34 +0,0 @@
|
||||
<<<<<<< HEAD
|
||||
{% extends "kontor/base.html" %}
|
||||
{% block title %}Comic Overview{% endblock %}
|
||||
{% block content %}
|
||||
=======
|
||||
{% load staticfiles %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static 'comics/style.css' %}" />
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Comic Overview</title>
|
||||
</head>
|
||||
<body>
|
||||
>>>>>>> backup
|
||||
<table>
|
||||
<thead><td>Name</td><td>current Order</td><td>completed</td></thead>
|
||||
{% for comic in comic_list %}
|
||||
<tr>
|
||||
<td><a href="{% url 'comics:detail' comic.id %}">{{ comic.title }}</a></td>
|
||||
<td>{{ comic.current_order }}</td>
|
||||
<td>{{ comic.completed }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<<<<<<< HEAD
|
||||
{% endblock %}
|
||||
=======
|
||||
</body>
|
||||
</html>
|
||||
>>>>>>> backup
|
||||
@@ -1,8 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
class ComicsViewsTestCase(TestCase):
|
||||
def test_index(self):
|
||||
resp = self.client.get('/comics/')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
@@ -1,10 +0,0 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'comics'
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
|
||||
]
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<<<<<<< HEAD
|
||||
from django.shortcuts import render
|
||||
<<<<<<< HEAD
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.views import generic
|
||||
|
||||
from .models import Comic
|
||||
# Create your views here.
|
||||
|
||||
|
||||
class IndexView(generic.ListView):
|
||||
template_name = 'comics/index.html'
|
||||
context_object_name = 'comic_list'
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return the list of comics."""
|
||||
return Comic.objects.all()
|
||||
|
||||
|
||||
class DetailView(generic.DetailView):
|
||||
model = Comic
|
||||
template_name = 'comics/detail.html'
|
||||
=======
|
||||
=======
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.views import generic
|
||||
>>>>>>> backup
|
||||
|
||||
from .models import Comic
|
||||
# Create your views here.
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
|
||||
|
||||
class IndexView(generic.ListView):
|
||||
template_name = 'comics/index.html'
|
||||
context_object_name = 'comic_list'
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return the list of comics."""
|
||||
return Comic.objects.all()
|
||||
|
||||
|
||||
class DetailView(generic.DetailView):
|
||||
model = Comic
|
||||
template_name = 'comics/detail.html'
|
||||
>>>>>>> backup
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
# Register your models here.
|
||||
@@ -1,7 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class HomeOfficeConfig(AppConfig):
|
||||
name = 'homeoffice'
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-20 16:58
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Expense',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Travel',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,10 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
class Travel(models.Model):
|
||||
pass
|
||||
|
||||
class Expense(models.Model):
|
||||
pass
|
||||
@@ -1,2 +0,0 @@
|
||||
{% extends "kontor/base.html" %}
|
||||
{% block title %}HomeOffice{% endblock %}
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
# Create your tests here.
|
||||
@@ -1,8 +0,0 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'homeoffice'
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
]
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
def index(request):
|
||||
return render(request, 'homeoffice/index.html')
|
||||
@@ -1,166 +0,0 @@
|
||||
"""
|
||||
Django settings for kontor project.
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
Generated by 'django-admin startproject' using Django 1.9.6.
|
||||
=======
|
||||
Generated by 'django-admin startproject' using Django 1.9.5.
|
||||
>>>>>>> initial setup
|
||||
|
||||
=======
|
||||
>>>>>>> backup
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.6/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.6/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
SECRET_KEY = '8s-(!r%0yu)b(hdkes_v#g8kp7)0ma851j+&43cds#duk!s-_c'
|
||||
=======
|
||||
SECRET_KEY = 'c)&86w07k)091bgi1llt+aol5$8in8g=n#+iba4784cdw$#h)^'
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
SECRET_KEY = 'i5qx(%mex)4ovh#y4m94b1(3xiw4%8+rx-!kpw9v4q*@0v6pd2'
|
||||
>>>>>>> backup
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
TEMPLATE_DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
<<<<<<< HEAD
|
||||
INSTALLED_APPS = [
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
'comics.apps.ComicsConfig',
|
||||
'library.apps.LibraryConfig',
|
||||
'tysc.apps.TyscConfig',
|
||||
'tradingcards.apps.TradingCardsConfig',
|
||||
'homeoffice.apps.HomeOfficeConfig',
|
||||
'medien.apps.MedienConfig',
|
||||
=======
|
||||
>>>>>>> initial setup
|
||||
=======
|
||||
'comics.apps.ComicsConfig',
|
||||
>>>>>>> add admin site for Comics
|
||||
=======
|
||||
INSTALLED_APPS = (
|
||||
'comics.apps.ComicsConfig',
|
||||
'tysc.apps.TyscConfig',
|
||||
'library.apps.LibraryConfig',
|
||||
>>>>>>> backup
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'kontor.urls'
|
||||
|
||||
<<<<<<< HEAD
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
<<<<<<< HEAD
|
||||
'DIRS': [os.path.join(BASE_DIR, 'templates')],
|
||||
=======
|
||||
'DIRS': [],
|
||||
>>>>>>> initial setup
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
<<<<<<< HEAD
|
||||
'django.template.context_processors.i18n',
|
||||
'django.template.context_processors.media',
|
||||
'django.template.context_processors.static',
|
||||
'django.template.context_processors.tz',
|
||||
=======
|
||||
>>>>>>> initial setup
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
=======
|
||||
>>>>>>> backup
|
||||
WSGI_APPLICATION = 'kontor.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
# 'ENGINE': 'django.db.backends.dummy',
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
}
|
||||
}
|
||||
|
||||
#from mongoengine import connect
|
||||
#connect('kontor')
|
||||
|
||||
#SESSION_ENGINE = 'mongoengine.django.sessions'
|
||||
#SESSION_SERIALIZER = 'mongoengine.django.sessions.BSONSerializer'
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/1.6/topics/i18n/
|
||||
|
||||
<<<<<<< HEAD
|
||||
LANGUAGE_CODE = 'de-de'
|
||||
=======
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
>>>>>>> initial setup
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.6/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
<<<<<<< HEAD
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, "static"),
|
||||
]
|
||||
=======
|
||||
>>>>>>> initial setup
|
||||
@@ -1,61 +0,0 @@
|
||||
from django.conf.urls import patterns, include, url
|
||||
|
||||
<<<<<<< HEAD
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/1.9/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.conf.urls import url, include
|
||||
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
|
||||
"""
|
||||
<<<<<<< HEAD
|
||||
from django.conf.urls import url, include
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import views as auth_views
|
||||
|
||||
from . import views
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = [
|
||||
#url(r'^admin/', admin.site.urls),
|
||||
url('^', include('django.contrib.auth.urls')),
|
||||
url(r'^$', views.index, name='index'),
|
||||
#url(r'^accounts/login/$', auth_views.login),
|
||||
url(r'^accounts/login/$', auth_views.login, {'template_name': 'kontor/login.html'}),
|
||||
url(r'^accounts/logout/$', auth_views.logout ),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^comics/', include('comics.urls')),
|
||||
url(r'^office/', include('homeoffice.urls')),
|
||||
url(r'^tradingcards/', include('tradingcards.urls')),
|
||||
url(r'^tysc/', include('tysc.urls')),
|
||||
url(r'^library/', include('library.urls')),
|
||||
url(r'^medien/', include('medien.urls')),
|
||||
=======
|
||||
from django.conf.urls import url
|
||||
=======
|
||||
>>>>>>> backup
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
<<<<<<< HEAD
|
||||
urlpatterns = [
|
||||
url(r'^admin/', admin.site.urls),
|
||||
>>>>>>> initial setup
|
||||
]
|
||||
=======
|
||||
urlpatterns = patterns('',
|
||||
# Examples:
|
||||
#url(r'^$', 'kontor.views.home', name='home'),
|
||||
# url(r'^blog/', include('blog.urls')),
|
||||
url(r'^comics/', include('comics.urls')),
|
||||
url(r'^tysc/', include('tysc.urls')),
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
>>>>>>> backup
|
||||
@@ -1,14 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
def index(request):
|
||||
<<<<<<< HEAD
|
||||
return render(request, 'kontor/index.html')
|
||||
=======
|
||||
return HttpResponse('You are in the Kontor application')
|
||||
>>>>>>> backup
|
||||
|
||||
|
||||
def home(request):
|
||||
return HttpResponse('You are in the Kontor application')
|
||||
@@ -1,14 +0,0 @@
|
||||
"""
|
||||
WSGI config for kontor project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kontor.settings")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
@@ -1,20 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Author
|
||||
from .models import Book
|
||||
<<<<<<< HEAD
|
||||
from .models import Category
|
||||
from .models import Edition
|
||||
from .models import Publisher
|
||||
=======
|
||||
>>>>>>> backup
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Author)
|
||||
admin.site.register(Book)
|
||||
<<<<<<< HEAD
|
||||
admin.site.register(Category)
|
||||
admin.site.register(Edition)
|
||||
admin.site.register(Publisher)
|
||||
=======
|
||||
>>>>>>> backup
|
||||
@@ -1,7 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LibraryConfig(AppConfig):
|
||||
name = 'library'
|
||||
@@ -1,473 +0,0 @@
|
||||
- model: library.author
|
||||
pk: 1
|
||||
fields: {name: Terry Pratchett}
|
||||
- model: library.author
|
||||
pk: 2
|
||||
fields: {name: Colin Forbes}
|
||||
- model: library.author
|
||||
pk: 3
|
||||
fields: {name: Markus Heitz}
|
||||
- model: library.author
|
||||
pk: 4
|
||||
fields: {name: Ralf Kuehnel}
|
||||
- model: library.author
|
||||
pk: 5
|
||||
fields: {name: Richard Murch}
|
||||
- model: library.author
|
||||
pk: 6
|
||||
fields: {name: Gunter Saake}
|
||||
- model: library.author
|
||||
pk: 7
|
||||
fields: {name: Kai-Uwe Sattler}
|
||||
- model: library.author
|
||||
pk: 8
|
||||
fields: {name: Joerg Thadeusz}
|
||||
- model: library.author
|
||||
pk: 9
|
||||
fields: {name: Stephan Burgdorff}
|
||||
- model: library.author
|
||||
pk: 10
|
||||
fields: {name: Christian Habbe}
|
||||
- model: library.author
|
||||
pk: 11
|
||||
fields: {name: Stephen Kenson}
|
||||
- model: library.author
|
||||
pk: 12
|
||||
fields: {name: Martin Fowler}
|
||||
- model: library.author
|
||||
pk: 13
|
||||
fields: {name: Ramnivas Laddad}
|
||||
- model: library.author
|
||||
pk: 14
|
||||
fields: {name: Thomas Gifford}
|
||||
- model: library.author
|
||||
pk: 15
|
||||
fields: {name: Rene Goscinny}
|
||||
- model: library.author
|
||||
pk: 16
|
||||
fields: {name: Albert Uderzo}
|
||||
- model: library.author
|
||||
pk: 17
|
||||
fields: {name: Mel Odem}
|
||||
- model: library.author
|
||||
pk: 18
|
||||
fields: {name: Harri Assmann}
|
||||
- model: library.author
|
||||
pk: 19
|
||||
fields: {name: Harald Schmidt}
|
||||
- model: library.author
|
||||
pk: 20
|
||||
fields: {name: Bruce Tate}
|
||||
- model: library.author
|
||||
pk: 21
|
||||
fields: {name: Mike Clark}
|
||||
- model: library.author
|
||||
pk: 22
|
||||
fields: {name: Bob Lee}
|
||||
- model: library.author
|
||||
pk: 23
|
||||
fields: {name: Patrick Linskey}
|
||||
- model: library.author
|
||||
pk: 24
|
||||
fields: {name: Jim Knipfel}
|
||||
- model: library.author
|
||||
pk: 25
|
||||
fields: {name: Carl Sargent}
|
||||
- model: library.author
|
||||
pk: 26
|
||||
fields: {name: Beate Sauer}
|
||||
- model: library.author
|
||||
pk: 27
|
||||
fields: {name: Kent Beck}
|
||||
- model: library.author
|
||||
pk: 28
|
||||
fields: {name: Erich Gamma}
|
||||
- model: library.author
|
||||
pk: 29
|
||||
fields: {name: Ilko-Sascha Kowalczuk}
|
||||
- model: library.author
|
||||
pk: 30
|
||||
fields: {name: Dalai Lama}
|
||||
- model: library.author
|
||||
pk: 31
|
||||
fields: {name: Horst Saecker}
|
||||
- model: library.author
|
||||
pk: 32
|
||||
fields: {name: Romain Sardou}
|
||||
- model: library.author
|
||||
pk: 33
|
||||
fields: {name: Berthold Daum}
|
||||
- model: library.author
|
||||
pk: 34
|
||||
fields: {name: Javier Sierra}
|
||||
- model: library.author
|
||||
pk: 35
|
||||
fields: {name: Dieter Hesselberger}
|
||||
- model: library.author
|
||||
pk: 36
|
||||
fields: {name: Anette Baecker}
|
||||
- model: library.author
|
||||
pk: 37
|
||||
fields: {name: Paul Baecker}
|
||||
- model: library.author
|
||||
pk: 38
|
||||
fields: {name: Lisa Smedmann}
|
||||
- model: library.author
|
||||
pk: 39
|
||||
fields: {name: Michael Cordy}
|
||||
- model: library.author
|
||||
pk: 40
|
||||
fields: {name: Stephen Fry}
|
||||
- model: library.author
|
||||
pk: 41
|
||||
fields: {name: Jonathan Bond}
|
||||
- model: library.author
|
||||
pk: 42
|
||||
fields: {name: Vince Flynn}
|
||||
- model: library.author
|
||||
pk: 43
|
||||
fields: {name: Eric-Emmanuel Schmitt}
|
||||
- model: library.author
|
||||
pk: 44
|
||||
fields: {name: Jak Koke}
|
||||
- model: library.author
|
||||
pk: 45
|
||||
fields: {name: Nigel Findley}
|
||||
- model: library.author
|
||||
pk: 46
|
||||
fields: {name: Edgar Noske}
|
||||
- model: library.author
|
||||
pk: 47
|
||||
fields: {name: Hannes Wertheim}
|
||||
- model: library.author
|
||||
pk: 48
|
||||
fields: {name: Frank Schaetzing}
|
||||
- model: library.author
|
||||
pk: 49
|
||||
fields: {name: Frank Pilz}
|
||||
- model: library.author
|
||||
pk: 50
|
||||
fields: {name: Frederick Forsyth}
|
||||
- model: library.author
|
||||
pk: 51
|
||||
fields: {name: Chris Kubasik}
|
||||
- model: library.author
|
||||
pk: 52
|
||||
fields: {name: Jordan K. Weisman}
|
||||
- model: library.author
|
||||
pk: 53
|
||||
fields: {name: Hans Georg Lehmann}
|
||||
- model: library.author
|
||||
pk: 54
|
||||
fields: {name: Nyx Smith}
|
||||
- model: library.author
|
||||
pk: 55
|
||||
fields: {name: Ferdinand Seibt}
|
||||
- model: library.author
|
||||
pk: 56
|
||||
fields: {name: Christopher Moore}
|
||||
- model: library.author
|
||||
pk: 57
|
||||
fields: {name: Jens Gieseke}
|
||||
- model: library.author
|
||||
pk: 58
|
||||
fields: {name: Bernd Lindner}
|
||||
- model: library.author
|
||||
pk: 59
|
||||
fields: {name: Horst Poetzsch}
|
||||
- model: library.author
|
||||
pk: 60
|
||||
fields: {name: Caroline Spector}
|
||||
- model: library.author
|
||||
pk: 61
|
||||
fields: {name: Peter Godman}
|
||||
- model: library.author
|
||||
pk: 62
|
||||
fields: {name: Hans Joachim Alpers}
|
||||
- model: library.author
|
||||
pk: 63
|
||||
fields: {name: Bernhard Schlink}
|
||||
- model: library.author
|
||||
pk: 64
|
||||
fields: {name: Rebecca Gable}
|
||||
- model: library.author
|
||||
pk: 65
|
||||
fields: {name: Douglas Adams}
|
||||
- model: library.author
|
||||
pk: 66
|
||||
fields: {name: Susan Cooper}
|
||||
- model: library.author
|
||||
pk: 67
|
||||
fields: {name: Donna W. Cross}
|
||||
- model: library.author
|
||||
pk: 68
|
||||
fields: {name: Peter Prange}
|
||||
- model: library.author
|
||||
pk: 69
|
||||
fields: {name: Tanja Kinkel}
|
||||
- model: library.author
|
||||
pk: 70
|
||||
fields: {name: Ken Follett}
|
||||
- model: library.author
|
||||
pk: 71
|
||||
fields: {name: Minette Walters}
|
||||
- model: library.author
|
||||
pk: 72
|
||||
fields: {name: Peter Tremayne}
|
||||
- model: library.author
|
||||
pk: 73
|
||||
fields: {name: Marion Zimmer Bradley}
|
||||
- model: library.author
|
||||
pk: 74
|
||||
fields: {name: Wolfgang Hohlbein}
|
||||
- model: library.author
|
||||
pk: 75
|
||||
fields: {name: Friedrich Wilhelm Graf}
|
||||
- model: library.author
|
||||
pk: 76
|
||||
fields: {name: Nyx Smith}
|
||||
- model: library.author
|
||||
pk: 78
|
||||
fields: {name: Ferdinand Seibt}
|
||||
- model: library.author
|
||||
pk: 79
|
||||
fields: {name: Christopher Moore}
|
||||
- model: library.author
|
||||
pk: 80
|
||||
fields: {name: Jens Gieseke}
|
||||
- model: library.author
|
||||
pk: 81
|
||||
fields: {name: Bernd Lindner}
|
||||
- model: library.author
|
||||
pk: 82
|
||||
fields: {name: Horst Poetzsch}
|
||||
- model: library.author
|
||||
pk: 84
|
||||
fields: {name: Caroline Spector}
|
||||
- model: library.author
|
||||
pk: 85
|
||||
fields: {name: Peter Godman}
|
||||
- model: library.author
|
||||
pk: 86
|
||||
fields: {name: Hans Joachim Alpers}
|
||||
- model: library.author
|
||||
pk: 87
|
||||
fields: {name: Bernhard Schlink}
|
||||
- model: library.author
|
||||
pk: 89
|
||||
fields: {name: Rebecca Gable}
|
||||
- model: library.author
|
||||
pk: 90
|
||||
fields: {name: Douglas Adams}
|
||||
- model: library.author
|
||||
pk: 91
|
||||
fields: {name: Susan Cooper}
|
||||
- model: library.author
|
||||
pk: 93
|
||||
fields: {name: Donna W. Cross}
|
||||
- model: library.author
|
||||
pk: 94
|
||||
fields: {name: Peter Prange}
|
||||
- model: library.author
|
||||
pk: 95
|
||||
fields: {name: Tanja Kinkel}
|
||||
- model: library.author
|
||||
pk: 96
|
||||
fields: {name: Ken Follett}
|
||||
- model: library.author
|
||||
pk: 97
|
||||
fields: {name: Minette Walters}
|
||||
- model: library.author
|
||||
pk: 99
|
||||
fields: {name: Peter Tremayne}
|
||||
- model: library.author
|
||||
pk: 101
|
||||
fields: {name: Marion Zimmer Bradley}
|
||||
- model: library.author
|
||||
pk: 102
|
||||
fields: {name: Wolfgang Hohlbein}
|
||||
- model: library.author
|
||||
pk: 103
|
||||
fields: {name: Friedrich Wilhelm Graf}
|
||||
- model: library.author
|
||||
pk: 104
|
||||
fields: {name: Terry Pratchett}
|
||||
- model: library.author
|
||||
pk: 105
|
||||
fields: {name: Daniel Suarez}
|
||||
- model: library.category
|
||||
pk: 1
|
||||
fields: {name: Science Fiction}
|
||||
- model: library.category
|
||||
pk: 2
|
||||
fields: {name: Roman}
|
||||
- model: library.category
|
||||
pk: 3
|
||||
fields: {name: Reference}
|
||||
- model: library.category
|
||||
pk: 4
|
||||
fields: {name: Fantasy}
|
||||
- model: library.category
|
||||
pk: 5
|
||||
fields: {name: Comics}
|
||||
- model: library.category
|
||||
pk: 6
|
||||
fields: {name: Satire}
|
||||
- model: library.category
|
||||
pk: 7
|
||||
fields: {name: Thriller}
|
||||
- model: library.edition
|
||||
pk: 1
|
||||
fields: {name: Paperback}
|
||||
- model: library.edition
|
||||
pk: 2
|
||||
fields: {name: Hardcover}
|
||||
- model: library.edition
|
||||
pk: 3
|
||||
fields: {name: Softcover}
|
||||
- model: library.publisher
|
||||
pk: 1
|
||||
fields: {name: Addison-Wesley Verlag}
|
||||
- model: library.publisher
|
||||
pk: 2
|
||||
fields: {name: O'Reilly Media}
|
||||
- model: library.publisher
|
||||
pk: 3
|
||||
fields: {name: O'Reilly & Associates}
|
||||
- model: library.publisher
|
||||
pk: 4
|
||||
fields: {name: Klett-Cotta}
|
||||
- model: library.publisher
|
||||
pk: 5
|
||||
fields: {name: Diogenes}
|
||||
- model: library.publisher
|
||||
pk: 6
|
||||
fields: {name: Jaron Verlag}
|
||||
- model: library.publisher
|
||||
pk: 7
|
||||
fields: {name: Merkur Verlag Rinteln}
|
||||
- model: library.publisher
|
||||
pk: 8
|
||||
fields: {name: Ehapa Verlag}
|
||||
- model: library.publisher
|
||||
pk: 9
|
||||
fields: {name: Markt+Technik Verlag}
|
||||
- model: library.publisher
|
||||
pk: 10
|
||||
fields: {name: Kiepenheuer & Witsch}
|
||||
- model: library.publisher
|
||||
pk: 11
|
||||
fields: {name: Goldmann Verlag}
|
||||
- model: library.publisher
|
||||
pk: 12
|
||||
fields: {name: Sams Publishing}
|
||||
- model: library.publisher
|
||||
pk: 13
|
||||
fields: {name: Wilhelm Heyne Verlag}
|
||||
- model: library.publisher
|
||||
pk: 14
|
||||
fields: {name: Amman Verlag & Co.}
|
||||
- model: library.publisher
|
||||
pk: 15
|
||||
fields: {name: Fischer Verlag}
|
||||
- model: library.publisher
|
||||
pk: 16
|
||||
fields: {name: BestBook}
|
||||
- model: library.publisher
|
||||
pk: 17
|
||||
fields: {name: List Verlag}
|
||||
- model: library.publisher
|
||||
pk: 18
|
||||
fields: {name: dpunkt.verlag GmbH}
|
||||
- model: library.publisher
|
||||
pk: 19
|
||||
fields: {name: Ullstein Verlag}
|
||||
- model: library.publisher
|
||||
pk: 20
|
||||
fields: {name: Piper Verlag}
|
||||
- model: library.publisher
|
||||
pk: 21
|
||||
fields: {name: Knaur Verlag}
|
||||
- model: library.publisher
|
||||
pk: 22
|
||||
fields: {name: Heyne Fantasy}
|
||||
- model: library.publisher
|
||||
pk: 23
|
||||
fields: {name: Manning Publications Co.}
|
||||
- model: library.publisher
|
||||
pk: 24
|
||||
fields: {name: ADAC Verlag}
|
||||
- model: library.publisher
|
||||
pk: 25
|
||||
fields: {name: dpunkt-Verlag}
|
||||
- model: library.publisher
|
||||
pk: 26
|
||||
fields: {name: Verlag Kiepenheuer & Witsch}
|
||||
- model: library.publisher
|
||||
pk: 27
|
||||
fields: {name: Hanser Wirtschaft}
|
||||
- model: library.publisher
|
||||
pk: 28
|
||||
fields: {name: Droemersche Verlagsanstalt}
|
||||
- model: library.publisher
|
||||
pk: 29
|
||||
fields: {name: Fischer Buecherei GmbH}
|
||||
- model: library.publisher
|
||||
pk: 30
|
||||
fields: {name: rororo Verlag}
|
||||
- model: library.publisher
|
||||
pk: 31
|
||||
fields: {name: Hoffmann und Campe}
|
||||
- model: library.publisher
|
||||
pk: 32
|
||||
fields: {name: Heyne Verlag}
|
||||
- model: library.publisher
|
||||
pk: 33
|
||||
fields: {name: dpunkt.verlag}
|
||||
- model: library.publisher
|
||||
pk: 34
|
||||
fields: {name: Dorling Kindersley}
|
||||
- model: library.publisher
|
||||
pk: 35
|
||||
fields: {name: Ammann Verlag}
|
||||
- model: library.publisher
|
||||
pk: 36
|
||||
fields: {name: Addison-Wesley}
|
||||
- model: library.publisher
|
||||
pk: 37
|
||||
fields: {name: Ueberreuter}
|
||||
- model: library.publisher
|
||||
pk: 38
|
||||
fields: {name: Bertelsmann Club}
|
||||
- model: library.publisher
|
||||
pk: 39
|
||||
fields: {name: Harriet Eder Verlag}
|
||||
- model: library.publisher
|
||||
pk: 40
|
||||
fields: {name: Marix Verlag}
|
||||
- model: library.publisher
|
||||
pk: 41
|
||||
fields: {name: Aufbau Taschenbuch Verlag}
|
||||
- model: library.publisher
|
||||
pk: 42
|
||||
fields: {name: Rowohlt Taschenbuch Verlag}
|
||||
- model: library.book
|
||||
pk: 1
|
||||
fields:
|
||||
title: 2XS
|
||||
publisher: null
|
||||
isbn: ''
|
||||
edition: 1
|
||||
pages: null
|
||||
category: 1
|
||||
authors: [58]
|
||||
- model: library.book
|
||||
pk: 2
|
||||
fields:
|
||||
title: Daemon
|
||||
publisher: 42
|
||||
isbn: 978 3 499 25643 1
|
||||
edition: 1
|
||||
pages: 639
|
||||
category: 7
|
||||
authors: [105]
|
||||
@@ -1,34 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
<<<<<<< HEAD
|
||||
# Generated by Django 1.9.6 on 2016-05-31 08:57
|
||||
=======
|
||||
# Generated by Django 1.9.2 on 2016-02-16 19:01
|
||||
>>>>>>> backup
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Author',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Book',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=40)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,67 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-24 12:30
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Category',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Edition',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Publisher',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=40)),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='authors',
|
||||
field=models.ManyToManyField(blank=True, to='library.Author'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='isbn',
|
||||
field=models.CharField(max_length=20, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='pages',
|
||||
field=models.IntegerField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='category',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='library.Category'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='edition',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='library.Edition'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='book',
|
||||
name='publisher',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='library.Publisher'),
|
||||
),
|
||||
]
|
||||
@@ -1,25 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.6 on 2016-06-24 12:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('library', '0002_auto_20160624_1230'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='book',
|
||||
name='isbn',
|
||||
field=models.CharField(blank=True, max_length=20, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='book',
|
||||
name='pages',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user