Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 154 additions & 16 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,172 @@
#!/usr/bin/env bash

# Define color codes for output formatting
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m'
NC='\033[0m' # No Color

# Define message prefixes
ERROR="${RED}[ERROR]${NC} "
INFO="${CYAN}[INFO]${NC} "
WARNING="${WARNING}[WARNING]${NC} "
WARNING="${YELLOW}[WARNING]${NC} "

rm -rf dist/bundle.js dist/typings/
# Initialize flags

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
BUILD=false
PACKAGE=false
UPLOAD=false

if [[ $? -eq 0 ]]; then
echo -e "${INFO}deleted bundle.js and typings.."
else
echo -e "${WARNING}could not delete old dist files, continuing.."
# Parse command-line options
while getopts ":bpu" opt; do
case ${opt} in

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
b )
BUILD=true
;;
p )
PACKAGE=true

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
;;
u )
UPLOAD=true
;;
\? )
echo -e "${ERROR}Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done

# If no options are provided, set all flags to true
if [ "$OPTIND" -eq 1 ]; then
BUILD=true
PACKAGE=true
UPLOAD=true
fi

npx rollup -c rollup.config.js
if [[ $? -ne 0 ]]; then
# Function to perform the build process
perform_build() {
echo -e "${INFO}Starting build process..."

# Remove existing build artifacts
rm -rf dist/bundle.js dist/typings/
if [[ $? -eq 0 ]]; then
echo -e "${INFO}Deleted old build artifacts."
else
echo -e "${WARNING}Could not delete old dist files, continuing..."
fi

# Run Rollup to build the project
npx rollup -c rollup.config.js
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Rollup build failed."
exit 1
fi
fi

# Copy build outputs to the Python package directory
cp dist/bundle.js src/general/styles.css lightweight_charts_esistjosh/js
if [[ $? -eq 0 ]]; then
echo -e "${INFO}Copied bundle.js and styles.css into Python package."
else
echo -e "${ERROR}Failed to copy build outputs into Python package."
exit 1
fi

echo -e "${GREEN}[BUILD SUCCESS]${NC}"
}

# Function to perform packaging and installation
perform_package() {
echo -e "${INFO}Starting packaging and installation..."

# Define the path to the virtual environment's Python interpreter
VENV_PYTHON="/home/linux/lightweight-charts-python/venv/bin/python"

# Build source distribution and wheel
sudo "$VENV_PYTHON" -m build --sdist
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to build source distribution."
exit 1
fi

sudo "$VENV_PYTHON" -m build --wheel
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to build wheel distribution."
exit 1
fi

# Install the package
sudo "$VENV_PYTHON" -m pip install .
if [[ $? -ne 0 ]]; then
echo -e "${ERROR}Failed to install the package."
exit 1
fi

echo -e "${GREEN}[PACKAGE & INSTALL SUCCESS]${NC}"
}

cp dist/bundle.js src/general/styles.css lightweight_charts_esistjosh/js
if [[ $? -eq 0 ]]; then
echo -e "${INFO}copied bundle.js, style.css into python package"
else
echo -e "${ERROR}could not copy dist into python package ?"
perform_upload() {
echo -e "${INFO}Starting upload process..."

# Define output directory
OUTPUT_DIR="./output"

# Remove existing output directory if it exists
if [ -d "$OUTPUT_DIR" ]; then
echo -e "${INFO}Removing existing output directory..."
sudo rm -rf "$OUTPUT_DIR"
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to remove existing output directory."
exit 1
fi
fi

# Create output directory
mkdir -p "$OUTPUT_DIR"
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to create output directory."
exit 1
fi

# Enable nullglob to handle cases where no files match the pattern
shopt -s nullglob
files=(./dist/*.tar.gz ./dist/*.whl)
shopt -u nullglob

if [ ${#files[@]} -eq 0 ]; then
echo -e "${WARNING}No distribution files found in ./dist/. Skipping upload."
return
fi

# Move distribution files to output directory
mv "${files[@]}" "$OUTPUT_DIR"/
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to move distribution files to output directory."
exit 1
fi

# Upload distributions using twine
"$VENV_PYTHON" -m twine upload "$OUTPUT_DIR"/*
if [[ $? -ne 0 ]]; then

Check notice

Code scanning / Shellcheck (reported by Codacy)

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Note

Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
echo -e "${ERROR}Failed to upload distributions to PyPI."
exit 1
fi

echo -e "${GREEN}[UPLOAD SUCCESS]${NC}"
}



# Execute build if the BUILD flag is set
if [ "$BUILD" = true ]; then
perform_build
fi

# Execute packaging if the PACKAGE flag is set
if [ "$PACKAGE" = true ]; then
perform_package
fi
echo -e "\n${GREEN}[BUILD SUCCESS]${NC}"

# Execute upload if the UPLOAD flag is set
if [ "$UPLOAD" = true ]; then
perform_upload
fi
29 changes: 29 additions & 0 deletions lightweight_charts_esistjosh/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,35 @@
self._last_bar = series
self.run_script(f'{self.id}.series.update({js_data(series)})')

def update_from_tick(self, series: pd.Series, cumulative_volume: bool = False):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing method docstring Warning

Missing method docstring
Comment thread Dismissed
series = self._series_datetime_format(series)
price = series['price']
time = series['time']

if self._last_bar is None or time > self._last_bar['time']:
# Start new candle from tick
bar = pd.Series({

Check warning

Code scanning / Prospector (reported by Codacy)

Black listed name "bar" (blacklisted-name) Warning

Black listed name "bar" (blacklisted-name)

Check warning

Code scanning / Pylint (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"
Comment thread Dismissed
'time': time,
'open': price,
'high': price,
'low': price,
'close': price,
'volume': series.get('volume', 0)
})
else:
# Update current candle with new tick
bar = self._last_bar.copy()

Check warning

Code scanning / Prospector (reported by Codacy)

Black listed name "bar" (blacklisted-name) Warning

Black listed name "bar" (blacklisted-name)

Check warning

Code scanning / Pylint (reported by Codacy)

Black listed name "bar" Warning

Black listed name "bar"
Comment thread Dismissed
bar['high'] = max(bar['high'], price)
bar['low'] = min(bar['low'], price)
bar['close'] = price
if 'volume' in series:
if cumulative_volume:
bar['volume'] += series['volume']
else:
bar['volume'] = series['volume']

self._last_bar = bar
self.update(bar, _from_tick=True)

Check warning

Code scanning / Prospector (reported by Codacy)

Unexpected keyword argument '_from_tick' in method call (unexpected-keyword-arg) Warning

Unexpected keyword argument '_from_tick' in method call (unexpected-keyword-arg)
Comment thread Dismissed

class Candlestick(SeriesCommon):
def __init__(self, chart: 'AbstractChart'):
Expand Down
2 changes: 1 addition & 1 deletion lightweight_charts_esistjosh/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
async def show_async(self):
self.show(block=False)
try:
from lightweight_charts import polygon
from lightweight_charts_esistjosh import polygon

Check warning

Code scanning / Prospector (reported by Codacy)

Import outside toplevel (lightweight_charts_esistjosh.polygon) (import-outside-toplevel) Warning

Import outside toplevel (lightweight_charts_esistjosh.polygon) (import-outside-toplevel)

Check warning

Code scanning / Pylint (reported by Codacy)

No name 'polygon' in module 'lightweight_charts_esistjosh' Warning

No name 'polygon' in module 'lightweight_charts_esistjosh'
Comment thread Dismissed
[asyncio.create_task(self.polygon.async_set(*args)) for args in polygon._set_on_load]
while 1:
while Chart.WV.emit_queue.empty() and self.is_alive:
Expand Down
4 changes: 2 additions & 2 deletions lightweight_charts_esistjosh/js/bundle.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions lightweight_charts_esistjosh/topbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
def __init__(self, topbar, initial_text, align, func):
super().__init__(topbar, value=initial_text, func=func)

callback_name = f'"{self.id}"' if func else ''
callback_name = f'"{self.id}"' if func else 'undefined'

self.run_script(f'{self.id} = {topbar.id}.makeTextBoxWidget("{initial_text}", "{align}", {callback_name})')
self.run_script(f'{self.id} = {topbar.id}.makeTextBoxWidget("{initial_text}", "{align}", "{callback_name}")')

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (117/100) Warning

Line too long (117/100)

def set(self, string):
self.value = string
Expand Down Expand Up @@ -114,7 +114,7 @@
if self._created:
return
self._created = True
#self.run_script(f'{self.id} = {self._chart.id}.createTopBar()')
self.run_script(f'{self.id} = {self._chart.id}.createTopBar()')

def __getitem__(self, item):
if widget := self._widgets.get(item):
Expand Down
2 changes: 1 addition & 1 deletion lightweight_charts_esistjosh/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class Pane:
def __init__(self, window):
from lightweight_charts import Window
from lightweight_charts_esistjosh import Window

Check warning

Code scanning / Prospector (reported by Codacy)

Import outside toplevel (lightweight_charts_esistjosh.Window) (import-outside-toplevel) Warning

Import outside toplevel (lightweight_charts_esistjosh.Window) (import-outside-toplevel)
Comment thread Dismissed
self.win: Window = window
self.run_script = window.run_script
self.bulk_run = window.bulk_run
Expand Down
26 changes: 13 additions & 13 deletions lightweight_charts_esistjosh/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import html

from .util import parse_event_message
from lightweight_charts import abstract
from .abstract import AbstractChart, Window, INDEX

try:
import wx.html2
Expand Down Expand Up @@ -58,32 +58,32 @@
asyncio.create_task(func(*args)) if asyncio.iscoroutinefunction(func) else func(*args)


class WxChart(abstract.AbstractChart):
class WxChart(AbstractChart):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing class docstring Warning

Missing class docstring

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing class docstring Warning

Missing class docstring
def __init__(self, parent, inner_width: float = 1.0, inner_height: float = 1.0,
scale_candles_only: bool = False, toolbox: bool = False):
if wx is None:
raise ModuleNotFoundError('wx.html2 was not found, and must be installed to use WxChart.')
self.webview: wx.html2.WebView = wx.html2.WebView.New(parent)
super().__init__(abstract.Window(self.webview.RunScript, 'window.wx_msg.postMessage.bind(window.wx_msg)'),
super().__init__(Window(self.webview.RunScript, 'window.wx_msg.postMessage.bind(window.wx_msg)'),

Check warning

Code scanning / Pylint (reported by Codacy)

Line too long (105/100) Warning

Line too long (105/100)

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Line too long (105/100) Warning

Line too long (105/100)
inner_width, inner_height, scale_candles_only, toolbox)

self.webview.Bind(wx.html2.EVT_WEBVIEW_LOADED, lambda e: wx.CallLater(500, self.win.on_js_load))
self.webview.Bind(wx.html2.EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, lambda e: emit_callback(self.win, e.GetString()))
self.webview.AddScriptMessageHandler('wx_msg')

self.webview.LoadURL("file://"+abstract.INDEX)
self.webview.LoadURL("file://"+INDEX)

def get_webview(self):
return self.webview


class QtChart(abstract.AbstractChart):
class QtChart(AbstractChart):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing class docstring Warning

Missing class docstring

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing class docstring Warning

Missing class docstring
def __init__(self, widget=None, inner_width: float = 1.0, inner_height: float = 1.0,
scale_candles_only: bool = False, toolbox: bool = False):
if QWebEngineView is None:
raise ModuleNotFoundError('QWebEngineView was not found, and must be installed to use QtChart.')
self.webview = QWebEngineView(widget)
super().__init__(abstract.Window(self.webview.page().runJavaScript, 'window.pythonObject.callback'),
super().__init__(Window(self.webview.page().runJavaScript, 'window.pythonObject.callback'),
inner_width, inner_height, scale_candles_only, toolbox)

self.web_channel = QWebChannel()
Expand All @@ -107,31 +107,31 @@
self.webview.loadFinished.connect(lambda: QTimer.singleShot(200, self.win.on_js_load))
if using_pyside6:
self.webview.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
self.webview.load(QUrl.fromLocalFile(abstract.INDEX))
self.webview.load(QUrl.fromLocalFile(INDEX))


def get_webview(self): return self.webview


class StaticLWC(abstract.AbstractChart):
class StaticLWC(AbstractChart):

Check warning

Code scanning / Pylint (reported by Codacy)

Missing class docstring Warning

Missing class docstring

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Missing class docstring Warning

Missing class docstring
def __init__(self, width=None, height=None, inner_width=1, inner_height=1,
scale_candles_only: bool = False, toolbox=False, autosize=True):

with open(abstract.INDEX.replace("index.html", 'styles.css'), 'r') as f:
with open(INDEX.replace("index.html", 'styles.css'), 'r') as f:

Check warning

Code scanning / Pylint (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style
css = f.read()
with open(abstract.INDEX.replace("index.html", 'bundle.js'), 'r') as f:
with open(INDEX.replace("index.html", 'bundle.js'), 'r') as f:

Check warning

Code scanning / Pylint (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style
Comment thread Dismissed
js = f.read()
with open(abstract.INDEX.replace("index.html", 'lightweight-charts.js'), 'r') as f:
with open(INDEX.replace("index.html", 'lightweight-charts.js'), 'r') as f:

Check warning

Code scanning / Pylint (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style

Check warning

Code scanning / Pylintpython3 (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style
lwc = f.read()

with open(abstract.INDEX, 'r') as f:
with open(INDEX, 'r') as f:

Check warning

Code scanning / Pylint (reported by Codacy)

Variable name "f" doesn't conform to snake_case naming style Warning

Variable name "f" doesn't conform to snake_case naming style
Comment thread Dismissed
self._html = f.read() \
.replace('<link rel="stylesheet" href="styles.css">', f"<style>{css}</style>") \
.replace(' src="./lightweight-charts.js">', f'>{lwc}') \
.replace(' src="./bundle.js">', f'>{js}') \
.replace('</body>\n</html>', '<script>')

super().__init__(abstract.Window(run_script=self.run_script), inner_width, inner_height,
super().__init__(Window(run_script=self.run_script), inner_width, inner_height,
scale_candles_only, toolbox, autosize)
self.width = width
self.height = height
Expand Down
Loading