Ticket #637: sage-637.patch

File sage-637.patch, 9.6 KB (added by was, 13 years ago)
  • sage/server/notebook/notebook.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1210482158 25200
    # Node ID 491affdce3fafbad8129208b2a5665497aaca464
    # Parent  eec6e44c279adeb4dd276879060b2acafdf52c1a
    trac #637 -- notebook improvement -- upload allow txt worksheets.
      1. Implement uploading .txt files (plain text worksheets).
      2. Add lots of related documentation, docstrings, doctests, etc., and clean up some related code.
    
    diff -r eec6e44c279a -r 491affdce3fa sage/server/notebook/notebook.py
    a b class Notebook(SageObject): 
    149149        except AttributeErrro:
    150150            dir = self.__dir
    151151        import shutil
    152         shutil.rmtree(dir)
     152        # We ignore_errors because in rare parallel doctesting
     153        # situations sometimes the directory gets cleaned up too
     154        # quickly, etc.
     155        shutil.rmtree(dir, ignore_errors=True)
    153156
    154157    ##########################################################
    155158    # Users
    class Notebook(SageObject): 
    726729    ##########################################################
    727730    # Importing and exporting worksheets to files
    728731    ##########################################################
    729     def export_worksheet(self, worksheet_filename, output_filename):
     732    def export_worksheet(self, worksheet_filename, output_filename, verbose=True):
     733        """
     734        Export a worksheet with given directory filenmae to output_filename.
     735       
     736        INPUT:
     737            worksheet_filename -- string
     738            output_filename -- string
     739            verbose -- bool (default: True) if True print some the tar
     740                       command used to extract the sws file.
     741                       
     742        OUTPUT:
     743            creates a file on the filesystem
     744        """
    730745        W = self.get_worksheet_with_filename(worksheet_filename)
    731746        W.save()
    732747        path = W.filename_without_owner()
    733748        cmd = 'cd "%s/%s/" && tar -jcf "%s" "%s"'%(
    734749            self.__worksheet_dir, W.owner(),
    735750            os.path.abspath(output_filename), path)
     751        if verbose:
     752            print cmd
    736753        e = os.system(cmd)
    737754        if e:
    738755            print "Failed to execute command to export worksheet:\n'%s'"%cmd
    class Notebook(SageObject): 
    752769        r"""
    753770        Upload the worksheet with name \var{filename} and make it have the
    754771        given owner.
     772
     773        INPUT:
     774            filename -- a string
     775            owner -- a string
     776           
     777        OUTPUT:
     778            worksheet -- a newly created worksheet
     779
     780        EXAMPLES:
     781        We create a notebook and import a plain text worksheet into it.
     782            sage: nb = sage.server.notebook.notebook.Notebook('notebook-test')
     783            sage: open('a.txt','w').write('foo\n{{{\n2+3\n}}}')
     784            sage: W = nb.import_worksheet('a.txt', 'admin')
     785
     786        W is our newly-created worksheet, with the 2+3 cell in it:
     787            sage: W.name()
     788            'foo'
     789            sage: W.cell_list()
     790            [Cell 0; in=2+3, out=]
     791            sage: nb.delete()
    755792        """
    756793        if not os.path.exists(filename):
    757794            raise ValueError, "no file %s"%filename
    758795
     796        # Figure out the file extension
     797        ext = os.path.splitext(filename)[1]
     798        if ext == '.txt':
     799            # A plain text file with {{{'s that defines a worksheet (not graphics).
     800            return self._import_worksheet_txt(filename, owner)
     801        elif ext == '.sws':
     802            # An sws file (really a tar.bz2) which defines a worksheet with graphics,
     803            # revisions, etc.
     804            return self._import_worksheet_sws(filename, owner)
     805        else:
     806            # We only support txt or sws files.
     807            raise ValueError, "unknown extension '%s'"%ext
     808           
     809    def _import_worksheet_txt(self, filename, owner):
     810        """
     811        Import a plain text file as a new worksheet.
     812
     813        INPUT:
     814            filename -- string; a filename that ends in .txt
     815            owner -- string; who will own this worksheet when imported
     816
     817        OUTPUT:
     818            a new worksheet
     819
     820        EXAMPLES:
     821        We create a worksheet, make a file, and import it using this function.
     822            sage: nb = sage.server.notebook.notebook.Notebook('notebook-test')
     823            sage: open('a.txt','w').write('foo\n{{{\na = 10\n}}}')
     824            sage: W = nb._import_worksheet_txt('a.txt', 'admin'); W
     825            [Cell 0; in=a = 10, out=]
     826            sage: nb.delete()       
     827        """
     828        # Open the worksheet txt file and load it in.
     829        worksheet_txt = open(filename).read()
     830        # Create a new worksheet with the write title and owner.
     831        worksheet = self.new_worksheet_with_title_from_text(worksheet_txt, owner)
     832        # Set the new worksheet to have the contents specified by that file.
     833        worksheet.edit_save(worksheet_txt)
     834        return worksheet
     835   
     836    def _import_worksheet_sws(self, filename, owner, verbose=True):
     837        """
     838        Import an sws format worksheet into this notebook as a new worksheet.
     839
     840        INPUT:
     841            filename -- string; a filename that ends in .sws; internally
     842                        it must be a tar'd bz2'd file.
     843            owner -- string
     844            verbose -- bool (default: True) if True print some the tar
     845                       command used to extract the sws file.
     846
     847        OUTPUT:
     848            a new worksheet
     849
     850        EXAMPLES:
     851        We create a notebook, then make a worksheet from a plain text file first.
     852            sage: nb = sage.server.notebook.notebook.Notebook('notebook-test')
     853            sage: open('a.txt','w').write('foo\n{{{\n2+3\n}}}')
     854            sage: W = nb.import_worksheet('a.txt', 'admin')
     855            sage: W.filename()
     856            'admin/0'
     857
     858
     859        We then export the worksheet to an sws file.
     860            sage: nb.export_worksheet(W.filename(),  'tmp.sws', verbose=False)
     861
     862        Now we import the sws.
     863            sage: nb._import_worksheet_sws('tmp.sws', 'admin', verbose=False)
     864            [Cell 0; in=2+3, out=]
     865
     866        Yep, it's there now (as admin/2):
     867            sage: nb.worksheet_names()
     868            ['admin/0', 'admin/2']
     869            sage: nb.delete()
     870        """
    759871        # Decompress the worksheet to a temporary directory.
    760872        tmp = tmp_dir()
    761873        cmd = 'cd "%s"; tar -jxf "%s"'%(tmp, os.path.abspath(filename))
    762         print cmd
     874        if verbose:
     875            print cmd
    763876        e = os.system(cmd)
    764877        if e:
    765878            raise ValueError, "Error decompressing saved worksheet."
    function save_worksheet_and_close() { 
    19142027            <body>
    19152028              <div class="upload_worksheet_menu" id="upload_worksheet_menu">
    19162029              %s
    1917               <h1><font size=+1>Upload worksheet from your computer to the Sage Notebook</font></h1>
     2030              <h1><font size=+1>Upload worksheet (an sws or txt file) to the Sage Notebook</font></h1>
    19182031              <hr>
    19192032              <form method="POST" action="upload_worksheet"
    19202033                    name="upload" enctype="multipart/form-data">
  • sage/server/notebook/twist.py

    diff -r eec6e44c279a -r 491affdce3fa sage/server/notebook/twist.py
    a b HISTORY_MAX_OUTPUT = 92*5 
    3535HISTORY_MAX_OUTPUT = 92*5
    3636HISTORY_NCOLS = 90
    3737
    38 from sage.misc.misc import SAGE_EXTCODE, SAGE_LOCAL, walltime, tmp_filename
     38from sage.misc.misc import SAGE_EXTCODE, SAGE_LOCAL, walltime, tmp_filename, tmp_dir
    3939from sage.misc.remote_file import get_remote_file
    4040
    4141p = os.path.join
    class UploadWorksheet(resource.PostableR 
    306306       
    307307    def render(self, ctx):
    308308        url = ctx.args['urlField'][0].strip()
     309        dir = ''  # we will delete the directory below if it is used
    309310        if url != '':
     311            # downloading a file from the internet
    310312            tmp = get_remote_file(url, verbose=True)
    311313        else:
    312             tmp = '%s/tmp.sws'%notebook.directory()
    313             f = file(tmp,'wb')
    314 
    315             # Blocking issues (?!)
     314            # uploading a file from the user's computer
     315            dir = tmp_dir()
     316            filename = ctx.files['fileField'][0][0]
     317            # Make tmp file in SAGE temp directory
     318            filename = '%s/%s'%(dir, filename)
     319            f = file(filename,'wb')
     320            # Then download to that file.
    316321            f.write(ctx.files['fileField'][0][2].read())
     322            # TODO: Server blocking issues (?!)
    317323            f.close()
    318324
    319325        try:
    320             W = notebook.import_worksheet(tmp, self.username)
    321             os.unlink(tmp)
    322             if ctx.args.has_key('nameField'):
    323                 new_name = ctx.args['nameField'][0].strip()
    324                 if new_name:
    325                     W.set_name(new_name)
     326            W = notebook.import_worksheet(filename, self.username)
     327            os.unlink(filename)
     328            # if a temp directory was created, we delete it now.
     329            if dir:
     330                shutil.rmtree(dir)
     331
    326332        except ValueError, msg:
    327333            s = "Error uploading worksheet '%s'."%msg
    328334            return http.Response(stream = message(s, '/'))
    329335
    330         name = ctx.args['nameField'][0].strip()
    331         if len(name) > 0:
    332             W.set_name(name)
    333            
     336        # If the user requested in the form a specific title for
     337        # the worksheet set it.
     338        if ctx.args.has_key('nameField'):
     339            new_name = ctx.args['nameField'][0].strip()
     340            if new_name:
     341                W.set_name(new_name)
     342               
    334343        return http.RedirectResponse('/home/'+W.filename())
    335344       
    336345