Skip to content

Commit

Permalink
Merge pull request #3 from salaheddinek/devSalah
Browse files Browse the repository at this point in the history
Dev salah
  • Loading branch information
salaheddinek authored May 7, 2022
2 parents 8129966 + 1e0cec7 commit 12104c2
Show file tree
Hide file tree
Showing 25 changed files with 913 additions and 382 deletions.
102 changes: 98 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,100 @@
# html-auto-2columns
Automatically format two columns in HTML text.
Automatically formats two columns in HTML text (this method adapts to the device screen dimensions).

![app_presentation](images/previews/app_presentation.gif)

Modify HTML page code to add 2 columns sections. This is done by
replacing ```<h6>``` elements that contain the following texts:

## Who can use this application?

This application is destined for people who wish to implement 2 columns in their blog, but also have access to the source HTML code. For example, **Shopify** has this functionality.

## Introduction

Firstly, we describe device aware 2 columns HTML.

The following image shows a web page displaying 2 columns in desktop view, and switches to one column in mobile view:

![sections_types](images/previews/sections_types.png)

In this image, the first example shows a classical columns order in the desktop view that follows the same one in the mobile view. Whereas, in the second example, it shows the inverse order of the columns order in the desktop view. Both views can be achieved by the following CSS code:

```css
.ss_container {
display: flex;
align-items: center;
}

.ss_column_1 {
width: 48%;
margin-right: 1em;
margin-left: 0em;
order: 1;
}

.ss_column_2 {
width: 48%;
margin-right: 0em;
margin-left: 1em;
order: 2;
}
@media only screen and (max-width: 600px) {
.ss_container {
display: initial;
align-items: initial;
}
.ss_column_1, .ss_column_2 {
float:none;
width:100%;
margin-right:0;
margin-left: 0;
}

}
```


## How to Install

The latest release can be downloaded from the link below (no installation needed):

[https://github.com/salaheddinek/html-auto-2columns/releases/latest](https://github.com/salaheddinek/html-auto-2columns/releases/latest)

Otherwise, The user can build the application using files in ```bundle``` folder:

## How to use

![application_preview](images/previews/app_preview.png)





Once the application is downloaded, it can run without installation.


Following these steps will get the desired results:

1. Copy the CSS code to your website, this need to be done only once.
2. Insert ```<h6>``` titles with the according tags in order to wrap the sections that need to be
formatted:

* For direct 2 columns section insert ```<h6> ... ###start### ... </h6>```followed by the content of the **first** columns, followed by ```<h6> ... ###next### ... </h6>```, followed by the content of the **second** column, followed by ```<h6> ... ###end### ... </h6>```.

* For opposite sides 2 columns ```<h6> ... ###start_inv### ... </h6>```followed by the content of the **second** columns, followed by ```<h6> ... ###next### ... </h6>```, followed by the content of the **first** column, followed by ```<h6> ... ###end### ... </h6>```.

3. Copy the source HTML code and paste it in the application *Original HTML text entry*.
4. Click on **process** button.
5. Copy the result *HTML code* and replace the original one on the website


The first GIF illustrates this process. Examples used in this GIF can be found in the ```examples``` folder.



## Final note

If you have any suggestions for the application, or you for the README presentation, please open a new issue in the GitHub issues section.


Modify Shopify page code to add 2 columns sections. This is done by
replacing <h6> elements that contain the following texts:
###start### (or ###start_inv### to inverse columns), ###next###, ###end###.
2 changes: 1 addition & 1 deletion bundle/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ def deploy_command(i_deploy_path, i_app_path, i_app_name, additional_params=""):
# ----+ freeze command -----+
additional_param = ""
if sys.platform.lower() == "darwin" or sys.platform.lower() == "win32":
app_icon = join_path(join_path(main_path, "icons"), "app.ico")
app_icon = join_path(join_path(main_path, "images"), "app.ico")
additional_param = "-i {}".format(app_icon)
deploy_command(deploy_path, app_path, app_name, additional_param)
Binary file removed icons/app.ico
Binary file not shown.
Binary file removed icons/app.png
Binary file not shown.
Binary file removed icons/app.xcf
Binary file not shown.
Binary file added images/app.ico
Binary file not shown.
Binary file added images/app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/previews/app_presentation.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/previews/app_preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/previews/sections_types.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PySide6
127 changes: 44 additions & 83 deletions src/__main__.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/python3
__version__ = '2.0'
__version__ = '2.2.0'
__author__ = 'Salah Eddine Kabbour'
__package__ = " html-auto-2columns"

Expand All @@ -9,52 +9,13 @@
import PySide6.QtCore as Qc
import PySide6.QtWidgets as Qw
from datetime import datetime
import paths
import config
import logging
import formatter
import qt_icons
import argparse
import sys
import os
import colorsys


LOGS_COLORS = {logging.INFO: "#206040", logging.WARNING: "#996633", logging.ERROR: "#ad1f1f"}

HELP_TEXT = """
Modify Shopify page code to add 2 columns sections. This is done by
replacing <h6> elements that contain the following texts:
###start### (or ###start_inv### to inverse columns), ###next###, ###end###.
"""


def change_lightness(in_hex_color, in_added_lightness):
c_hex = in_hex_color.lstrip('#')
lv = len(c_hex)
r, g, b = tuple(int(c_hex[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
h, l, s = colorsys.rgb_to_hls(r / 255.0, g / 255.0, b / 255.0)
n_l = l + in_added_lightness
n_l = max(0, min(1, n_l))
r, g, b = colorsys.hls_to_rgb(h, n_l, s)
return '#%02x%02x%02x' % (int(r * 255), int(g * 255), int(b * 255))


def setup_logging(logging_lvl, save_logs_to_file):
init_logger = logging.getLogger(__package__)
init_logger.setLevel(logging_lvl)
i_formatter = logging.Formatter('[%(levelname)s] [%(asctime)s] - %(message)s', "%Y-%m-%d %H:%M:%S")
ch = logging.StreamHandler()
ch.setFormatter(i_formatter)
init_logger.addHandler(ch)
if save_logs_to_file:
log_file_path = paths.get_logs_path(__package__)
if os.path.exists(log_file_path):
os.remove(log_file_path)
handler = logging.FileHandler(log_file_path, encoding='utf8')
n_formatter = logging.Formatter('[%(levelname)s] [%(asctime)s] - %(message)s', "%H:%M:%S")
handler.setFormatter(n_formatter)
handler.setLevel(logging_lvl)
init_logger.addHandler(handler)
import styling


class MainWindow(Qw.QMainWindow):
Expand All @@ -76,7 +37,7 @@ def __init__(self):
self.saved_settings = {
"clear_elements": True,
"save_origins_to_file": False,
"save_file_path": paths.get_save_file_path(),
"save_file_path": config.get_save_file_path(),
}
self.ui_settings.ledit_save_path.setText(self.saved_settings["save_file_path"])
self.enable_disable_save_path_line_edit()
Expand Down Expand Up @@ -139,40 +100,60 @@ def show_hide_settings(self):
if self.show_settings:
self.show_settings = False
self.ui.btn_settings.setDisabled(False)
self.ui.btn_settings.setDown(False)
self.ui.wid_settings.hide()
self.ui.wid_html.show()
else:
self.show_settings = True
self.ui.btn_settings.setDisabled(True)
self.ui.btn_settings.setDown(True)
self.ui.wid_settings.show()
self.ui.wid_html.hide()

def change_save_path(self):
name = Qw.QFileDialog.getSaveFileName(self, 'Save File', dir=config.get_save_file_path())
name = name[0]
if name != "":
self.ui_settings.ledit_save_path.setText(name)

def copy_to_clipboard(self):
clipboard = Qg.QClipboard()
clipboard.setText(self.ui.plain_text_processed.toPlainText())
self.log("Copied processed HTML text to clipboard")

def _connect_signals(self):
self.ui.btn_process.clicked.connect(self.process_html)
self.ui.btn_clear.clicked.connect(self.clear_entries)
self.ui.btn_settings.clicked.connect(self.show_hide_settings)
self.ui.btn_quit.clicked.connect(self.close_app)
self.ui.btn_logs.clicked.connect(self.show_hide_logs)
self.ui.btn_help.clicked.connect(self.help_msg.exec)
self.ui.btn_copy.clicked.connect(self.copy_to_clipboard)

self.ui_settings.cbox_save_origins.clicked.connect(self.enable_disable_save_path_line_edit)
self.ui_settings.btn_ok.clicked.connect(self.save_settings)
self.ui_settings.btn_cancel.clicked.connect(self.cancel_settings)
self.ui_settings.btn_change.clicked.connect(self.change_save_path)
# Qc.QObject.connect(self.ui.btn_process, Qc.SIGNAL("clicked()"), self.process_link())

def _style_app(self):
self.Buttons_list = [self.ui.btn_process, self.ui.btn_quit, self.ui.btn_clear, self.ui.btn_help,
self.ui.btn_logs, self.ui.btn_settings,
self.ui.btn_logs, self.ui.btn_settings, self.ui.btn_copy, self.ui_settings.btn_change,
self.ui_settings.btn_ok, self.ui_settings.btn_cancel]
for button in self.Buttons_list:
btn_color = button.palette().color(Qg.QPalette.Button).name()
button.setStyleSheet(self._generate_button_stylesheet(change_lightness(btn_color, -0.05)))
button.setStyleSheet(styling.generate_button_stylesheet(btn_color))

self.Tool_Buttons_list = [self.ui.btn_help, self.ui.btn_logs, self.ui.btn_settings]
for button in self.Tool_Buttons_list:
btn_color = button.palette().color(Qg.QPalette.Button).name()
button.setStyleSheet(styling.generate_tool_button_stylesheet(btn_color))

frames = [self.ui.plain_text_logs, self.ui.plain_text_html, self.ui.frame, self.ui.plain_text_processed]
frames = [self.ui.plain_text_logs, self.ui.plain_text_html, self.ui.plain_text_processed]
for frame in frames:
frame.setStyleSheet(self._generate_plain_text_edit_stylesheet())
frame.setStyleSheet(styling.generate_frame_stylesheet(styling.COLORS["entry_bg"]))

self.ui_settings.ledit_save_path.setStyleSheet(
styling.generate_line_edit_stylesheet(styling.COLORS["entry_bg"]))
self.ui.frame.setStyleSheet(styling.generate_frame_stylesheet())

self.i_stg = qt_icons.qt_icon_from_text_image(qt_icons.SETTINGS_ICON)
self.ui.btn_settings.setIcon(self.i_stg)
Expand All @@ -187,6 +168,9 @@ def _style_app(self):
self.i_q = qt_icons.qt_icon_from_text_image(qt_icons.EXIT_ICON)
self.ui.btn_quit.setIcon(self.i_q)

self.i_cp = qt_icons.qt_icon_from_text_image(qt_icons.COPY_ICON)
self.ui.btn_copy.setIcon(self.i_cp)

self.i_c = qt_icons.qt_icon_from_text_image(qt_icons.CLEAR_ICON)
self.ui.btn_clear.setIcon(self.i_c)
self.ui_settings.btn_cancel.setIcon(self.i_c)
Expand All @@ -197,10 +181,13 @@ def _style_app(self):
self.i_sv = qt_icons.qt_icon_from_text_image(qt_icons.SAVE_ICON)
self.ui_settings.btn_ok.setIcon(self.i_sv)

self.i_ch = qt_icons.qt_icon_from_text_image(qt_icons.CHANGE_ICON)
self.ui_settings.btn_change.setIcon(self.i_ch)

# message box
# self.help_msg.setStyleSheet("color: red; background-color: green;")
self.help_msg.setWindowTitle("About page")
self.help_msg.setText(HELP_TEXT)
self.help_msg.setText(config.HELP_TEXT)

@Qc.Slot()
def log(self, msg, log_lvl=logging.INFO, time=5000):
Expand All @@ -212,44 +199,15 @@ def log(self, msg, log_lvl=logging.INFO, time=5000):
now = datetime.now()
ui_log = "<span>[<span style='color: {};'>{}</span>] [{}] - {}</span>"
keys = {logging.INFO: "INFO", logging.WARNING: "WARN", logging.ERROR: "ERROR"}
self.ui.plain_text_logs.appendHtml(ui_log.format(LOGS_COLORS[log_lvl],
self.ui.plain_text_logs.appendHtml(ui_log.format(styling.LOGS_COLORS[log_lvl],
keys[log_lvl],
now.strftime("%H:%M:%S"),
msg.capitalize()))
s_font = self.ui.statusbar.font()
self.ui.statusbar.setStyleSheet(f"color: {LOGS_COLORS[log_lvl]}")
self.ui.statusbar.setStyleSheet(f"color: {styling.LOGS_COLORS[log_lvl]}")
self.ui.statusbar.setFont(s_font)
self.ui.statusbar.showMessage(bar_msg, time)

@staticmethod
def _generate_button_stylesheet(hex_color):
c = hex_color
lighter_c = change_lightness(c, 0.1)
light_c = change_lightness(c, 0.05)
dark_c = change_lightness(c, -0.05)
darker_c = change_lightness(c, -0.15)

ss = ""
ss += "QPushButton {"
ss += f"background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 {light_c}, stop:1 {c});"
ss += f"border-radius:3px; border: solid {darker_c}; "
ss += "border-width: 1px 2px 2px 1px;"
ss += "padding: 10px 15px 10px 15px;"
ss += "}"
ss += "QPushButton:hover {"
ss += f"background-color: qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 {lighter_c}, stop:1 {light_c});"
ss += "}"
ss += f"QPushButton:pressed {{background-color: {dark_c};}}"
ss_tb = ss.replace("QPushButton", "QToolButton")
ss_tb = ss_tb.replace("padding: 10px 15px 10px 15px;", "padding: 7px 7px 7px 7px;")
# print(ss_tb)
return ss + ss_tb

@staticmethod
def _generate_plain_text_edit_stylesheet():
ss = "QFrame {border-width: 1; border-radius: 3; border-style: solid; border-color: rgb(180, 180, 180)}"
return ss


def boolean_string(s):
if s not in {'False', 'True'}:
Expand All @@ -259,7 +217,10 @@ def boolean_string(s):

if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,
description='Download links from a specific website')
description='Modify Shopify page code to add 2 columns sections. This is done by '
'replacing <h6> elements that contain the following texts: '
'###start### (or ###start_inv### to inverse columns), ###next###, '
'###end###.')
parser.add_argument('-s', '--style', help='Qt application style', type=str,
default="Fusion", metavar='\b')
parser.add_argument('-l', '--log_level', help='FATAL = 50, ERROR = 40, WARNING = 30, INFO = 20, DEBUG = 10, '
Expand All @@ -275,7 +236,7 @@ def boolean_string(s):
exit(0)

# Initiate logger
setup_logging(args.log_level, args.logs_file)
config.setup_logging(__package__, args.log_level, args.logs_file)

# initiate App
app = Qw.QApplication(sys.argv)
Expand Down
Loading

0 comments on commit 12104c2

Please sign in to comment.