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:
$ sage -n jupyter