Beispiel #1
0
    def wrapper(username, id, **kwds):
        print "id is", id
        worksheet_filename = username + "/" + id
        try:
            worksheet = kwds['worksheet'] = g.notebook.get_worksheet_with_filename(worksheet_filename)
        except KeyError:
            return current_app.message(_("You do not have permission to access this worksheet"))
        
        with worksheet_locks[worksheet]:
            owner = worksheet.owner()

            if owner != '_sage_' and g.username != owner:
                if not worksheet.is_published():
                    if (not g.username in worksheet.collaborators() and
                        not g.notebook.user_manager().user_is_admin(g.username)):
                        return current_app.message(_("You do not have permission to access this worksheet"))

            if not worksheet.is_published():
                worksheet.set_active(g.username)

            #This was in twist.Worksheet.childFactory
            from base import notebook_updates
            notebook_updates()

            return f(username, id, **kwds)
Beispiel #2
0
    def wrapper(username, id, **kwds):
        worksheet_filename = username + "/" + id
        try:
            worksheet = kwds[
                'worksheet'] = g.notebook.get_worksheet_with_filename(
                    worksheet_filename)
        except KeyError:
            return current_app.message(
                _("You do not have permission to access this worksheet"),
                username=g.username)

        with worksheet_locks[worksheet]:
            owner = worksheet.owner()

            if owner != '_sage_' and g.username != owner:
                if not worksheet.is_published():
                    if (not g.username in worksheet.collaborators()
                            and not g.notebook.user_manager().user_is_admin(
                                g.username)):
                        return current_app.message(_(
                            "You do not have permission to access this worksheet"
                        ),
                                                   username=g.username)

            if not worksheet.is_published():
                worksheet.set_active(g.username)

            #This was in twist.Worksheet.childFactory
            from .base import notebook_updates
            notebook_updates()

            return f(username, id, **kwds)
def upload_worksheet():
    from sage.misc.misc import tmp_filename, tmp_dir
    from werkzeug import secure_filename
    import zipfile

    #XXX: i18n
    backlinks = """ Return to <a href="/upload" title="Upload a worksheet"><strong>Upload File</strong></a>."""

    url = request.values['url'].strip()
    dir = ''
    if url:
        #Downloading a file from the internet
        import urllib
        filename = tmp_filename() + ('.zip'
                                     if url.endswith('.zip') else '.sws')
        urllib.urlretrieve(url, filename)
    else:
        #Uploading a file from the user's computer
        dir = tmp_dir()
        file = request.files['file']
        if file.filename == '':
            return current_app.message(
                "Please specify a worksheet to load.%s" % backlinks)

        filename = secure_filename(file.filename)
        filename = os.path.join(dir, filename)
        file.save(filename)

    new_name = request.values.get('name', None)

    try:
        try:
            if filename.endswith('.zip'):
                # Extract all the .sws files from a zip file.
                zip_file = zipfile.ZipFile(filename)
                sws_file = os.path.join(dir, "tmp.sws")
                for sws in zip_file.namelist():
                    if sws.endswith('.sws'):
                        open(sws_file, 'w').write(zip_file.read(
                            sws))  # 2.6 zip_file.extract(sws, sws_file)
                        W = g.notebook.import_worksheet(sws_file, g.username)
                        if new_name:
                            W.set_name("%s - %s" % (new_name, W.name()))
                return redirect(url_for('home', username=g.username))

            else:
                W = g.notebook.import_worksheet(filename, g.username)

        except Exception, msg:
            s = 'There was an error uploading the worksheet.  It could be an old unsupported format or worse.  If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet.  Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s' % backlinks
            return current_app.message(s, url_for('home', username=g.username))
        finally:
            # Clean up the temporarily uploaded filename.
            os.unlink(filename)
            # if a temp directory was created, we delete it now.
            if dir:
                import shutil
                shutil.rmtree(dir)
Beispiel #4
0
def worksheet_jsmol_data(worksheet):
    """
    Jmol/JSmol callback

    The jmol applet does not take the data inline, but calls back at
    this URI to get one or more base64-encoded data files.
    """
    # Defaults taken from upstream jsmol.php
    query = request.values.get('query', 
        "http://cactus.nci.nih.gov/chemical/structure/ethanol/file?format=sdf&get3d=True")
    call = request.values.get('call', u'getRawDataFromDatabase')
    database = request.values.get('database', '_')
    encoding = request.values.get('encoding', None)

    current_app.logger.debug('JSmol call:  %s', call)
    current_app.logger.debug('JSmol query: %s', query)
    if encoding == None:
        def encoder(x): 
            return x
    elif encoding == u'base64':
        import base64
        def encoder(x): 
            # JSmol expects the magic ';base64,' in front of output
            return ';base64,' + base64.encodestring(x)
    else:
        current_app.logger.error('Invalid JSmol encoding %s', encoding)
        return current_app.message(_('Invalid JSmol encoding: ' + str(encoding)), username=g.username)

    if call == u'getRawDataFromDatabase':
        # Annoyingly, JMol prepends the worksheet url (not: the
        # request url) to the query. Strip off:
        worksheet_url = request.base_url[:-len('/jsmol')]
        pattern = worksheet_url + '/cells/(?P<cell_id>[0-9]*)/(?P<filename>.*)'
        match = re.match(pattern, query)
        if match is None:
            current_app.logger.error('Invalid JSmol query %s, does not match %s', query, pattern)
            return current_app.message(_('Invalid JSmol query: ' + query), username=g.username)
        cell_id = match.group('cell_id')
        filename = match.group('filename')
        filename = filename.rsplit('?',1)[0] # appended query is only for cache busting
        filename = secure_filename(filename)   # never trust input
        filename = os.path.join(worksheet.cells_directory(), cell_id, filename)
        with open(filename, 'r') as f:
            data = f.read()
            response = make_response(encoder(data))
    else:
        current_app.logger.error('Invalid JSmol request %s', call)
        return current_app.message(_('Invalid JSmol request: ' + str(call)), username=g.username)

    # Taken from upstream jsmol.php
    is_binary = '.gz' in query
    # Non-standard Content-Type taken from upstream jsmol.php
    if is_binary:
        response.headers['Content-Type'] = 'Content-Type: text/plain; charset=x-user-defined';
    else:
        response.headers['Content-Type'] = 'Content-Type: application/json';
    return response
Beispiel #5
0
def worksheet_do_upload_data(worksheet):
    from werkzeug import secure_filename

    worksheet_url = url_for_worksheet(worksheet)
    upload_url = worksheet_upload_data.url_for(worksheet)

    #XXX: i18n
    backlinks = """ Return to <a href="%s" title="Upload or create a data file in a wide range of formats"><strong>Upload or Create Data File</strong></a> or <a href="%s" title="Interactively use the worksheet"><strong>%s</strong></a>.""" % (upload_url, worksheet_url, worksheet.name())


    if 'file' not in request.files:
        #XXX: i18n
        return current_app.message('Error uploading file (missing field "file").%s' % backlinks, worksheet_url)
    else:
        file = request.files['file']
        
    text_fields = ['url', 'new', 'name']
    for field in text_fields:
        if field not in request.values:
            #XXX: i18n
            return current_app.message('Error uploading file (missing %s arg).%s' % (field, backlinks), worksheet_url)


    name = request.values.get('name', '').strip()
    new_field = request.values.get('new', '').strip()
    url = request.values.get('url', '').strip()

    name = name or file.filename or new_field
    if url and not name:
        name = url.split('/')[-1]
    name = secure_filename(name)

    if not name:
        #XXX: i18n
        return current_app.message('Error uploading file (missing filename).%s' % backlinks, worksheet_url)

    #XXX: disk access
    dest = os.path.join(worksheet.data_directory(), name)
    if os.path.exists(dest):
        if not os.path.isfile(dest):
            #XXX: i18n
            return current_app.message('Suspicious filename "%s" encountered uploading file.%s' % (name, backlinks), worksheet_url)
        os.unlink(dest)


    response = redirect(worksheet_datafile.url_for(worksheet, name=name))

    if url != '':
        #XXX: Finish me!
        pass
    elif new_field:
        open(dest, 'w').close()
        return response
    else:
        file.save(dest)
        return response        
def upload_worksheet():
    from sage.misc.misc import tmp_filename, tmp_dir
    from werkzeug import secure_filename
    import zipfile
    
    #XXX: i18n
    backlinks = """ Return to <a href="/upload" title="Upload a worksheet"><strong>Upload File</strong></a>."""

    url = request.values['url'].strip()
    dir = ''
    if url:
        #Downloading a file from the internet
        import urllib
        filename = tmp_filename() + ('.zip' if url.endswith('.zip') else '.sws')
        urllib.urlretrieve(url, filename)
    else:
        #Uploading a file from the user's computer
        dir = tmp_dir()
        file = request.files['file']
        if file.filename == '':
            return current_app.message("Please specify a worksheet to load.%s" % backlinks)

        filename = secure_filename(file.filename)
        filename = os.path.join(dir, filename)
        file.save(filename)

    new_name = request.values.get('name', None)

    try:
        try:
            if filename.endswith('.zip'):
                # Extract all the .sws files from a zip file.
                zip_file = zipfile.ZipFile(filename)
                sws_file = os.path.join(dir, "tmp.sws")
                for sws in zip_file.namelist():
                    if sws.endswith('.sws'):
                        open(sws_file, 'w').write(zip_file.read(sws)) # 2.6 zip_file.extract(sws, sws_file)
                        W = g.notebook.import_worksheet(sws_file, g.username)
                        if new_name:
                            W.set_name("%s - %s" % (new_name, W.name()))
                return redirect(url_for('home', username=g.username))

            else:
                W = g.notebook.import_worksheet(filename, g.username)

        except Exception, msg:
            s = 'There was an error uploading the worksheet.  It could be an old unsupported format or worse.  If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet.  Alternatively, an sws file is just a bzip2 tarball; take a look inside!%s' % backlinks
            return current_app.message(s, url_for('home', username=g.username))
        finally:
            # Clean up the temporarily uploaded filename.
            os.unlink(filename)
            # if a temp directory was created, we delete it now.
            if dir:
                import shutil
                shutil.rmtree(dir)
Beispiel #7
0
def forgot_pass():
    if not g.notebook.conf()['email']:
        return current_app.message(
            _('The account recovery system is not active.'))

    username = request.values.get('username', '').strip()
    if not username:
        return render_template(
            os.path.join('html', 'accounts', 'account_recovery.html'))

    def error(msg):
        return current_app.message(msg, url_for('forgot_pass'))

    try:
        user = g.notebook.user(username)
    except KeyError:
        return error(_('Username is invalid.'))

    if not user.is_email_confirmed():
        return error(_("The e-mail address hasn't been confirmed."))

    #XXX: some of this could be factored out into a random passowrd
    #function.  There are a few places in admin.py that also use it.
    from random import choice
    import string
    chara = string.letters + string.digits
    old_pass = user.password()
    password = ''.join([choice(chara) for i in range(8)])

    from sagenb.notebook.smtpsend import send_mail
    from sagenb.notebook.register import build_password_msg
    # TODO: make this come from the server settings

    listenaddr = g.notebook.interface
    port = g.notebook.port
    fromaddr = 'no-reply@%s' % listenaddr
    body = build_password_msg(password, username, listenaddr, port,
                              g.notebook.secure)
    destaddr = user.get_email()
    try:
        send_mail(fromaddr, destaddr, _("Sage Notebook Account Recovery"),
                  body)
    except ValueError:
        # the email address is invalid
        return error(
            _("The new password couldn't be sent to %(dest)s.", dest=destaddr))
    else:
        g.notebook.user_manager().set_password(username, password)

    return current_app.message(
        _("A new password has been sent to your e-mail address."),
        url_for('base.index'))
Beispiel #8
0
def worksheet_link_datafile(worksheet):
    target_worksheet_filename = request.values['target']
    data_filename = request.values['filename']
    src = os.path.abspath(os.path.join(
        worksheet.data_directory(), data_filename))
    target_ws =  g.notebook.get_worksheet_with_filename(target_worksheet_filename)
    target = os.path.abspath(os.path.join(
        target_ws.data_directory(), data_filename))
    if target_ws.owner() != g.username and not target_ws.is_collaborator(g.username):
        return current_app.message(_("illegal link attempt!"), worksheet_datafile.url_for(worksheet, name=data_filename), username=g.username)
    if os.path.exists(target):
        return current_app.message(_("The data filename already exists in other worksheet\nDelete the file in the other worksheet before creating a link."), worksheet_datafile.url_for(worksheet, name=data_filename), username=g.username)
    os.link(src,target)
    return redirect(worksheet_datafile.url_for(worksheet, name=data_filename))
Beispiel #9
0
def worksheet_link_datafile(worksheet):
    target_worksheet_filename = request.values['target']
    data_filename = request.values['filename']
    src = os.path.abspath(os.path.join(
        worksheet.data_directory(), data_filename))
    target_ws =  g.notebook.get_worksheet_with_filename(target_worksheet_filename)
    target = os.path.abspath(os.path.join(
        target_ws.data_directory(), data_filename))
    if target_ws.owner() != g.username and not target_ws.is_collaborator(g.username):
        return current_app.message(_("illegal link attempt!"), worksheet_datafile.url_for(worksheet, name=data_filename))
    if os.path.exists(target):
        return current_app.message(_("The data filename already exists in other worksheet\nDelete the file in the other worksheet before creating a link."), worksheet_datafile.url_for(worksheet, name=data_filename))
    os.link(src,target)
    return redirect(worksheet_datafile.url_for(worksheet, name=data_filename))
Beispiel #10
0
def worksheet_invite_collab(worksheet):
    owner = worksheet.owner()
    id_number = worksheet.id_number()
    old_collaborators = set(worksheet.collaborators())
    collaborators = set([u.strip() for u in request.values.get('collaborators', '').split(',') if u!=owner])
    if len(collaborators-old_collaborators)>500:
        # to prevent abuse, you can't add more than 500 collaborators at a time
        return current_app.message(_("Error: can't add more than 500 collaborators at a time"), cont=url_for_worksheet(worksheet))
    worksheet.set_collaborators(collaborators)
    user_manager = g.notebook.user_manager()
    # add worksheet to new collaborators
    for u in collaborators-old_collaborators:
        try:
            user_manager.user(u).viewable_worksheets().add((owner, id_number))
        except KeyError:
            # user doesn't exist
            pass
    # remove worksheet from ex-collaborators
    for u in old_collaborators-collaborators:
        try:
            user_manager.user(u).viewable_worksheets().discard((owner, id_number))
        except KeyError:
            # user doesn't exist
            pass

    return redirect(url_for_worksheet(worksheet))
Beispiel #11
0
def worksheet_file(path):
    # Create a live Sage worksheet from the given path.
    if not os.path.exists(path):
        return current_app.message(_('Document does not exist.'))

    doc_page_html = open(path).read()
    from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor
    doc_page = SphinxHTMLProcessor().process_doc_html(doc_page_html)

    title = (extract_title(doc_page_html).replace('&mdash;', '--') or
             'Live Sage Documentation')

    W = doc_worksheet()
    W.edit_save(doc_page)
    W.set_system('sage')
    W.set_name(title)
    W.save()
    W.quit()

    # FIXME: For some reason, an extra cell gets added so we
    # remove it here.
    W.cell_list().pop()

    return g.notebook.html(worksheet_filename=W.filename(),
                           username=g.username)
Beispiel #12
0
 def wrapper(*args, **kwds):
     if not g.notebook.user_manager().user_is_admin(g.username):
         return current_app.message(
             _("You do not have permission to access this location"),
             cont=url_for('base.index'),
             username=g.username)
     return f(*args, **kwds)
Beispiel #13
0
def add_user():
    from sagenb.notebook.misc import is_valid_username
    from sagenb.misc.misc import SAGE_VERSION
    template_dict = {'admin': g.notebook.user_manager().user(g.username).is_admin(),
            'username': g.username, 'sage_version': SAGE_VERSION}
    if 'username' in request.values:
        if request.values['cancel']:
            return redirect(url_for('users'))
        username = request.values['username']
        if not is_valid_username(username):
            return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                                   error='username_invalid', username_input=username, **template_dict)

        from random import choice
        import string
        chara = string.letters + string.digits
        password = ''.join([choice(chara) for i in range(8)])
        if username in g.notebook.user_manager().usernames():
            return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                                   error='username_taken', username_input=username, **template_dict)
        g.notebook.user_manager().add_user(username, password, '', force=True)

        message = _('The temporary password for the new user <em>%(username)s</em> is <em>%(password)s</em>',
                          username=username, password=password)
        return current_app.message(message, cont='/adduser', title=_('New User'))
    else:
        return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                               **template_dict)
Beispiel #14
0
def add_user():
    from sagenb.notebook.misc import is_valid_username
    template_dict = {'admin': g.notebook.user_manager().user(g.username).is_admin(),
                     'username': g.username}
    if 'username' in request.values:
        username = request.values['username']
        if not is_valid_username(username):
            return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                                   error='username_invalid', username=username, **template_dict)

        from random import choice
        import string
        chara = string.letters + string.digits
        password = ''.join([choice(chara) for i in range(8)])
        if username in g.notebook.user_manager().usernames():
            return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                                   error='username_taken', username_input=username, **template_dict)
        g.notebook.user_manager().add_user(username, password, '', force=True)

        message = _('The temporary password for the new user <em>%(username)s</em> is <em>%(password)s</em>',
                          username=username, password=password)
        return current_app.message(message, cont='/adduser', title=_('New User'))
    else:
        return render_template(os.path.join('html', 'settings', 'admin_add_user.html'),
                               **template_dict)
Beispiel #15
0
def worksheet_file(path):
    # Create a live Sage worksheet from the given path.
    if not os.path.exists(path):
        return current_app.message(_('Document does not exist.'),
                                   username=g.username)

    doc_page_html = open(path).read()
    from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor
    doc_page = SphinxHTMLProcessor().process_doc_html(doc_page_html)

    title = (extract_title(doc_page_html).replace('&mdash;', '--')
             or 'Live Sage Documentation')

    W = doc_worksheet()
    W.edit_save(doc_page)
    W.set_system('sage')
    W.set_name(title)
    W.save()
    W.quit()

    # FIXME: For some reason, an extra cell gets added so we
    # remove it here.
    W.cell_list().pop()

    return g.notebook.html(worksheet_filename=W.filename(),
                           username=g.username)
Beispiel #16
0
def worksheet_revisions(worksheet):
    """
    Show a list of revisions of this worksheet.
    """
    if 'action' not in request.values:
        if 'rev' in request.values:
            return g.notebook.html_specific_revision(g.username, worksheet,
                                                       request.values['rev'])
        else:
            return g.notebook.html_worksheet_revision_list(g.username, worksheet)
    else:
        rev = request.values['rev']
        action = request.values['action']
        if action == 'revert':
            import bz2
            worksheet.save_snapshot(g.username)
            #XXX: Requires access to filesystem
            txt = bz2.decompress(open(worksheet.get_snapshot_text_filename(rev)).read())
            worksheet.delete_cells_directory()
            worksheet.edit_save(txt)
            return redirect(url_for_worksheet(worksheet))
        elif action == 'publish':
            import bz2
            W = g.notebook.publish_worksheet(worksheet, g.username)
            txt = bz2.decompress(open(worksheet.get_snapshot_text_filename(rev)).read())
            W.delete_cells_directory()
            W.edit_save(txt)
            return redirect(url_for_worksheet(W))
        else:
            return current_app.message(_('Error'))
Beispiel #17
0
        def wrapper(*args, **kwds):
            # We remove the first two arguments corresponding to the
            # username and the worksheet id
            username_id = args[:2]
            args = args[2:]

            #####################
            # Public worksheets #
            #####################
            # _sage_ is used by live docs and published interacts
            if username_id and username_id[0] in ["_sage_"]:
                if target.split("/")[0] not in published_commands_allowed:
                    raise NotImplementedError("User _sage_ can not access URL %s" % target)
            if g.notebook.readonly_user(g.username):
                if target.split("/")[0] not in readonly_commands_allowed:
                    return current_app.message(
                        _("Account is in read-only mode"), cont=url_for("worksheet_listing.home", username=g.username)
                    )

            # Make worksheet a non-keyword argument appearing before the
            # other non-keyword arguments.
            worksheet = kwds.pop("worksheet", None)
            if worksheet is not None:
                args = (worksheet,) + args

            return f(*args, **kwds)
Beispiel #18
0
def worksheet_data(worksheet, filename):
    dir = os.path.abspath(worksheet.data_directory())
    if not os.path.exists(dir):
        return current_app.message(_('No data files'))
    else:
        from flask.helpers import send_from_directory
        return send_from_directory(worksheet.data_directory(), filename)
Beispiel #19
0
        def wrapper(*args, **kwds):
            #We remove the first two arguments corresponding to the
            #username and the worksheet id
            username_id = args[:2]
            args = args[2:]

            #####################
            # Public worksheets #
            #####################
            #_sage_ is used by live docs and published interacts
            if username_id and username_id[0] in ['_sage_']:
                if target.split('/')[0] not in published_commands_allowed:
                    raise NotImplementedError(
                        "User _sage_ can not access URL %s" % target)
            if g.notebook.readonly_user(g.username):
                if target.split('/')[0] not in readonly_commands_allowed:
                    return current_app.message(
                        _("Account is in read-only mode"),
                        cont=url_for('worksheet_listing.home',
                                     username=g.username))

            #Make worksheet a non-keyword argument appearing before the
            #other non-keyword arguments.
            worksheet = kwds.pop('worksheet', None)
            if worksheet is not None:
                args = (worksheet, ) + args

            return f(*args, **kwds)
Beispiel #20
0
def worksheet_invite_collab(worksheet):
    owner = worksheet.owner()
    id_number = worksheet.id_number()
    old_collaborators = set(worksheet.collaborators())
    collaborators = set([
        u.strip() for u in request.values.get('collaborators', '').split(',')
        if u != owner
    ])
    if len(collaborators - old_collaborators) > 500:
        # to prevent abuse, you can't add more than 500 collaborators at a time
        return current_app.message(
            _("Error: can't add more than 500 collaborators at a time"),
            cont=url_for_worksheet(worksheet),
            username=g.username)
    worksheet.set_collaborators(collaborators)
    user_manager = g.notebook.user_manager()
    # add worksheet to new collaborators
    for u in collaborators - old_collaborators:
        try:
            user_manager.user(u).viewable_worksheets().add((owner, id_number))
        except (ValueError, LookupError):
            # user doesn't exist
            pass
    # remove worksheet from ex-collaborators
    for u in old_collaborators - collaborators:
        try:
            user_manager.user(u).viewable_worksheets().discard(
                (owner, id_number))
        except (ValueError, LookupError):
            # user doesn't exist
            pass

    return redirect(url_for_worksheet(worksheet))
Beispiel #21
0
def worksheet_revisions(worksheet):
    """
    Show a list of revisions of this worksheet.
    """
    if 'action' not in request.values:
        if 'rev' in request.values:
            return g.notebook.html_specific_revision(g.username, worksheet,
                                                     request.values['rev'])
        else:
            return g.notebook.html_worksheet_revision_list(
                g.username, worksheet)
    else:
        rev = request.values['rev']
        action = request.values['action']
        if action == 'revert':
            import bz2
            worksheet.save_snapshot(g.username)
            #XXX: Requires access to filesystem
            txt = bz2.decompress(
                open(worksheet.get_snapshot_text_filename(rev)).read())
            worksheet.delete_cells_directory()
            worksheet.edit_save(txt)
            return redirect(url_for_worksheet(worksheet))
        elif action == 'publish':
            import bz2
            W = g.notebook.publish_worksheet(worksheet, g.username)
            txt = bz2.decompress(
                open(worksheet.get_snapshot_text_filename(rev)).read())
            W.delete_cells_directory()
            W.edit_save(txt)
            return redirect(url_for_worksheet(W))
        else:
            return current_app.message(_('Error'), username=g.username)
Beispiel #22
0
def worksheet_data(worksheet, filename):
    dir = os.path.abspath(worksheet.data_directory())
    if not os.path.exists(dir):
        return current_app.message(_('No data files'), username=g.username)
    else:
        from flask.helpers import send_from_directory
        return send_from_directory(worksheet.data_directory(), filename)
Beispiel #23
0
def forgot_pass():
    if not g.notebook.conf()["email"]:
        return current_app.message(_("The account recovery system is not active."))

    username = request.values.get("username", "").strip()
    if not username:
        return render_template(os.path.join("html", "accounts", "account_recovery.html"))

    def error(msg):
        return current_app.message(msg, url_for("forgot_pass"))

    try:
        user = g.notebook.user(username)
    except KeyError:
        return error(_("Username is invalid."))

    if not user.is_email_confirmed():
        return error(_("The e-mail address hasn't been confirmed."))

    # XXX: some of this could be factored out into a random passowrd
    # function.  There are a few places in admin.py that also use it.
    from random import choice
    import string

    chara = string.letters + string.digits
    old_pass = user.password()
    password = "".join([choice(chara) for i in range(8)])

    from sagenb.notebook.smtpsend import send_mail
    from sagenb.notebook.register import build_password_msg

    # TODO: make this come from the server settings

    listenaddr = g.notebook.interface
    port = g.notebook.port
    fromaddr = "no-reply@%s" % listenaddr
    body = build_password_msg(password, username, listenaddr, port, g.notebook.secure)
    destaddr = user.get_email()
    try:
        send_mail(fromaddr, destaddr, _("Sage Notebook Account Recovery"), body)
    except ValueError:
        # the email address is invalid
        return error(_("The new password couldn't be sent to %(dest)s.", dest=destaddr))
    else:
        g.notebook.user_manager().set_password(username, password)

    return current_app.message(_("A new password has been sent to your e-mail address."), url_for("base.index"))
Beispiel #24
0
def public_worksheet_download(id, title):
    from worksheet import unconditional_download
    worksheet_filename =  "pub" + "/" + id
    try:
        worksheet = g.notebook.get_worksheet_with_filename(worksheet_filename)
    except KeyError:
        return current_app.message(_("You do not have permission to access this worksheet"))
    return unconditional_download(worksheet, title)
Beispiel #25
0
def public_worksheet_cells(id, filename):
    worksheet_filename =  "pub" + "/" + id
    try:
        worksheet = g.notebook.get_worksheet_with_filename(worksheet_filename)
    except KeyError:
        return current_app.message("You do not have permission to access this worksheet") #XXX: i18n
    from flask.helpers import send_from_directory
    return send_from_directory(worksheet.cells_directory(), filename)
Beispiel #26
0
def upload():
    from sagenb.misc.misc import SAGE_VERSION
    if g.notebook.readonly_user(g.username):
        return current_app.message(_("Account is in read-only mode"),
                                   cont=url_for('home', username=g.username))
    return render_template(os.path.join('html', 'upload.html'),
                           username=g.username,
                           sage_version=SAGE_VERSION)
Beispiel #27
0
def new_worksheet():
    if g.notebook.readonly_user(g.username):
        return current_app.message(
            _("Account is in read-only mode"), cont=url_for("worksheet_listing.home", username=g.username)
        )

    W = g.notebook.create_new_worksheet(gettext("Untitled"), g.username)
    return redirect(url_for_worksheet(W))
Beispiel #28
0
def public_worksheet_download(id, title):
    from worksheet import unconditional_download
    worksheet_filename =  "pub" + "/" + id
    try:
        worksheet = g.notebook.get_worksheet_with_filename(worksheet_filename)
    except KeyError:
        return current_app.message(_("You do not have permission to access this worksheet"))
    return unconditional_download(worksheet, title)
Beispiel #29
0
def public_worksheet_cells(id, filename):
    worksheet_filename =  "pub" + "/" + id
    try:
        worksheet = g.notebook.get_worksheet_with_filename(worksheet_filename)
    except KeyError:
        return current_app.message("You do not have permission to access this worksheet") #XXX: i18n
    from flask.helpers import send_from_directory
    return send_from_directory(worksheet.cells_directory(), filename)
Beispiel #30
0
def new_worksheet():
    if g.notebook.readonly_user(g.username):
        return current_app.message(_("Account is in read-only mode"),
                                   cont=url_for('worksheet_listing.home',
                                                username=g.username))

    W = g.notebook.create_new_worksheet(gettext("Untitled"), g.username)
    return redirect(url_for_worksheet(W))
Beispiel #31
0
def forgot_pass():
    if not g.notebook.conf()['email']:
        return current_app.message('The account recovery system is not active.')

    username = request.values.get('username', '').strip()
    if not username:
        return render_template(os.path.join('html', 'accounts', 'account_recovery.html'))

    def error(msg):
        return current_app.message(msg, url_for('forgot_pass'))

    try:
        user = g.notebook.user(request.values[username])
    except KeyError:
        return error('Username is invalid.')

    if not user.is_email_confirmed():
        return error("The e-mail address hasn't been confirmed.")

    #XXX: some of this could be factored out into a random passowrd
    #function.  There are a few places in admin.py that also use it.
    from random import choice
    import string
    chara = string.letters + string.digits
    old_pass = user.password()
    password = ''.join([choice(chara) for i in range(8)])
    user.set_password(password)

    from sagenb.notebook.smtpsend import send_mail
    from sagenb.notebook.register import build_password_msg
    # TODO: make this come from the server settings

    listenaddr = g.notebook.interface
    port = g.notebook.port
    fromaddr = 'no-reply@%s' % listenaddr
    body = build_password_msg(password, username, listenaddr, port, g.notebook.secure)
    destaddr = user.get_email()
    try:
        send_mail(fromaddr, destaddr, "Sage Notebook Account Recovery", body)
    except ValueError:
        # the email address is invalid
        user.set_password(old_pass)
        return error("The new password couldn't be sent."%destaddr)

    return current_app.message("A new password has been sent to your e-mail address.", url_for('base.index'))
Beispiel #32
0
def worksheet_rate(worksheet):
    ## if user_type(self.username) == "guest":
    ##     return HTMLResponse(stream = message(
    ##         'You must <a href="/">login first</a> in order to rate this worksheet.', ret))

    rating = int(request.values['rating'])
    if rating < 0 or rating >= 5:
        return current_app.message(_("Gees -- You can't fool the rating system that easily!"),
                          url_for_worksheet(worksheet), username=g.username)

    comment = request.values['comment']
    worksheet.rate(rating, comment, g.username)
    s = _("""
    Thank you for rating the worksheet <b><i>%(worksheet_name)s</i></b>!
    You can <a href="rating_info">see all ratings of this worksheet.</a>
    """, worksheet_name=worksheet.name())
    #XXX: Hardcoded url
    return current_app.message(s.strip(), '/pub/', title=_('Rating Accepted'), username=g.username)
Beispiel #33
0
def render_worksheet_list(args, pub, username):
    """
    Returns a rendered worksheet listing.

    INPUT:

    -  ``args`` - ctx.args where ctx is the dict passed
       into a resource's render method

    -  ``pub`` - boolean, True if this is a listing of
       public worksheets

    -  ``username`` - the user whose worksheets we are
       listing
       
    - ``kwds`` - additional info for template rendering

    OUTPUT:

    a string
    """

    from sagenb.notebook.notebook import sort_worksheet_list
    from sagenb.misc.misc import unicode_str, SAGE_VERSION

    typ = args['typ'] if 'typ' in args else 'active'
    search = unicode_str(args['search']) if 'search' in args else None
    sort = args['sort'] if 'sort' in args else 'last_edited'
    reverse = (args['reverse'] == 'True') if 'reverse' in args else False
    readonly = g.notebook.readonly_user(g.username)
    try:
        if not pub:
            worksheets = g.notebook.worksheet_list_for_user(username,
                                                            typ=typ,
                                                            sort=sort,
                                                            search=search,
                                                            reverse=reverse)
        else:
            worksheets = g.notebook.worksheet_list_for_public(username,
                                                              sort=sort,
                                                              search=search,
                                                              reverse=reverse)
    except ValueError as E:
        # for example, the sort key was not valid
        print "Error displaying worksheet listing: ", E
        return current_app.message(_("Error displaying worksheet listing."))

    worksheet_filenames = [x.filename() for x in worksheets]

    if pub and (not username or username == tuple([])):
        username = '******'

    accounts = g.notebook.user_manager().get_accounts()
    sage_version = SAGE_VERSION
    site_name = g.site_name
    return render_template('html/worksheet_listing.html', **locals())
Beispiel #34
0
def confirm():
    if not g.notebook.conf()['email']:
        return current_app.message(_('The confirmation system is not active.'))
    key = int(request.values.get('key', '-1'))
    
    invalid_confirm_key = _("""\
    <h1>Invalid confirmation key</h1>
    <p>You are reporting a confirmation key that has not been assigned by this
    server. Please <a href="/register">register</a> with the server.</p>
    """)
    try:
        username = waiting[key]
        user = g.notebook.user(username)
        user.set_email_confirmation(True)
    except KeyError:
        return current_app.message(invalid_confirm_key, '/register')
    success = _("""<h1>Email address confirmed for user %(username)s</h1>""", username=username)
    del waiting[key]
    return current_app.message(success, title=_('Email Confirmed'))
Beispiel #35
0
def home(username):
    if not g.notebook.user_manager().user_is_admin(
            g.username) and username != g.username:
        return current_app.message(
            _("User '%(user)s' does not have permission to view the home page of '%(name)s'.",
              user=g.username,
              name=username))
    else:
        return render_worksheet_list(request.args,
                                     pub=False,
                                     username=username)
Beispiel #36
0
def worksheet_datafile(worksheet):
    #XXX: This requires that the worker filesystem be accessible from
    #the server.
    dir = os.path.abspath(worksheet.data_directory())
    filename = request.values['name']
    if request.values.get('action', '') == 'delete':
        path = os.path.join(dir, filename)
        os.unlink(path)
        return current_app.message("Successfully deleted '%s'"%filename) #XXX: i18n
    else:
        return g.notebook.html_download_or_delete_datafile(worksheet, g.username, filename)
Beispiel #37
0
def worksheet_datafile(worksheet):
    #XXX: This requires that the worker filesystem be accessible from
    #the server.
    dir = os.path.abspath(worksheet.data_directory())
    filename = request.values['name']
    if request.values.get('action', '') == 'delete':
        path = os.path.join(dir, filename)
        os.unlink(path)
        return current_app.message(_("Successfully deleted '%(filename)s'", filename=filename),
                                   cont=url_for_worksheet(worksheet), username=g.username)
    else:
        return g.notebook.html_download_or_delete_datafile(worksheet, g.username, filename)
Beispiel #38
0
def worksheet_link_datafile(worksheet):
    target_worksheet_filename = request.values['target']
    data_filename = request.values['filename']
    src = os.path.abspath(os.path.join(
        worksheet.data_directory(), data_filename))
    target_ws =  g.notebook.get_worksheet_with_filename(target_worksheet_filename)
    target = os.path.abspath(os.path.join(
        target_ws.data_directory(), data_filename))
    if target_ws.owner() != g.username and not target_ws.is_collaborator(g.username):
        return current_app.message("illegal link attempt!") #XXX: i18n
    os.system('ln "%s" "%s"'%(src, target))
    return redirect(worksheet_link_datafile.url_for(worksheet, name=data_filename))
Beispiel #39
0
def worksheet_list():
    """
    Returns a worksheet listing.

    INPUT:

    -  ``args`` - ctx.args where ctx is the dict passed
       into a resource's render method

    -  ``pub`` - boolean, True if this is a listing of
       public worksheets

    -  ``username`` - the user whose worksheets we are
       listing

    OUTPUT:

    a string
    """
    
    from sagenb.notebook.notebook import sort_worksheet_list
    from sagenb.misc.misc import unicode_str, SAGE_VERSION
    from sagenb.notebook.misc import encode_response
    
    r = {}

    pub = 'pub' in request.args    
    readonly = g.notebook.readonly_user(g.username)
    typ = request.args['type'] if 'type' in request.args else 'active'
    search = unicode_str(request.args['search']) if 'search' in request.args else None
    sort = request.args['sort'] if 'sort' in request.args else 'last_edited'
    reverse = (request.args['reverse'] == 'True') if 'reverse' in request.args else False
    try:
        if not pub:
            r['worksheets'] = [x.basic() for x in g.notebook.worksheet_list_for_user(g.username, typ=typ, sort=sort, search=search, reverse=reverse)]
        else:
            r['worksheets'] = [x.basic() for x in g.notebook.worksheet_list_for_public(g.username, sort=sort, search=search, reverse=reverse)]

    except ValueError as E:
        # for example, the sort key was not valid
        print "Error displaying worksheet listing: ", E
        return current_app.message(_("Error displaying worksheet listing."))

    #if pub and (not g.username or g.username == tuple([])):
    #    r['username'] = '******'

    r['accounts'] = g.notebook.user_manager().get_accounts()
    r['sage_version'] = SAGE_VERSION
    # r['pub'] = pub
    
    return encode_response(r)
Beispiel #40
0
def worksheet_link_datafile(worksheet):
    target_worksheet_filename = request.values['target']
    data_filename = request.values['filename']
    src = os.path.abspath(
        os.path.join(worksheet.data_directory(), data_filename))
    target_ws = g.notebook.get_worksheet_with_filename(
        target_worksheet_filename)
    target = os.path.abspath(
        os.path.join(target_ws.data_directory(), data_filename))
    if target_ws.owner() != g.username and not target_ws.is_collaborator(
            g.username):
        return current_app.message("illegal link attempt!")  #XXX: i18n
    os.system('ln "%s" "%s"' % (src, target))
    return redirect(
        worksheet_link_datafile.url_for(worksheet, name=data_filename))
Beispiel #41
0
def render_worksheet_list(args, pub, username):
    """
    Returns a rendered worksheet listing.

    INPUT:

    -  ``args`` - ctx.args where ctx is the dict passed
       into a resource's render method

    -  ``pub`` - boolean, True if this is a listing of
       public worksheets

    -  ``username`` - the user whose worksheets we are
       listing

    OUTPUT:

    a string
    """

    from sagenb.notebook.notebook import sort_worksheet_list
    from sagenb.misc.misc import unicode_str, SAGE_VERSION

    typ = args['typ'] if 'typ' in args else 'active'
    search = unicode_str(args['search']) if 'search' in args else None
    sort = args['sort'] if 'sort' in args else 'last_edited'
    reverse = (args['reverse'] == 'True') if 'reverse' in args else False
    readonly = g.notebook.readonly_user(g.username)
    try:
        if not pub:
            worksheets = g.notebook.worksheet_list_for_user(username, typ=typ, sort=sort,
                                                              search=search, reverse=reverse)
        else:
            worksheets = g.notebook.worksheet_list_for_public(username, sort=sort,
                                                                search=search, reverse=reverse)
    except ValueError as E:
        # for example, the sort key was not valid
        print "Error displaying worksheet listing: ", E
        return current_app.message(_("Error displaying worksheet listing."))

    worksheet_filenames = [x.filename() for x in worksheets]

    if pub and (not username or username == tuple([])):
        username = '******'

    accounts = g.notebook.user_manager().get_accounts()
    sage_version = SAGE_VERSION
    return render_template('html/worksheet_listing.html', **locals())
Beispiel #42
0
def unconditional_download(worksheet, title):
    from sagenb.misc.misc import tmp_filename
    from flask.helpers import send_file
    filename = tmp_filename() + '.sws'

    if title.endswith('.sws'):
        title = title[:-4]

    try:
        #XXX: Accessing the hard disk.
        g.notebook.export_worksheet(worksheet.filename(), filename, title)
    except KeyError:
        return current_app.message(_('No such worksheet.'))

    from flask.helpers import send_file
    return send_file(filename, mimetype='application/sage')
Beispiel #43
0
def unconditional_download(worksheet, title):
    from sagenb.misc.misc import tmp_filename
    from flask.helpers import send_file
    filename = tmp_filename() + '.sws'

    if title.endswith('.sws'):
        title = title[:-4]

    try:
        #XXX: Accessing the hard disk.
        g.notebook.export_worksheet(worksheet.filename(), filename, title)
    except KeyError:
        return current_app.message(_('No such worksheet.'))

    from flask.helpers import send_file
    return send_file(filename, mimetype='application/sage')
Beispiel #44
0
def add_user():
    from sagenb.notebook.misc import is_valid_username
    from sagenb.misc.misc import SAGE_VERSION

    template_dict = {
        "admin": g.notebook.user_manager().user(g.username).is_admin(),
        "username": g.username,
        "sage_version": SAGE_VERSION,
    }
    if "username" in request.values:
        if request.values["cancel"]:
            return redirect(url_for("users"))
        username = request.values["username"]
        if not is_valid_username(username):
            return render_template(
                os.path.join("html", "settings", "admin_add_user.html"),
                error="username_invalid",
                username_input=username,
                **template_dict
            )

        from random import choice
        import string

        chara = string.letters + string.digits
        password = "".join([choice(chara) for i in range(8)])
        if username in g.notebook.user_manager().usernames():
            return render_template(
                os.path.join("html", "settings", "admin_add_user.html"),
                error="username_taken",
                username_input=username,
                **template_dict
            )
        g.notebook.user_manager().add_user(username, password, "", force=True)

        message = _(
            "The temporary password for the new user <em>%(username)s</em> is <em>%(password)s</em>",
            username=username,
            password=password,
        )
        return current_app.message(message, cont="/adduser", title=_("New User"))
    else:
        return render_template(os.path.join("html", "settings", "admin_add_user.html"), **template_dict)
Beispiel #45
0
def worksheet_file(path):
    # Create a live Sage worksheet out of path and render it.
    if not os.path.exists(path):
        return current_app.message('Document does not exist.')

    doc_page_html = open(path).read()
    from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor
    doc_page = SphinxHTMLProcessor().process_doc_html(doc_page_html)

    title = extract_title(doc_page_html).replace('&mdash;', '--')
    doc_page = title + '\nsystem:sage\n\n' + doc_page

    W = doc_worksheet()
    W.edit_save(doc_page)

    #FIXME: For some reason, an extra cell gets added
    #so we remove it here.
    cells = W.cell_list()
    cells.pop()

    return g.notebook.html(worksheet_filename=W.filename(),
                           username=g.username)
Beispiel #46
0
def worksheet_file(path):
    # Create a live Sage worksheet out of path and render it.
    if not os.path.exists(path):
        return current_app.message('Document does not exist.')

    doc_page_html = open(path).read()
    from sagenb.notebook.docHTMLProcessor import SphinxHTMLProcessor
    doc_page = SphinxHTMLProcessor().process_doc_html(doc_page_html)

    title = extract_title(doc_page_html).replace('&mdash;','--')
    doc_page = title + '\nsystem:sage\n\n' + doc_page

    W = doc_worksheet()
    W.edit_save(doc_page)

    #FIXME: For some reason, an extra cell gets added
    #so we remove it here.
    cells = W.cell_list()
    cells.pop()

    return g.notebook.html(worksheet_filename=W.filename(),
                         username=g.username)
Beispiel #47
0
def add_user():
    from sagenb.notebook.twist import is_valid_username
    template_dict = {
        'admin': g.notebook.user_manager().user(g.username).is_admin(),
        'username': g.username
    }
    if 'username' in request.values:
        username = request.values['username']
        if not is_valid_username(username):
            return render_template(os.path.join('html', 'settings',
                                                'admin_add_user.html'),
                                   error='username_invalid',
                                   username=username,
                                   **template_dict)

        from random import choice
        import string
        chara = string.letters + string.digits
        password = ''.join([choice(chara) for i in range(8)])
        if username in g.notebook.user_manager().usernames():
            return render_template(os.path.join('html', 'settings',
                                                'admin_add_user.html'),
                                   error='username_taken',
                                   username_input=username,
                                   **template_dict)
        g.notebook.user_manager().add_user(username, password, '', force=True)

        #XXX: i18n
        return current_app.message(
            'The temporary password for the new user <em>%s</em> is <em>%s</em>'
            % (username, password),
            '/adduser',
            title=u'New User')
    else:
        return render_template(
            os.path.join('html', 'settings', 'admin_add_user.html'),
            **template_dict)
Beispiel #48
0
def upload_worksheet():
    from sage.misc.misc import tmp_filename, tmp_dir
    from werkzeug.utils import secure_filename
    import zipfile

    if g.notebook.readonly_user(g.username):
        return current_app.message(_("Account is in read-only mode"), cont=url_for('home', username=g.username))

    backlinks = _("""Return to <a href="/upload" title="Upload a worksheet"><strong>Upload File</strong></a>.""")

    url = request.values['url'].strip()
    dir = ''
    if url != '':
        #Downloading a file from the internet
        # The file will be downloaded from the internet and saved
        # to a temporary file with the same extension
        path = urlparse.urlparse(url).path
        extension = os.path.splitext(path)[1].lower()
        if extension not in ["", ".txt", ".sws", ".zip", ".html", ".rst"]:
            # Or shall we try to import the document as an sws when in doubt?
            return current_app.message("Unknown worksheet extension: %s. %s" % (extension, backlinks))
        filename = tmp_filename()+extension
        try:
            import re
            matches = re.match("file://(?:localhost)?(/.+)", url)
            if matches:
                if g.notebook.interface != 'localhost':
                    return current_app.message(_("Unable to load file URL's when not running on localhost.\n%(backlinks)s",backlinks=backlinks))

                import shutil
                shutil.copy(matches.group(1),filename)
            else:
                my_urlretrieve(url, filename, backlinks=backlinks)

        except RetrieveError as err:
            return current_app.message(str(err))

    else:
        #Uploading a file from the user's computer
        dir = tmp_dir()
        file = request.files['file']
        if file.filename is None:
            return current_app.message(_("Please specify a worksheet to load.\n%(backlinks)s",backlinks=backlinks))

        filename = secure_filename(file.filename)
        if len(filename)==0:
            return current_app.message(_("Invalid filename.\n%(backlinks)s",backlinks=backlinks))

        filename = os.path.join(dir, filename)
        file.save(filename)

    new_name = request.values.get('name', None)

    try:
        try:
            if filename.endswith('.zip'):
                # Extract all the .sws files from a zip file.
                zip_file = zipfile.ZipFile(filename)
                for subfilename in zip_file.namelist():
                    prefix, extension = os.path.splitext(subfilename)
                    # Mac zip files contain files like __MACOSX/._worksheet.sws
                    # which are metadata files, so we skip those as
                    # well as any other files we won't understand
                    if extension in ['.sws', '.html', '.txt', '.rst'] and not prefix.startswith('__MACOSX/'):
                        tmpfilename = os.path.join(dir, "tmp" + extension)
                        try:
                            tmpfilename = zip_file.extract(subfilename, tmpfilename)
                        except AttributeError:
                            open(tmpfilename, 'w').write(zip_file.read(subfilename))
                        W = g.notebook.import_worksheet(tmpfilename, g.username)
                        if new_name:
                            W.set_name("%s - %s" % (new_name, W.name()))
                    else:
                        print "Unknown extension, file %s is ignored" % subfilename
                return redirect(url_for('home', username=g.username))

            else:
                if url and extension in ['', '.html']:
                    linked_sws = parse_link_rel(url, filename)
                    if linked_sws:
                        # just grab 1st URL; perhaps later add interface for
                        # downloading multiple linked .sws
                        try:
                            filename = my_urlretrieve(linked_sws[0]['url'], backlinks=backlinks)[0]
                            print 'Importing {0}, linked to from {1}'.format(linked_sws[0]['url'], url)
                        except RetrieveError as err:
                            return current_app.message(str(err))
                W = g.notebook.import_worksheet(filename, g.username)
        except Exception, msg:
            print 'error uploading worksheet', msg
            s = _('There was an error uploading the worksheet.  It could be an old unsupported format or worse.  If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet.  Alternatively, an sws file is just a bzip2 tarball; take a look inside!\n%(backlinks)s', backlinks=backlinks)
            return current_app.message(s, url_for('home', username=g.username))
        finally:
            # Clean up the temporarily uploaded filename.
            os.unlink(filename)
            # if a temp directory was created, we delete it now.
            if dir:
                import shutil
                shutil.rmtree(dir)
Beispiel #49
0
def upload():
    if g.notebook.readonly_user(g.username):
        return current_app.message(_("Account is in read-only mode"), cont=url_for('home', username=g.username))
    return render_template(os.path.join('html', 'upload.html'),
                           username=g.username)
Beispiel #50
0
def worksheet_do_upload_data(worksheet):
    worksheet_url = url_for_worksheet(worksheet)
    upload_url = worksheet_upload_data.url_for(worksheet)

    backlinks = _(
        """ Return to <a href="%(upload_url)s" title="Upload or create a data file in a wide range of formats"><strong>Upload or Create Data File</strong></a> or <a href="%(worksheet_url)s" title="Interactively use the worksheet"><strong>%(worksheet_name)s</strong></a>.""",
        upload_url=upload_url,
        worksheet_url=worksheet_url,
        worksheet_name=worksheet.name())

    if 'file' not in request.files:
        return current_app.message(_(
            'Error uploading file (missing field "file"). %(backlinks)s',
            backlinks=backlinks),
                                   worksheet_url,
                                   username=g.username)
    else:
        file = request.files['file']

    text_fields = ['url', 'new', 'name']
    for field in text_fields:
        if field not in request.values:
            return current_app.message(_(
                'Error uploading file (missing %(field)s arg).%(backlinks)s',
                field=field,
                backlinks=backlinks),
                                       worksheet_url,
                                       username=g.username)

    name = request.values.get('name', '').strip()
    new_field = request.values.get('new', '').strip()
    url = request.values.get('url', '').strip()

    name = name or file.filename or new_field
    if url and not name:
        name = url.split('/')[-1]
    name = secure_filename(name)

    if not name:
        return current_app.message(
            _('Error uploading file (missing filename).%(backlinks)s',
              backlinks=backlinks), worksheet_url)

    if url != '':
        import urllib2
        from urlparse import urlparse
        # we normalize the url by parsing it first
        parsedurl = urlparse(url)
        if not parsedurl[0] in ('http', 'https', 'ftp'):
            return current_app.message(_(
                'URL must start with http, https, or ftp.%(backlinks)s',
                backlinks=backlinks),
                                       worksheet_url,
                                       username=g.username)
        download = urllib2.urlopen(parsedurl.geturl())

    #XXX: disk access
    dest = os.path.join(worksheet.data_directory(), name)
    if os.path.exists(dest):
        if not os.path.isfile(dest):
            return current_app.message(_(
                'Suspicious filename "%(filename)s" encountered uploading file.%(backlinks)s',
                filename=filename,
                backlinks=backlinks),
                                       worksheet_url,
                                       username=g.username)
        os.unlink(dest)

    response = redirect(worksheet_datafile.url_for(worksheet, name=name))

    matches = re.match("file://(?:localhost)?(/.+)", url)
    if matches:
        f = file(dest, 'wb')
        f.write(open(matches.group(1)).read())
        f.close()
        return response

    elif url != '':
        with open(dest, 'w') as f:
            f.write(download.read())
        return response
    elif new_field:
        open(dest, 'w').close()
        return response
    else:
        file.save(dest)
        return response
Beispiel #51
0
                            print 'Importing {0}, linked to from {1}'.format(
                                linked_sws[0]['url'], url)
                        except RetrieveError as err:
                            return current_app.message(str(err))
                W = g.notebook.import_worksheet(filename, g.username)
        except Exception, msg:
            print 'error uploading worksheet', msg
            s = _(
                'There was an error uploading the worksheet.  It could be an old unsupported format or worse.  If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet.  Alternatively, an sws file is just a bzip2 tarball; take a look inside!\n%(backlinks)s',
                backlinks=backlinks)
            return current_app.message(s, url_for('home', username=g.username))
        finally:
            # Clean up the temporarily uploaded filename.
            os.unlink(filename)
            # if a temp directory was created, we delete it now.
            if dir:
                import shutil
                shutil.rmtree(dir)

    except ValueError, msg:
        s = _("Error uploading worksheet '%(msg)s'.%(backlinks)s",
              msg=msg,
              backlinks=backlinks)
        return current_app.message(s, url_for('home', username=g.username))

    if new_name:
        W.set_name(new_name)

    from worksheet import url_for_worksheet
    return redirect(url_for_worksheet(W))
Beispiel #52
0
def upload_worksheet():
    from sage.misc.all import tmp_filename, tmp_dir
    from werkzeug.utils import secure_filename
    import zipfile

    if g.notebook.readonly_user(g.username):
        return current_app.message(_("Account is in read-only mode"),
                                   cont=url_for('home', username=g.username))

    backlinks = _(
        """Return to <a href="/upload" title="Upload a worksheet"><strong>Upload File</strong></a>."""
    )

    url = request.values['url'].strip()
    dir = ''
    if url != '':
        #Downloading a file from the internet
        # The file will be downloaded from the internet and saved
        # to a temporary file with the same extension
        path = urlparse.urlparse(url).path
        extension = os.path.splitext(path)[1].lower()
        if extension not in ["", ".txt", ".sws", ".zip", ".html", ".rst"]:
            # Or shall we try to import the document as an sws when in doubt?
            return current_app.message(
                _("Unknown worksheet extension: %(ext)s. %(links)s",
                  ext=extension,
                  links=backlinks))
        filename = tmp_filename() + extension
        try:
            import re
            matches = re.match("file://(?:localhost)?(/.+)", url)
            if matches:
                if g.notebook.interface != 'localhost':
                    return current_app.message(
                        _("Unable to load file URL's when not running on localhost.\n%(backlinks)s",
                          backlinks=backlinks))

                import shutil
                shutil.copy(matches.group(1), filename)
            else:
                my_urlretrieve(url, filename, backlinks=backlinks)

        except RetrieveError as err:
            return current_app.message(str(err))

    else:
        #Uploading a file from the user's computer
        dir = tmp_dir()
        file = request.files['file']
        if file.filename is None:
            return current_app.message(
                _("Please specify a worksheet to load.\n%(backlinks)s",
                  backlinks=backlinks))

        filename = secure_filename(file.filename)
        if len(filename) == 0:
            return current_app.message(
                _("Invalid filename.\n%(backlinks)s", backlinks=backlinks))

        filename = os.path.join(dir, filename)
        file.save(filename)

    new_name = request.values.get('name', None)

    try:
        try:
            if filename.endswith('.zip'):
                # Extract all the .sws files from a zip file.
                zip_file = zipfile.ZipFile(filename)
                for subfilename in zip_file.namelist():
                    prefix, extension = os.path.splitext(subfilename)
                    # Mac zip files contain files like __MACOSX/._worksheet.sws
                    # which are metadata files, so we skip those as
                    # well as any other files we won't understand
                    if extension in ['.sws', '.html', '.txt', '.rst'
                                     ] and not prefix.startswith('__MACOSX/'):
                        tmpfilename = os.path.join(dir, "tmp" + extension)
                        try:
                            tmpfilename = zip_file.extract(
                                subfilename, tmpfilename)
                        except AttributeError:
                            open(tmpfilename,
                                 'w').write(zip_file.read(subfilename))
                        W = g.notebook.import_worksheet(
                            tmpfilename, g.username)
                        if new_name:
                            W.set_name("%s - %s" % (new_name, W.name()))
                    else:
                        print "Unknown extension, file %s is ignored" % subfilename
                return redirect(url_for('home', username=g.username))

            else:
                if url and extension in ['', '.html']:
                    linked_sws = parse_link_rel(url, filename)
                    if linked_sws:
                        # just grab 1st URL; perhaps later add interface for
                        # downloading multiple linked .sws
                        try:
                            filename = my_urlretrieve(linked_sws[0]['url'],
                                                      backlinks=backlinks)[0]
                            print 'Importing {0}, linked to from {1}'.format(
                                linked_sws[0]['url'], url)
                        except RetrieveError as err:
                            return current_app.message(str(err))
                W = g.notebook.import_worksheet(filename, g.username)
        except Exception, msg:
            print 'error uploading worksheet', msg
            s = _(
                'There was an error uploading the worksheet.  It could be an old unsupported format or worse.  If you desperately need its contents contact the <a href="http://groups.google.com/group/sage-support">sage-support group</a> and post a link to your worksheet.  Alternatively, an sws file is just a bzip2 tarball; take a look inside!\n%(backlinks)s',
                backlinks=backlinks)
            return current_app.message(s, url_for('home', username=g.username))
        finally:
            # Clean up the temporarily uploaded filename.
            os.unlink(filename)
            # if a temp directory was created, we delete it now.
            if dir:
                import shutil
                shutil.rmtree(dir)
Beispiel #53
0
def home(username):
    if not g.notebook.user_manager().user_is_admin(g.username) and username != g.username:
        #XXX: i18n
        return current_app.message("User '%s' does not have permission to view the home page of '%s'."%(g.username, username))
    else:
        return render_worksheet_list(request.args, pub=False, username=username)
Beispiel #54
0
def settings_page():
    error = None
    redirect_to_home = None
    redirect_to_logout = None
    nu = g.notebook.user_manager().user(g.username)

    autosave = int(request.values.get('autosave', 0))*60
    if autosave:
        nu['autosave_interval'] = autosave
        redirect_to_home = True

    old = request.values.get('old-pass', None)
    new = request.values.get('new-pass', None)
    two = request.values.get('retype-pass', None)

    if new or two:
        if not old:
            error = 'Old password not given'
        elif not g.notebook.user_manager().check_password(g.username, old):
            error = 'Incorrect password given'
        elif not new:
            error = 'New password not given'
        elif not two:
            error = 'Please type in new password again.'
        elif new != two:
            error = 'The passwords you entered do not match.'

        if not error:
            # The browser may auto-fill in "old password," even
            # though the user may not want to change her password.
            g.notebook.user_manager().set_password(g.username, new)
            redirect_to_logout = True

    if g.notebook.conf()['email']:
        newemail = request.values.get('new-email', None)
        if newemail:
            nu.set_email(newemail)
            ##nu.set_email_confirmation(False)
            redirect_to_home = True

    if error:
        return current_app.message(error, url_for('settings_page'))

    if redirect_to_logout:
        return redirect(url_for('authentication.logout'))

    if redirect_to_home:
        return redirect(url_for('worksheet_listing.home', username=g.username))

    td = {}
    td['username'] = g.username

    td['autosave_intervals'] = ((i, ' selected') if nu['autosave_interval']/60 == i else (i, '') for i in range(1, 10, 2))

    td['email'] = g.notebook.conf()['email']
    if td['email']:
        td['email_address'] = nu.get_email() or 'None'
        if nu.is_email_confirmed():
            td['email_confirmed'] = 'Confirmed'
        else:
            td['email_confirmed'] = 'Not confirmed'

    td['admin'] = nu.is_admin()

    return render_template(os.path.join('html', 'settings', 'account_settings.html'), **td)
 def error(msg):
     return current_app.message(msg, url_for('forgot_pass'))
Beispiel #56
0
 def error(msg):
     return current_app.message(msg, url_for("forgot_pass"))
Beispiel #57
0
def doc_live_base():
    return current_app.message('nothing to see.', username=g.username)