Calum Lind c3a2c67b98 [Py3] A large set of fixes for tests to pass under Python 3
The usual minor fixes for unicode/bytes for library calls.

The minimum Twisted version is now 16 for Python 3 support so remove old
code and start replacing deprecated methods.

Raised the minimum TLS version to 1.2 for the web server.
2018-06-27 16:41:21 +01:00

161 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright (C) 2011 Nick Lanham <nick@afternight.org>
# Copyright (C) 2008-2009 Ido Abramovich <ido.deluge@gmail.com>
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import unicode_literals
import logging
from deluge.ui.console.modes.basemode import add_string, mkpad, mkpanel
from deluge.ui.console.utils.colors import get_color_pair
try:
import curses
except ImportError:
pass
log = logging.getLogger(__name__)
class BaseWindow(object):
"""
BaseWindow creates a curses screen to be used for showing panels and popup dialogs
"""
def __init__(self, title, width, height, posy=0, posx=0, encoding=None):
"""
Args:
title (str): The title of the panel
width (int): Width of the panel
height (int): Height of the panel
posy (int): Position of the panel's first row relative to the terminal screen
posx (int): Position of the panel's first column relative to the terminal screen
encoding (str): Terminal encoding
"""
self.title = title
self.posy, self.posx = posy, posx
if encoding is None:
from deluge import component
encoding = component.get('ConsoleUI').encoding
self.encoding = encoding
self.panel = mkpanel(curses.COLOR_GREEN, height, width, posy, posx)
self.outer_screen = self.panel.window()
self.outer_screen.bkgdset(0, curses.COLOR_RED)
by, bx = self.outer_screen.getbegyx()
self.screen = mkpad(get_color_pair('white', 'black'), height - 1, width - 2)
self._height, self._width = self.outer_screen.getmaxyx()
@property
def height(self):
return self._height
@property
def width(self):
return self._width
def add_string(self, row, string, scr=None, **kwargs):
scr = scr if scr else self.screen
add_string(row, string, scr, self.encoding, **kwargs)
def hide(self):
self.panel.hide()
def show(self):
self.panel.show()
def hidden(self):
return self.panel.hidden()
def set_title(self, title):
self.title = title
@property
def visible_content_pane_size(self):
y, x = self.outer_screen.getmaxyx()
return (y - 2, x - 2)
@property
def visible_content_pane_height(self):
y, x = self.visible_content_pane_size
return y
@property
def visible_content_pane_width(self):
y, x = self.visible_content_pane_size
return x
def getmaxyx(self):
return self.screen.getmaxyx()
def resize_window(self, rows, cols):
self.outer_screen.resize(rows, cols)
self.screen.resize(rows - 2, cols - 2)
self._height, self._width = rows, cols
def move_window(self, posy, posx):
posy = int(posy)
posx = int(posx)
self.outer_screen.mvwin(posy, posx)
self.posy = posy
self.posx = posx
self._height, self._width = self.screen.getmaxyx()
def ensure_content_pane_height(self, height):
max_y, max_x = self.screen.getmaxyx()
if max_y < height:
self.screen.resize(height, max_x)
def draw_scroll_indicator(self, screen):
content_height = self.get_content_height()
if content_height <= self.visible_content_pane_height:
return
percent_scroll = float(self.lineoff) / (content_height - self.visible_content_pane_height)
indicator_row = int(self.visible_content_pane_height * percent_scroll) + 1
# Never greater than height
indicator_row = min(indicator_row, self.visible_content_pane_height)
indicator_col = self.width + 1
add_string(
indicator_row, '{!red,black,bold!}#', screen, self.encoding,
col=indicator_col, pad=False, trim=False,
)
def refresh(self):
height, width = self.visible_content_pane_size
self.outer_screen.erase()
self.outer_screen.border(0, 0, 0, 0)
if self.title:
toff = max(1, (self.width // 2) - (len(self.title) // 2))
self.add_string(0, '{!white,black,bold!}%s' % self.title, scr=self.outer_screen, col=toff, pad=False)
self.draw_scroll_indicator(self.outer_screen)
self.outer_screen.noutrefresh()
try:
# pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol
# the p arguments refer to the upper left corner of the pad region to be displayed and
# the s arguments define a clipping box on the screen within which the pad region is to be displayed.
pminrow = self.lineoff
pmincol = 0
sminrow = self.posy + 1
smincol = self.posx + 1
smaxrow = height + self.posy
smaxcol = width + self.posx
self.screen.noutrefresh(pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol)
except curses.error as ex:
import traceback
log.warn(
'Error on screen.noutrefresh(%s, %s, %s, %s, %s, %s) Error: %s\nStack: %s',
pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol, ex, ''.join(traceback.format_stack()),
)