more work on routing controllers

Signed-off-by: Adam Stokes <adam.stokes@ubuntu.com>
This commit is contained in:
Adam Stokes 2015-06-23 12:40:10 -04:00
parent dcb0337fdc
commit c780386ceb
10 changed files with 193 additions and 27 deletions

View File

@ -20,6 +20,7 @@ import urwid
import urwid.curses_display
from subiquity.palette import STYLES, STYLES_MONO
from subiquity.controllers.welcome import WelcomeController
from subiquity.app import Application
def parse_options(argv):
@ -44,11 +45,7 @@ def main():
screen.set_terminal_properties(256)
screen.register_palette(STYLES)
def unhandled_input(key):
if key in ('Q', 'q', 'esc'):
raise urwid.ExitMainLoop()
urwid.MainLoop(WelcomeController().show(), screen=screen,
unhandled_input=unhandled_input).run()
Application(screen, opts).start()
if __name__ == '__main__':
main()

71
subiquity/app.py Normal file
View File

@ -0,0 +1,71 @@
# Copyright 2015 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" Application entry point """
import urwid
from subiquity.routes import Routes
class ApplicationError(Exception):
""" Exception in Application Class """
pass
class Application:
def __init__(self, screen, opts):
self.screen = screen
self.opts = opts
self.initial_controller = Routes.first()
# Setup eventloop
self.loop = self._build_loop()
self.loop.set_alarm_in(2, self.update)
def _build_loop(self):
""" Builds urwid eventloop, passing in itself to the controllers
for further display manipulation
"""
return urwid.MainLoop(self.initial_controller(routes=Routes,
application=self).show(),
screen=self.screen,
unhandled_input=self.unhandled_input)
def unhandled_input(self, key):
if key in ('Q', 'q', 'esc'):
raise urwid.ExitMainLoop()
if key in ('r', 'R'):
self.redraw_screen()
def redraw_screen(self):
try:
self.loop.draw_screen()
except AssertionError as e:
# self.log.exception("exception failure in redraw_screen")
raise e
def set_alarm_in(self, interval, cb):
self.loop.set_alarm_in(interval, cb)
def update(self, *args, **kwds):
if self.loop is not None:
self.redraw_screen()
self.set_alarm_in(1, self.update)
def start(self):
try:
self.loop.run()
except:
raise ApplicationError("Exception in loop.run()")

View File

@ -16,9 +16,21 @@
from abc import ABCMeta, abstractmethod
class BaseControllerError(Exception):
""" Basecontroller exception """
pass
class BaseController(metaclass=ABCMeta):
controller_name = None
def __init__(self, routes, application):
""" Basecontroller
:param :class:`subiquity.app.Application` application: App class
"""
self.application = application
self.routes = routes
@classmethod
def name(cls):
if cls.controller_name:
@ -41,3 +53,15 @@ class BaseController(metaclass=ABCMeta):
to move to the next controller or end the install.
"""
pass
def next_controller(self, *args, **kwds):
next_controller = self.routes.next()
next_controller(routes=self.routes,
application=self.application).show(*args, **kwds)
self.application.redraw_screen()
def prev_controller(self, *args, **kwds):
prev_controller = self.routes.prev()
prev_controller(routes=self.routes,
application=self.application).show(*args, **kwds)
self.application.redraw_screen()

View File

@ -13,7 +13,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from subiquity.controllers import BaseController
from subiquity.controllers import BaseController, BaseControllerError
from subiquity.views.installpath import InstallpathView
from subiquity.models.installpath import InstallpathModel
@ -28,8 +28,9 @@ class InstallpathController(BaseController):
def finish(self, install_selection=None):
if install_selection is None:
self.prev_controller("WelcomeController")
raise BaseControllerError("No install selection found")
else:
raise SystemExit("Install selection: {}".format(install_selection))
raise BaseControllerError(
"Install selection: {}".format(install_selection))
__controller_class__ = InstallpathController

View File

@ -32,7 +32,7 @@ class WelcomeController(BaseController):
raise SystemExit("No language selected, exiting as there are no "
"more previous controllers to render.")
self.selected_language = language
subprocess.check_call("/usr/local/bin/curtin_wrap.sh")
return
# subprocess.check_call("/usr/local/bin/curtin_wrap.sh")
self.next_controller()
__controller_class__ = WelcomeController

72
subiquity/routes.py Normal file
View File

@ -0,0 +1,72 @@
# Copyright 2015 Canonical, Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from subiquity.controllers.welcome import WelcomeController
from subiquity.controllers.installpath import InstallpathController
class RoutesError(Exception):
""" Error in routes """
pass
class Routes:
""" Defines application routes and maps to their controller
Routes are inserted top down from start to finish. Maintaining
this order is required for routing to work.
"""
routes = [WelcomeController,
InstallpathController]
current_route_idx = 0
@classmethod
def route(cls, idx):
""" Include route listing in controllers """
try:
_route = cls.routes[idx]
except IndexError:
raise RoutesError("Failed to load Route at index: {}".format(idx))
return _route
@classmethod
def first(cls):
""" first controller/start of install """
return cls.route(0)
@classmethod
def last(cls):
""" end of install, last controller """
return cls.route(-1)
@classmethod
def go_to_beginning(cls):
cls.current_route_idx = 0
return cls.route(0)
@classmethod
def go_to_end(cls):
cls.current_route_idx = len(cls.routes) - 1
return cls.route(-1)
@classmethod
def next(cls):
cls.current_route_idx = cls.current_route_idx + 1
return cls.route(cls.current_route_idx)
@classmethod
def prev(cls):
cls.current_route_idx = cls.current_route_idx - 1
return cls.route(cls.current_route_idx)

View File

@ -30,8 +30,8 @@ class Header(WidgetWrap):
excerpt = ""
def __init__(self):
title_widget = Padding.push_10(Color.body(Text(self.title)))
excerpt_widget = Padding.push_10(Color.body(Text(self.excerpt)))
title_widget = Padding.center_79(Color.body(Text(self.title)))
excerpt_widget = Padding.center_79(Color.body(Text(self.excerpt)))
pile = Pile([Text(""),
title_widget,
Text(""),
@ -51,7 +51,7 @@ class Footer(WidgetWrap):
def __init__(self):
border = Text("")
message_widget = Padding.push_10(Color.body(Text(self.message)))
message_widget = Padding.center_79(Color.body(Text(self.message)))
status = Pile([border, message_widget])
super().__init__(status)
@ -59,8 +59,9 @@ class Footer(WidgetWrap):
class Body(WidgetWrap):
""" Body widget
"""
body = Pile([Text("Welcome to the Ubuntu Server Installation",
align="center")])
def __init__(self):
self.text = [
Text("Welcome to the Ubuntu Server Installation", align="center")
]
super().__init__(Pile(self.text))
super().__init__(self.body)

View File

@ -19,9 +19,9 @@ from urwid import Frame, WidgetWrap
from subiquity.ui.anchors import Header, Footer, Body
class BaseFrame(WidgetWrap):
class SubiquityUI(WidgetWrap):
def __init__(self):
_frame = Frame(Body(),
self.frame = Frame(Body(),
Header(),
Footer())
super().__init__(_frame)
super().__init__(self._frame)

View File

@ -32,13 +32,13 @@ class InstallpathView(WidgetWrap):
self.model = model
self.cb = cb
self.items = []
self.layout = [
self.body = [
Header(),
Padding.center_79(self._build_model_inputs()),
Padding.pull_50(self._build_buttons()),
Padding.center_20(self._build_buttons()),
Footer()
]
super().__init__(ListBox(self.layout))
super().__init__(ListBox(self.body))
def _build_buttons(self):
self.buttons = [

View File

@ -29,13 +29,13 @@ class WelcomeView(WidgetWrap):
self.model = model
self.cb = cb
self.items = []
self.layout = [
self.body = [
Header(),
Padding.center_79(self._build_model_inputs()),
Padding.center_20(self._build_buttons()),
Footer()
]
super().__init__(ListBox(self.layout))
super().__init__(ListBox(self.body))
def _build_buttons(self):
self.buttons = [