mirror of
https://src.fedoraproject.org/rpms/sagemath.git
synced 2025-04-18 10:19:03 -04:00
The sagemath notebook is discontinued and not ported to python3. This commit adds patches to make it start, have minimal functionality and show a disclaimer, explaining to user to use the jupyter notebook.
351 lines
18 KiB
Diff
351 lines
18 KiB
Diff
diff -up build/pkgs/sagenb/src/sagenb/flask_version/base.py.orig build/pkgs/sagenb/src/sagenb/flask_version/base.py
|
|
--- build/pkgs/sagenb/src/sagenb/flask_version/base.py.orig 2019-09-05 13:19:45.878376777 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/flask_version/base.py 2019-09-05 13:27:08.353250002 -0300
|
|
@@ -140,7 +140,7 @@ def localization_js():
|
|
locale=repr(get_locale())
|
|
if _localization_cache.get(locale,None) is None:
|
|
data = render_template(os.path.join('js/localization.js'), N_=N_, nN_=nN_)
|
|
- _localization_cache[locale] = (data, sha1(repr(data)).hexdigest())
|
|
+ _localization_cache[locale] = (data, sha1(repr(data).encode('ascii')).hexdigest())
|
|
data,datahash = _localization_cache[locale]
|
|
|
|
if request.environ.get('HTTP_IF_NONE_MATCH', None) == datahash:
|
|
@@ -158,7 +158,7 @@ def mathjax_js():
|
|
if _mathjax_js_cache is None:
|
|
from sagenb.misc.misc import mathjax_macros
|
|
data = render_template('js/mathjax_sage.js', theme_mathjax_macros=mathjax_macros)
|
|
- _mathjax_js_cache = (data, sha1(repr(data)).hexdigest())
|
|
+ _mathjax_js_cache = (data, sha1(repr(data).encode('ascii')).hexdigest())
|
|
data,datahash = _mathjax_js_cache
|
|
|
|
if request.environ.get('HTTP_IF_NONE_MATCH', None) == datahash:
|
|
@@ -173,7 +173,7 @@ def mathjax_js():
|
|
def keyboard_js(browser_os):
|
|
from sagenb.notebook.keyboards import get_keyboard
|
|
data = get_keyboard(browser_os)
|
|
- datahash=sha1(data).hexdigest()
|
|
+ datahash=sha1(str(data).encode('ascii')).hexdigest()
|
|
if request.environ.get('HTTP_IF_NONE_MATCH', None) == datahash:
|
|
response = make_response('',304)
|
|
else:
|
|
@@ -490,7 +490,7 @@ def create_app(path_to_notebook, *args,
|
|
filename = os.path.join(SRC, path)
|
|
if os.path.isfile(filename):
|
|
from cgi import escape
|
|
- src = escape(open(filename).read().decode('utf-8','ignore'))
|
|
+ src = escape(open(filename).read().decode('ascii'))
|
|
if (os.path.splitext(filename)[1] in
|
|
['.py','.c','.cc','.h','.hh','.pyx','.pxd']):
|
|
return render_template(os.path.join('html', 'source_code.html'),
|
|
diff -up build/pkgs/sagenb/src/sagenb/misc/format.py.orig build/pkgs/sagenb/src/sagenb/misc/format.py
|
|
--- build/pkgs/sagenb/src/sagenb/misc/format.py.orig 2019-09-05 13:20:21.507608139 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/misc/format.py 2019-09-05 13:27:08.353250002 -0300
|
|
@@ -126,7 +126,7 @@ import sys
|
|
sys.ps1 = "%s"
|
|
print("START%s")
|
|
%s
|
|
-""" % (prompt, number, displayhook_hack(string).encode('utf-8', 'ignore'))
|
|
+""" % (prompt, number, displayhook_hack(string).encode('ascii'))
|
|
try:
|
|
string = '# -*- coding: utf-8 -*-\n' + relocate_future_imports(string)
|
|
except SyntaxError:
|
|
diff -up build/pkgs/sagenb/src/sagenb/misc/misc.py.orig build/pkgs/sagenb/src/sagenb/misc/misc.py
|
|
--- build/pkgs/sagenb/src/sagenb/misc/misc.py.orig 2019-09-05 13:20:31.231671284 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/misc/misc.py 2019-09-05 13:27:08.354250008 -0300
|
|
@@ -424,7 +424,7 @@ def set_permissive_permissions(filename)
|
|
stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | \
|
|
stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)
|
|
|
|
-def encoded_str(obj, encoding='utf-8'):
|
|
+def encoded_str(obj, encoding='ascii'):
|
|
r"""
|
|
Takes an object and returns an encoded str human-readable representation.
|
|
|
|
@@ -445,7 +445,7 @@ def encoded_str(obj, encoding='utf-8'):
|
|
return binary_type(obj)
|
|
|
|
|
|
-def unicode_str(obj, encoding='utf-8'):
|
|
+def unicode_str(obj, encoding='ascii'):
|
|
r"""
|
|
Takes an object and returns a unicode human-readable representation.
|
|
|
|
diff -up build/pkgs/sagenb/src/sagenb/misc/support.py.orig build/pkgs/sagenb/src/sagenb/misc/support.py
|
|
--- build/pkgs/sagenb/src/sagenb/misc/support.py.orig 2019-09-05 13:20:40.258729902 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/misc/support.py 2019-09-05 13:27:08.356250022 -0300
|
|
@@ -279,7 +279,7 @@ def docstring(obj_name, globs, system='s
|
|
s += newline
|
|
s += sageinspect.sage_getdoc(obj, obj_name)
|
|
s = s.rstrip()
|
|
- return html_markup(s.decode('utf-8'))
|
|
+ return html_markup(s.decode('ascii'))
|
|
|
|
|
|
def html_markup(s):
|
|
@@ -433,7 +433,7 @@ def syseval(system, cmd, dir=None):
|
|
if hasattr(system.__class__, 'chdir'):
|
|
system.chdir(dir)
|
|
if isinstance(cmd, text_type):
|
|
- cmd = cmd.encode('utf-8', 'ignore')
|
|
+ cmd = cmd.encode('ascii')
|
|
return system.eval(cmd, sage_globals, locals=sage_globals)
|
|
|
|
######################################################################
|
|
diff -up build/pkgs/sagenb/src/sagenb/misc/worksheet2rst.py.orig build/pkgs/sagenb/src/sagenb/misc/worksheet2rst.py
|
|
--- build/pkgs/sagenb/src/sagenb/misc/worksheet2rst.py.orig 2019-09-05 13:20:49.848792176 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/misc/worksheet2rst.py 2019-09-05 13:27:08.356250022 -0300
|
|
@@ -200,5 +200,5 @@ if __name__=='__main__':
|
|
text = sys.stdin.read()
|
|
images_dir = sys.argv[2] if len(sys.argv)>2 else ''
|
|
|
|
- print(worksheet2rst(text, images_dir).encode('utf-8'))
|
|
+ print(worksheet2rst(text, images_dir).encode('ascii'))
|
|
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/challenge.py.orig build/pkgs/sagenb/src/sagenb/notebook/challenge.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/challenge.py.orig 2019-09-05 13:20:58.515848457 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/challenge.py 2019-09-05 13:27:08.356250022 -0300
|
|
@@ -529,7 +529,7 @@ class reCAPTCHAChallenge(AbstractChallen
|
|
|
|
def encode_if_necessary(s):
|
|
if isinstance(s, unicode):
|
|
- return s.encode('utf-8')
|
|
+ return s.encode('ascii')
|
|
return s
|
|
|
|
params = urlencode({
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/css.py.orig build/pkgs/sagenb/src/sagenb/notebook/css.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/css.py.orig 2019-09-05 13:21:08.792915193 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/css.py 2019-09-05 13:27:08.357250028 -0300
|
|
@@ -58,5 +58,5 @@ def css(color='default'):
|
|
user_css = '\n' + open(user_css_path).read()
|
|
|
|
data = main_css + user_css
|
|
- _css_cache = (data, sha1(data).hexdigest())
|
|
+ _css_cache = (data, sha1(str(data).encode('ascii')).hexdigest())
|
|
return _css_cache
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/js.py.orig build/pkgs/sagenb/src/sagenb/notebook/js.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/js.py.orig 2019-09-05 13:21:17.511971810 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/js.py 2019-09-05 13:27:08.357250028 -0300
|
|
@@ -84,7 +84,7 @@ def javascript():
|
|
if debug_mode:
|
|
# TODO: maybe we should return a random hash so that the code
|
|
# is reloaded on every refresh
|
|
- return s, sha1(s).hexdigest()
|
|
+ return s, sha1(str(s).encode('ascii')).hexdigest()
|
|
|
|
# TODO: use minify here, which is more standard (and usually safer
|
|
# and with gzip compression, smaller); But first inquire about the
|
|
@@ -92,7 +92,7 @@ def javascript():
|
|
# Evil" clause in the license. Does that prevent us from
|
|
# distributing it (i.e., it adds an extra condition to the
|
|
# software)? See http://www.crockford.com/javascript/jsmin.py.txt
|
|
- s = JavaScriptCompressor().getPacked(s.encode('utf-8'))
|
|
+ s = JavaScriptCompressor().getPacked(s.encode('ascii'))
|
|
_cache_javascript = (s, sha1(s).hexdigest())
|
|
|
|
return _cache_javascript
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/register.py.orig build/pkgs/sagenb/src/sagenb/notebook/register.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/register.py.orig 2019-09-05 13:21:26.247028528 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/register.py 2019-09-05 13:27:08.358250034 -0300
|
|
@@ -22,7 +22,7 @@ def build_msg(key, username, addr, port,
|
|
'%(url_prefix)s://%(addr)s:%(port)s/confirm?key=%(key)s\n\n'
|
|
'You will be taken to a page which will confirm that you have indeed registered.',
|
|
url_prefix=url_prefix, addr=addr, port=port, key=key)
|
|
- return s.encode('utf-8')
|
|
+ return s.encode('ascii')
|
|
|
|
def build_password_msg(key, username, addr, port, secure):
|
|
url_prefix = "https" if secure else "http"
|
|
@@ -31,7 +31,7 @@ def build_password_msg(key, username, ad
|
|
'Sign in at %(url_prefix)s://%(addr)s:%(port)s/\n\n'
|
|
'Make sure to reset your password by going to Settings in the upper right bar.',
|
|
key=key, url_prefix=url_prefix, addr=addr, port=port)
|
|
- return s.encode('utf-8')
|
|
+ return s.encode('ascii')
|
|
|
|
def make_key():
|
|
from random import randint
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/smtpsend.py.orig build/pkgs/sagenb/src/sagenb/notebook/smtpsend.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/smtpsend.py.orig 2019-09-05 13:21:35.087085930 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/smtpsend.py 2019-09-05 13:27:08.358250034 -0300
|
|
@@ -18,20 +18,15 @@ AUTHOR:
|
|
|
|
Bobby Moretti
|
|
"""
|
|
-from twisted.mail import smtp, relaymanager # problematic with python 3
|
|
-from email.mime.base import MIMEBase
|
|
-from email.mime.multipart import MIMEMultipart
|
|
-import sys
|
|
-
|
|
+from twisted.mail.smtp import sendmail
|
|
+from twisted.internet.task import react
|
|
+from email.mime.text import MIMEText
|
|
|
|
def buildMessage(fromaddr, toaddr, subject, body):
|
|
- message = MIMEMultipart()
|
|
+ message = MIMEText(body)
|
|
message['From'] = fromaddr
|
|
message['To'] = toaddr
|
|
message['Subject'] = subject
|
|
- textPart = MIMEBase('text', 'plain')
|
|
- textPart.set_payload(body)
|
|
- message.attach(textPart)
|
|
return message
|
|
|
|
def sendComplete(result):
|
|
@@ -42,16 +37,10 @@ def handleError(error):
|
|
|
|
def send_mail(fromaddr, toaddr, subject, body, on_success=sendComplete, on_failure=handleError):
|
|
try:
|
|
- recpt_domain = toaddr.split('@')[1].encode("ascii")
|
|
- except (ValueError, IndexError, UnicodeDecodeError):
|
|
- raise ValueError("mal-formed destination address")
|
|
- message = buildMessage(fromaddr, toaddr, subject, body)
|
|
- messageData = message.as_string(unixfrom=False)
|
|
-
|
|
- def on_found_record(mx_rec):
|
|
- smtp_server = str(mx_rec.name)
|
|
- sending = smtp.sendmail(smtp_server, fromaddr, [toaddr], messageData)
|
|
- sending.addCallback(on_success).addErrback(on_failure)
|
|
-
|
|
- relaymanager.MXCalculator().getMX(recpt_domain).addCallback(on_found_record)
|
|
+ d = sendmail("localhost", fromaddr, toaddr, message)
|
|
+ d.addBoth(print)
|
|
+ except:
|
|
+ handleError(sys.exc_info()[0])
|
|
+ return
|
|
+ sendComplete()
|
|
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/user_manager.py.orig build/pkgs/sagenb/src/sagenb/notebook/user_manager.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/user_manager.py.orig 2019-09-05 13:21:45.143151229 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/user_manager.py 2019-09-05 13:27:08.360250047 -0300
|
|
@@ -461,7 +461,7 @@ class SimpleUserManager(UserManager):
|
|
if encrypt:
|
|
salt = user.generate_salt()
|
|
new_password = 'sha256${0}${1}'.format(salt,
|
|
- hashlib.sha256(salt + new_password).hexdigest())
|
|
+ hashlib.sha256(str(salt + new_password).encode('ascii')).hexdigest())
|
|
self._passwords[username] = new_password
|
|
# need to make sure password in the user object is synced
|
|
# for compatibility only the user object data is stored in the 'users.pickle'
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/user.py.orig build/pkgs/sagenb/src/sagenb/notebook/user.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/user.py.orig 2019-09-05 13:21:54.855214298 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/user.py 2019-09-05 13:27:08.360250047 -0300
|
|
@@ -185,7 +185,7 @@ class User(object):
|
|
if encrypt:
|
|
salt = generate_salt()
|
|
self._password = 'sha256${0}${1}'.format(salt,
|
|
- hashlib.sha256(salt + password).hexdigest())
|
|
+ hashlib.sha256(str(salt + password).encode('ascii')).hexdigest())
|
|
else:
|
|
self._password = password
|
|
self._temporary_password = ''
|
|
diff -up build/pkgs/sagenb/src/sagenb/notebook/worksheet.py.orig build/pkgs/sagenb/src/sagenb/notebook/worksheet.py
|
|
--- build/pkgs/sagenb/src/sagenb/notebook/worksheet.py.orig 2019-09-05 13:26:14.467900092 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/notebook/worksheet.py 2019-09-05 13:27:08.361250054 -0300
|
|
@@ -313,7 +313,7 @@ class Worksheet(object):
|
|
|
|
d = {#############
|
|
# basic identification
|
|
- 'name': unicode(self.name()),
|
|
+ 'name': str(self.name().encode('ascii')),
|
|
'id_number': int(self.id_number()),
|
|
|
|
#############
|
|
@@ -2157,9 +2157,9 @@ class Worksheet(object):
|
|
filename = self.worksheet_html_filename()
|
|
|
|
if os.path.exists(filename):
|
|
- contents = open(filename).read().decode('utf-8', 'ignore')
|
|
+ contents = open(filename).read().decode('ascii')
|
|
else:
|
|
- contents = u' '
|
|
+ contents = ' '
|
|
|
|
try:
|
|
r = [unicode(x.lower()) for x in [self.owner(), self.publisher(), self.name(), contents]]
|
|
@@ -2190,8 +2190,8 @@ class Worksheet(object):
|
|
if E is None:
|
|
E = self.edit_text()
|
|
worksheet_html = self.worksheet_html_filename()
|
|
- open(filename, 'w').write(bz2.compress(E.encode('utf-8', 'ignore')))
|
|
- open(worksheet_html, 'w').write(self.body().encode('utf-8', 'ignore'))
|
|
+ open(filename, 'w').write(bz2.compress(E.encode('ascii')))
|
|
+ open(worksheet_html, 'w').write(self.body().encode('ascii'))
|
|
self.limit_snapshots()
|
|
try:
|
|
X = self.__saved_by_info
|
|
@@ -3930,7 +3930,7 @@ except (KeyError, IOError):
|
|
"""
|
|
# The extra newline below is necessary, since otherwise source
|
|
# code introspection doesn't include the last line.
|
|
- return 'open("%s","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("%s"),globals())+"\\n"); execfile(os.path.abspath("%s"))'%(CODE_PY, base64.b64encode(s.encode('utf-8', 'ignore')), CODE_PY)
|
|
+ return 'open("%s","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("%s"),globals())+"\\n"); execfile(os.path.abspath("%s"))'%(CODE_PY, base64.b64encode(s.encode('ascii')), CODE_PY)
|
|
|
|
##########################################################
|
|
# Loading and attaching files
|
|
@@ -4114,7 +4114,7 @@ except (KeyError, IOError):
|
|
os.makedirs(code)
|
|
spyx = os.path.abspath(os.path.join(code, 'sage%s.spyx'%id))
|
|
if not (os.path.exists(spyx) and open(spyx).read() == cmd):
|
|
- open(spyx,'w').write(cmd.encode('utf-8', 'ignore'))
|
|
+ open(spyx,'w').write(cmd.encode('ascii'))
|
|
return '_support_.cython_import_all("%s", globals())'%spyx
|
|
|
|
def check_for_system_switching(self, input, cell):
|
|
diff -up build/pkgs/sagenb/src/sagenb/storage/filesystem_storage.py.orig build/pkgs/sagenb/src/sagenb/storage/filesystem_storage.py
|
|
--- build/pkgs/sagenb/src/sagenb/storage/filesystem_storage.py.orig 2019-09-05 13:22:17.198359375 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/storage/filesystem_storage.py 2019-09-05 13:27:08.361250054 -0300
|
|
@@ -106,7 +106,7 @@ class FilesystemDatastore(Datastore):
|
|
|
|
def _deep_user_path(self, username):
|
|
from hashlib import md5
|
|
- h = md5(username).hexdigest()
|
|
+ h = md5(str(username).encode('ascii')).hexdigest()
|
|
base = ['__store__', h[:1], h[:2], h[:3], h[:4]]
|
|
path = os.path.join(*base)
|
|
self._makepath(self._abspath(os.path.join(self._home_path, path)))
|
|
@@ -397,7 +397,7 @@ class FilesystemDatastore(Datastore):
|
|
# todo -- add check if changed
|
|
filename = self._worksheet_html_filename(username, id_number)
|
|
with atomic_write(self._abspath(filename)) as f:
|
|
- f.write(worksheet.body().encode('utf-8', 'ignore'))
|
|
+ f.write(str(worksheet.body()))
|
|
|
|
def create_worksheet(self, username, id_number):
|
|
"""
|
|
@@ -548,7 +548,7 @@ class FilesystemDatastore(Datastore):
|
|
|
|
worksheet_txt = members[0].name
|
|
W = self.load_worksheet(username, id_number)
|
|
- W.edit_save_old_format(T.extractfile(worksheet_txt).read().decode('utf-8', 'ignore'))
|
|
+ W.edit_save_old_format(T.extractfile(worksheet_txt).read().decode('ascii'))
|
|
# '/' is right, since old worksheets always unix
|
|
dir = worksheet_txt.split('/')[0]
|
|
|
|
diff -up build/pkgs/sagenb/src/sagenb/testing/selenium/selenium.py.orig build/pkgs/sagenb/src/sagenb/testing/selenium/selenium.py
|
|
--- build/pkgs/sagenb/src/sagenb/testing/selenium/selenium.py.orig 2019-09-05 13:22:27.220424454 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/testing/selenium/selenium.py 2019-09-05 13:27:08.361250054 -0300
|
|
@@ -199,9 +199,9 @@ class selenium:
|
|
|
|
def do_command(self, verb, args):
|
|
conn = http.client.HTTPConnection(self.host, self.port)
|
|
- body = u'cmd=' + urllib.quote_plus(unicode(verb).encode('utf-8'))
|
|
+ body = u'cmd=' + urllib.quote_plus(unicode(verb).encode('ascii'))
|
|
for i in range(len(args)):
|
|
- body += '&' + unicode(i+1) + '=' + urllib.quote_plus(unicode(args[i]).encode('utf-8'))
|
|
+ body += '&' + unicode(i+1) + '=' + urllib.quote_plus(unicode(args[i]).encode('ascii'))
|
|
if (None != self.sessionId):
|
|
body += "&sessionId=" + unicode(self.sessionId)
|
|
headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}
|
|
diff -up build/pkgs/sagenb/src/sagenb/data/sage/html/worksheet_listing.html.orig ./build/pkgs/sagenb/src/sagenb/data/sage/html/worksheet_listing.html
|
|
--- build/pkgs/sagenb/src/sagenb/data/sage/html/worksheet_listing.html.orig 2019-09-05 15:39:56.829175774 -0300
|
|
+++ build/pkgs/sagenb/src/sagenb/data/sage/html/worksheet_listing.html 2019-09-05 15:40:26.822369920 -0300
|
|
@@ -45,6 +45,7 @@ INPUT:
|
|
<h1>{{ gettext('Account is read only. You may download or delete worksheets or data.') }}</h1>
|
|
{% endif %}
|
|
<h3><a href="https://trac.sagemath.org/ticket/25837">{{ gettext('This notebook is deprecated. Click here for details.') }}</a></h3>
|
|
+<h5>The sagemath rpm package was built with python3, but the sagemath notebook is discontinued and has not been ported to python3.<br>Only minimal functionality to browse documentation is available.<br>Please run the shell command:<br><code>$ sage -n jupyter</code><br>to use the jupyter notebook.</h5>
|
|
<div id="user-main-controls" class="user-controls">
|
|
{% if pub is not defined or not pub %}
|
|
<a href="/new_worksheet" target="_blank">{{ gettext('New Worksheet') }}</a>
|