Example #1
0
def do_paste(request):
    syntax = request.POST['syntax']
    if syntax == '[none]':
        syntax = ''
    elif syntax == '[auto]':
        lexer = pygments.lexers.guess_lexer(request.POST['content'])
        syntax = lexer.aliases[0]
    elif syntax.startswith('['):
        raise ValueError

    content = request.POST['content']
    lines = content.count('\n')
    if content[-1] != '\n':
        lines += 1

    paste = Paste(
        author=request.user,
        title=request.POST.get('title', ''),
        syntax=syntax,
        content=content,
        size=len(content),
        lines=lines,
    )
    session.add(paste)
    session.flush()

    return HTTPSeeOther(location=request.route_url('pastebin.view', id=paste.id))
Example #2
0
def new__post(request):
    post = BlogPost(
        title=request.POST['title'],
        content=request.POST['content'],
    )
    session.add(post)
    session.flush()

    return HTTPSeeOther(location=request.route_url('blog.index'))
Example #3
0
def new__post(request):
    post = BlogPost(
        title=request.POST['title'],
        content=request.POST['content'],
    )
    session.add(post)
    session.flush()

    return HTTPSeeOther(location=request.route_url('blog.index'))
Example #4
0
def comic_admin_folders_new_do(request):
    # TODO error checking...  might be no POSTs, for example
    folder = session.query(GalleryFolder).get(request.POST['relativeto'])
    if not folder:
        # TODO
        raise HTTPBadRequest

    where = request.POST['where']
    if where == 'before':
        # "Before" really means taking its place, so the target folder and
        # every subsequent folder should scoot forwards two places
        left = folder.left
    elif where == 'after':
        # New folder's left should immediately follow the target folder's right
        left = folder.right + 1
    elif where == 'child':
        # New folder should go where its parents' current right is -- in case
        # there are already children, this puts the new folder last
        left = folder.right
    else:
        # TODO
        raise HTTPBadRequest

    # Shift any endpoints after the new left ahead by 2.  This will cover both
    # ancestors and unrelated folders that are further along
    (
        session.query(GalleryFolder)
        .filter(GalleryFolder.left >= left)
        .update({
            GalleryFolder.left: GalleryFolder.left + 2,
        }, synchronize_session=False)
    )
    (
        session.query(GalleryFolder)
        .filter(GalleryFolder.right >= left)
        .update({
            GalleryFolder.right: GalleryFolder.right + 2,
        }, synchronize_session=False)
    )

    # Create the new folder
    # TODO title has to be unique, non-blank, or somethin
    session.add(GalleryFolder(
        title=request.POST['title'],
        left=left,
        right=left + 1,
        # TODO temporary hack until i get rid of comics entirely
        comic_id=folder.comic_id,
    ))

    return HTTPSeeOther(
        location=request.route_url('comic.admin') + '#manage-folders')
Example #5
0
def express_love__do(request):
    # TODO real form handling thx

    source = request.user
    # TODO error handling lol
    target = session.query(User).filter_by(name=request.POST['target']).one()

    session.add(Love(
        source=source,
        target=target,
        comment=request.POST['comment'],
    ))

    return HTTPSeeOther(request.route_url('love.list'))
Example #6
0
def permissions_grant(request):
    # TODO error checking, eh.  is there even a flash thing yet, haha
    data = dict(
        group_id=request.POST['group'],
        scope=request.POST['scope'],
        permission=request.POST['priv'],
    )

    existing = session.query(GroupPermission).filter_by(**data).all()

    if not existing:
        session.add(GroupPermission(**data))

    return HTTPSeeOther(location=request.route_url('__core__.admin.permissions'))
Example #7
0
def comic_admin_folders_new_do(request):
    # TODO error checking...  might be no POSTs, for example
    folder = session.query(GalleryFolder).get(request.POST['relativeto'])
    if not folder:
        # TODO
        raise HTTPBadRequest

    where = request.POST['where']
    if where == 'before':
        # "Before" really means taking its place, so the target folder and
        # every subsequent folder should scoot forwards two places
        left = folder.left
    elif where == 'after':
        # New folder's left should immediately follow the target folder's right
        left = folder.right + 1
    elif where == 'child':
        # New folder should go where its parents' current right is -- in case
        # there are already children, this puts the new folder last
        left = folder.right
    else:
        # TODO
        raise HTTPBadRequest

    # Shift any endpoints after the new left ahead by 2.  This will cover both
    # ancestors and unrelated folders that are further along
    (session.query(GalleryFolder).filter(GalleryFolder.left >= left).update(
        {
            GalleryFolder.left: GalleryFolder.left + 2,
        },
        synchronize_session=False))
    (session.query(GalleryFolder).filter(GalleryFolder.right >= left).update(
        {
            GalleryFolder.right: GalleryFolder.right + 2,
        },
        synchronize_session=False))

    # Create the new folder
    # TODO title has to be unique, non-blank, or somethin
    session.add(
        GalleryFolder(
            title=request.POST['title'],
            left=left,
            right=left + 1,
            # TODO temporary hack until i get rid of comics entirely
            comic_id=folder.comic_id,
        ))

    return HTTPSeeOther(location=request.route_url('comic.admin') +
                        '#manage-folders')
Example #8
0
def permissions_grant(request):
    # TODO error checking, eh.  is there even a flash thing yet, haha
    data = dict(
        group_id=request.POST['group'],
        scope=request.POST['scope'],
        permission=request.POST['priv'],
    )

    existing = session.query(GroupPermission).filter_by(**data).all()

    if not existing:
        session.add(GroupPermission(**data))

    return HTTPSeeOther(
        location=request.route_url('__core__.admin.permissions'))
Example #9
0
def express_love__do(request):
    # TODO real form handling thx

    source = request.user
    # TODO error handling lol
    target = session.query(User).filter_by(name=request.POST['target']).one()

    session.add(
        Love(
            source=source,
            target=target,
            comment=request.POST['comment'],
        ))

    return HTTPSeeOther(request.route_url('love.list'))
Example #10
0
def comic_admin_folders_new_do(request):
    # TODO error checking...  might be no POSTs, for example
    folder = session.query(GalleryFolder).get(request.POST['relativeto'])
    if not folder:
        # TODO
        raise HTTPBadRequest

    where = request.POST['where']
    if where == 'before':
        # "Before" really means taking its place, so the target folder and
        # every subsequent folder should scoot forwards two places
        left = folder.left
    elif where == 'after':
        # New folder's left should immediately follow the target folder's right
        left = folder.right + 1
    elif where == 'child':
        # Target folder needs to widen by 2, then the new folder should go just
        # before its right -- in case there are already children, this puts the
        # new folder last
        folder.right += 2
        session.flush()
        left = folder.right - 2
    else:
        # TODO
        raise HTTPBadRequest

    # Push everyone else forwards by 2
    (
        session.query(GalleryFolder)
        .filter(GalleryFolder.left >= left)
        .update({
            GalleryFolder.left: GalleryFolder.left + 2,
            GalleryFolder.right: GalleryFolder.right + 2,
        }, synchronize_session=False)
    )

    # Create the new folder
    # TODO title has to be unique, non-blank, or somethin
    session.add(GalleryFolder(
        title=request.POST['title'],
        left=left,
        right=left + 1,
        # TODO temporary hack until i get rid of comics entirely
        comic_id=folder.comic_id,
    ))

    return HTTPSeeOther(
        location=request.route_url('comic.admin') + '#manage-folders')
Example #11
0
def create_user(parser, args):
    engine = engine_from_config(vars(args), 'sqlalchemy.')
    session.configure(bind=engine)

    with transaction.manager:
        all_groups = {
            group.name: group
            for group in session.query(Group)
        }

    username = input('username: '******'email: ').strip()
    password = getpass.getpass('password: '******'confirm password: '******'t match!")
        sys.exit(1)

    group_names = []
    if all_groups:
        print()
        print("available groups: {}".format(', '.join(all_groups)))
        group_names = input('comma-separated list of groups to add to: ').strip().split(',')

    with transaction.manager:
        pwhash = bcrypt.hashpw(
            password.encode('utf8'),
            bcrypt.gensalt(14),
        ).decode('ascii')

        # TODO would be neat to have a password field that hashes on assignment
        # and does the right thing with equality check
        user = User(name=username, email=email, password=pwhash, groups=[])
        for group_name in group_names:
            user.groups.append(all_groups[group_name])
        session.add(user)
        session.flush()
        userid = user.id

    print()
    print("created user {} with id {}".format(username, userid))
Example #12
0
def register__do(request):
    # TODO finish this
    raise HTTPForbidden

    # TODO check for duplicate username haha.
    # TODO and er duplicate email, which is less likely to happen i suppose
    user = User(
        email=request.session['pending_auth']['persona_email'],
        name=request.POST['username'],
    )
    session.add(user)
    session.flush()

    url = request.session['pending_auth']['return_to']
    # TODO this is the sort of thing that should only happen if the transaction
    # succeeds otherwise!
    del request.session['pending_auth']

    return HTTPSeeOther(
        location=url,
        headers=remember(request, user),
    )
Example #13
0
def register__do(request):
    # TODO finish this
    raise HTTPForbidden

    # TODO check for duplicate username haha.
    # TODO and er duplicate email, which is less likely to happen i suppose
    user = User(
        email=request.session['pending_auth']['persona_email'],
        name=request.POST['username'],
    )
    session.add(user)
    session.flush()

    url = request.session['pending_auth']['return_to']
    # TODO this is the sort of thing that should only happen if the transaction
    # succeeds otherwise!
    del request.session['pending_auth']

    return HTTPSeeOther(
        location=url,
        headers=remember(request, user),
    )
Example #14
0
def init_db(parser, args):
    settings = vars(args)

    # Logging
    # TODO this should probably go in the main entry point
    coloredlogs.install(level=logging.INFO)
    # TODO what is this for, it was debug-only, is there any reason we wouldn't want it
    #logging.basicConfig()
    #logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

    # Plugin loading
    plugin_list = import_plugins(settings.get('spline.plugins', ()))

    engine = engine_from_config(settings, 'sqlalchemy.')
    session.configure(bind=engine)

    Base.metadata.create_all(engine, checkfirst=True)

    comic_title = settings.get('spline.comic_name')
    chapter_title = settings.get('spline.chapter_name')

    with transaction.manager:
        try:
            g = session.query(Group).filter_by(id=1).one()
        except:
            g = Group(id=1, name='admin')
            session.add(g)
        try:
            gp0 = session.query(GroupPermission).filter_by(id=1).one()
        except:
            gp0 = GroupPermission(id=1, scope='core', permission='admin')
            gp0.group = g
            session.add(gp0)
        # Only needed if the comic plugin is loaded
        if 'spline_comic' in plugin_list:
            from spline_comic.models import Comic, ComicChapter
            try:
                gp1 = session.query(GroupPermission).filter_by(id=1).one()
            except:
                gp1 = GroupPermission(id=1, scope='comic', permission='admin')
                gp1.group = g
                session.add(gp1)
            try:
                comic = session.query(Comic).filter_by(id=1).one()
            except:
                comic = Comic(id=1, title=comic_title, config_timezone='GMT')
                session.add(comic)
            try:
                chap = session.query(ComicChapter).filter_by(id=1).one()
            except:
                chap = ComicChapter(id=1, title=chapter_title, left=0, right=0)
                chap.comic = comic
                session.add(chap)
        # Only needed if the wiki is loaded
        if 'spline_wiki' in plugin_list:
            try:
                gp2 = session.query(GroupPermission).filter_by(id=2).one()
            except:
                gp2 = GroupPermission(id=2, scope='wiki', permission='edit')
                gp2.group = g
                session.add(gp2)
Example #15
0
def comic_upload_do(request):
    # TODO validation and all that boring stuff
    file_upload = request.POST['file']
    fh = file_upload.file

    from spline.feature.filestore import IStorage
    storage = request.registry.queryUtility(IStorage)

    _, ext = os.path.splitext(file_upload.filename)
    filename = storage.store(fh, ext)
    # TODO ha ha this is stupid
    # TODO very skinny images shouldn't be blindly made 200x200
    fh.seek(0)
    thumb = subprocess.check_output(
        ['convert', '-', '-resize', '200x200', '-'], stdin=fh)
    # TODO this interface is bad also
    thumbname = storage.store(BytesIO(thumb), ext)

    # TODO wire into transaction so the file gets deleted on rollback

    last_chapter = (session.query(ComicChapter).filter(
        ComicChapter.id == int(request.POST['chapter'])).one())

    when = request.POST['when']
    if when == 'now':
        date_published = datetime.now(pytz.utc)
    elif when == 'queue':
        last_queued, queue_next_date = _get_last_queued_date()
        date_published = datetime.combine(
            queue_next_date,
            time(tzinfo=XXX_HARDCODED_TIMEZONE),
        )
        date_published = date_published.astimezone(pytz.utc)

    # Fetch next page number and ordering.  Also need to shift everyone else
    # forwards by one if this is bumping the queue.  Blurgh.
    max_order, = (session.query(func.max(ComicPage.order)).filter(
        ComicPage.date_published <= date_published).first())
    if max_order is None:
        max_order = 0
    next_order = max_order + 1

    (session.query(ComicPage).filter(ComicPage.order >= next_order).update(
        {ComicPage.order: ComicPage.order + 1}))

    max_page_number, = (session.query(func.max(
        ComicPage.page_number)).with_parent(last_chapter).filter(
            ComicPage.date_published <= date_published).first())
    if max_page_number is None:
        max_page_number = 0
    next_page_number = max_page_number + 1

    (session.query(ComicPage).with_parent(last_chapter).filter(
        ComicPage.page_number >= next_page_number).update(
            {ComicPage.page_number: ComicPage.page_number + 1}))

    page = ComicPage(
        chapter=last_chapter,
        author=request.user,
        date_published=date_published,
        timezone=XXX_HARDCODED_TIMEZONE.zone,
        order=next_order,
        page_number=next_page_number,

        # TODO more validation here too
        title=request.POST['title'],
        comment=request.POST['comment'],
        media=[
            GalleryMedia_Image(
                image_file=os.path.basename(filename),
                thumbnail_file=os.path.basename(thumbname),
            )
        ],
    )

    if request.POST.get('iframe_url'):
        url = request.POST['iframe_url']
        # If it's a YouTube URL, convert to the embed URL automatically
        # TODO this seems like a neat thing to do for many other services and
        # make a tiny library out of, if it's not done already?
        # TODO why doesn't this use urlparse???
        m = re.match(
            '^(?:https?://)?(?:www[.])?youtube[.]com/watch[?]v=([-_0-9a-zA-Z]+)(?:&|$)',
            url)
        if m:
            url = "https://www.youtube.com/embed/{}?rel=0".format(m.group(1))

        m = re.match('^(?:https?://)?youtu[.]be/([-_0-9a-zA-Z]+)(?:[?]|$)',
                     url)
        if m:
            url = "https://www.youtube.com/embed/{}?rel=0".format(m.group(1))

        try:
            width = int(request.POST['iframe_width'])
        except (KeyError, ValueError):
            width = 800
        try:
            height = int(request.POST['iframe_height'])
        except (KeyError, ValueError):
            height = 600

        page.media.append(
            GalleryMedia_IFrame(url=url, width=width, height=height))

    session.add(page)
    session.flush()

    return HTTPSeeOther(location=request.resource_url(page))
Example #16
0
def initdb(**settings):

    engine = engine_from_config(settings, 'sqlalchemy.')
    session.configure(bind=engine)

    config = Configurator(settings=settings)

    # Logging
    config.include('spline.lib.logging')

    # Plugin loading
    debug = settings.get('spline.debug')
    if debug:
        logging.basicConfig()
        logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
    plugin_list = []
    try:
        for plugins in settings.get('spline.plugins', ()):
            plugin, route_prefix = plugins.split(':', 1)
            importlib.import_module(plugin)
            plugin_list.append(plugin)
    except TypeError:
        pass
    Base.metadata.create_all(engine, checkfirst=True)

    adm_name = settings.get('spline.admin_name')
    adm_pw = settings.get('spline.admin_pw')
    adm_email = settings.get('spline.admin_email')
    comic_title = settings.get('spline.comic_name')
    chapter_title = settings.get('spline.chapter_name')
    p = adm_pw.encode('utf8')
    pw = hashpw(p, gensalt(14))

    with transaction.manager:
        try:
            u = session.query(User).filter_by(id=1).one()
        except:
            u = User(id=1, email=adm_email, name=adm_name, password=pw.decode('ascii'))
            session.add(u)
        try:
            g = session.query(Group).filter_by(id=1).one()
        except:
            g = Group(id=1, name='admin')
            g.users.append(u)
            session.add(g)
        try:
            gp0 = session.query(GroupPermission).filter_by(id=1).one()
        except:
            gp0 = GroupPermission(id=1, scope='core', permission='admin')
            gp0.group = g
            session.add(gp0)
        # Only needed if the comic plugin is loaded
        if 'spline_comic' in plugin_list:
            from spline_comic.models import Comic, ComicChapter
            try:
                gp1 = session.query(GroupPermission).filter_by(id=1).one()
            except:
                gp1 = GroupPermission(id=1, scope='comic', permission='admin')
                gp1.group = g
                session.add(gp1)
            try:
                comic = session.query(Comic).filter_by(id=1).one()
            except:
                comic = Comic(id=1, title=comic_title, config_timezone='GMT')
                session.add(comic)
            try:
                chap = session.query(ComicChapter).filter_by(id=1).one()
            except:
                chap = ComicChapter(id=1, title=chapter_title, left=0, right=0)
                chap.comic = comic
                session.add(chap)
        # Only needed if the wiki is loaded
        if 'spline_wiki' in plugin_list:
            try:
                gp2 = session.query(GroupPermission).filter_by(id=2).one()
            except:
                gp2 = GroupPermission(id=2, scope='wiki', permission='edit')
                gp2.group = g
                session.add(gp2)
Example #17
0
def comic_upload_do(request):
    # TODO validation and all that boring stuff
    file_upload = request.POST['file']
    fh = file_upload.file

    from spline.feature.filestore import IStorage
    storage = request.registry.queryUtility(IStorage)

    _, ext = os.path.splitext(file_upload.filename)
    filename = storage.store(fh, ext)
    # TODO ha ha this is stupid
    # TODO very skinny images shouldn't be blindly made 200x200
    fh.seek(0)
    thumb = subprocess.check_output(['convert', '-', '-resize', '200x200', '-'], stdin=fh)
    # TODO this interface is bad also
    thumbname = storage.store(BytesIO(thumb), ext)

    # TODO wire into transaction so the file gets deleted on rollback

    last_chapter = (
        session.query(ComicChapter)
        .filter(ComicChapter.id == int(request.POST['chapter']))
        .one()
    )

    when = request.POST['when']
    if when == 'now':
        date_published = datetime.now(pytz.utc)
    elif when == 'queue':
        last_queued, queue_next_date = _get_last_queued_date()
        date_published = datetime.combine(
            queue_next_date,
            time(tzinfo=XXX_HARDCODED_TIMEZONE),
        )
        date_published = date_published.astimezone(pytz.utc)

    # Fetch next page number and ordering.  Also need to shift everyone else
    # forwards by one if this is bumping the queue.  Blurgh.
    max_order, = (
        session.query(func.max(ComicPage.order))
        .filter(ComicPage.date_published <= date_published)
        .first()
    )
    if max_order is None:
        max_order = 0
    next_order = max_order + 1

    (
        session.query(ComicPage)
        .filter(ComicPage.order >= next_order)
        .update({ComicPage.order: ComicPage.order + 1})
    )

    max_page_number, = (
        session.query(func.max(ComicPage.page_number))
        .with_parent(last_chapter)
        .filter(ComicPage.date_published <= date_published)
        .first()
    )
    if max_page_number is None:
        max_page_number = 0
    next_page_number = max_page_number + 1

    (
        session.query(ComicPage)
        .with_parent(last_chapter)
        .filter(ComicPage.page_number >= next_page_number)
        .update({ComicPage.page_number: ComicPage.page_number + 1})
    )

    page = ComicPage(
        chapter=last_chapter,
        author=request.user,
        date_published=date_published,
        timezone=XXX_HARDCODED_TIMEZONE.zone,

        order=next_order,
        page_number=next_page_number,

        # TODO more validation here too
        title=request.POST['title'],
        comment=request.POST['comment'],

        media=[
            GalleryMedia_Image(
                image_file=os.path.basename(filename),
                thumbnail_file=os.path.basename(thumbname),
            )
        ],
    )

    if request.POST.get('iframe_url'):
        url = request.POST['iframe_url']
        # If it's a YouTube URL, convert to the embed URL automatically
        # TODO this seems like a neat thing to do for many other services and
        # make a tiny library out of, if it's not done already?
        # TODO why doesn't this use urlparse???
        m = re.match(
            '^(?:https?://)?(?:www[.])?youtube[.]com/watch[?]v=([-_0-9a-zA-Z]+)(?:&|$)',
            url)
        if m:
            url = "https://www.youtube.com/embed/{}?rel=0".format(m.group(1))

        m = re.match('^(?:https?://)?youtu[.]be/([-_0-9a-zA-Z]+)(?:[?]|$)', url)
        if m:
            url = "https://www.youtube.com/embed/{}?rel=0".format(m.group(1))

        try:
            width = int(request.POST['iframe_width'])
        except (KeyError, ValueError):
            width = 800
        try:
            height = int(request.POST['iframe_height'])
        except (KeyError, ValueError):
            height = 600

        page.media.append(GalleryMedia_IFrame(
            url=url, width=width, height=height))

    session.add(page)
    session.flush()

    return HTTPSeeOther(location=request.resource_url(page))