Compare commits

..

No commits in common. "master" and "v3.0" have entirely different histories.
master ... v3.0

13 changed files with 2731 additions and 269 deletions

2
.gitignore vendored
View File

@ -1,5 +1,4 @@
.idea/ .idea/
.DS_Store
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
@ -84,7 +83,6 @@ celerybeat-schedule
# virtualenv # virtualenv
venv/ venv/
ENV/ ENV/
.venv
# Spyder project settings # Spyder project settings
.spyderproject .spyderproject

View File

@ -2,7 +2,6 @@
# coding=utf-8 # coding=utf-8
import sys import sys
import datetime
import os import os
import wx import wx
import wx.html import wx.html
@ -37,7 +36,7 @@ class AboutDlg(wx.Dialog):
</a> </a>
</p> </p>
<p>&copy; {2} Marcel St&ouml;r. Licensed under MIT.</p> <p>&copy; 2018 Marcel St&ouml;r. Licensed under MIT.</p>
<p> <p>
<wxp module="wx" class="Button"> <wxp module="wx" class="Button">
@ -55,7 +54,7 @@ class AboutDlg(wx.Dialog):
html = HtmlWindow(self, wx.ID_ANY, size=(420, -1)) html = HtmlWindow(self, wx.ID_ANY, size=(420, -1))
if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo: if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo:
html.SetStandardFonts() html.SetStandardFonts()
txt = self.text.format(self._get_bundle_dir(), __version__, datetime.datetime.now().year) txt = self.text.format(self._get_bundle_dir(), __version__)
html.SetPage(txt) html.SetPage(txt)
ir = html.GetInternalRepresentation() ir = html.GetInternalRepresentation()
html.SetSize((ir.GetWidth() + 25, ir.GetHeight() + 25)) html.SetSize((ir.GetWidth() + 25, ir.GetHeight() + 25))
@ -66,7 +65,6 @@ class AboutDlg(wx.Dialog):
def _get_bundle_dir(): def _get_bundle_dir():
# set by PyInstaller, see http://pyinstaller.readthedocs.io/en/v3.2/runtime-information.html # set by PyInstaller, see http://pyinstaller.readthedocs.io/en/v3.2/runtime-information.html
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False):
# noinspection PyUnresolvedReferences,PyProtectedMember
return sys._MEIPASS return sys._MEIPASS
else: else:
return os.path.dirname(os.path.abspath(__file__)) return os.path.dirname(os.path.abspath(__file__))

111
Main.py
View File

@ -13,12 +13,11 @@ import json
import images as images import images as images
from serial import SerialException from serial import SerialException
from serial.tools import list_ports from serial.tools import list_ports
import locale from esptool import ESPLoader
from esptool import NotImplementedInROMError
from argparse import Namespace
# see https://discuss.wxpython.org/t/wxpython4-1-1-python3-8-locale-wxassertionerror/35168 __version__ = "3.0"
locale.setlocale(locale.LC_ALL, 'C')
__version__ = "5.1.0"
__flash_help__ = ''' __flash_help__ = '''
<p>This setting is highly dependent on your device!<p> <p>This setting is highly dependent on your device!<p>
<p> <p>
@ -33,8 +32,6 @@ __flash_help__ = '''
</ul> </ul>
</p> </p>
''' '''
__auto_select__ = "Auto-select"
__auto_select_explanation__ = "(first port with Espressif device)"
__supported_baud_rates__ = [9600, 57600, 74880, 115200, 230400, 460800, 921600] __supported_baud_rates__ = [9600, 57600, 74880, 115200, 230400, 460800, 921600]
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -61,11 +58,6 @@ class RedirectText:
# noinspection PyStatementEffect # noinspection PyStatementEffect
None None
# esptool >=3 handles output differently of the output stream is not a TTY
# noinspection PyMethodMayBeStatic
def isatty(self):
return True
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -79,36 +71,43 @@ class FlashingThread(threading.Thread):
def run(self): def run(self):
try: try:
command = [] initial_baud = min(ESPLoader.ESP_ROM_BAUD, self._config.baud)
if not self._config.port.startswith(__auto_select__): esp = ESPLoader.detect_chip(self._config.port, initial_baud)
command.append("--port") print("Chip is %s" % (esp.get_chip_description()))
command.append(self._config.port)
command.extend(["--baud", str(self._config.baud), esp = esp.run_stub()
"--after", "no_reset",
"write_flash", if self._config.baud > initial_baud:
# https://github.com/espressif/esptool/issues/599 try:
"--flash_size", "detect", esp.change_baud(self._config.baud)
"--flash_mode", self._config.mode, except NotImplementedInROMError:
"0x00000", self._config.firmware_path]) print("WARNING: ROM doesn't support changing baud rate. Keeping initial baud rate %d." %
initial_baud)
args = Namespace()
args.flash_size = "detect"
args.flash_mode = self._config.mode
args.flash_freq = "40m"
args.no_progress = False
args.no_stub = False
args.verify = False # TRUE is deprecated
args.compress = True
args.addr_filename = [[int("0x00000", 0), open(self._config.firmware_path, 'rb')]]
print("Configuring flash size...")
esptool.detect_flash_size(esp, args)
esp.flash_set_parameters(esptool.flash_size_bytes(args.flash_size))
if self._config.erase_before_flash: if self._config.erase_before_flash:
command.append("--erase-all") esptool.erase_flash(esp, args)
esptool.write_flash(esp, args)
print("Command: esptool.py %s\n" % " ".join(command)) # The last line printed by esptool is "Leaving..." -> some indication that the process is done is needed
print("\nDone.")
esptool.main(command)
# The last line printed by esptool is "Staying in bootloader." -> some indication that the process is
# done is needed
print("\nFirmware successfully flashed. Unplug/replug or reset device \nto switch back to normal boot "
"mode.")
except SerialException as e: except SerialException as e:
self._parent.report_error(e.strerror) self._parent.report_error(e.strerror)
raise e raise e
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -154,7 +153,7 @@ class FlashConfig:
class NodeMcuFlasher(wx.Frame): class NodeMcuFlasher(wx.Frame):
def __init__(self, parent, title): def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, size=(725, 650), wx.Frame.__init__(self, parent, -1, title, size=(700, 650),
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE) style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self._config = FlashConfig.load(self._get_config_file_path()) self._config = FlashConfig.load(self._get_config_file_path())
@ -165,11 +164,9 @@ class NodeMcuFlasher(wx.Frame):
sys.stdout = RedirectText(self.console_ctrl) sys.stdout = RedirectText(self.console_ctrl)
self.SetMinSize((640, 480))
self.Centre(wx.BOTH) self.Centre(wx.BOTH)
self.Show(True) self.Show(True)
print("Connect your device")
print("\nIf you chose the serial port auto-select feature you might need to ")
print("turn off Bluetooth")
def _init_ui(self): def _init_ui(self):
def on_reload(event): def on_reload(event):
@ -207,15 +204,6 @@ class NodeMcuFlasher(wx.Frame):
panel = wx.Panel(self) panel = wx.Panel(self)
# Fix popup that never goes away.
def onHover(event):
global hovered
if(len(hovered) != 0 ):
hovered[0].Dismiss()
hovered = []
panel.Bind(wx.EVT_MOTION,onHover)
hbox = wx.BoxSizer(wx.HORIZONTAL) hbox = wx.BoxSizer(wx.HORIZONTAL)
fgs = wx.FlexGridSizer(7, 2, 10, 10) fgs = wx.FlexGridSizer(7, 2, 10, 10)
@ -223,8 +211,9 @@ class NodeMcuFlasher(wx.Frame):
self.choice = wx.Choice(panel, choices=self._get_serial_ports()) self.choice = wx.Choice(panel, choices=self._get_serial_ports())
self.choice.Bind(wx.EVT_CHOICE, on_select_port) self.choice.Bind(wx.EVT_CHOICE, on_select_port)
self._select_configured_port() self._select_configured_port()
bmp = images.Reload.GetBitmap()
reload_button = wx.Button(panel, label="Reload") reload_button = wx.BitmapButton(panel, id=wx.ID_ANY, bitmap=bmp,
size=(bmp.GetWidth() + 7, bmp.GetHeight() + 7))
reload_button.Bind(wx.EVT_BUTTON, on_reload) reload_button.Bind(wx.EVT_BUTTON, on_reload)
reload_button.SetToolTip("Reload serial device list") reload_button.SetToolTip("Reload serial device list")
@ -233,7 +222,8 @@ class NodeMcuFlasher(wx.Frame):
serial_boxsizer = wx.BoxSizer(wx.HORIZONTAL) serial_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
serial_boxsizer.Add(self.choice, 1, wx.EXPAND) serial_boxsizer.Add(self.choice, 1, wx.EXPAND)
serial_boxsizer.Add(reload_button, flag=wx.LEFT, border=10) serial_boxsizer.AddStretchSpacer(0)
serial_boxsizer.Add(reload_button, 0, wx.ALIGN_RIGHT, 20)
baud_boxsizer = wx.BoxSizer(wx.HORIZONTAL) baud_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
@ -284,11 +274,10 @@ class NodeMcuFlasher(wx.Frame):
button.Bind(wx.EVT_BUTTON, on_clicked) button.Bind(wx.EVT_BUTTON, on_clicked)
self.console_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL) self.console_ctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL)
self.console_ctrl.SetFont(wx.Font((0, 13), wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, self.console_ctrl.SetFont(wx.Font(13, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
wx.FONTWEIGHT_NORMAL)) self.console_ctrl.SetBackgroundColour(wx.BLACK)
self.console_ctrl.SetBackgroundColour(wx.WHITE) self.console_ctrl.SetForegroundColour(wx.RED)
self.console_ctrl.SetForegroundColour(wx.BLUE) self.console_ctrl.SetDefaultStyle(wx.TextAttr(wx.RED))
self.console_ctrl.SetDefaultStyle(wx.TextAttr(wx.BLUE))
port_label = wx.StaticText(panel, label="Serial port") port_label = wx.StaticText(panel, label="Serial port")
file_label = wx.StaticText(panel, label="NodeMCU firmware") file_label = wx.StaticText(panel, label="NodeMCU firmware")
@ -296,8 +285,6 @@ class NodeMcuFlasher(wx.Frame):
flashmode_label = wx.StaticText(panel, label="Flash mode") flashmode_label = wx.StaticText(panel, label="Flash mode")
def on_info_hover(event): def on_info_hover(event):
global hovered
if(len(hovered) == 0):
from HtmlPopupTransientWindow import HtmlPopupTransientWindow from HtmlPopupTransientWindow import HtmlPopupTransientWindow
win = HtmlPopupTransientWindow(self, wx.SIMPLE_BORDER, __flash_help__, "#FFB6C1", (410, 140)) win = HtmlPopupTransientWindow(self, wx.SIMPLE_BORDER, __flash_help__, "#FFB6C1", (410, 140))
@ -307,8 +294,6 @@ class NodeMcuFlasher(wx.Frame):
win.Position(image_position, (0, image_size[1])) win.Position(image_position, (0, image_size[1]))
win.Popup() win.Popup()
hovered = [win]
icon = wx.StaticBitmap(panel, wx.ID_ANY, images.Info.GetBitmap()) icon = wx.StaticBitmap(panel, wx.ID_ANY, images.Info.GetBitmap())
icon.Bind(wx.EVT_MOTION, on_info_hover) icon.Bind(wx.EVT_MOTION, on_info_hover)
@ -316,7 +301,7 @@ class NodeMcuFlasher(wx.Frame):
flashmode_label_boxsizer = wx.BoxSizer(wx.HORIZONTAL) flashmode_label_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
flashmode_label_boxsizer.Add(flashmode_label, 1, wx.EXPAND) flashmode_label_boxsizer.Add(flashmode_label, 1, wx.EXPAND)
flashmode_label_boxsizer.AddStretchSpacer(0) flashmode_label_boxsizer.AddStretchSpacer(0)
flashmode_label_boxsizer.Add(icon) flashmode_label_boxsizer.Add(icon, 0, wx.ALIGN_RIGHT, 20)
erase_label = wx.StaticText(panel, label="Erase flash") erase_label = wx.StaticText(panel, label="Erase flash")
console_label = wx.StaticText(panel, label="Console") console_label = wx.StaticText(panel, label="Console")
@ -344,7 +329,7 @@ class NodeMcuFlasher(wx.Frame):
@staticmethod @staticmethod
def _get_serial_ports(): def _get_serial_ports():
ports = [__auto_select__ + " " + __auto_select_explanation__] ports = [""]
for port, desc, hwid in sorted(list_ports.comports()): for port, desc, hwid in sorted(list_ports.comports()):
ports.append(port) ports.append(port)
return ports return ports
@ -404,8 +389,6 @@ class NodeMcuFlasher(wx.Frame):
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
class MySplashScreen(wx.adv.SplashScreen): class MySplashScreen(wx.adv.SplashScreen):
def __init__(self): def __init__(self):
global hovered
hovered = []
wx.adv.SplashScreen.__init__(self, images.Splash.GetBitmap(), wx.adv.SplashScreen.__init__(self, images.Splash.GetBitmap(),
wx.adv.SPLASH_CENTRE_ON_SCREEN | wx.adv.SPLASH_TIMEOUT, 2500, None, -1) wx.adv.SPLASH_CENTRE_ON_SCREEN | wx.adv.SPLASH_TIMEOUT, 2500, None, -1)
self.Bind(wx.EVT_CLOSE, self._on_close) self.Bind(wx.EVT_CLOSE, self._on_close)
@ -435,8 +418,6 @@ class MySplashScreen(wx.adv.SplashScreen):
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
class App(wx.App, wx.lib.mixins.inspection.InspectionMixin): class App(wx.App, wx.lib.mixins.inspection.InspectionMixin):
def OnInit(self): def OnInit(self):
# see https://discuss.wxpython.org/t/wxpython4-1-1-python3-8-locale-wxassertionerror/35168
self.ResetLocale()
wx.SystemOptions.SetOption("mac.window-plain-transition", 1) wx.SystemOptions.SetOption("mac.window-plain-transition", 1)
self.SetAppName("NodeMCU PyFlasher") self.SetAppName("NodeMCU PyFlasher")

View File

@ -1,19 +1,22 @@
# NodeMCU PyFlasher # NodeMCU PyFlasher
[![License](https://marcelstoer.github.io/nodemcu-pyflasher/images/mit-license-badge.svg)](https://github.com/marcelstoer/nodemcu-pyflasher/blob/master/LICENSE) [![License](https://marcelstoer.github.io/nodemcu-pyflasher/images/mit-license-badge.svg)](https://github.com/marcelstoer/nodemcu-pyflasher/blob/master/LICENSE)
[![Github Downloads (all assets, all releases)](https://img.shields.io/github/downloads/marcelstoer/nodemcu-pyflasher/total.svg?style=flat)](https://github.com/marcelstoer/nodemcu-pyflasher/releases) [![Github Releases](https://img.shields.io/github/downloads/marcelstoer/nodemcu-pyflasher/total.svg?style=flat)](https://github.com/marcelstoer/nodemcu-pyflasher/releases)
[![GitHub Downloads (all assets, latest release)](https://img.shields.io/github/downloads/marcelstoer/nodemcu-pyflasher/latest/total?style=flat)](https://github.com/marcelstoer/nodemcu-pyflasher/releases) [![PayPal Donation](https://marcelstoer.github.io/nodemcu-pyflasher/images/donate-paypal-badge.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HFN4ZMET5XS2Q)
[![PayPal Donation](https://img.shields.io/badge/donate_through-PayPal-%23009cde?logo=paypal)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HFN4ZMET5XS2Q) [![Twitter URL](https://marcelstoer.github.io/nodemcu-pyflasher/images/twitter-badge.svg)](https://twitter.com/intent/tweet?text=Wow:&url=https%3A%2F%2Fgithub.com%2Fmarcelstoer%2Fnodemcu-pyflasher)
[![Facebook URL](https://marcelstoer.github.io/nodemcu-pyflasher/images/facebook-badge.svg)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fgithub.com%2Fmarcelstoer%2Fnodemcu-pyflasher)
Self-contained [NodeMCU](https://github.com/nodemcu/nodemcu-firmware) flasher with GUI based on [esptool.py](https://github.com/espressif/esptool) and [wxPython](https://www.wxpython.org/). Self-contained [NodeMCU](https://github.com/nodemcu/nodemcu-firmware) flasher with GUI based on [esptool.py](https://github.com/espressif/esptool) and [wxPython](https://www.wxpython.org/).
![Image of NodeMCU PyFlasher GUI](images/gui.png) ![Image of NodeMCU PyFlasher GUI](images/gui.png)
## Installation ## Installation
NodeMCU PyFlasher doesn't have to be installed, just double-click it and it'll start. Check the [releases section](https://github.com/marcelstoer/nodemcu-pyflasher/releases) for downloads for your platform. For every release there's at least a .exe file for Windows. Starting from 3.0 there's also a .dmg for macOS. NodeMCU PyFlasher doesn't have to be installed, just double-click it and it'll start. Check the [releases section](https://github.com/marcelstoer/nodemcu-pyflasher/releases) for downloads for your platform. For every release there's at least a .exe file for Windows.
## Status ## Status
Scan the [list of open issues](https://github.com/marcelstoer/nodemcu-pyflasher/issues) for bugs and pending features. Scan the [list of open issues](https://github.com/marcelstoer/nodemcu-pyflasher/issues) for bugs and pending features.
- Due to [pyinstaller/pyinstaller#2355](https://github.com/pyinstaller/pyinstaller/issues/2355) I can't provide an app bundle for macOS yet. The PyInstaller `.spec` file and the build script are ready, though. Of course you can still *run* the application on macOS. Clone this repo and then do `python nodemcu-pyflasher.py` (see "[Build it yourself](#build-it-yourself)" for pre-requisits).
**Note** **Note**
This is my first Python project. If you have constructive feedback as for how to improve the code please do reach out to me. This is my first Python project. If you have constructive feedback as for how to improve the code please do reach out to me.
@ -29,19 +32,9 @@ All open-source development by the author is donationware. Show your love and su
## Build it yourself ## Build it yourself
If you want to build this application yourself you need to: If you want to build this application yourself you need to:
- Install [Python 3.x](https://www.python.org/downloads/) and [Pip](https://pip.pypa.io/en/stable/installing/) (it comes with Python if installed from `python.org`). - Install Python
- Create a virtual environment with `python -m venv venv` - Install [wxPython 3.x](https://sourceforge.net/projects/wxpython/files/wxPython/) (not 4.0 betas!)
- Activate the virtual environment with `. venv/bin/activate` (`. venv/Scripts/activate` if you are on Windows with [Cygwin](https://www.cygwin.com/) or [Mingw](http://mingw.org/)) - Install [esptool.py](https://github.com/espressif/esptool#easy-installation) which brings pySerial or install pySerial standalone
- Run `pip install -r requirements.txt`
**A note on Linux:** As described on the [downloads section of `wxPython`](https://www.wxpython.org/pages/downloads/), wheels for Linux are complicated and may require you to run something like this to install `wxPython` correctly:
```bash
# Assuming you are running it on Ubuntu 18.04 LTS with GTK3
pip install -U \
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 \
wxPython
```
## Why this project exists ## Why this project exists

View File

@ -1,60 +1,30 @@
# -*- mode: python ; coding: utf-8 -*- # -*- mode: python -*-
import os block_cipher = None
# We need to add the flasher stub JSON files explicitly: https://github.com/espressif/esptool/issues/1059 a = Analysis(['nodemcu-pyflasher.py'],
venv_python_folder_name = next(d for d in os.listdir('./.venv/lib') if d.startswith('python') and os.path.isdir(os.path.join('./.venv/lib', d))) binaries=None,
local_stub_flasher_path = "./.venv/lib/{}/site-packages/esptool/targets/stub_flasher".format(venv_python_folder_name) datas=[("images", "images")],
a = Analysis(
['nodemcu-pyflasher.py'],
pathex=[],
binaries=[],
datas=[
("images", "images"),
("{}/1".format(local_stub_flasher_path), "./esptool/targets/stub_flasher/1"),
("{}/2".format(local_stub_flasher_path), "./esptool/targets/stub_flasher/2")
],
hiddenimports=[], hiddenimports=[],
hookspath=[], hookspath=[],
hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
excludes=[], excludes=[],
noarchive=False, win_no_prefer_redirects=False,
optimize=0, win_private_assemblies=False,
) cipher=block_cipher)
pyz = PYZ(a.pure) pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE( exe = EXE(pyz,
pyz,
a.scripts, a.scripts,
[],
exclude_binaries=True,
name='NodeMCU PyFlasher',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries, a.binaries,
a.zipfiles,
a.datas, a.datas,
name='NodeMCU-PyFlasher',
debug=False,
strip=False, strip=False,
upx=True, upx=True,
upx_exclude=[], console=False , icon='images/icon-256.icns')
name='NodeMCU PyFlasher', app = BUNDLE(exe,
icon='images/icon-256.icns' name='NodeMCU-PyFlasher-3.0.app',
) icon='./images/icon-256.icns',
app = BUNDLE(
coll,
name='NodeMCU PyFlasher.app',
version='5.1.0',
icon='images/icon-256.icns',
bundle_identifier='com.frightanic.nodemcu-pyflasher') bundle_identifier='com.frightanic.nodemcu-pyflasher')

View File

@ -1,46 +1,26 @@
# -*- mode: python ; coding: utf-8 -*- # -*- mode: python -*-
# We need to add the flasher stub JSON files explicitly: https://github.com/espressif/esptool/issues/1059 block_cipher = None
local_stub_flasher_path = "./.venv/Lib/site-packages/esptool/targets/stub_flasher"
a = Analysis( a = Analysis(['nodemcu-pyflasher.py'],
['nodemcu-pyflasher.py'],
pathex=[],
binaries=[], binaries=[],
datas=[ datas=[("images", "images")],
("images", "images"),
("{}/1".format(local_stub_flasher_path), "./esptool/targets/stub_flasher/1"),
("{}/2".format(local_stub_flasher_path), "./esptool/targets/stub_flasher/2")
],
hiddenimports=[], hiddenimports=[],
hookspath=[], hookspath=[],
hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
excludes=[], excludes=[],
noarchive=False, win_no_prefer_redirects=False,
optimize=0, win_private_assemblies=False,
) cipher=block_cipher)
pyz = PYZ(a.pure) pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE( exe = EXE(pyz,
pyz,
a.scripts, a.scripts,
a.binaries, a.binaries,
a.zipfiles,
a.datas, a.datas,
[], name='NodeMCU-PyFlasher-3.0',
name='NodeMCU-PyFlasher',
version='windows-version-info.txt',
debug=False, debug=False,
bootloader_ignore_signals=False,
strip=False, strip=False,
upx=True, upx=True,
upx_exclude=[], console=False , icon='images\\icon-256.ico')
runtime_tmpdir=None,
console=False,
icon='images\\icon-256.ico',
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

View File

@ -1,13 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#rm -fr build dist #rm -fr build dist
VERSION=5.1.0
NAME="NodeMCU PyFlasher"
DIST_NAME="NodeMCU-PyFlasher"
pyinstaller --log-level=DEBUG \ pyinstaller --log-level=DEBUG \
--noconfirm \ --noconfirm \
build-on-mac.spec build-on-mac.spec
# https://github.com/sindresorhus/create-dmg
create-dmg "dist/$NAME.app"
mv "$NAME $VERSION.dmg" "dist/$DIST_NAME.dmg"

12
esptool-py-why-here.txt Normal file
View File

@ -0,0 +1,12 @@
If esptool.py is installed using python setup.py` from a checked out version it creates something like the following
in the Python environment
esptool.py file containing
#!/usr/local/opt/python/bin/python2.7
# EASY-INSTALL-SCRIPT: 'esptool==1.3.dev0','esptool.py'
__requires__ = 'esptool==1.3.dev0'
__import__('pkg_resources').run_script('esptool==1.3.dev0', 'esptool.py')
PyInstaller (and cx_Freeze) doesn't support pkg_resources and complains about 'ImportError: "No module named
pkg_resources"'. This can be avoided if the application maintains a local copy of esptool.py.

2599
esptool.py Executable file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 405 KiB

View File

@ -1,6 +0,0 @@
esptool==4.8.1
pyserial~=3.5
wxPython==4.2.2
PyInstaller==6.11.1
httplib2>=0.18.1
pyinstaller-versionfile>=2.0.0

View File

@ -1,9 +0,0 @@
# https://github.com/DudeNr33/pyinstaller-versionfile
# create-version-file windows-metadata.yaml --outfile windows-version-info.txt
Version: 5.1.0
CompanyName: Marcel Stör
FileDescription: NodeMCU PyFlasher
InternalName: NodeMCU PyFlasher
LegalCopyright: © Marcel Stör. All rights reserved.
OriginalFilename: NodeMCU-PyFlasher.exe
ProductName: NodeMCU PyFlasher

View File

@ -1,46 +0,0 @@
# GENERATED FILE. DO NOT EDIT. Created by running create-version-file windows-metadata.yaml --outfile windows-version-info.txt
#
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0. Must always contain 4 elements.
filevers=(5,1,0,0),
prodvers=(5,1,0,0),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x40004,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904B0',
[StringStruct(u'CompanyName', u'Marcel Stör'),
StringStruct(u'FileDescription', u'NodeMCU PyFlasher'),
StringStruct(u'FileVersion', u'5.1.0.0'),
StringStruct(u'InternalName', u'NodeMCU PyFlasher'),
StringStruct(u'LegalCopyright', u'© Marcel Stör. All rights reserved.'),
StringStruct(u'OriginalFilename', u'NodeMCU-PyFlasher.exe'),
StringStruct(u'ProductName', u'NodeMCU PyFlasher'),
StringStruct(u'ProductVersion', u'5.1.0.0')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
]
)