Make monasca-ui python3 compatible
In order to make monasca-ui python3 compatible this patch set: - Add six to requirements.txt - Add py35 to tox.ini - Replace dict.iteritems() with six.iteritems(dict) - Replace prit msg with print(msg) - Replace unicode with six.text_type(msg) - Replaces urlparse with six.moves.urllib - Python 3 getting the keys() of a dict returns a dict_keys object instead of a list - python 2.x calling keys makes a copy of the key that you can iterate over while modifying the dict. This doesn't work in python 3.x because keys returns an iterator instead of a list. Another way is to use list to force a copy of the keys to be made. Story: 2000975 Task: 4129 Signed-off-by: Charles Short <zulcss@gmail.com> Change-Id: Ibc644a734edceea0b36f2df2c73300d1e4db925f
This commit is contained in:
parent
c0ab99a070
commit
4cfdc71d70
@ -19,6 +19,7 @@ from django.core.paginator import Paginator, EmptyPage
|
|||||||
from django.core.urlresolvers import reverse_lazy, reverse # noqa
|
from django.core.urlresolvers import reverse_lazy, reverse # noqa
|
||||||
from django.utils.translation import ugettext as _ # noqa
|
from django.utils.translation import ugettext as _ # noqa
|
||||||
from django.views.generic import TemplateView # noqa
|
from django.views.generic import TemplateView # noqa
|
||||||
|
import six
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
@ -154,7 +155,7 @@ class AlarmDetailView(TemplateView):
|
|||||||
except exc.HttpError:
|
except exc.HttpError:
|
||||||
msg = _("Notification %s has already been deleted.") % id
|
msg = _("Notification %s has already been deleted.") % id
|
||||||
notifications.append({"id": id,
|
notifications.append({"id": id,
|
||||||
"name": unicode(msg),
|
"name": six.text_type(msg),
|
||||||
"type": "",
|
"type": "",
|
||||||
"address": ""})
|
"address": ""})
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ from django import forms as django_forms
|
|||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.utils import html
|
from django.utils import html
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
import six
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
@ -116,7 +117,7 @@ class NotificationCreateWidget(forms.Select):
|
|||||||
output = '<table id="notification_table" ' + \
|
output = '<table id="notification_table" ' + \
|
||||||
'class="table table-condensed">'
|
'class="table table-condensed">'
|
||||||
output += '<thead><tr><th>%s</th></tr></thead>' % \
|
output += '<thead><tr><th>%s</th></tr></thead>' % \
|
||||||
unicode(_("Name"))
|
six.text_type(_("Name"))
|
||||||
if value:
|
if value:
|
||||||
idx = 1
|
idx = 1
|
||||||
for notification in value:
|
for notification in value:
|
||||||
@ -143,7 +144,7 @@ class NotificationCreateWidget(forms.Select):
|
|||||||
output += '<td><a href="" id="remove_notif_button">X</a></td>'
|
output += '<td><a href="" id="remove_notif_button">X</a></td>'
|
||||||
output += '</td></tr>'
|
output += '</td></tr>'
|
||||||
output += '</table>'
|
output += '</table>'
|
||||||
label = unicode(_("+ Add more"))
|
label = six.text_type(_("+ Add more"))
|
||||||
output += '<a href="" id="add_notification_button">%s</a>' % (label)
|
output += '<a href="" id="add_notification_button">%s</a>' % (label)
|
||||||
return html.format_html(output)
|
return html.format_html(output)
|
||||||
|
|
||||||
@ -221,10 +222,10 @@ class BaseAlarmForm(forms.SelfHandlingForm):
|
|||||||
if notification_choices:
|
if notification_choices:
|
||||||
if len(notification_choices) > 1:
|
if len(notification_choices) > 1:
|
||||||
notification_choices.insert(
|
notification_choices.insert(
|
||||||
0, ("", unicode(_("Select Notification"))))
|
0, ("", six.text_type(_("Select Notification"))))
|
||||||
else:
|
else:
|
||||||
notification_choices.insert(
|
notification_choices.insert(
|
||||||
0, ("", unicode(_("No notifications available."))))
|
0, ("", six.text_type(_("No notifications available."))))
|
||||||
|
|
||||||
self.fields['notifications'].choices = notification_choices
|
self.fields['notifications'].choices = notification_choices
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ class GraphMetric(tables.LinkAction):
|
|||||||
metric = datum['metrics'][0]['name']
|
metric = datum['metrics'][0]['name']
|
||||||
dimensions = datum['metrics'][0].get('dimensions', {})
|
dimensions = datum['metrics'][0].get('dimensions', {})
|
||||||
query = "?metric=%s" % metric
|
query = "?metric=%s" % metric
|
||||||
for key, value in dimensions.iteritems():
|
for key, value in dimensions.items():
|
||||||
query += "&dim_%s=%s" % (key, value)
|
query += "&dim_%s=%s" % (key, value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Catches case where Grafana 2 is not enabled.
|
# Catches case where Grafana 2 is not enabled.
|
||||||
|
@ -25,6 +25,7 @@ from django.utils.dateparse import parse_datetime
|
|||||||
from django.utils.translation import ugettext as _ # noqa
|
from django.utils.translation import ugettext as _ # noqa
|
||||||
from django.utils.translation import ugettext_lazy
|
from django.utils.translation import ugettext_lazy
|
||||||
from django.views.generic import View # noqa
|
from django.views.generic import View # noqa
|
||||||
|
import six
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
@ -100,12 +101,12 @@ def generate_status(request):
|
|||||||
service_alarms = alarms_by_service.setdefault(service, [])
|
service_alarms = alarms_by_service.setdefault(service, [])
|
||||||
service_alarms.append(a)
|
service_alarms.append(a)
|
||||||
for row in SERVICES:
|
for row in SERVICES:
|
||||||
row['name'] = unicode(row['name'])
|
row['name'] = six.text_type(row['name'])
|
||||||
for service in row['services']:
|
for service in row['services']:
|
||||||
service_alarms = alarms_by_service.get(service['name'], [])
|
service_alarms = alarms_by_service.get(service['name'], [])
|
||||||
service['class'] = get_status(service_alarms)
|
service['class'] = get_status(service_alarms)
|
||||||
service['icon'] = get_icon(service['class'])
|
service['icon'] = get_icon(service['class'])
|
||||||
service['display'] = unicode(service['display'])
|
service['display'] = six.text_type(service['display'])
|
||||||
return SERVICES
|
return SERVICES
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class KibanaProxyViewTest(helpers.TestCase):
|
|||||||
|
|
||||||
def test_get_relative_url_with_unicode(self):
|
def test_get_relative_url_with_unicode(self):
|
||||||
"""Tests if it properly converts multibyte characters."""
|
"""Tests if it properly converts multibyte characters."""
|
||||||
import urlparse
|
from six.moves.urllib import parse as urlparse
|
||||||
|
|
||||||
self.view.request = self.request_factory.get(
|
self.view.request = self.request_factory.get(
|
||||||
'/', data={'a': 1, 'b': 2}
|
'/', data={'a': 1, 'b': 2}
|
||||||
|
@ -16,8 +16,6 @@ import base64
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import urllib
|
|
||||||
import urllib2
|
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@ -29,6 +27,8 @@ from django.views.decorators.csrf import csrf_exempt
|
|||||||
from django.views.generic import TemplateView # noqa
|
from django.views.generic import TemplateView # noqa
|
||||||
from openstack_auth import utils as auth_utils
|
from openstack_auth import utils as auth_utils
|
||||||
from openstack_dashboard import policy
|
from openstack_dashboard import policy
|
||||||
|
import six
|
||||||
|
from six.moves import urllib
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
|
|
||||||
@ -79,8 +79,8 @@ def get_dashboard_links(request):
|
|||||||
non_project_keys = {'fileName', 'title'}
|
non_project_keys = {'fileName', 'title'}
|
||||||
try:
|
try:
|
||||||
for project_link in settings.DASHBOARDS:
|
for project_link in settings.DASHBOARDS:
|
||||||
key = project_link.keys()[0]
|
key = list(project_link)[0]
|
||||||
value = project_link.values()[0]
|
value = list(project_link.values())[0]
|
||||||
if key in non_project_keys:
|
if key in non_project_keys:
|
||||||
#
|
#
|
||||||
# we're not indexed by project, just return
|
# we're not indexed by project, just return
|
||||||
@ -129,8 +129,8 @@ def get_monitoring_services(request):
|
|||||||
non_project_keys = {'name', 'groupBy'}
|
non_project_keys = {'name', 'groupBy'}
|
||||||
try:
|
try:
|
||||||
for group in settings.MONITORING_SERVICES:
|
for group in settings.MONITORING_SERVICES:
|
||||||
key = group.keys()[0]
|
key = list(group.keys())[0]
|
||||||
value = group.values()[0]
|
value = list(group.values())[0]
|
||||||
if key in non_project_keys:
|
if key in non_project_keys:
|
||||||
#
|
#
|
||||||
# we're not indexed by project, just return
|
# we're not indexed by project, just return
|
||||||
@ -194,7 +194,7 @@ def generate_status(request):
|
|||||||
service_alarms.append(a)
|
service_alarms.append(a)
|
||||||
monitoring_services = copy.deepcopy(get_monitoring_services(request))
|
monitoring_services = copy.deepcopy(get_monitoring_services(request))
|
||||||
for row in monitoring_services:
|
for row in monitoring_services:
|
||||||
row['name'] = unicode(row['name'])
|
row['name'] = six.text_type(row['name'])
|
||||||
if 'groupBy' in row:
|
if 'groupBy' in row:
|
||||||
alarms_by_group = {}
|
alarms_by_group = {}
|
||||||
for a in alarms:
|
for a in alarms:
|
||||||
@ -220,7 +220,7 @@ def generate_status(request):
|
|||||||
service_alarms = alarms_by_service.get(service['name'], [])
|
service_alarms = alarms_by_service.get(service['name'], [])
|
||||||
service['class'] = get_status(service_alarms)
|
service['class'] = get_status(service_alarms)
|
||||||
service['icon'] = get_icon(service['class'])
|
service['icon'] = get_icon(service['class'])
|
||||||
service['display'] = unicode(service['display'])
|
service['display'] = six.text_type(service['display'])
|
||||||
return monitoring_services
|
return monitoring_services
|
||||||
|
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ class MonascaProxyView(TemplateView):
|
|||||||
if len(dimension_name_value) == 2:
|
if len(dimension_name_value) == 2:
|
||||||
name = dimension_name_value[0].encode('utf8')
|
name = dimension_name_value[0].encode('utf8')
|
||||||
value = dimension_name_value[1].encode('utf8')
|
value = dimension_name_value[1].encode('utf8')
|
||||||
dim_dict[name] = urllib.unquote(value)
|
dim_dict[name] = urllib.parse.unquote(value)
|
||||||
else:
|
else:
|
||||||
raise Exception('Dimensions are malformed')
|
raise Exception('Dimensions are malformed')
|
||||||
|
|
||||||
@ -329,10 +329,10 @@ class StatusView(TemplateView):
|
|||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
|
|
||||||
|
|
||||||
class _HttpMethodRequest(urllib2.Request):
|
class _HttpMethodRequest(urllib.request.Request):
|
||||||
|
|
||||||
def __init__(self, method, url, **kwargs):
|
def __init__(self, method, url, **kwargs):
|
||||||
urllib2.Request.__init__(self, url, **kwargs)
|
urllib.request.Request.__init__(self, url, **kwargs)
|
||||||
self.method = method
|
self.method = method
|
||||||
|
|
||||||
def get_method(self):
|
def get_method(self):
|
||||||
@ -359,15 +359,15 @@ class KibanaProxyView(generic.View):
|
|||||||
method, proxy_request_url, data=data, headers=headers
|
method, proxy_request_url, data=data, headers=headers
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
response = urllib2.urlopen(proxy_request)
|
response = urllib.request.urlopen(proxy_request)
|
||||||
|
|
||||||
except urllib2.HTTPError as e:
|
except urllib.error.HTTPError as e:
|
||||||
return http.HttpResponse(
|
return http.HttpResponse(
|
||||||
e.read(),
|
e.read(),
|
||||||
status=e.code,
|
status=e.code,
|
||||||
content_type=e.hdrs['content-type']
|
content_type=e.hdrs['content-type']
|
||||||
)
|
)
|
||||||
except urllib2.URLError as e:
|
except urllib.error.URLError as e:
|
||||||
return http.HttpResponse(e.reason, 404)
|
return http.HttpResponse(e.reason, 404)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -406,7 +406,7 @@ class KibanaProxyView(generic.View):
|
|||||||
return self.read(request.method, url, request.body, headers)
|
return self.read(request.method, url, request.body, headers)
|
||||||
|
|
||||||
def get_relative_url(self, url):
|
def get_relative_url(self, url):
|
||||||
url = urllib.quote(url.encode('utf-8'))
|
url = urllib.parse.quote(url.encode('utf-8'))
|
||||||
params_str = self.request.GET.urlencode()
|
params_str = self.request.GET.urlencode()
|
||||||
|
|
||||||
if params_str:
|
if params_str:
|
||||||
|
@ -5,3 +5,4 @@ oslo.log>=3.36.0 # Apache-2.0
|
|||||||
python-monascaclient>=1.7.0 # Apache-2.0
|
python-monascaclient>=1.7.0 # Apache-2.0
|
||||||
Django<2.0,>=1.8 # BSD
|
Django<2.0,>=1.8 # BSD
|
||||||
horizon>=13.0.0 # Apache-2.0
|
horizon>=13.0.0 # Apache-2.0
|
||||||
|
six>=1.10.0 # MIT
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
Installation script for the OpenStack Dashboard development virtualenv.
|
Installation script for the OpenStack Dashboard development virtualenv.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@ -69,12 +71,12 @@ HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'],
|
|||||||
def check_dependencies():
|
def check_dependencies():
|
||||||
"""Make sure virtualenv is in the path."""
|
"""Make sure virtualenv is in the path."""
|
||||||
|
|
||||||
print 'Checking dependencies...'
|
print('Checking dependencies...')
|
||||||
if not HAS_VIRTUALENV:
|
if not HAS_VIRTUALENV:
|
||||||
print 'Virtual environment not found.'
|
print('Virtual environment not found.')
|
||||||
# Try installing it via easy_install...
|
# Try installing it via easy_install...
|
||||||
if HAS_EASY_INSTALL:
|
if HAS_EASY_INSTALL:
|
||||||
print 'Installing virtualenv via easy_install...',
|
print('Installing virtualenv via easy_install...', end=' ')
|
||||||
run_command(['easy_install', 'virtualenv'],
|
run_command(['easy_install', 'virtualenv'],
|
||||||
die_message='easy_install failed to install virtualenv'
|
die_message='easy_install failed to install virtualenv'
|
||||||
'\ndevelopment requires virtualenv, please'
|
'\ndevelopment requires virtualenv, please'
|
||||||
@ -84,28 +86,28 @@ def check_dependencies():
|
|||||||
' requires virtualenv, please install it using your'
|
' requires virtualenv, please install it using your'
|
||||||
' favorite package management tool and ensure'
|
' favorite package management tool and ensure'
|
||||||
' virtualenv is in your path')
|
' virtualenv is in your path')
|
||||||
print 'virtualenv installation done.'
|
print('virtualenv installation done.')
|
||||||
else:
|
else:
|
||||||
die('easy_install not found.\n\nInstall easy_install'
|
die('easy_install not found.\n\nInstall easy_install'
|
||||||
' (python-setuptools in ubuntu) or virtualenv by hand,'
|
' (python-setuptools in ubuntu) or virtualenv by hand,'
|
||||||
' then rerun.')
|
' then rerun.')
|
||||||
print 'dependency check done.'
|
print('dependency check done.')
|
||||||
|
|
||||||
|
|
||||||
def create_virtualenv(venv=VENV):
|
def create_virtualenv(venv=VENV):
|
||||||
"""Creates the virtual environment and installs PIP only into the
|
"""Creates the virtual environment and installs PIP only into the
|
||||||
virtual environment
|
virtual environment
|
||||||
"""
|
"""
|
||||||
print 'Creating venv...',
|
print('Creating venv...', end=' ')
|
||||||
run_command(['virtualenv', '-q', '--no-site-packages', VENV])
|
run_command(['virtualenv', '-q', '--no-site-packages', VENV])
|
||||||
print 'done.'
|
print('done.')
|
||||||
print 'Installing pip in virtualenv...',
|
print('Installing pip in virtualenv...', end=' ')
|
||||||
if not run_command([WITH_VENV, 'easy_install', 'pip']).strip():
|
if not run_command([WITH_VENV, 'easy_install', 'pip']).strip():
|
||||||
die("Failed to install pip.")
|
die("Failed to install pip.")
|
||||||
print 'done.'
|
print('done.')
|
||||||
print 'Installing distribute in virtualenv...'
|
print('Installing distribute in virtualenv...')
|
||||||
pip_install('distribute>=0.6.24')
|
pip_install('distribute>=0.6.24')
|
||||||
print 'done.'
|
print('done.')
|
||||||
|
|
||||||
|
|
||||||
def pip_install(*args):
|
def pip_install(*args):
|
||||||
@ -114,8 +116,8 @@ def pip_install(*args):
|
|||||||
|
|
||||||
|
|
||||||
def install_dependencies(venv=VENV):
|
def install_dependencies(venv=VENV):
|
||||||
print "Installing dependencies..."
|
print("Installing dependencies...")
|
||||||
print "(This may take several minutes, don't panic)"
|
print("(This may take several minutes, don't panic)")
|
||||||
pip_install('-r', TEST_REQUIRES)
|
pip_install('-r', TEST_REQUIRES)
|
||||||
pip_install('-r', PIP_REQUIRES)
|
pip_install('-r', PIP_REQUIRES)
|
||||||
|
|
||||||
@ -127,7 +129,7 @@ def install_dependencies(venv=VENV):
|
|||||||
|
|
||||||
|
|
||||||
def install_horizon():
|
def install_horizon():
|
||||||
print 'Installing horizon module in development mode...'
|
print('Installing horizon module in development mode...')
|
||||||
run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=ROOT)
|
run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=ROOT)
|
||||||
|
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ can run:
|
|||||||
|
|
||||||
$ source .venv/bin/activate
|
$ source .venv/bin/activate
|
||||||
"""
|
"""
|
||||||
print summary
|
print(summary)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
Loading…
Reference in New Issue
Block a user