Пример #1
0
 def get(self, library_class):
     matching_libraries = [
         i for i in self.libraries_by_name.values()
         if isinstance(i, library_class)
     ]
     if not matching_libraries:
         raise ProgrammerError(
             'No library "%s" found in the config.web.frontend_libraries' %
             library_class)
     elif len(matching_libraries) > 1:
         raise ProgrammerError(
             'More than "%s" found in the config.web.frontend_libraries' %
             library_class)
     return matching_libraries[0]
Пример #2
0
 def stop_thread(self, join=True):
     self.running = False
     if self.httpd_thread and join:
         self.httpd_thread.join(5)
         if self.httpd_thread.is_alive():
             raise ProgrammerError('Timed out after 5 seconds waiting for httpd serving thread to end')
     self.httpd_thread = None
Пример #3
0
 def __init__(self, stacked=False, justified=False):
     super(PillLayout, self).__init__(key='pill', justified=justified)
     if all([stacked, justified]):
         raise ProgrammerError(
             'Pills must be stacked or justified, but not both')
     self.stacked = stacked
     self.justified = justified
Пример #4
0
 def get_widget_class_for(self, task):
     config = ExecutionContext.get_context().config
     for widget_class in config.workflowui.task_widgets:
         if issubclass(widget_class,
                       TaskWidget) and widget_class.displays(task):
             return widget_class
     raise ProgrammerError('no Widget found to display %s' % task)
Пример #5
0
 def __init__(self, allowed_options, prefix=None, xs=None, sm=None, md=None, lg=None, xl=None):
     self.prefix = prefix
     self.allowed_options = allowed_options
     all_options = {'xs':xs, 'sm':sm, 'md':md, 'lg':lg, 'xl':xl}
     self.device_options = {DeviceClass(device_class_name): option_value for (device_class_name, option_value) in all_options.items() if option_value}
     if not all([i in self.allowed_options for i in self.device_options.values()]):
         raise ProgrammerError('Illegal option. Allowed options: %s, got: %s' % (self.allowed_options, self.device_options))
Пример #6
0
 def __init__(self,
              collapse_below_device_class,
              center_contents=False,
              fixed_to=None,
              align_toggle_left=False,
              collapse_brand_with_content=False,
              colour_theme=None,
              bg_scheme=None,
              text=None):
     super().__init__(fixed_to=fixed_to,
                      center_contents=center_contents,
                      colour_theme=colour_theme,
                      bg_scheme=bg_scheme)
     self.collapse_below_device_class = DeviceClass(
         collapse_below_device_class)
     self.collapse_brand_with_content = collapse_brand_with_content
     self.align_toggle_left = align_toggle_left
     if not self.collapse_below_device_class.one_smaller:
         raise ProgrammerError(
             ('There is no device class smaller than %s' %
              self.collapse_below_device_class) +
             ' It does not make sense to collapse only '
             'if the viewport is smaller than the smallest device')
     self.text = text
     self.collapsing_content = None
Пример #7
0
 def installed_version(self):
     latest_declared_version = self.get_versions()[-1]
     installed_version_string = self.distribution.version
     if str(latest_declared_version.version_number) != '.'.join(installed_version_string.split('.')[:2]):
         raise ProgrammerError('Installed version %s of %s, does not match the latest declared version %s'
                               % (installed_version_string, self.name, latest_declared_version))
     return latest_declared_version
Пример #8
0
    def read(self):
        with io.open(self.filename, 'rb') as dhtml_file:

            def strain(name, attrs):
                if name == 'title':
                    return True
                if name == 'div' and dict(attrs).get('id', None) in self.ids:
                    return True
                return False

            soup = BeautifulSoup(dhtml_file,
                                 "lxml",
                                 parse_only=SoupStrainer(strain))
            parser = html_parser.HTMLParser()
            self.title = parser.unescape(
                soup.title.decode_contents()) if soup.title else _('Untitled')
            for an_id in self.ids:
                found_elements = soup.find_all(id=an_id)
                if found_elements:
                    number_of_ids = len(found_elements)
                    if number_of_ids != 1:
                        raise ProgrammerError(
                            'Expected to find one element with id "%s", but found %s'
                            % (an_id, number_of_ids))
                    [element] = found_elements
                    self.elements[an_id] = element.decode_contents()
                else:
                    self.elements[an_id] = ''
            self.original_encoding = soup.original_encoding
Пример #9
0
 def __init__(self, *column_definitions):
     super(ColumnLayout, self).__init__()
     if not all([
             isinstance(column_definition, six.string_types +
                        (ColumnOptions, ))
             for column_definition in column_definitions
     ]):
         raise ProgrammerError(
             'All column definitions are expected be either a ColumnOptions object of a column name, got %s'
             % six.text_type(column_definitions))
     self.added_column_definitions = []
     self.add_slots = False
     self.add_gutters = True
     self.alignment = Alignment()
     self.content_justification = ContentJustification()
     self.columns = OrderedDict(
     )  #: A dictionary containing the added columns, keyed by column name.
     self.column_definitions = OrderedDict()
     for column_definition in column_definitions:
         if isinstance(column_definition, six.string_types):
             name, options = column_definition, ColumnOptions(
                 column_definition)
         else:
             name, options = column_definition.name, column_definition
         self.column_definitions[name] = options
Пример #10
0
 def get_collaborator(self, account):            
     collaborators = self.collaborators.filter_by(account=account)
     count = collaborators.count()
     if count == 1:
         return collaborators.one()
     if count > 1:
         raise ProgrammerError('There can be only one Collaborator per account. Here is more than one.')
     return None
Пример #11
0
 def check_grids_nesting(self):
     for widget, parents_set in self.parent_widget_pairs(set([])):
         if isinstance(widget.layout, ColumnLayout):
             if not any(
                     isinstance(parent.layout, Container)
                     for parent in parents_set):
                 raise ProgrammerError(('%s does not have a parent with Layout of type %s.' % (widget, Container))+\
                   ' %s has a ColumnLayout, and thus needs to have an anchestor with a Container Layout.' % widget)
Пример #12
0
 def __init__(self, *column_definitions):
     if not all([
             isinstance(column_definition, tuple)
             for column_definition in column_definitions
     ]):
         raise ProgrammerError('All column definitions are expected a tuple of the form (name, %s), got %s' %\
                               (ResponsiveSize, column_definitions))
     self.added_sizes = []
     super(ColumnLayout, self).__init__(*column_definitions)
Пример #13
0
    def __init__(self, left=None, right=None):
        super(ResponsiveFloat, self).__init__()
        if left and right:
            raise ProgrammerError(
                'Both left= and right= have been given. Specify left or right, not both.'
            )

        self.left = ResponsivePull('left', left)
        self.right = ResponsivePull('right', right)
Пример #14
0
def reahl_scope():
    try:
        return ExecutionContext.get_context_id()
    except NoContextFound:
        message = 'Database code can normally only be executed by code executed as part of handling a Request.'
        message += ' Such code is then executed within the context of, for example, a database transaction.'
        message += ' Looks like you attempted to execute database code from the wrong place, since no such context'
        message += ' could be found.'
        raise ProgrammerError(message)
Пример #15
0
 def tear_down_attributes(self):
     for generator in reversed(self.attribute_generators):
         try:
             next(generator)
         except StopIteration:
             pass
         else:
             name = generator.__qualname__ 
             raise ProgrammerError('%s is yielding more than one element. \'new_\' methods should only yield a single element' % name)
Пример #16
0
 def __init__(self, url, config):
     self.config = config
     self.connection_uri = url
     uri_parts = urllib_parse.urlparse(url)
     self.user_name = self.unquote(uri_parts.username)
     self.password = self.unquote(uri_parts.password)
     self.host = self.unquote(uri_parts.hostname)
     self.port = uri_parts.port
     self.database_name = self.unquote(uri_parts.path[1:] if uri_parts.path.startswith('/') else uri_parts.path)
     if not self.database_name:
         raise ProgrammerError('Please specify a database name in reahlsystem.connection_uri')
Пример #17
0
    def set_brand(self, brand_html_element):
        """Sets `brand_html_element` to be used as branding.

        :param brand_html_element: An :class:`~reahl.web.ui.HTMLElement` to be used as branding.
        """
        if self.brand:
            raise ProgrammerError('Brand has already been set to: %s' %
                                  self.brand)

        self.contents_container.insert_child(0, brand_html_element)
        brand_html_element.append_class('navbar-brand')
        self.brand = brand_html_element
Пример #18
0
 def __init__(self, size, left=False, right=False):
     super().__init__()
     self.size = size
     if left and right:
         self.side = 'x'
     elif left:
         self.side = 'l'
     elif right:
         self.side = 'r'
     else:
         raise ProgrammerError(
             'Left and right are both False: Set at least one')
Пример #19
0
    def set_brand(self, brand_htmlwidget):
        """Sets `brand_widget` to be used as branding.

        :param brand_htmlwidget: An :class:`~reahl.web.ui.HTMLWidget` to be used as branding.
        """
        if self.brand:
            raise ProgrammerError('Brand has already been set to: %s' % self.brand)

        self.insert_brand_widget(brand_htmlwidget)
        brand_htmlwidget.append_class('navbar-brand')
        self.brand = brand_htmlwidget
        return self.brand
Пример #20
0
 def __init__(self,
              stacked=False,
              content_alignment=None,
              content_justification=None):
     super().__init__(key='pill',
                      content_alignment=content_alignment,
                      content_justification=content_justification)
     if all([stacked, content_alignment or content_justification]):
         raise ProgrammerError(
             'Pills must be stacked, aligned or justified, but you cannot give all options together'
         )
     self.stacked = stacked
Пример #21
0
 def create_view(self, relative_path, user_interface, file_path=None):
     if not user_interface is self:
         raise ProgrammerError('get_file called on %s with %s as user_interface' % (self, user_interface))
     file_url_path = file_path
     filename = self.filesystem_path(file_url_path)
     logging.debug('Finding a static file on filesystem %s' % filename)
     if self.is_dynamic(filename):
         statics = self.statics(file_url_path)
         slot_contents = {'main_slot': DJHTMLWidget.factory(statics['div'])}
         return UrlBoundView(user_interface, file_url_path, statics['title'], slot_contents, cacheable=True)
     elif self.is_static(filename):
         return FileView(user_interface, FileOnDisk(filename, file_url_path))
     raise CannotCreate()
Пример #22
0
 def __init__(self,
              key=None,
              content_alignment=None,
              content_justification=None):
     super().__init__()
     if content_alignment and content_justification:
         raise ProgrammerError(
             'Cannot set content_alignment and content_justfication at the same time'
         )
     self.content_alignment = ContentAlignment(content_alignment)
     self.content_justification = ContentJustification(
         content_justification)
     self.key = key
Пример #23
0
 def schedule(self, phase, scheduling_migration, scheduling_context,
              to_call, *args, **kwargs):
     if phase == 'drop_fk':
         self.current_drop_fk_phase.append(
             (to_call, scheduling_migration, scheduling_context, args,
              kwargs))
     else:
         try:
             self.phases[phase].append((to_call, scheduling_migration,
                                        scheduling_context, args, kwargs))
         except KeyError as e:
             raise ProgrammerError('A phase with name<%s> does not exist.' %
                                   phase)
Пример #24
0
    def add_toggle(self, target_html_element, text=None):
        """Adds a link that toggles the display of the given `target_html_element`.

        :param target_html_element: A :class:`~reahl.web.ui.HTMLElement`
        :keyword text: Text to be used on the toggle link.
        """
        if not target_html_element.css_id_is_set:
            raise ProgrammerError(
                '%s has no css_id set. A toggle is required to have a css_id' %
                target_html_element)
        target_html_element.append_class('collapse')
        toggle = CollapseToggle(self.view, target_html_element, text=text)
        self.contents_container.add_child(toggle)
        return toggle
Пример #25
0
    def add_toggle(self, target_html_element, text=None, left_aligned=False):
        """Adds a link that toggles the display of the given `target_html_element`.

        :param target_html_element: A :class:`~reahl.web.ui.HTMLElement`
        :param text: Text to be used on the toggle link. If None, the boostrap navbar-toggler-icon is used
        :keyword left_aligned: If True, ensure that the toggle is to the far left.
        """
        if not target_html_element.css_id_is_set:
            raise ProgrammerError('%s has no css_id set. A toggle is required to have a css_id' % target_html_element)
        target_html_element.append_class('collapse')
        toggle = CollapseToggle(self.view, target_html_element, text=text)
        index = 1 if (self.brand and not left_aligned) else 0
        self.main_container.insert_child(index, toggle)

        self.toggle = toggle
        return toggle
Пример #26
0
    def customise_widget(self):
        super().customise_widget()
        if not self.widget.css_id_is_set:
            raise ProgrammerError('%s has no css_id set. A %s can only be used with a Widget that has a css_id' %
                                  (self.widget, self.__class__))

        collapsing_content = Div(self.view, css_id='%s_collapsable' % self.widget.css_id)
        collapsing_content.append_class('navbar-collapse')
        self.collapsing_content = collapsing_content
        self.contents_container.add_child(collapsing_content)
        self.contents_container = collapsing_content

        self.add_toggle(collapsing_content, text=self.text, left_aligned=self.align_toggle_left)

        toggle_size = self.collapse_below_device_class.one_smaller
        self.nav.append_class('navbar-expand-%s' % toggle_size.name)
Пример #27
0
    def __init__(self,
                 fixed_to=None,
                 full=False,
                 center_contents=False,
                 colour_theme=None,
                 bg_scheme=None):
        super(NavbarLayout, self).__init__()
        if fixed_to and full:
            raise ProgrammerError(
                'Both fixed_to and full are given. Give fixed_to or full, but not both'
            )

        self.fixed = NavbarFixed(fixed_to)
        self.full = HTMLAttributeValueOption('navbar-full', full)
        self.center_contents = center_contents
        self.colour_theme = ColourTheme(colour_theme)
        self.bg_scheme = BackgroundScheme(bg_scheme)
        self.brand = None
        self.contents_container = None
Пример #28
0
 def __init__(self,
              collapse_below_device_class,
              fixed_to=None,
              full=False,
              center_contents=False,
              colour_theme=None,
              bg_scheme=None,
              text=None):
     super(ResponsiveLayout, self).__init__(fixed_to=fixed_to,
                                            full=full,
                                            center_contents=center_contents,
                                            colour_theme=colour_theme,
                                            bg_scheme=bg_scheme)
     self.collapse_below_device_class = DeviceClass(
         collapse_below_device_class)
     if not self.collapse_below_device_class.one_smaller:
         raise ProgrammerError(('There is no device class smaller than %s' % self.collapse_below_device_class)+\
                               ' It does not make sense to collapse only if the viewport is smaller than the smallest device')
     self.text = text
Пример #29
0
    def customise_widget(self):
        super(ResponsiveLayout, self).customise_widget()
        if not self.widget.css_id_is_set:
            raise ProgrammerError('%s has no css_id set. A %s can only be used with a Widget that has a css_id' % \
                                (self.widget, self.__class__))

        collapsable = Div(self.view,
                          css_id='%s_collapsable' % self.widget.css_id)
        collapsable.append_class('collapse')
        toggle_widget = CollapseToggle(
            self.view,
            collapsable,
            text=self.text,
            hide_for_size=self.collapse_below_device_class)
        toggle_size = self.collapse_below_device_class.one_smaller
        collapsable.append_class('navbar-toggleable-%s' %
                                 toggle_size.class_label)

        self.contents_container.add_child(toggle_widget)
        self.contents_container.add_child(collapsable)
        self.contents_container = collapsable
Пример #30
0
    def execute(self,
                sql,
                login_username=None,
                password=None,
                database_name=None):
        login_args = {}
        if not (database_name or self.database_name):
            raise ProgrammerError('no database name specified')
        login_args['dbname'] = database_name or self.database_name
        if self.host:
            login_args['host'] = self.host
        if self.port:
            login_args['port'] = self.port
        login_args['user'] = login_username or getpass.getuser()
        if password:
            login_args['password'] = password

        with psycopg2.connect(**login_args) as connection:
            connection.set_isolation_level(
                psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
            with connection.cursor() as cursor:
                return cursor.execute(sql)