def validate_self(self) -> (bool, List[str]): """ Validate this document against the article xml schema. :return: Tuple of boolean validation result and optional list of error messages. :raise UnrecognizedFileException if html parse fails """ with open(self.get_path(), 'r') as file: html_string = file.read() self._valid, errors = Tools.validate(html_string, 'schema_article.xsd') return self._valid, errors
def __init__(self, parent, articles: Dict[str, WhitebearDocumentArticle], index: WhitebearDocumentIndex, css: WhitebearDocumentCSS): """ Display a modal dialog with a message with the text being selectable. :param parent: Parent frame. """ wx.Dialog.__init__(self, parent, style=wx.DEFAULT_DIALOG_STYLE, title=Strings.label_upload, size=(Numbers.upload_dialog_width, Numbers.upload_dialog_height)) self.small_font = wx.Font(Numbers.text_field_font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False) self.bold_small_font = wx.Font(Numbers.text_field_font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False) self._config_manager: ConfigManager = ConfigManager.get_instance() self._articles = articles self._index = index self._css = css # Contains unique id and disk path for each file in the file list even those unchecked. self._upload_dict: Dict[int, Tuple[str, bool]] = {} self._finished_uploads: List[str] = [] self._id_counter = 0 self._invalid_files = 0 self._sftp_thread = None # If a menu or index is invalid, upload must be prevented until the user fixes it in a different dialog. self._prevent_upload = False self._main_horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._right_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._config_sizer = wx.StaticBoxSizer(wx.VERTICAL, self, Strings.label_sftp) self._upload_info_sizer = wx.StaticBoxSizer( wx.HORIZONTAL, self, Strings.label_upload_information) # File list sizer self._filelist_sizer = wx.BoxSizer(wx.VERTICAL) self._file_list = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_HRULES) self._file_list.SetFont(self.small_font) self._file_list.InsertColumn(0, Strings.label_files_to_upload, format=wx.LIST_FORMAT_LEFT) self._file_list.SetColumnWidth(0, Numbers.upload_filelist_width) # Scrolling is slow because of checked checkboxes, empty boxes are ok. self._file_list.EnableCheckBoxes() self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add) self._filelist_sizer.Add(self._file_list, flag=wx.EXPAND, border=Numbers.widget_border_size, proportion=1) self._filelist_sizer.Add(self._add_button, flag=wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=Numbers.widget_border_size) # IP, port sizer self._ip_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_ip_port = wx.StaticText(self, -1, Strings.label_ip_port + ': ') self._field_ip_port = wx.TextCtrl(self, -1) self._ip_sub_sizer.Add(self._label_ip_port, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._ip_sub_sizer.Add(4, -1) self._ip_sub_sizer.Add(self._field_ip_port, proportion=1) self._config_sizer.Add(self._ip_sub_sizer, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=Numbers.widget_border_size) self._field_ip_port_tip = Tools.get_warning_tip( self._field_ip_port, Strings.label_ip_port) self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip) # User self._user_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_user = wx.StaticText(self, -1, Strings.label_user + ': ') self._field_user = wx.TextCtrl(self, -1) self._user_sub_sizer.Add(self._label_user, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._user_sub_sizer.Add(17, -1) self._user_sub_sizer.Add(self._field_user, proportion=1) self._config_sizer.Add(self._user_sub_sizer, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=Numbers.widget_border_size) self._field_user_tip = Tools.get_warning_tip(self._field_user, Strings.label_user) self._field_user_tip.SetMessage(Strings.label_user_tip) # Key file self._keyfile_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_keyfile = wx.StaticText(self, -1, Strings.label_key_file + ': ') self._field_keyfile = wx.TextCtrl(self, -1) self._keyfile_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse) self._keyfile_sub_sizer.Add(self._label_keyfile, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._keyfile_sub_sizer.Add(self._field_keyfile, proportion=1) self._keyfile_sub_sizer.Add(self._keyfile_button, flag=wx.LEFT, border=Numbers.widget_border_size) self._config_sizer.Add(self._keyfile_sub_sizer, flag=wx.EXPAND | wx.ALL, border=Numbers.widget_border_size) self._field_keyfile_tip = Tools.get_warning_tip( self._field_keyfile, Strings.label_key_file) self._field_keyfile_tip.SetMessage(Strings.label_key_file_tip) # Upload bar self._gauge_sizer = wx.BoxSizer(wx.VERTICAL) self._upload_gauge = wx.Gauge(self, -1, style=wx.GA_VERTICAL) self._upload_gauge.SetRange(100) self._upload_gauge.SetValue(1) self._gauge_sizer.Add(self._upload_gauge, 1, flag=wx.EXPAND) # Upload statistics self._info_left_sizer = wx.BoxSizer(wx.VERTICAL) self._info_right_sizer = wx.BoxSizer(wx.VERTICAL) self._label_connection = wx.StaticText(self, -1, Strings.label_connection + ':') self._content_connection = wx.StaticText(self, -1, Strings.label_none) self._info_left_sizer.Add(self._label_connection, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_connection, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._label_num_invalid_files = wx.StaticText( self, -1, Strings.label_invalid_files + ':') self._content_num_invalid_files = wx.StaticText(self, -1, '0') self._content_num_invalid_files.SetForegroundColour(wx.RED) font: wx.Font = self._content_num_invalid_files.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self._content_num_invalid_files.SetFont(font) self._info_left_sizer.Add(self._label_num_invalid_files, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_num_invalid_files, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._label_num_files = wx.StaticText( self, -1, Strings.label_files_to_upload + ':') self._content_num_files = wx.StaticText(self, -1, '0') self._info_left_sizer.Add(self._label_num_files, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_num_files, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._label_successful = wx.StaticText( self, -1, Strings.label_successful_uploads + ':') self._content_successful = wx.StaticText(self, -1, '0') self._content_successful.SetForegroundColour(Numbers.DARK_GREEN_COLOR) self._info_left_sizer.Add(self._label_successful, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_successful, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._label_failed = wx.StaticText(self, -1, Strings.label_failed_uploads + ':') self._content_failed = wx.StaticText(self, -1, '0') self._content_failed.SetForegroundColour(wx.RED) self._info_left_sizer.Add(self._label_failed, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_failed, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._label_current_file = wx.StaticText( self, -1, Strings.label_uploading_file + ':') self._content_current_file = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._info_left_sizer.Add(self._label_current_file, flag=wx.BOTTOM | wx.LEFT, border=Numbers.widget_border_size) self._info_right_sizer.Add(self._content_current_file, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._content_percentage = wx.StaticText(self, -1, '0 %') self._info_right_sizer.Add(self._content_percentage, flag=wx.BOTTOM, border=Numbers.widget_border_size) self._upload_info_sizer.Add(self._info_left_sizer, 1, flag=wx.EXPAND) self._upload_info_sizer.Add(self._info_right_sizer, 2, flag=wx.EXPAND) self._structure_message = wx.StaticText(self, -1, Strings.label_server_structure) self._overwrite_message = wx.StaticText(self, -1, Strings.label_server_overwrite) # Upload button self._upload_button_sizer = wx.BoxSizer(wx.HORIZONTAL) self._upload_button = wx.Button(self, wx.ID_FILE, Strings.button_upload, style=wx.BU_EXACTFIT) self._button_to_upload() self._upload_button_sizer.AddStretchSpacer() self._upload_button_sizer.Add(self._upload_button, flag=wx.ALIGN_CENTER) self._upload_button_sizer.AddStretchSpacer() # Put it all together self._right_vertical_sizer.Add(self._config_sizer, flag=wx.RIGHT | wx.EXPAND, border=Numbers.widget_border_size) self._right_vertical_sizer.Add(self._upload_info_sizer, flag=wx.RIGHT | wx.EXPAND, border=Numbers.widget_border_size) self._right_vertical_sizer.Add(self._structure_message) self._right_vertical_sizer.Add(self._overwrite_message) self._right_vertical_sizer.Add(self._upload_button_sizer, 1, flag=wx.EXPAND) self._main_horizontal_sizer.Add(self._filelist_sizer, flag=wx.EXPAND | wx.ALL, border=Numbers.widget_border_size) self._main_horizontal_sizer.Add(self._right_vertical_sizer, 1, flag=wx.EXPAND) self._main_horizontal_sizer.Add(self._gauge_sizer, flag=wx.EXPAND) self.SetSizer(self._main_horizontal_sizer) self.Bind(wx.EVT_LIST_ITEM_CHECKED, self._check_handler, self._file_list) self.Bind(wx.EVT_LIST_ITEM_UNCHECKED, self._check_handler, self._file_list) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._keyfile_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._upload_button) self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_ip_port) self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_user) self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_keyfile) self.Bind(wx.EVT_CLOSE, self._close_button_handler, self) self._display_dialog_contents()
def __init__(self, parent, video: Video): """ Display a dialog with information about the video where the user can edit it. :param parent: Parent frame. :param video: Video instance being edited by this dialog. """ super().__init__(parent, title=Strings.label_dialog_edit_video, size=(Numbers.edit_video_dialog_width, Numbers.edit_video_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._video = video self._config_manager = ConfigManager.get_instance() self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Title sub sizer self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_video_title = wx.StaticText(self, -1, Strings.label_link_title + ': ') self._field_video_link_title = wx.TextCtrl(self, -1) self._title_sub_sizer.Add(self._label_video_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._title_sub_sizer.Add((5, -1)) self._title_sub_sizer.Add(self._field_video_link_title, proportion=1) self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_video_link_title_tip = Tools.get_warning_tip(self._field_video_link_title, Strings.label_video_link_title) # Url sub sizer self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_video_url = wx.StaticText(self, -1, Strings.label_url + ': ') self._field_video_url = wx.TextCtrl(self, -1) self._url_sub_sizer.Add(self._label_video_url, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._url_sub_sizer.Add((34, -1)) self._url_sub_sizer.Add(self._field_video_url, proportion=1) self._information_sizer.Add(self._url_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_video_url_tip = Tools.get_warning_tip(self._field_video_url, Strings.label_url) # Size self._video_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_video_size = wx.StaticText(self, -1, Strings.label_video_size + ': ') self._content_video_size = wx.StaticText(self, -1, Strings.label_none) self._video_size_sub_sizer.Add(self._label_video_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._video_size_sub_sizer.Add(self._content_video_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._information_sizer.Add(self._video_size_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() grouping_sizer.Add(self._ok_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) self._display_dialog_contents() # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self._original_url = self._video.get_url()[0] self._original_title = self._video.get_title()[0]
def __init__(self, parent, menus: Dict[str, WhitebearDocumentMenu], articles: Dict[str, WhitebearDocumentArticle], css: WhitebearDocumentCSS, index: WhitebearDocumentIndex): """ Display a dialog that allows editing additional data used in html generation. Default main title, author, contact, keywords, main page meta description. script, main page red/black text :param parent: The parent frame. :param menus: Currently loaded dictionary of menus. :param articles: Currently loaded dictionary of articles. :param css: Currently loaded css document. :param index: Currently loaded index document. """ wx.Dialog.__init__(self, parent, title=Strings.label_dialog_new_document, size=(Numbers.new_file_dialog_width, Numbers.new_file_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._config_manager: ConfigManager = ConfigManager.get_instance() self._doc = None self._menus = menus self._articles = articles self._css_document = css self._index = index self._article_image = None self._menu_item = None self._document_path = None self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Name sub sizer self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_file_name = wx.StaticText(self, -1, Strings.label_file_name + ': ') self._field_name = wx.TextCtrl(self, -1) self._name_sub_sizer.Add(self._label_file_name, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._name_sub_sizer.Add(self._field_name, proportion=1) self._information_sizer.Add(self._name_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_name_tip = Tools.get_warning_tip(self._field_name, Strings.label_file_name) self._field_name.SetBackgroundColour(Numbers.RED_COLOR) self._field_name_tip.SetMessage(Strings.warning_empty) choices: List[str] = [ menu.get_page_name()[0] for menu in self._menus.values() ] choices.append('-') # Category sub sizer self._category_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_category = wx.StaticText( self, -1, Strings.label_target_section + ': ') self._box_menu = wx.ComboBox(self, -1, choices=choices, style=wx.CB_DROPDOWN | wx.CB_SORT | wx.CB_READONLY) self._box_menu.SetSelection(0) self._box_menu.SetBackgroundColour(Numbers.RED_COLOR) self._category_sub_sizer.Add(self._label_category, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._category_sub_sizer.Add(16, -1) self._category_sub_sizer.Add(self._box_menu, proportion=1) self._information_sizer.Add(self._category_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Image buttons self._image_buttons_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._menu_logo_button = wx.Button( self, wx.ID_FILE1, style=wx.BU_EXACTFIT | wx.BORDER_NONE, size=wx.Size(Numbers.menu_logo_image_size, Numbers.menu_logo_image_size)) self._menu_logo_button.Disable() self._menu_logo_button.SetBitmap( wx.Bitmap( wx.Image(Fetch.get_resource_path('menu_image.png'), wx.BITMAP_TYPE_PNG))) self._main_image_button = wx.Button(self, wx.ID_FILE2, style=wx.BU_EXACTFIT | wx.BORDER_NONE) self._main_image_button.Disable() self._main_image_button.SetBitmap( wx.Bitmap( wx.Image(Fetch.get_resource_path('article_image.png'), wx.BITMAP_TYPE_PNG))) self._image_buttons_sub_sizer.Add(self._main_image_button, 1, flag=wx.EXPAND) self._image_buttons_sub_sizer.Add(Numbers.widget_border_size, Numbers.widget_border_size) self._image_buttons_sub_sizer.Add(self._menu_logo_button, 1, flag=wx.EXPAND) self._information_sizer.Add(self._image_buttons_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() self._ok_button.Disable() grouping_sizer.Add(self._ok_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_TEXT, self._handle_fields, self._field_name) self.Bind(wx.EVT_BUTTON, self._handle_image_buttons, self._main_image_button) self.Bind(wx.EVT_BUTTON, self._handle_image_buttons, self._menu_logo_button) self.Bind(wx.EVT_COMBOBOX, self._handle_fields, self._box_menu) # If there are no menus, disable the dialog. if not choices: self._field_name.Disable() self._box_menu.Disable()
def convert_to_html(self) -> None: """ Converts this document into a html white bear article page. :return: None :raise UnrecognizedFileException if template file can not be validated. :raise UnrecognizedFileException if html parse fails. :raise UnrecognizedFileException if generated html fails validation. :raises UnrecognizedFileException if xml schema is incorrect. """ with open(Fetch.get_resource_path('article_template.html'), 'r') as template: template_string = template.read() is_valid, errors = Tools.validate(template_string, 'schema_article_template.xsd') if not is_valid: raise UnrecognizedFileException( Strings.exception_html_syntax_error + '\n' + 'article_template.html ' + str(errors)) parsed_template = BeautifulSoup(template_string, 'html5lib') # Fill title. title: Tag = parsed_template.find(name='title') title.string = self._page_name + ' - ' + self._menu_section.get_section_name( ) + ' | ' + Strings.page_name # Fill description. description = parsed_template.find_all(name='meta', attrs={ 'name': 'description', 'content': True }) if len(description) == 1: description[0]['content'] = self._meta_description else: raise UnrecognizedFileException( Strings.exception_parse_multiple_descriptions) # Fill keywords. keywords = parsed_template.find_all(name='meta', attrs={ 'name': 'keywords', 'content': True }) if len(keywords) == 1: keywords[0]['content'] = ', '.join(self._meta_keywords) else: raise UnrecognizedFileException( Strings.exception_parse_multiple_keywords) # Fill author. author = parsed_template.find_all(name='meta', attrs={ 'name': 'author', 'content': True }) if len(author) == 1: author[0]['content'] = self._config_manager.get_author() else: raise UnrecognizedFileException( Strings.exception_parse_multiple_authors) # Fill script. script = parsed_template.find(name='script') script.string = self._config_manager.get_script() # Fill global title. figure = parsed_template.find(name='header').figure figure.figcaption.string = self._config_manager.get_global_title() heading = parsed_template.find(name='h1', attrs={'id': 'heading'}) heading.string = self._config_manager.get_global_title() # Activate correct menu, generate menu items according to menus. menu_container = parsed_template.find(name='nav') for instance in sorted(self._menus.values(), key=lambda x: x.get_section_name(), reverse=True): new_item = parsed_template.new_tag('a', attrs={ 'class': 'menu', 'href': instance.get_filename(), 'title': instance.get_page_name()[0] }) new_item.string = instance.get_page_name()[0] if instance.get_filename() == self._menu_section.get_filename(): new_item['id'] = 'active' menu_container.append(new_item) # Fill main page title. article = parsed_template.find(name='article', attrs={'class': 'textPage'}) article.h2.string = self._page_name # Fill date. parsed_template.find(name='p', attrs={ 'id': 'date' }).string = self._date # Fill main image. main_image_figure = parsed_template.find(name='figure', attrs={'id': 'articleImg'}) main_image_figure.a['href'] = self.get_article_image( ).get_full_filename() main_image_figure.a['title'] = self.get_article_image().get_link_title( )[0] main_image_figure.img['src'] = self.get_article_image( ).get_thumbnail_filename() main_image_figure.img['alt'] = self.get_article_image().get_image_alt( )[0] main_image_figure.figcaption.string = self.get_article_image( ).get_caption()[0] # Fill main text. text_section = parsed_template.find(name='section', attrs='mainText') if not self._enabled: # Save the disabled state into the html, once the article is enabled, this special class will be removed. text_section['class'] = 'mainText disabled' for element in self.get_main_text_elements(): if isinstance(element, Heading): size = 'h3' if element.get_size() == Heading.SIZE_H3 else 'h4' text = element.get_text().get_text() color = element.get_text().get_color() new_h = parsed_template.new_tag(size) new_h.string = text if color != Strings.color_black: # Black text is default, so ignore it. new_h['class'] = color text_section.append(new_h) elif isinstance(element, ImageInText): new_div = parsed_template.new_tag('div', attrs={'class': 'center'}) href = element.get_full_filename() title = element.get_link_title()[0] src = element.get_thumbnail_filename() alt = element.get_image_alt()[0] width = element.get_thumbnail_size()[0] height = element.get_thumbnail_size()[1] new_a = parsed_template.new_tag('a', attrs={ 'href': href, 'target': Strings.blank, 'title': title }) new_img = parsed_template.new_tag('img', attrs={ 'src': src, 'alt': alt, 'width': width, 'height': height }) new_a.append(new_img) new_div.append(new_a) text_section.append(new_div) elif isinstance(element, Video): new_div = parsed_template.new_tag('div', attrs={'class': 'center'}) title = element.get_title()[0] width = element.get_size()[0] height = element.get_size()[1] src = element.get_url()[0] new_iframe = parsed_template.new_tag('iframe', attrs={ 'title': title, 'height': height, 'width': width, 'src': src, 'allowfullscreen': None }) new_div.append(new_iframe) text_section.append(new_div) elif isinstance(element, Paragraph): new_p = parsed_template.new_tag('p') new_p = self._convert_text_contents(new_p, element, parsed_template) text_section.append(new_p) elif isinstance(element, UnorderedList): new_ul = parsed_template.new_tag('ul') for par in element.get_paragraphs(): new_li = parsed_template.new_tag('li') self._convert_text_contents(new_li, par, parsed_template) new_ul.append(new_li) text_section.append(new_ul) # Fill aside images. aside = parsed_template.find(name='aside') for img in self._aside_images: new_figure = parsed_template.new_tag('figure') new_figcaption = parsed_template.new_tag( 'figcaption', attrs={'class': 'photoCaption'}) href = img.get_full_filename() title = img.get_link_title()[0] src = img.get_thumbnail_filename() alt = img.get_image_alt()[0] text = img.get_caption()[0] new_figcaption.string = text new_a = parsed_template.new_tag('a', attrs={ 'href': href, 'target': Strings.blank, 'title': title }) # Width and height are different from the thumbnail here because the image expands in the page. new_img = parsed_template.new_tag( 'img', attrs={ 'src': src, 'alt': alt, 'width': Numbers.aside_thumbnail_width, 'height': Numbers.aside_thumbnail_height, 'class': 'imgAside' }) new_a.append(new_img) new_figure.append(new_a) new_figure.append(new_figcaption) aside.append(new_figure) output = str(parsed_template) is_valid, errors = Tools.validate(output, 'schema_article.xsd') if not is_valid: raise UnrecognizedFileException(Strings.exception_bug + '\n' + self.get_filename() + ' \n' + str(errors)) self._html = output # Save the fact that this file is changed into the list of file that we need to upload. This survives editor # exit and can be restored on start. This list is cleared when a file is uploaded. self._config_manager.store_not_uploaded(self.get_filename())
def convert_to_html(self) -> None: """ Converts this document into a html white bear article page. :return: None :raise UnrecognizedFileException if template file can not be validated. :raise UnrecognizedFileException if html parse fails. :raise UnrecognizedFileException if generated html fails validation. :raises UnrecognizedFileException if xml schema is incorrect. """ self.update_content() with open(Fetch.get_resource_path('index_template.html'), 'r') as template: template_string = template.read() is_valid, errors = Tools.validate(template_string, 'schema_index_template.xsd') if not is_valid: raise UnrecognizedFileException( Strings.exception_html_syntax_error + '\n' + 'index_template.html ' + str(errors)) parsed_template = BeautifulSoup(template_string, 'html5lib') # Fill title. title: Tag = parsed_template.find(name='title') title.string = self._page_name + ' | ' + self._global_title # Fill description. description = parsed_template.find_all(name='meta', attrs={ 'name': 'description', 'content': True }) if len(description) == 1: description[0]['content'] = self._meta_description else: raise UnrecognizedFileException( Strings.exception_parse_multiple_descriptions) # Fill keywords. keywords = parsed_template.find_all(name='meta', attrs={ 'name': 'keywords', 'content': True }) if len(keywords) == 1: keywords[0]['content'] = self._meta_keywords else: raise UnrecognizedFileException( Strings.exception_parse_multiple_authors) # Fill author. author = parsed_template.find_all(name='meta', attrs={ 'name': 'author', 'content': True }) if len(author) == 1: author[0]['content'] = self._author else: raise UnrecognizedFileException( Strings.exception_parse_multiple_descriptions) # Fill script. script = parsed_template.find(name='script') script.string = self._script # Fill global title. figure = parsed_template.find(name='header').figure figure.figcaption.string = self._global_title heading = parsed_template.find(name='h1', attrs={'id': 'heading'}) heading.string = self._global_title # Activate correct menu, generate menu items according to menus. menu_container = parsed_template.find(name='nav') for instance in sorted(self._menus.values(), key=lambda x: x.get_section_name(), reverse=True): new_item = parsed_template.new_tag('a', attrs={ 'class': 'menu', 'href': instance.get_filename(), 'title': instance.get_page_name()[0] }) new_item.string = instance.get_page_name()[0] if instance.get_filename() == self.get_filename(): new_item['id'] = 'active' menu_container.append(new_item) # Fill main page title. article = parsed_template.find(name='article', attrs={'class': 'indexPage'}) article.h2.string = self._page_name # Fill text. new_black_p = parsed_template.new_tag('p') new_black_p.string = self._black_text new_red_p = parsed_template.new_tag('p') new_strong = parsed_template.new_tag('strong', attrs={'class': 'red'}) new_strong.string = self._red_text new_red_p.append(new_strong) article.h2.insert_after(new_red_p) article.h2.insert_after(new_black_p) # Fill news. news = parsed_template.find(name='h3', attrs={'id': 'news'}) # Sort all articles by date. sorted_articles = sorted(self._articles.values(), key=lambda x: x.get_computable_date(), reverse=True) new_ul = parsed_template.new_tag('ul') limit = self._number_of_news for index, item in enumerate(sorted_articles): if index >= limit: break if item.test_self(self._config_manager.get_online_test()): new_li = parsed_template.new_tag('li') href = item.get_filename() title = item.get_page_name()[0] date = item.get_date()[0] + ' ' new_a = parsed_template.new_tag('a', attrs={ 'href': href, 'title': title }) new_a.string = title new_li.string = date new_li.append(new_a) new_ul.append(new_li) else: # Add the next article to news. limit = limit + 1 news.insert_after(new_ul) # Fill contact. contact = parsed_template.find(name='h3', attrs={'id': 'contact'}) # Insert the author's contact as an image. image: wx.Bitmap = Tools.create_image(self._contact) image_path = os.path.join(self._working_directory, Strings.folder_images, Strings.contact_file) image.SaveFile(image_path, wx.BITMAP_TYPE_PNG) src = os.path.join(Strings.folder_images, Strings.contact_file) new_img = parsed_template.new_tag('img', attrs={ 'width': image.GetWidth(), 'height': image.GetHeight(), 'src': src, 'alt': Strings.contact_default_alt }) contact.insert_after(new_img) # Fill design. new_p = parsed_template.new_tag('p') new_p.string = 'Web design: ' + self._author new_img.insert_after(new_p) # Fill aside images from the newest articles. latest_images = [] for article in sorted_articles: if article.is_enabled(): images = article.get_aside_images() if images: latest_images.append(images[0]) if len(latest_images) >= Numbers.max_index_images: break aside = parsed_template.find(name='aside') for img in latest_images: new_figure = parsed_template.new_tag('figure') new_figcaption = parsed_template.new_tag( 'figcaption', attrs={'class': 'photoCaption'}) href = img.get_full_filename() title = img.get_link_title()[0] src = img.get_thumbnail_filename() alt = img.get_image_alt()[0] text = img.get_caption()[0] new_figcaption.string = text new_a = parsed_template.new_tag('a', attrs={ 'href': href, 'target': Strings.blank, 'title': title }) # Width and height are different from the thumbnail here because the image expands in the page. new_img = parsed_template.new_tag( 'img', attrs={ 'src': src, 'alt': alt, 'width': Numbers.aside_thumbnail_width, 'height': Numbers.aside_thumbnail_height, 'class': 'imgAside' }) new_a.append(new_img) new_figure.append(new_a) new_figure.append(new_figcaption) aside.append(new_figure) output = str(parsed_template) is_valid, errors = Tools.validate(output, 'schema_index.xsd') if not is_valid: raise UnrecognizedFileException(Strings.exception_bug + '\n' + self.get_filename() + ' \n' + str(errors)) self._html = output
from Tools.Tools import Tools d = Tools() d.openBrower('http://www.baidu.com/') d.closeBrower()
def __init__(self, parent, no_cancel: bool = False): """ Display a dialog that allows editing additional data used in html generation. Default main title, author, contact, keywords, main page meta description. script, main page red/black text :param parent: The parent frame. :param no_cancel: Do not display cancel button. Used to force page setup completion. """ super().__init__(parent, title=Strings.label_dialog_page_setup, size=(Numbers.page_setup_dialog_width, Numbers.page_setup_dialog_height), style=wx.CAPTION) self._config_manager: ConfigManager = ConfigManager.get_instance() # Multiple inheritance with spellchecked object was causing trouble, so we have our own method. self._checker = SpellCheckerWithIgnoreList( self._config_manager.get_spelling_lang()) # This is used just for seo testing keywords and description. self._test_doc: WhitebearDocument = WhitebearDocument('') self._save_all = False self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Title sub sizer self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_main_title = wx.StaticText( self, -1, Strings.label_global_title + ': ') self._field_global_title = wx.TextCtrl(self, -1) self._title_sub_sizer.Add(self._label_main_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._title_sub_sizer.Add((2, -1)) self._title_sub_sizer.Add(self._field_global_title, proportion=1) self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_global_title_tip = Tools.get_warning_tip( self._field_global_title, Strings.label_global_title) self._field_global_title_tip.SetMessage(Strings.label_main_title_tip) # Url sub sizer self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_url = wx.StaticText(self, -1, Strings.label_website_url + ': ') self._field_url = wx.TextCtrl(self, -1) self._url_sub_sizer.Add(self._label_url, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._url_sub_sizer.Add((44, -1)) self._url_sub_sizer.Add(self._field_url, proportion=1) self._information_sizer.Add(self._url_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_url_tip = Tools.get_warning_tip(self._field_url, Strings.label_website_url) self._field_url_tip.SetMessage(Strings.label_website_url_tip) # Author sub sizer self._author_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_author = wx.StaticText(self, -1, Strings.label_author + ': ') self._field_author = wx.TextCtrl(self, -1) self._label_news = wx.StaticText(self, -1, Strings.label_number_of_news + ': ') self._news_spinner = wx.SpinCtrl(self, -1, style=wx.SP_ARROW_KEYS, min=Numbers.min_news, max=Numbers.max_news, initial=Numbers.default_news) self._author_sub_sizer.Add(self._label_author, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._author_sub_sizer.Add((20, -1)) self._author_sub_sizer.Add(self._field_author, proportion=1) self._author_sub_sizer.Add(Numbers.widget_border_size, Numbers.widget_border_size) self._author_sub_sizer.Add(self._label_news, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._author_sub_sizer.Add(Numbers.widget_border_size, Numbers.widget_border_size) self._author_sub_sizer.Add(self._news_spinner, proportion=0.3) self._information_sizer.Add(self._author_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_author_tip = Tools.get_warning_tip(self._field_author, Strings.label_author) self._field_author_tip.SetMessage(Strings.label_author_tip) # e-mail sub sizer self._contact_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_contact = wx.StaticText(self, -1, Strings.label_contact + ': ') self._field_contact = wx.TextCtrl(self, -1) self._contact_sub_sizer.Add(self._label_contact, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._contact_sub_sizer.Add((14, -1)) self._contact_sub_sizer.Add(self._field_contact, proportion=1) self._information_sizer.Add(self._contact_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_contact_tip = Tools.get_warning_tip( self._field_contact, Strings.label_contact) self._field_contact_tip.SetMessage(Strings.label_contact_tip) # Keywords sub sizer self._meta_keywords_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_meta_keywords = wx.StaticText( self, -1, Strings.label_default_keywords + ': ') self._field_meta_keywords = wx.TextCtrl(self, -1) self._meta_keywords_sub_sizer.Add(self._label_meta_keywords, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._meta_keywords_sub_sizer.Add(self._field_meta_keywords, proportion=1) self._information_sizer.Add(self._meta_keywords_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_keywords_tip = Tools.get_warning_tip( self._field_meta_keywords, Strings.label_article_keywords) self._field_keywords_tip.SetMessage(Strings.label_default_keywords_tip) # -------------------------------------------------------------------------------------------------------------- # Description sub sizer self._meta_description_sub_sizer = wx.BoxSizer(wx.VERTICAL) self._label_meta_description = wx.StaticText( self, -1, Strings.label_main_meta_description + ': ') self._field_meta_description = wx.TextCtrl(self, -1, size=wx.Size(-1, 60), style=wx.TE_MULTILINE) self._meta_description_sub_sizer.Add(self._label_meta_description, flag=wx.ALIGN_LEFT) self._meta_description_sub_sizer.Add(3, 3) self._meta_description_sub_sizer.Add(self._field_meta_description, proportion=1, flag=wx.EXPAND) self._information_sizer.Add(self._meta_description_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_description_tip = Tools.get_warning_tip( self._field_meta_description, Strings.label_main_meta_description) self._field_description_tip.SetMessage( Strings.label_main_description_tip) # Script sub sizer self._script_sub_sizer = wx.BoxSizer(wx.VERTICAL) self._label_script = wx.StaticText(self, -1, Strings.label_script + ': ') self._field_script = wx.TextCtrl(self, -1, size=wx.Size(-1, 135), style=wx.TE_MULTILINE) self._script_sub_sizer.Add(self._label_script, flag=wx.ALIGN_LEFT) self._script_sub_sizer.Add(3, 3) self._script_sub_sizer.Add(self._field_script, proportion=1, flag=wx.EXPAND) self._information_sizer.Add(self._script_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_script_tip = Tools.get_warning_tip(self._field_script, Strings.label_script) self._field_script_tip.SetMessage(Strings.label_script_tip) # Black text sub sizer self._black_text_sub_sizer = wx.BoxSizer(wx.VERTICAL) self._label_black_text = wx.StaticText( self, -1, Strings.label_main_page_text + ': ') self._field_black_text = wx.TextCtrl(self, -1, size=wx.Size(-1, 135), style=wx.TE_MULTILINE) self._black_text_sub_sizer.Add(self._label_black_text, flag=wx.ALIGN_LEFT) self._black_text_sub_sizer.Add(3, 3) self._black_text_sub_sizer.Add(self._field_black_text, proportion=1, flag=wx.EXPAND) self._information_sizer.Add(self._black_text_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_black_text_tip = Tools.get_warning_tip( self._field_black_text, Strings.label_main_page_text) self._field_black_text_tip.SetMessage(Strings.label_main_page_text_tip) # Red text sub sizer self._red_text_sub_sizer = wx.BoxSizer(wx.VERTICAL) self._label_red_text = wx.StaticText( self, -1, Strings.label_main_page_warning + ': ') self._label_red_text.SetForegroundColour(wx.RED) self._field_red_text = wx.TextCtrl(self, -1, size=wx.Size(-1, 135), style=wx.TE_MULTILINE) self._field_red_text.SetForegroundColour(wx.RED) self._red_text_sub_sizer.Add(self._label_red_text, flag=wx.ALIGN_LEFT) self._red_text_sub_sizer.Add(3, 3) self._red_text_sub_sizer.Add(self._field_red_text, proportion=1, flag=wx.EXPAND) self._information_sizer.Add(self._red_text_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_red_text_tip = Tools.get_warning_tip( self._field_red_text, Strings.label_main_page_warning) self._field_red_text_tip.SetMessage( Strings.label_main_page_warning_tip) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() grouping_sizer.Add(self._ok_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) if no_cancel: self._cancel_button.Hide() # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.TOP, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self._display_dialog_contents()
def __init__(self, parent, link: Link): """ Display a dialog with information about the link where the user can edit it. :param parent: Parent frame. :param link: the Link instance to display. """ super().__init__(parent, title=Strings.label_dialog_edit_link, size=(Numbers.edit_link_dialog_width, Numbers.edit_link_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._link = link self._config_manager = ConfigManager.get_instance() self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Link URL sub sizer self._url_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_url = wx.StaticText(self, -1, Strings.label_url + ': ') choices = self._link.get_loaded_pages() choices.append(Strings.index + Strings.extension_html) self._field_url = wx.ComboBox(self, -1, choices=choices, style=wx.CB_DROPDOWN | wx.CB_SORT) # Fires when you type in the box self.Bind(wx.EVT_TEXT, self._combobox_handler, self._field_url) self._url_sub_sizer.Add(self._label_url, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._url_sub_sizer.Add((35, -1)) self._url_sub_sizer.Add(self._field_url, proportion=1) self._information_sizer.Add(self._url_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_url_tip = Tools.get_warning_tip(self._field_url, Strings.label_url) # Link title sub sizer self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_link_title = wx.StaticText(self, -1, Strings.label_link_title + ': ') self._field_link_title = wx.TextCtrl(self, -1) self._title_sub_sizer.Add(self._label_link_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._title_sub_sizer.Add((8, -1)) self._title_sub_sizer.Add(self._field_link_title, proportion=1) self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_link_title_tip = Tools.get_warning_tip( self._field_link_title, Strings.label_link_title) # Link text sub sizer self._text_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_link_text = wx.StaticText(self, -1, Strings.label_text + ': ') self._field_link_text = wx.TextCtrl(self, -1) self._text_sub_sizer.Add(self._label_link_text, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._text_sub_sizer.Add((35, -1)) self._text_sub_sizer.Add(self._field_link_text, proportion=1) self._information_sizer.Add(self._text_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_link_text_tip = Tools.get_warning_tip( self._field_link_text, Strings.label_text) # Target blank checkbox self._checkbox_target_blank = wx.CheckBox( self, -1, label=Strings.label_open_in_new_page) self._checkbox_target_blank.SetValue(True) self._checkbox_target_blank.Disable() # Local link checkbox self._checkbox_local = wx.CheckBox(self, -1, label=Strings.label_link_local) self._checkbox_local.Disable() self._information_sizer.Add(self._checkbox_target_blank, flag=wx.TOP, border=Numbers.widget_border_size) self._information_sizer.Add(self._checkbox_local, flag=wx.TOP, border=Numbers.widget_border_size) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() self._delete_button = wx.Button(self, wx.ID_DELETE, Strings.button_remove_link) grouping_sizer.Add(self._ok_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._delete_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) self._display_dialog_contents() # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._delete_button) self._original_text = self._link.get_text()[0] self._original_url = self._link.get_url()[0] self._original_title = self._link.get_title()[0]
def convert_to_html(self) -> None: """ Converts this document into a html white bear menu page. :return: None :raise UnrecognizedFileException if template file can not be validated. :raise UnrecognizedFileException if html parse fails. :raise UnrecognizedFileException if generated html fails validation. :raises UnrecognizedFileException if xml schema is incorrect. """ with open(Fetch.get_resource_path('menu_template.html'), 'r') as template: template_string = template.read() is_valid, errors = Tools.validate(template_string, 'schema_menu_template.xsd') if not is_valid: raise UnrecognizedFileException(Strings.exception_html_syntax_error + '\n' + 'menu_template.html ' + str(errors)) parsed_template = BeautifulSoup(template_string, 'html5lib') # Fill title. title: Tag = parsed_template.find(name='title') title.string = Strings.menu_title_stump + ' ' + self._page_name + ' | ' + Strings.page_name # Fill description. description = parsed_template.find_all(name='meta', attrs={'name': 'description', 'content': True}) if len(description) == 1: description[0]['content'] = self._meta_description else: raise UnrecognizedFileException(Strings.exception_parse_multiple_descriptions) # Fill keywords. keywords = parsed_template.find_all(name='meta', attrs={'name': 'keywords', 'content': True}) if len(keywords) == 1: keywords[0]['content'] = ', '.join(self._meta_keywords) else: raise UnrecognizedFileException(Strings.exception_parse_multiple_keywords) # Fill author. author = parsed_template.find_all(name='meta', attrs={'name': 'author', 'content': True}) if len(author) == 1: author[0]['content'] = self._config_manager.get_author() else: raise UnrecognizedFileException(Strings.exception_parse_multiple_authors) # Fill script. script = parsed_template.find(name='script') script.string = self._config_manager.get_script() # Fill global title. figure = parsed_template.find(name='header').figure figure.figcaption.string = self._config_manager.get_global_title() heading = parsed_template.find(name='h1', attrs={'id': 'heading'}) heading.string = self._config_manager.get_global_title() # Activate correct menu, generate menu items according to menus. menu_container = parsed_template.find(name='nav') for instance in sorted(self._menus.values(), key=lambda x: x.get_section_name(), reverse=True): new_item = parsed_template.new_tag('a', attrs={'class': 'menu', 'href': instance.get_filename(), 'title': instance.get_page_name()[0]}) new_item.string = instance.get_page_name()[0] if instance.get_filename() == self._file_name: new_item['id'] = 'active' menu_container.append(new_item) # Fill main page title. article = parsed_template.find(name='article', attrs={'class': 'menuPage'}) article.h2.string = self._page_name # Fill menu items. menu_container = parsed_template.find(name='nav', attrs={'class': 'sixItems'}) for item in self._menu_items: item: MenuItem attrs = {'class': 'link'} if not item.get_article(): # Skip deleted articles. continue if not item.get_article().test_self(self._config_manager.get_online_test()): # Hide this menu item because this article is not yet finished or is deleted. The item will be available # for future parsing though so the editor will load the menu item correctly for the unfinished article. attrs['class'] = 'link hidden' new_div = parsed_template.new_tag('div', attrs=attrs) href = item.get_link_href() title = item.get_link_title()[0] width = item.get_image_size()[0] height = item.get_image_size()[1] src = item.get_filename() alt = item.get_image_alt()[0] text = item.get_article_name()[0] new_a = parsed_template.new_tag('a', attrs={'href': href, 'title': title}) new_img = parsed_template.new_tag('img', attrs={'width': width, 'height': height, 'src': src, 'alt': alt}) new_p = parsed_template.new_tag('p') new_p.string = text new_a.append(new_img) new_div.append(new_a) new_div.append(new_p) menu_container.append(new_div) output = str(parsed_template) is_valid, errors = Tools.validate(output, 'schema_menu.xsd') if not is_valid: raise UnrecognizedFileException(Strings.exception_bug + '\n' + self.get_filename() + ' \n' + str(errors)) self._html = output
''' Created on 2 Jul 2019 @author: wvx67826 ''' import numpy as np from astropy.io import ascii import matplotlib.pyplot as plt from Tools.Tools import Tools dr = Tools() folder = "Y:\\SQUID\\Relm\\3dice\\" filename = folder + "HvM_NoAu_00001.dat" with open(filename, 'r') as f: meta = True tMeta = [] tData = [] # break up the meta and data for line in f: tMeta.append(line) if not meta: tData.append(line) if "[Data]" in line: meta = False k = np.genfromtxt(tData, names=True, delimiter=",") l = ascii.read(tData, delimiter=',') print l["Magnetic Field (Oe)"][0] x = "Magnetic Field (Oe)" y = "Moment (emu)" #"DC Moment Fixed Ctr (emu)" #"Moment (emu)"#
def __init__(self, parent, item: MenuItem, work_dir: str): """ Display a dialog with information about the image where the user can edit it. :param parent: Parent frame. :param item: MenuItem instance being edited by this dialog. :param work_dir: Working directory of the editor. """ super().__init__(parent, title=Strings.label_dialog_edit_menu_item, size=(Numbers.edit_aside_image_dialog_width, Numbers.edit_menu_item_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._work_dir = work_dir self._original_item: MenuItem = item self._item_copy: MenuItem = self._original_item.copy() self._item_copy.test_self() self._alt_lock = False self._title_lock = False self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Disk location self._full_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self.label_image_full_path = wx.StaticText(self, -1, Strings.label_image + ': ') self.content_image_full_path = wx.StaticText( self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._full_disk_location_sub_sizer.Add(self.label_image_full_path, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._full_disk_location_sub_sizer.Add(self.content_image_full_path, 1, flag=wx.EXPAND) self._information_sizer.Add(self._full_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Link href self._href_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_href = wx.StaticText(self, -1, Strings.label_target + ': ') self._content_href = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._href_sub_sizer.Add(self._label_href, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._href_sub_sizer.Add(self._content_href, 1, flag=wx.EXPAND) self._information_sizer.Add(self._href_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Original size self._image_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_size = wx.StaticText(self, -1, Strings.label_size + ': ') self._content_image_size = wx.StaticText(self, -1, Strings.label_none) self._image_size_sub_sizer.Add(self._label_image_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._image_size_sub_sizer.Add((16, -1)) self._image_size_sub_sizer.Add(self._content_image_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._information_sizer.Add(self._image_size_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Image name sub sizer self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_item_name = wx.StaticText(self, -1, Strings.label_menu_name + ': ') self._field_item_name = wx.TextCtrl(self, -1) self._name_sub_sizer.Add(self._label_item_name, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._name_sub_sizer.Add((22, -1)) self._name_sub_sizer.Add(self._field_item_name, proportion=1) self._information_sizer.Add(self._name_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_item_name_tip = Tools.get_warning_tip( self._field_item_name, Strings.label_menu_item_name) # Image link title sub sizer self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_title = wx.StaticText( self, -1, Strings.label_link_title + ': ') self._field_image_link_title = wx.TextCtrl(self, wx.ID_FILE2) self._title_sub_sizer.Add(self._label_image_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._title_sub_sizer.Add((44, -1)) self._title_sub_sizer.Add(self._field_image_link_title, proportion=1) self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_image_link_title_tip = Tools.get_warning_tip( self._field_image_link_title, Strings.label_article_image_link_title) # Image alt sub sizer self._alt_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_alt = wx.StaticText( self, -1, Strings.label_alt_description + ': ') self._field_image_alt = wx.TextCtrl(self, wx.ID_FILE1) self._alt_sub_sizer.Add(self._label_image_alt, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._alt_sub_sizer.Add((5, -1)) self._alt_sub_sizer.Add(self._field_image_alt, proportion=1) self._information_sizer.Add(self._alt_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_image_alt_tip = Tools.get_warning_tip( self._field_image_alt, Strings.label_article_image_alt) # Image preview self._image_sizer = wx.BoxSizer(wx.VERTICAL) placeholder_image: wx.Image = wx.Image(Numbers.menu_logo_image_size, Numbers.menu_logo_image_size) placeholder_image.Replace(0, 0, 0, 245, 255, 255) self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(placeholder_image)) # Item name menu_text_field_font = wx.Font(Numbers.text_field_font_size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False) self._content_item_name = wx.StaticText( self, -1, Strings.label_article_menu_logo_name_placeholder, style=wx.ALIGN_CENTRE_HORIZONTAL) self._content_item_name.SetMaxSize((Numbers.menu_logo_image_size, -1)) self._content_item_name.SetFont(menu_text_field_font) self._image_sizer.Add(self._bitmap, flag=wx.CENTER | wx.ALL, border=1) self._image_sizer.Add(self._content_item_name, flag=wx.CENTER | wx.ALL, border=1) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() self._browse_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse) self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add) grouping_sizer.Add(self._ok_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._browse_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._add_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._horizontal_sizer.Add(self._image_sizer, 0, flag=wx.TOP | wx.RIGHT | wx.EXPAND, border=Numbers.widget_border_size) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_TEXT, self._handle_name_change, self._field_item_name) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button) self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_alt) self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_link_title)
def __init__(self, parent, menus: Dict[str, WhitebearDocumentMenu], work_dir: str): """ Display a dialog that allows editing additional data used in html generation. Default main title, author, contact, keywords, main page meta description. script, main page red/black text :param parent: The parent frame. :param menus: A dictionary of filename.html, WhitebearDocumentMenu :param work_dir: Working directory of the editor. """ super().__init__(parent, title=Strings.label_dialog_edit_menu, size=(Numbers.edit_menu_dialog_width, Numbers.edit_menu_dialog_height), style=wx.CAPTION) self._config_manager: ConfigManager = ConfigManager.get_instance() self._menus = menus self._menu = None self._save_all = False self._work_dir = work_dir self._main_horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._left_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._right_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Menu list choices = list(self._menus.keys()) self._menu_list = wx.ListBox(self, -1, size=(Numbers.minimal_panel_size, -1), choices=choices, style=wx.LB_SINGLE) if self._menus: self._menu_list.SetSelection(0) self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add) self._left_vertical_sizer.Add(self._menu_list, 1, flag=wx.TOP | wx.LEFT, border=Numbers.widget_border_size) self._left_vertical_sizer.Add(self._add_button, flag=wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, border=Numbers.widget_border_size) # Page name sub sizer self._page_name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_page_name = wx.StaticText(self, -1, Strings.label_menu_name + ': ') self._field_page_name = wx.TextCtrl(self, -1) self._page_name_sub_sizer.Add(self._label_page_name, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._page_name_sub_sizer.Add((2, -1)) self._page_name_sub_sizer.Add(self._field_page_name, proportion=1) self._information_sizer.Add(self._page_name_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_page_name_tip = Tools.get_warning_tip( self._field_page_name, Strings.label_menu_name) self._field_page_name_tip.SetMessage(Strings.label_menu_name) # Keywords sub sizer self._meta_keywords_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_meta_keywords = wx.StaticText( self, -1, Strings.label_default_keywords + ': ') self._field_meta_keywords = wx.TextCtrl(self, -1) self._meta_keywords_sub_sizer.Add(self._label_meta_keywords, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._meta_keywords_sub_sizer.Add((15, -1)) self._meta_keywords_sub_sizer.Add(self._field_meta_keywords, proportion=1) self._information_sizer.Add(self._meta_keywords_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_keywords_tip = Tools.get_warning_tip( self._field_meta_keywords, Strings.label_menu_meta_keywords) self._field_keywords_tip.SetMessage(Strings.label_menu_meta_keywords) # -------------------------------------------------------------------------------------------------------------- # Description sub sizer self._meta_description_sub_sizer = wx.BoxSizer(wx.VERTICAL) self._label_meta_description = wx.StaticText( self, -1, Strings.label_meta_description + ': ') self._field_meta_description = wx.TextCtrl(self, -1, size=(-1, 121), style=wx.TE_MULTILINE) self._meta_description_sub_sizer.Add(self._label_meta_description, flag=wx.ALIGN_LEFT) self._meta_description_sub_sizer.Add(3, 3) self._meta_description_sub_sizer.Add(self._field_meta_description, proportion=1, flag=wx.EXPAND) self._information_sizer.Add(self._meta_description_sub_sizer, 1, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=Numbers.widget_border_size) self._field_description_tip = Tools.get_warning_tip( self._field_meta_description, Strings.label_meta_description) self._field_description_tip.SetMessage( Strings.label_menu_meta_description) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_save) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button.SetDefault() self._spellcheck_button = wx.Button(self, wx.ID_SPELL_CHECK, Strings.button_spellcheck) grouping_sizer.Add(self._ok_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add( (Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._spellcheck_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._right_vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._main_horizontal_sizer.Add(self._left_vertical_sizer, flag=wx.EXPAND) self._main_horizontal_sizer.Add(self._right_vertical_sizer, 1, flag=wx.EXPAND) self._right_vertical_sizer.Add(self._button_sizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_horizontal_sizer) # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._spellcheck_button) self.Bind(wx.EVT_BUTTON, self._handle_new_menu_button, self._add_button) self.Bind(wx.EVT_LISTBOX, self._menu_list_handler, self._menu_list) for field in (self._field_page_name, self._field_meta_keywords, self._field_meta_description): self.Bind(wx.EVT_TEXT, self._text_handler, field) if not self._menus: # Disable all but the new menu button. self._field_page_name.Disable() self._field_meta_keywords.Disable() self._field_meta_description.Disable() self._ok_button.Disable() self._display_dialog_contents()
def _validate_fields(self) -> bool: """ Validate configuration fields. :return: True if validation passed """ result = True # Check IP:port ip_port = self._field_ip_port.GetValue().split(':', 2) try: if not self._field_ip_port.GetValue(): self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) elif len(ip_port) > 2 or len( ip_port) < 2 or not ip_port[0] or not ip_port[1]: self._field_ip_port_tip.SetMessage( Strings.warning_incorrect_format) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) result = False elif int(ip_port[1]) < 1 or int(ip_port[1]) > 65535: self._field_ip_port_tip.SetMessage( Strings.warning_incorrect_port) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) result = False ip = ip_port[0].split('.', 4) if len(ip) < 4 or len(ip) > 4 or not ip: self._field_ip_port_tip.SetMessage( Strings.warning_incorrect_ip_format) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) result = False for num in ip: if int(num) < 0 or int(num) > 255: self._field_ip_port_tip.SetMessage( Strings.warning_incorrect_ip_format) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) result = False except ValueError as _: self._field_ip_port_tip.SetMessage( Strings.warning_incorrect_format) Tools.set_field_background(self._field_ip_port, Numbers.RED_COLOR) result = False if result: self._field_ip_port_tip.SetMessage(Strings.label_ip_port_tip) Tools.set_field_background(self._field_ip_port, Numbers.GREEN_COLOR) self._config_manager.store_ip_port(self._field_ip_port.GetValue()) # Check username username = self._field_user.GetValue() if len(username) > Numbers.default_max_length or len(username) < 1: self._field_user_tip.SetMessage(Strings.seo_error_length + ': 1-' + str(Numbers.default_max_length)) Tools.set_field_background(self._field_user, Numbers.RED_COLOR) result = False else: self._field_user_tip.SetMessage(Strings.label_user_tip) Tools.set_field_background(self._field_user, Numbers.GREEN_COLOR) self._config_manager.store_user(self._field_user.GetValue()) # Check keyfile existence key_path = self._field_keyfile.GetValue() if not os.path.exists(key_path) or not os.access(key_path, os.R_OK): self._field_keyfile_tip.SetMessage( Strings.warning_keyfile_inaccessible) Tools.set_field_background(self._field_keyfile, Numbers.RED_COLOR) result = False elif oct(stat.S_IMODE(os.stat(key_path).st_mode)) != oct( Numbers.private_key_permissions): self._field_keyfile_tip.SetMessage( Strings.warning_keyfile_permissions) Tools.set_field_background(self._field_keyfile, Numbers.RED_COLOR) result = False else: self._field_keyfile_tip.SetMessage(Strings.label_key_file_tip) Tools.set_field_background(self._field_keyfile, Numbers.GREEN_COLOR) self._config_manager.store_keyfile(self._field_keyfile.GetValue()) if not result or self._count_checked_files( ) == 0 or self._prevent_upload: self._upload_button.Disable() if self._prevent_upload: self._content_num_invalid_files.SetLabelText( str(self._invalid_files) + ' - ' + Strings.warning_fatal_invalidity) else: self._upload_button.Enable() return result
class Yhdlogin(): def __init__(self): self.instance = Tools() def login(self, username, password): # self.instance.openBrower("http://www.yhd.com/") # self.instance.wait(3) self.instance.clickEvent("class_name", "hd_login_link") self.instance.wait(3) self.instance.inputEvent("name", "credentials.username", username) self.instance.inputEvent("name", "credentials.password", password) self.instance.clickEvent("id", "login_button") self.instance.wait(2) try: get_text = self.instance.getText("class_name", "hd_login_name") self.instance.moveElement("class_name", "hd_login_name") self.instance.clickEvent("class_name", "hd_login_out") except: get_text = self.instance.getText("class_name", "error_tips") return get_text
def __init__(self, parent, work_dir: str): """ This dialog helps with adding a new menu logo into the folder structure of the website. Display a dialog with information about the image where the user can edit it. :param parent: Parent frame. :param work_dir: The working directory of the editor. """ wx.Dialog.__init__(self, parent, title=Strings.label_dialog_add_logo, size=(Numbers.add_logo_dialog_width, Numbers.add_logo_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) self._image_path = None self._image_name = None self._menu_image = None self._logos_path = None self._working_directory = work_dir self._file_path = None self._config_manager = ConfigManager.get_instance() # Disk location self._original_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_original_path = wx.StaticText(self, -1, Strings.label_image + ': ') self._content_image_original_path = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._original_disk_location_sub_sizer.Add(self._label_image_original_path, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._original_disk_location_sub_sizer.Add(self._content_image_original_path, 1, flag=wx.EXPAND) self._information_sizer.Add(self._original_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Original size self._image_original_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_size = wx.StaticText(self, -1, Strings.label_size + ': ') self._content_image_size = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._image_original_size_sub_sizer.Add(self._label_image_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._image_original_size_sub_sizer.Add((14, -1)) self._image_original_size_sub_sizer.Add(self._content_image_size, 1, flag=wx.EXPAND) self._information_sizer.Add(self._image_original_size_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Image name sub sizer self._name_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_name = wx.StaticText(self, -1, Strings.label_name + ': ') self._field_image_name = wx.TextCtrl(self, -1) self._field_image_name.Disable() self._name_sub_sizer.Add(self._label_image_name, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._name_sub_sizer.Add((5, -1)) self._name_sub_sizer.Add(self._field_image_name, proportion=1) self._information_sizer.Add(self._name_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_image_name_tip = Tools.get_warning_tip(self._field_image_name, Strings.label_image_name) self._field_image_name_tip.SetMessage('') # Image preview self._image_sizer = wx.BoxSizer(wx.VERTICAL) self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(wx.Image(Fetch.get_resource_path('menu_image_missing.png'), wx.BITMAP_TYPE_PNG))) self._image_sizer.Add(self._bitmap, flag=wx.ALL, border=1) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._save_button = wx.Button(self, wx.ID_OK, Strings.button_save) self._browse_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse) self._save_button.Disable() self._browse_button.SetDefault() grouping_sizer.Add(self._save_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._browse_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._horizontal_sizer.Add(self._image_sizer, flag=wx.TOP | wx.RIGHT, border=Numbers.widget_border_size) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._save_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button) self.Bind(wx.EVT_TEXT, self._switch_default_button, self._field_image_name)
def __init__(self): self.instance = Tools()
def _seo_test(self) -> bool: """ SEO test meta keywords and meta description. :return: True if seo is ok. """ result = True # Keywords test. # Spellcheck here is a part of the seo tests. correct, message, color = self._test_doc.seo_test_keywords( self._field_meta_keywords.GetValue()) result = result and correct self._field_meta_keywords.SetBackgroundColour(color) self._field_keywords_tip.SetMessage( Strings.label_default_keywords_tip + '\n\n' + Strings.seo_check + '\n' + message) # Description test. correct, message, color = self._test_doc.seo_test_description( self._field_meta_description.GetValue()) result = result and correct Tools.set_field_background(self._field_meta_description, color) self._field_description_tip.SetMessage( Strings.label_main_description_tip + '\n\n' + Strings.seo_check + '\n' + message) # Check emptiness. # Check length and spelling. for sp, field, tip, msg in ((True, self._field_global_title, self._field_global_title_tip, Strings.label_main_title_tip), (True, self._field_author, self._field_author_tip, Strings.label_author_tip), (False, self._field_contact, self._field_contact_tip, Strings.label_contact_tip), (False, self._field_url, self._field_url_tip, Strings.label_website_url_tip), (False, self._field_script, self._field_script_tip, Strings.label_script_tip), (True, self._field_black_text, self._field_black_text_tip, Strings.label_main_page_text_tip), (True, self._field_red_text, self._field_red_text_tip, Strings.label_main_page_warning_tip)): if field in (self._field_global_title, self._field_author, self._field_contact, self._field_url) and \ (len(field.GetValue()) > Numbers.default_max_length or len(field.GetValue()) < 1): result = False Tools.set_field_background(field, Numbers.RED_COLOR) tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' + Strings.seo_error_length + ': 1 - ' + str(Numbers.default_max_length)) elif field in (self._field_script, self._field_black_text, self._field_red_text) and not field.GetValue(): result = False Tools.set_field_background(field, Numbers.RED_COLOR) tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' + Strings.seo_error_not_empty) elif not self._spell_check(field.GetValue()) and sp: # Run spellcheck on this field. # In other cases spellcheck is done by the object copy and error messages are set in it. # Here we do not have the copy and have to do it as part of this method again. # Keywords and description already have a spellcheck in their builtin seo test. result = False Tools.set_field_background(field, Numbers.RED_COLOR) tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' + Strings.spelling_error) else: Tools.set_field_background(field, Numbers.GREEN_COLOR) tip.SetMessage(msg + '\n\n' + Strings.seo_check + '\n' + Strings.status_ok) return result
def __init__(self, parent, image: ImageInText, working_dir: str): """ Display a dialog with information about the image where the user can edit it. :param parent: Parent frame. :param image: ImageInText instance being edited by this dialog. :param working_dir: Working directory of the editor """ super().__init__(parent, title=Strings.label_dialog_edit_image, size=(Numbers.edit_text_image_dialog_width, Numbers.edit_text_image_dialog_height), style=wx.DEFAULT_DIALOG_STYLE) self._work_dir = working_dir self._original_image: ImageInText = image self._image_copy: ImageInText = self._original_image.copy() self._image_copy.test_self() self._alt_lock = False self._main_vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) self._vertical_sizer = wx.BoxSizer(wx.VERTICAL) self._information_sizer = wx.BoxSizer(wx.VERTICAL) # Disk locations self._full_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_full_path = wx.StaticText(self, -1, Strings.label_image_path + ': ') self._content_image_full_path = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._full_disk_location_sub_sizer.Add(self._label_image_full_path, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._full_disk_location_sub_sizer.Add(self._content_image_full_path, 1, flag=wx.EXPAND) self._information_sizer.Add(self._full_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._thumb_disk_location_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_thumbnail_path = wx.StaticText(self, -1, Strings.label_image_thumbnail_path + ': ') self._content_image_thumbnail_path = wx.StaticText(self, -1, Strings.label_none, style=wx.ST_ELLIPSIZE_MIDDLE | wx.ST_NO_AUTORESIZE) self._thumb_disk_location_sub_sizer.Add(self._label_image_thumbnail_path, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._thumb_disk_location_sub_sizer.Add(self._content_image_thumbnail_path, 1, flag=wx.EXPAND) self._information_sizer.Add(self._thumb_disk_location_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Original size self._image_original_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_original_size = wx.StaticText(self, -1, Strings.label_original_size + ': ') self._content_image_original_size = wx.StaticText(self, -1, Strings.label_none) self._image_original_size_sub_sizer.Add(self._label_image_original_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._image_original_size_sub_sizer.Add((16, -1)) self._image_original_size_sub_sizer.Add(self._content_image_original_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._information_sizer.Add(self._image_original_size_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Thumbnail size self._image_thumbnail_size_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_thumbnail_size = wx.StaticText(self, -1, Strings.label_thumbnail_size + ': ') self._content_image_thumbnail_size = wx.StaticText(self, -1, Strings.label_none) self._image_thumbnail_size_sub_sizer.Add(self._label_image_thumbnail_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._image_thumbnail_size_sub_sizer.Add(self._content_image_thumbnail_size, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._information_sizer.Add(self._image_thumbnail_size_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) # Image link title sub sizer self._title_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_title = wx.StaticText(self, -1, Strings.label_link_title + ': ') self._field_image_link_title = wx.TextCtrl(self, -1) self._title_sub_sizer.Add(self._label_image_title, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._title_sub_sizer.Add((44, -1)) self._title_sub_sizer.Add(self._field_image_link_title, proportion=1) self._information_sizer.Add(self._title_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_image_link_title_tip = Tools.get_warning_tip(self._field_image_link_title, Strings.label_article_image_link_title) # Image alt sub sizer self._alt_sub_sizer = wx.BoxSizer(wx.HORIZONTAL) self._label_image_alt = wx.StaticText(self, -1, Strings.label_alt_description + ': ') self._field_image_alt = wx.TextCtrl(self, wx.ID_FILE2) self._alt_sub_sizer.Add(self._label_image_alt, flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) self._alt_sub_sizer.Add((5, -1)) self._alt_sub_sizer.Add(self._field_image_alt, proportion=1) self._information_sizer.Add(self._alt_sub_sizer, flag=wx.EXPAND | wx.TOP, border=Numbers.widget_border_size) self._field_image_alt_tip = Tools.get_warning_tip(self._field_image_alt, Strings.label_article_image_alt) # Target blank checkbox all link always open in new page self._checkbox_target_blank = wx.CheckBox(self, -1, label=Strings.label_open_in_new_page) self._checkbox_target_blank.SetValue(True) self._checkbox_target_blank.Disable() self._information_sizer.Add(self._checkbox_target_blank, flag=wx.TOP, border=Numbers.widget_border_size) # Image preview self._image_sizer = wx.BoxSizer(wx.VERTICAL) placeholder_image: wx.Image = wx.Image(Numbers.main_image_width, Numbers.main_image_height) placeholder_image.Replace(0, 0, 0, 245, 255, 255) self._bitmap = wx.StaticBitmap(self, -1, wx.Bitmap(placeholder_image)) self._image_sizer.Add(self._bitmap, flag=wx.ALL, border=1) # Buttons self._button_sizer = wx.BoxSizer(wx.VERTICAL) grouping_sizer = wx.BoxSizer(wx.HORIZONTAL) self._cancel_button = wx.Button(self, wx.ID_CANCEL, Strings.button_cancel) self._ok_button = wx.Button(self, wx.ID_OK, Strings.button_ok) self._ok_button.SetDefault() self._browse_button = wx.Button(self, wx.ID_OPEN, Strings.button_browse) self._add_button = wx.Button(self, wx.ID_ADD, Strings.button_add) grouping_sizer.Add(self._ok_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._cancel_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._browse_button) grouping_sizer.Add((Numbers.widget_border_size, Numbers.widget_border_size)) grouping_sizer.Add(self._add_button) self._button_sizer.Add(grouping_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) # Putting the sizers together self._vertical_sizer.Add(self._information_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=Numbers.widget_border_size) self._horizontal_sizer.Add(self._vertical_sizer, 1) self._horizontal_sizer.Add(self._image_sizer, flag=wx.TOP | wx.RIGHT, border=Numbers.widget_border_size) self._main_vertical_sizer.Add(self._horizontal_sizer, 1, flag=wx.EXPAND) self._main_vertical_sizer.Add(self._button_sizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=Numbers.widget_border_size) self.SetSizer(self._main_vertical_sizer) self._display_dialog_contents() # Disable auto copy of fields if the fields contain different data. if self._field_image_alt.GetValue() != self._field_image_link_title.GetValue(): self._alt_lock = True # Bind handlers self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._ok_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._cancel_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._browse_button) self.Bind(wx.EVT_BUTTON, self._handle_buttons, self._add_button) self.Bind(wx.EVT_TEXT, self._handle_edit, self._field_image_link_title) self.Bind(wx.EVT_TEXT, self._lock_fields, self._field_image_alt)