示例#1
0
def npc_visibility(npcid: int, campaignid: int):
    if not current_user.is_authenticated:
        abort(403)

    npc = NPC.query.get(npcid)
    if npc is None:
        abort(404)

    if npc.campaign.id != campaignid:
        abort(404)

    if current_user.profile != npc.campaign.user:
        abort(403)

    if request.method == 'POST':
        data = request.get_json()
        assert data is not None
        logger.debug(data)
        if data['visibility']:
            logger.debug(f"Showing NPC {npc.character.title}")
            npc.visible = True
        else:
            logger.debug(f"Hiding NPC {npc.character.title}")
            npc.visible = False

        session.commit()

        logger.debug(data)

    response = {
        'npc': npcid,
        'campaign': campaignid,
        'visibility': npc.visible
    }
    return jsonify(response)
示例#2
0
def delete_folder(id=None):
    deletefolderform = DeleteAssetFolderForm(prefix="deletefolderform")
    folder = AssetFolder.query.get(id)

    if not folder.owner == current_user.profile:
        logger.debug("Not deleting folder for other person")
        abort(403)

    if folder.parent is None:
        logger.debug("Can't delete top folder")
        abort(403)

    if deletefolderform.validate_on_submit():
        logger.debug("Delete an empty folder")
        parent_id = folder.parent.id

        if str(folder.id) != deletefolderform.id.data:
            logger.debug(f"Wrong ids specified {folder.id} "
                         f"and {deletefolderform.id.data}")
            abort(403)

        if folder.files:
            logger.debug("Folder contains files")
            abort(403)

        session.delete(folder)
        session.commit()
        return redirect(url_for('userassets.index', folder_id=parent_id))

    return redirect(url_for('userassets.index', folder_id=id))
示例#3
0
def editjson(id: int):
    """Lets the user edit the raw json of the character."""
    c = get_character(id, check_author=True)
    form = ImportForm(obj=c)

    if form.validate_on_submit():
        assert form.body.data is not None
        c.title = form.title.data
        c.body = form.body.data

        if form.migration.data:
            logger.debug("Trying to migrate data")
            data = form.body.data
            c.body = migrate(data, latest, migrations=migrations)
        elif form.conversion.data:
            logger.debug("Conversion is checked")
            data = form.body.data
            c.body = convert_from_dholes(data)

        logentry = LogEntry(c, "JSON edited", user_id=current_user.id)
        session.add(logentry)

        session.commit()
        return redirect(url_for('character.view', id=c.id))

    form.submit.label.text = 'Save'

    validation_errors = c.validate()

    return render_template('character/import.html.jinja',
                           title="Edit JSON",
                           validation_errors=validation_errors,
                           form=form,
                           type=None)
示例#4
0
def update(id: int):
    character = get_character(id, check_author=True)

    if request.method == "POST":
        update = request.get_json()
        assert update is not None
        for setting in update:
            character.set_attribute(setting)
            field = setting['field']
            subfield = setting.get('subfield', '')
            value = setting['value']
            type = setting.get('type', 'value')
            if type == 'portrait' and value is not None:
                value = "[image]"

            log_subfield = ''
            if subfield is not None and subfield != 'None':
                log_subfield = ' ' + subfield
            log_message = (f"set {type} on {field}{log_subfield}: {value}")

            logentry = LogEntry(character,
                                log_message,
                                user_id=current_user.id)
            session.add(logentry)

        character.store_data()
        session.commit()

    return "OK"
示例#5
0
def api_invite_delete(id):
    invite = Invite.query.get(id)
    if current_user.profile.id != invite.owner_id:
        abort(403)
    session.delete(invite)
    session.commit()

    return jsonify({'html': 'Deleted'})
示例#6
0
def create():
    form = CreateForm()
    if form.validate_on_submit():
        c = Campaign(title=form.title.data, user_id=current_user.profile.id)
        session.add(c)
        session.commit()
        return redirect(url_for('campaign.view', id=c.id))
    return render_template('campaign/create.html.jinja', form=form)
示例#7
0
def folder(id: int):
    c = get_character(id, check_author=True)
    form = ChooseFolderForm()
    if form.validate_on_submit():
        c.folder = form.folder_id.data  # type: ignore
        session.commit()

    return render_template('character/move_to_folder.html.jinja',
                           form=form,
                           character=c)
示例#8
0
def create_folder(folder_id=None):
    folderform = NewFolderForm(prefix="newfolderform")
    if folderform.validate_on_submit():
        logger.debug("Create a new folder")
        folder = AssetFolder(parent_id=folderform.parent_id.data,
                             title=folderform.title.data,
                             owner=current_user.profile)
        session.add(folder)
        session.commit()
    return redirect(url_for('userassets.index', folder_id=folder_id))
示例#9
0
def delete(fileid, filename):
    logger.debug("Delete asset")
    asset = Asset.query.get(fileid)
    form = DeleteAssetForm(prefix="deleteasset")
    if form.validate_on_submit():
        if asset.owner != current_user.profile:
            abort(403)
        flash("You just deleted an asset")
        session.delete(asset)
        session.commit()

    return redirect(url_for('userassets.index', folder_id=asset.folder_id))
示例#10
0
def folders(folder_id=None):
    new_folder_form = NewFolderForm(prefix='new_folder')

    if new_folder_form.validate_on_submit():
        print("From validated, add folder")
        folder = Folder()
        new_folder_form.populate_obj(folder)
        session.add(folder)
        session.commit()
        return redirect('/content')
    else:
        print("Form did not validate")
        # return redirect(request.url)

    new_folder_form.owner_id.data = current_user.profile.id
    new_folder_form.parent_id.data = folder_id

    current_folder = Folder.query.get(folder_id)

    folders = None
    characters = None
    campaigns = None
    tree = []

    if current_folder is None:
        folders = current_user.profile.folders.filter(
            Folder.parent_id.__eq__(None))
        characters = current_user.profile.characters.filter(
            Character.folder_id.__eq__(None))
        campaigns = current_user.profile.campaigns.filter(
            campaignmodels.Campaign.folder_id.__eq__(None))

    else:
        folders = current_folder.subfolders
        characters = current_folder.characters
        campaigns = current_folder.campaigns
        f = current_folder
        while f.parent:
            tree.append(f.parent)
            f = f.parent
            tree.reverse()

    data = {
        'current_folder': current_folder,
        'tree': tree,
        'folders': folders,
        'characters': characters,
        'campaigns': campaigns
    }
    return render_template('content/folders.html.jinja',
                           new_folder_form=new_folder_form,
                           data=data)
示例#11
0
def reset_password(token: str):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    user = User.verify_reset_password_token(token)
    form = ResetPasswordForm()
    if form.validate_on_submit():
        if user is not None:
            user.set_password(form.password.data)
        session.commit()
        flash('Your password has been reset.')
        return redirect(url_for('auth.login'))
    return render_template('auth/reset_password.html.jinja', form=form)
示例#12
0
def register():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        session.add(user)
        session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('auth.login'))
    return render_template('auth/register.html.jinja',
                           title='Register',
                           form=form)
示例#13
0
def remove_player(id: int, playerid: int):
    form = RemovePlayerForm()
    c = Campaign.query.get(id)
    player = UserProfile.query.get(playerid)

    if form.validate_on_submit():
        c.players.remove(player)
        session.commit()
        return redirect(url_for('campaign.view', id=c.id))

    form.id.data = c.id
    form.player.data = player.id
    return render_template('campaign/removeplayer.html.jinja',
                           player=player,
                           campaign=c,
                           form=form)
示例#14
0
def index():

    user_profile = UserProfile.query.get(current_user.id)

    if user_profile is None:
        user_profile = UserProfile(user_id=current_user.id)
        session.add(user_profile)
        session.commit()

    logger.info(f"Showing profile {user_profile.id}")

    characters = user_profile.characters
    folders = user_profile.folders  # .filter(Folder.parent_id.__eq__(None))
    return render_template('profile/profile.html.jinja',
                           profile=user_profile,
                           characters=characters,
                           folders=folders)
示例#15
0
def view(id, character, editable):
    subskillform = SubskillForm(prefix="subskillform")
    if editable and subskillform.data and subskillform.validate_on_submit():
        character.add_subskill(subskillform.name.data,
                               subskillform.parent.data)
        logentry = LogEntry(character,
                            f"add subskill {subskillform.name.data} " +
                            f"under {subskillform.parent.data}",
                            user_id=current_user.id)
        session.add(logentry)

        character.store_data()
        session.commit()
        return redirect(url_for('character.view', id=id))

    skillform = SkillForm(prefix="skillform")
    if editable and skillform.data and skillform.validate_on_submit():
        skills = character.skills()
        for skill in skills:
            if skillform.name.data == skill['name']:
                flash("Skill already exists")
                return redirect(url_for('character.view', id=id))

        character.add_skill(skillform.name.data)
        character.store_data()
        logentry = LogEntry(character,
                            f"add skill {subskillform.name.data}",
                            user_id=current_user.id)
        session.add(logentry)

        session.commit()
        return redirect(url_for('character.view', id=id))

    typeheader = "1920s Era Investigator"
    if character.game and character.game[1] == "Modern":
        typeheader = "Modern Era"

    shared = Invite.query_for(character).count()

    return render_template('character/coc7e/sheet.html.jinja',
                           shared=shared,
                           character=character,
                           typeheader=typeheader,
                           editable=editable,
                           skillform=skillform,
                           subskillform=subskillform)
示例#16
0
def remove_npc(id: int, characterid: int):
    npc = NPC.query.get(characterid)

    form = RemoveCharacterForm()

    if form.validate_on_submit():
        if npc.campaign.id == id:
            session.delete(npc)
            session.commit()
        return redirect(url_for('campaign.view', id=id))

    form.id.data = npc.campaign.id
    form.character.data = npc.character.id

    return render_template('campaign/removecharacter.html.jinja',
                           character=npc.character,
                           campaign=npc.campaign,
                           form=form)
示例#17
0
def move(fileid, filename):
    asset = Asset.query.get(fileid)
    redirect_id = asset.folder.id
    form = MoveAssetForm(prefix="moveasset")
    if form.validate_on_submit():
        if asset.owner != current_user.profile:
            abort(403)
        destinationfolder = form.folder.data
        if destinationfolder is not None:
            logger.debug(f"Move {asset.system_path} "
                         f"to {destinationfolder.system_path}")
            os.replace(asset.system_path,
                       destinationfolder.system_path / asset.filename)
            asset.folder = destinationfolder
            session.commit()
            flash("You moved your file")

    return redirect(url_for('userassets.index', folder_id=redirect_id))
示例#18
0
def delete(id: int):
    """Delete a character."""
    character = get_character(id, check_author=True)

    if current_user.profile.id != character.user_id:
        abort(404)

    form = DeleteForm()
    if form.validate_on_submit():
        session.delete(character)
        session.commit()
        return redirect(url_for('character.index'))

    form.character_id.data = character.id

    return render_template('character/delete_character.html.jinja',
                           form=form,
                           character=character)
示例#19
0
def manage_npc(id: int, npcid: int):
    npc = NPC.query.get(npcid)

    transferform = NPCTransferForm(prefix="npctransfer", npc_id=npcid)

    if npc is None:
        return abort(404)

    if npc.campaign_id != id:
        return abort(404)

    if current_user.profile != npc.campaign.user:
        return abort(404)

    if transferform.submit.data:
        if transferform.validate_on_submit():
            player = UserProfile.query.get(transferform.player.data)
            campaign = npc.campaign

            # Create a copy of the character
            new_character = Character(title=npc.character.title,
                                      body=npc.character.body,
                                      user_id=player.id)

            session.add(new_character)

            # Add the character to the campaign
            campaign.characters.append(new_character)

            # Remove the NPC
            session.delete(npc)

            # Commit changes
            session.commit()

            return redirect(url_for('campaign.view', id=campaign.id))

    transferform.player.choices = [(p.id, p.user.username)
                                   for p in npc.campaign.players]

    return render_template('campaign/managenpc.html.jinja',
                           npc=npc,
                           transferform=transferform)
示例#20
0
def remove_character(id: int, characterid: int):
    c = Campaign.query.get(id)
    char = Character.query.get(characterid)

    if current_user.profile.id != c.user_id \
            and char.user_id != current_user.profile.id:
        abort(404)
    form = RemoveCharacterForm()

    if form.validate_on_submit():
        c.characters.remove(char)
        session.commit()
        return redirect(url_for('campaign.view', id=c.id))

    form.id.data = c.id
    form.character.data = char.id
    return render_template('campaign/removecharacter.html.jinja',
                           character=char,
                           campaign=c,
                           form=form)
示例#21
0
def create(chartype: str):

    character_module = globals()[chartype] if chartype in globals() else core

    form = getattr(character_module, 'CreateForm', CreateForm)()
    template = getattr(character_module, 'CREATE_TEMPLATE',
                       'character/create.html.jinja')

    if form.validate_on_submit():
        logger.debug(f"Creating new character specified by {form.data}")
        char_data = character_module.new_character(**form.data)
        c = Character(title=form.title.data,
                      body=char_data,
                      user_id=current_user.profile.id)
        session.add(c)
        session.commit()
        return redirect(url_for('character.view', id=c.id))

    form.system.data = chartype
    return render_template(template, form=form, type=type)
示例#22
0
def import_character(type=None, id: int = None, code: str = None):
    logger.debug(f"{type}, {code}, {id}")
    character = None
    if id:
        character = get_character(id, check_author=True)
    elif code is not None:
        invite = Invite.query.get(code)
        if invite is None or invite.table != Character.__tablename__:
            return "Invalid code"
        character = Character.query.get(invite.object_id)

    form = ImportForm(obj=character)
    if form.validate_on_submit():
        c = Character(title=form.title.data,
                      body=form.body.data,
                      user_id=current_user.profile.id)
        session.add(c)
        session.commit()
        return redirect(url_for('character.view', id=c.id))
    return render_template('character/import.html.jinja', form=form, type=None)
示例#23
0
def handout_players(campaignid: int, handoutid: int):
    if not current_user.is_authenticated:
        abort(403)

    handout = Handout.query.get(handoutid)
    if handout is None:
        abort(404)

    if handout.campaign.id != campaignid:
        abort(404)

    if current_user.profile != handout.campaign.user:
        abort(403)

    if request.method == 'POST':
        data = request.get_json()
        assert data is not None

        player = handout.campaign.players_by_id.get(data['player_id'], None)
        if player is not None:
            if data['state']:
                if player not in handout.players:
                    logger.debug(f"Adding player {player} to {handout}")
                    handout.players.append(player)
            else:
                if player in handout.players:
                    logger.debug(f"Removing player {player} to {handout}")
                    handout.players.remove(player)

            session.commit()

        logger.debug(data)

    response = {
        'players': {
            p.user.username: p in handout.players
            for p in handout.campaign.players
        }
    }
    return jsonify(response)
示例#24
0
def upload_file(folder_id=None):
    form = UploadForm(prefix='fileupload')
    if form.validate_on_submit():
        fileobject = form.uploaded.data
        folder: AssetFolder = AssetFolder.query.get(form.folder_id.data)

        if folder.owner != current_user.profile:
            abort(403)

        if fileobject.filename:
            filename = secure_filename(fileobject.filename)

            folder.system_path.mkdir(parents=True, exist_ok=True)
            fileobject.save(folder.system_path / filename)

            asset = Asset(filename=fileobject.filename,
                          folder=folder,
                          owner=current_user.profile)
            session.add(asset)
            session.commit()

    return redirect(url_for('userassets.index', folder_id=folder_id))
示例#25
0
def edit(id: int):
    c = Campaign.query.get(id)
    form = EditForm(obj=c, prefix="campaign_edit")
    folderform = ChooseFolderForm(prefix="choose_folder")

    if form.submit.data and form.validate_on_submit():
        form.populate_obj(c)
        session.add(c)
        session.commit()
        return redirect(url_for('campaign.view', id=c.id))

    if folderform.choose.data and folderform.validate_on_submit():
        print("Folder form submitted!")
        c.folder = folderform.folder_id.data
        session.commit()
        return redirect(url_for('campaign.view', id=c.id))

    folderform.folder_id.data = c.folder

    return render_template('campaign/edit.html.jinja',
                           form=form,
                           folderform=folderform)
示例#26
0
def share(id: int):
    """Share a character."""
    character = get_character(id, check_author=True)
    logger.debug("Finding previous invite")
    invite = Invite.query_for(character).first()
    logger.debug(f"Invites found {invite}")
    if not invite:
        logger.debug(f"Creating an invite for character {character.id}")
        invite = Invite(character)
        invite.owner_id = character.user_id
        session.add(invite)
        session.commit()

    share_url = url_for('character.shared', code=invite.id, _external=True)

    form = None

    html_response = render_template('character/api_share.html.jinja',
                                    form=form,
                                    url=share_url,
                                    code=invite.id)

    return jsonify({'url': share_url, 'html': html_response})
示例#27
0
def invite_delete(id):
    invite = Invite.query.get(id)
    if current_user.profile.id != invite.owner_id:
        logger.debug("Wrong user")
        abort(403)
    form = DeleteInviteForm()
    if form.validate_on_submit():
        logger.debug("Delete form validated")
        session.delete(invite)
        session.commit()
        return redirect('/')

    objclass = get_class_by_tablename(invite.table)
    obj = None
    if objclass is not None:
        obj = objclass.query.get(invite.object_id)

    form.id.data = invite.id

    return render_template('main/invite_delete.html.jinja',
                           obj=obj,
                           invite=invite,
                           form=form)
示例#28
0
def index(folder_id=None):
    if current_user.profile.assetfolders.count() < 1:
        logger.debug("Creating initial folder")
        rootfolder = AssetFolder(title='assets', owner=current_user.profile)
        session.add(rootfolder)
        session.commit()

    if folder_id is not None:
        folder = AssetFolder.query.get(folder_id)
    else:
        folder = current_user.profile.assetfolders \
            .filter(AssetFolder.parent_id.__eq__(None)).first()

    form = UploadForm(folder_id=folder.id, prefix="fileupload")
    folderform = NewFolderForm(parent_id=folder.id, prefix="newfolderform")
    deletefolderform = DeleteAssetFolderForm(id=folder.id,
                                             prefix="deletefolderform")

    return render_template('userassets/assets.html.jinja',
                           form=form,
                           folderform=folderform,
                           deletefolderform=deletefolderform,
                           folder=folder)
示例#29
0
def message_player(campaign_id: int, player_id: int = None):
    c = Campaign.query.get(campaign_id)
    player = None
    if player_id:
        player = UserProfile.query.get(player_id)

    form = MessagePlayerForm()

    if form.validate_on_submit():
        flash(form.message.data)
        logger.debug(request.form)

        message = Message()
        form.populate_obj(message)
        if not form.to_id.data:
            message.to_id = None  # type: ignore

        session.add(message)
        session.commit()

        return redirect(url_for('campaign.view', id=c.id))

    form.campaign_id.data = c.id
    form.to_id.data = player_id
    form.from_id.data = c.user_id

    messages = c.messages.filter(
        or_(
            and_(Message.to_id == player_id,
                 Message.from_id == current_user.profile.id),
            and_(Message.to_id == current_user.profile.id,
                 Message.from_id == player_id)))
    return render_template('campaign/message_player.html.jinja',
                           player=player,
                           campaign=c,
                           form=form,
                           messages=messages)
示例#30
0
def join(code: str):
    inv = Invite.query.get(code)

    if inv is None or inv.table != Campaign.__tablename__:
        return "Invalid code"

    joinform = JoinCampaignForm()
    if joinform.validate_on_submit():
        campaign = Campaign.query.get(inv.object_id)
        player = current_user.profile
        if player not in campaign.players:
            campaign.players.append(player)
            session.commit()

        return redirect(url_for('campaign.view', id=campaign.id))

    flash("Valid code")

    campaign = Campaign.query.get(inv.object_id)
    joinform = JoinCampaignForm(invite_code=code)

    return render_template('campaign/joincampaign.html.jinja',
                           campaign=campaign,
                           joinform=joinform)