Ticket #637: sage-637.patch
File sage-637.patch, 9.6 KB (added by , 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): 149 149 except AttributeErrro: 150 150 dir = self.__dir 151 151 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) 153 156 154 157 ########################################################## 155 158 # Users … … class Notebook(SageObject): 726 729 ########################################################## 727 730 # Importing and exporting worksheets to files 728 731 ########################################################## 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 """ 730 745 W = self.get_worksheet_with_filename(worksheet_filename) 731 746 W.save() 732 747 path = W.filename_without_owner() 733 748 cmd = 'cd "%s/%s/" && tar -jcf "%s" "%s"'%( 734 749 self.__worksheet_dir, W.owner(), 735 750 os.path.abspath(output_filename), path) 751 if verbose: 752 print cmd 736 753 e = os.system(cmd) 737 754 if e: 738 755 print "Failed to execute command to export worksheet:\n'%s'"%cmd … … class Notebook(SageObject): 752 769 r""" 753 770 Upload the worksheet with name \var{filename} and make it have the 754 771 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() 755 792 """ 756 793 if not os.path.exists(filename): 757 794 raise ValueError, "no file %s"%filename 758 795 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 """ 759 871 # Decompress the worksheet to a temporary directory. 760 872 tmp = tmp_dir() 761 873 cmd = 'cd "%s"; tar -jxf "%s"'%(tmp, os.path.abspath(filename)) 762 print cmd 874 if verbose: 875 print cmd 763 876 e = os.system(cmd) 764 877 if e: 765 878 raise ValueError, "Error decompressing saved worksheet." … … function save_worksheet_and_close() { 1914 2027 <body> 1915 2028 <div class="upload_worksheet_menu" id="upload_worksheet_menu"> 1916 2029 %s 1917 <h1><font size=+1>Upload worksheet from your computerto the Sage Notebook</font></h1>2030 <h1><font size=+1>Upload worksheet (an sws or txt file) to the Sage Notebook</font></h1> 1918 2031 <hr> 1919 2032 <form method="POST" action="upload_worksheet" 1920 2033 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 35 35 HISTORY_MAX_OUTPUT = 92*5 36 36 HISTORY_NCOLS = 90 37 37 38 from sage.misc.misc import SAGE_EXTCODE, SAGE_LOCAL, walltime, tmp_filename 38 from sage.misc.misc import SAGE_EXTCODE, SAGE_LOCAL, walltime, tmp_filename, tmp_dir 39 39 from sage.misc.remote_file import get_remote_file 40 40 41 41 p = os.path.join … … class UploadWorksheet(resource.PostableR 306 306 307 307 def render(self, ctx): 308 308 url = ctx.args['urlField'][0].strip() 309 dir = '' # we will delete the directory below if it is used 309 310 if url != '': 311 # downloading a file from the internet 310 312 tmp = get_remote_file(url, verbose=True) 311 313 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. 316 321 f.write(ctx.files['fileField'][0][2].read()) 322 # TODO: Server blocking issues (?!) 317 323 f.close() 318 324 319 325 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 326 332 except ValueError, msg: 327 333 s = "Error uploading worksheet '%s'."%msg 328 334 return http.Response(stream = message(s, '/')) 329 335 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 334 343 return http.RedirectResponse('/home/'+W.filename()) 335 344 336 345