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:
Charles Short 2018-03-26 14:05:14 +00:00
parent c0ab99a070
commit 4cfdc71d70
9 changed files with 46 additions and 40 deletions

View File

@ -19,6 +19,7 @@ from django.core.paginator import Paginator, EmptyPage
from django.core.urlresolvers import reverse_lazy, reverse # noqa
from django.utils.translation import ugettext as _ # noqa
from django.views.generic import TemplateView # noqa
import six
from horizon import exceptions
from horizon import forms
@ -154,7 +155,7 @@ class AlarmDetailView(TemplateView):
except exc.HttpError:
msg = _("Notification %s has already been deleted.") % id
notifications.append({"id": id,
"name": unicode(msg),
"name": six.text_type(msg),
"type": "",
"address": ""})

View File

@ -19,6 +19,7 @@ from django import forms as django_forms
from django.template.loader import get_template
from django.utils import html
from django.utils.translation import ugettext_lazy as _ # noqa
import six
from horizon import exceptions
from horizon import forms
@ -116,7 +117,7 @@ class NotificationCreateWidget(forms.Select):
output = '<table id="notification_table" ' + \
'class="table table-condensed">'
output += '<thead><tr><th>%s</th></tr></thead>' % \
unicode(_("Name"))
six.text_type(_("Name"))
if value:
idx = 1
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></tr>'
output += '</table>'
label = unicode(_("+ Add more"))
label = six.text_type(_("+ Add more"))
output += '<a href="" id="add_notification_button">%s</a>' % (label)
return html.format_html(output)
@ -221,10 +222,10 @@ class BaseAlarmForm(forms.SelfHandlingForm):
if notification_choices:
if len(notification_choices) > 1:
notification_choices.insert(
0, ("", unicode(_("Select Notification"))))
0, ("", six.text_type(_("Select Notification"))))
else:
notification_choices.insert(
0, ("", unicode(_("No notifications available."))))
0, ("", six.text_type(_("No notifications available."))))
self.fields['notifications'].choices = notification_choices

View File

@ -166,7 +166,7 @@ class GraphMetric(tables.LinkAction):
metric = datum['metrics'][0]['name']
dimensions = datum['metrics'][0].get('dimensions', {})
query = "?metric=%s" % metric
for key, value in dimensions.iteritems():
for key, value in dimensions.items():
query += "&dim_%s=%s" % (key, value)
except AttributeError:
# Catches case where Grafana 2 is not enabled.

View File

@ -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_lazy
from django.views.generic import View # noqa
import six
from horizon import exceptions
from horizon import forms
@ -100,12 +101,12 @@ def generate_status(request):
service_alarms = alarms_by_service.setdefault(service, [])
service_alarms.append(a)
for row in SERVICES:
row['name'] = unicode(row['name'])
row['name'] = six.text_type(row['name'])
for service in row['services']:
service_alarms = alarms_by_service.get(service['name'], [])
service['class'] = get_status(service_alarms)
service['icon'] = get_icon(service['class'])
service['display'] = unicode(service['display'])
service['display'] = six.text_type(service['display'])
return SERVICES

View File

@ -43,7 +43,7 @@ class KibanaProxyViewTest(helpers.TestCase):
def test_get_relative_url_with_unicode(self):
"""Tests if it properly converts multibyte characters."""
import urlparse
from six.moves.urllib import parse as urlparse
self.view.request = self.request_factory.get(
'/', data={'a': 1, 'b': 2}

View File

@ -16,8 +16,6 @@ import base64
import copy
import json
import logging
import urllib
import urllib2
from django import http
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 openstack_auth import utils as auth_utils
from openstack_dashboard import policy
import six
from six.moves import urllib
from horizon import exceptions
@ -79,8 +79,8 @@ def get_dashboard_links(request):
non_project_keys = {'fileName', 'title'}
try:
for project_link in settings.DASHBOARDS:
key = project_link.keys()[0]
value = project_link.values()[0]
key = list(project_link)[0]
value = list(project_link.values())[0]
if key in non_project_keys:
#
# we're not indexed by project, just return
@ -129,8 +129,8 @@ def get_monitoring_services(request):
non_project_keys = {'name', 'groupBy'}
try:
for group in settings.MONITORING_SERVICES:
key = group.keys()[0]
value = group.values()[0]
key = list(group.keys())[0]
value = list(group.values())[0]
if key in non_project_keys:
#
# we're not indexed by project, just return
@ -194,7 +194,7 @@ def generate_status(request):
service_alarms.append(a)
monitoring_services = copy.deepcopy(get_monitoring_services(request))
for row in monitoring_services:
row['name'] = unicode(row['name'])
row['name'] = six.text_type(row['name'])
if 'groupBy' in row:
alarms_by_group = {}
for a in alarms:
@ -220,7 +220,7 @@ def generate_status(request):
service_alarms = alarms_by_service.get(service['name'], [])
service['class'] = get_status(service_alarms)
service['icon'] = get_icon(service['class'])
service['display'] = unicode(service['display'])
service['display'] = six.text_type(service['display'])
return monitoring_services
@ -271,7 +271,7 @@ class MonascaProxyView(TemplateView):
if len(dimension_name_value) == 2:
name = dimension_name_value[0].encode('utf8')
value = dimension_name_value[1].encode('utf8')
dim_dict[name] = urllib.unquote(value)
dim_dict[name] = urllib.parse.unquote(value)
else:
raise Exception('Dimensions are malformed')
@ -329,10 +329,10 @@ class StatusView(TemplateView):
content_type='application/json')
class _HttpMethodRequest(urllib2.Request):
class _HttpMethodRequest(urllib.request.Request):
def __init__(self, method, url, **kwargs):
urllib2.Request.__init__(self, url, **kwargs)
urllib.request.Request.__init__(self, url, **kwargs)
self.method = method
def get_method(self):
@ -359,15 +359,15 @@ class KibanaProxyView(generic.View):
method, proxy_request_url, data=data, headers=headers
)
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(
e.read(),
status=e.code,
content_type=e.hdrs['content-type']
)
except urllib2.URLError as e:
except urllib.error.URLError as e:
return http.HttpResponse(e.reason, 404)
else:
@ -406,7 +406,7 @@ class KibanaProxyView(generic.View):
return self.read(request.method, url, request.body, headers)
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()
if params_str:

View File

@ -5,3 +5,4 @@ oslo.log>=3.36.0 # Apache-2.0
python-monascaclient>=1.7.0 # Apache-2.0
Django<2.0,>=1.8 # BSD
horizon>=13.0.0 # Apache-2.0
six>=1.10.0 # MIT

View File

@ -22,6 +22,8 @@
Installation script for the OpenStack Dashboard development virtualenv.
"""
from __future__ import print_function
import os
import subprocess
import sys
@ -69,12 +71,12 @@ HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'],
def check_dependencies():
"""Make sure virtualenv is in the path."""
print 'Checking dependencies...'
print('Checking dependencies...')
if not HAS_VIRTUALENV:
print 'Virtual environment not found.'
print('Virtual environment not found.')
# Try installing it via easy_install...
if HAS_EASY_INSTALL:
print 'Installing virtualenv via easy_install...',
print('Installing virtualenv via easy_install...', end=' ')
run_command(['easy_install', 'virtualenv'],
die_message='easy_install failed to install virtualenv'
'\ndevelopment requires virtualenv, please'
@ -84,28 +86,28 @@ def check_dependencies():
' requires virtualenv, please install it using your'
' favorite package management tool and ensure'
' virtualenv is in your path')
print 'virtualenv installation done.'
print('virtualenv installation done.')
else:
die('easy_install not found.\n\nInstall easy_install'
' (python-setuptools in ubuntu) or virtualenv by hand,'
' then rerun.')
print 'dependency check done.'
print('dependency check done.')
def create_virtualenv(venv=VENV):
"""Creates the virtual environment and installs PIP only into the
virtual environment
"""
print 'Creating venv...',
print('Creating venv...', end=' ')
run_command(['virtualenv', '-q', '--no-site-packages', VENV])
print 'done.'
print 'Installing pip in virtualenv...',
print('done.')
print('Installing pip in virtualenv...', end=' ')
if not run_command([WITH_VENV, 'easy_install', 'pip']).strip():
die("Failed to install pip.")
print 'done.'
print 'Installing distribute in virtualenv...'
print('done.')
print('Installing distribute in virtualenv...')
pip_install('distribute>=0.6.24')
print 'done.'
print('done.')
def pip_install(*args):
@ -114,8 +116,8 @@ def pip_install(*args):
def install_dependencies(venv=VENV):
print "Installing dependencies..."
print "(This may take several minutes, don't panic)"
print("Installing dependencies...")
print("(This may take several minutes, don't panic)")
pip_install('-r', TEST_REQUIRES)
pip_install('-r', PIP_REQUIRES)
@ -127,7 +129,7 @@ def install_dependencies(venv=VENV):
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)
@ -140,7 +142,7 @@ can run:
$ source .venv/bin/activate
"""
print summary
print(summary)
def main():

View File

@ -1,5 +1,5 @@
[tox]
envlist = py27,pep8
envlist = py27,pep8,py35
minversion = 2.6
skipsdist = True