Skip to content

Commit

Permalink
Merge branch 'Bouni:main' into speedup-fix--add-index-table
Browse files Browse the repository at this point in the history
  • Loading branch information
gyohng authored Jul 3, 2024
2 parents b5b4299 + 50baeeb commit 16dfd26
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 40 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ This plugin makes use of a lot of icons from the excellent [Material Design Icon
## Development

1. Fork repo
2. Fit clone forked repo
2. Git clone forked repo
3. Install pre-commit `pip install pre-commit`
4. Setup pre-commit `pre-commit run`
5. Create feature branch `git switch -c my-awesome-feature`
Expand Down
1 change: 1 addition & 0 deletions events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
AssignPartsEvent, EVT_ASSIGN_PARTS_EVENT = NewEvent()
PopulateFootprintListEvent, EVT_POPULATE_FOOTPRINT_LIST_EVENT = NewEvent()
UpdateSetting, EVT_UPDATE_SETTING = NewEvent()
LogboxAppendEvent, EVT_LOGBOX_APPEND_EVENT = NewEvent()
17 changes: 10 additions & 7 deletions fabrication.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
except ImportError:
NO_DRILL_SHAPE = PCB_PLOT_PARAMS.NO_DRILL_SHAPE

from .helpers import get_exclude_from_pos


class Fabrication:
Expand Down Expand Up @@ -241,7 +240,7 @@ def zip_gerber_excellon(self):
continue
filePath = os.path.join(folderName, filename)
zipfile.write(filePath, os.path.basename(filePath))
self.logger.info("Finished generating ZIP file")
self.logger.info("Finished generating ZIP file %s", os.path.join(self.outputdir, zipname))

def generate_cpl(self):
"""Generate placement file (CPL)."""
Expand All @@ -258,9 +257,12 @@ def generate_cpl(self):
writer.writerow(
["Designator", "Val", "Package", "Mid X", "Mid Y", "Rotation", "Layer"]
)
for part in self.parent.store.read_pos_parts():
fp = self.board.FindFootprintByReference(part[0])
if get_exclude_from_pos(fp):
footprints = sorted(self.board.Footprints(), key = lambda x: x.GetReference())
for fp in footprints:
part = self.parent.store.get_part(fp.GetReference())
if not part: # No matching part in the database, continue
continue
if part[6] == 1: # Exclude from POS
continue
if not add_without_lcsc and not part[3]:
continue
Expand All @@ -276,7 +278,8 @@ def generate_cpl(self):
"top" if fp.GetLayer() == 0 else "bottom",
]
)
self.logger.info("Finished generating CPL file")
self.logger.info("Finished generating CPL file %s", os.path.join(self.outputdir, cplname))


def generate_bom(self):
"""Generate BOM file."""
Expand All @@ -293,4 +296,4 @@ def generate_bom(self):
if not add_without_lcsc and not part[3]:
continue
writer.writerow(part)
self.logger.info("Finished generating BOM file")
self.logger.info("Finished generating BOM file %s", os.path.join(self.outputdir, bomname))
39 changes: 31 additions & 8 deletions library.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,36 @@ def search(self, parameters):
query = f"SELECT {s} FROM parts WHERE "

match_chunks = []
like_chunks = []

query_chunks = []

# Build 'match_chunks' and 'like_chunks' arrays
#
# FTS5 (https://www.sqlite.org/fts5.html) has a substring limit of
# at least 3 characters.
# 'Substrings consisting of fewer than 3 unicode characters do not
# match any rows when used with a full-text query'
#
# However, they will still match with a LIKE.
#
# So extract out the <3 character strings and add a 'LIKE' term
# for each of those.
if parameters["keyword"] != "":
keywords = parameters["keyword"].split(" ")
keywords_intermediate = []
match_keywords_intermediate = []
for w in keywords:
# skip over empty keywords
if w != "":
kw = f'"{w}"'
keywords_intermediate.append(kw)
keywords_entry = " AND ".join(keywords_intermediate)
match_chunks.append(f"{keywords_entry}")
if len(w) < 3: # LIKE entry
kw = f"description LIKE '%{w}%'"
like_chunks.append(kw)
else: # MATCH entry
kw = f'"{w}"'
match_keywords_intermediate.append(kw)
if match_keywords_intermediate:
match_entry = " AND ".join(match_keywords_intermediate)
match_chunks.append(f"{match_entry}")

if "manufacturer" in parameters and parameters["manufacturer"] != "":
p = parameters["manufacturer"]
Expand Down Expand Up @@ -171,17 +189,22 @@ def search(self, parameters):
if parameters["stock"]:
query_chunks.append('"Stock" > "0"')

if not match_chunks and not query_chunks:
if not match_chunks and not like_chunks and not query_chunks:
return []

if match_chunks:
query += "parts MATCH '"
query += " AND ".join(match_chunks)
query += "'"

if query_chunks:
if like_chunks:
if match_chunks:
query += " AND "
query += " AND ".join(like_chunks)

if query_chunks:
if match_chunks or like_chunks:
query += " AND "
query += " AND ".join(query_chunks)

query += f' ORDER BY "{self.order_by}" COLLATE naturalsort {self.order_dir}'
Expand Down Expand Up @@ -426,7 +449,7 @@ def download(self):
"Parts db is split into %s parts. Proceeding to download...", r.text
)
cnt = int(r.text)
self.logger.debug("Removing any spurios old zip part files...")
self.logger.debug("Removing any spurious old zip part files...")
for p in glob(str(Path(self.datadir) / (chunk_file_stub + "*"))):
self.logger.debug("Removing %s.", p)
os.unlink(p)
Expand Down
49 changes: 29 additions & 20 deletions mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
from .const import Column
from .events import (
EVT_ASSIGN_PARTS_EVENT,
EVT_LOGBOX_APPEND_EVENT,
EVT_MESSAGE_EVENT,
EVT_POPULATE_FOOTPRINT_LIST_EVENT,
EVT_RESET_GAUGE_EVENT,
EVT_UPDATE_GAUGE_EVENT,
EVT_UPDATE_SETTING,
LogboxAppendEvent,
)
from .fabrication import Fabrication
from .helpers import (
Expand Down Expand Up @@ -65,13 +67,15 @@
ID_CONTEXT_MENU_ADD_ROT_BY_PACKAGE = wx.NewIdRef()
ID_CONTEXT_MENU_ADD_ROT_BY_NAME = wx.NewIdRef()


class KicadProvider:
"""KiCad implementation of the provider, see standalone_impl.py for the stub version."""

def get_pcbnew(self):
"""Get the pcbnew instance."""
return kicad_pcbnew


class JLCPCBTools(wx.Dialog):
"""JLCPCBTools main dialog."""

Expand Down Expand Up @@ -218,7 +222,7 @@ def __init__(self, parent, kicad_provider=KicadProvider()):
self,
wx.ID_ANY,
wx.DefaultPosition,
wx.Size(128, -1),
wx.Size(int(self.scale_factor * 128), -1),
wx.TB_VERTICAL | wx.TB_TEXT | wx.TB_NODIVIDER,
)

Expand Down Expand Up @@ -501,6 +505,7 @@ def __init__(self, parent, kicad_provider=KicadProvider()):
self.Bind(EVT_ASSIGN_PARTS_EVENT, self.assign_parts)
self.Bind(EVT_POPULATE_FOOTPRINT_LIST_EVENT, self.populate_footprint_list)
self.Bind(EVT_UPDATE_SETTING, self.update_settings)
self.Bind(EVT_LOGBOX_APPEND_EVENT, self.logbox_append)

self.enable_part_specific_toolbar_buttons(False)

Expand All @@ -515,6 +520,10 @@ def __init__(self, parent, kicad_provider=KicadProvider()):

def quit_dialog(self, *_):
"""Destroy dialog on close."""
root = logging.getLogger()
root.removeHandler(self.logging_handler1)
root.removeHandler(self.logging_handler2)

self.Destroy()
self.EndModal(0)

Expand Down Expand Up @@ -616,13 +625,13 @@ def populate_footprint_list(self, *_):
# First check if the part name mathes
for regex, correction in corrections:
if re.search(regex, str(part[1])):
part[8] = correction
part[8] = str(correction)
break
# If there was no match for the part name, check if the package matches
if part[8] == "":
for regex, correction in corrections:
if re.search(regex, str(part[2])):
part[8] = correction
part[8] = str(correction)
break

self.footprint_list.AppendItem(part)
Expand Down Expand Up @@ -897,6 +906,10 @@ def update_settings(self, e):
self.settings[e.section][e.setting] = e.value
self.save_settings()

def logbox_append(self, e):
"""Write text to the logbox."""
self.logbox.WriteText(e.msg)

def load_settings(self):
"""Load settings from settings.json."""
with open(os.path.join(PLUGIN_PATH, "settings.json"), encoding="utf-8") as j:
Expand Down Expand Up @@ -1089,19 +1102,19 @@ def init_logger(self):
root = logging.getLogger()
root.setLevel(logging.DEBUG)
# Log to stderr
handler1 = logging.StreamHandler(sys.stderr)
handler1.setLevel(logging.DEBUG)
self.logging_handler1 = logging.StreamHandler(sys.stderr)
self.logging_handler1.setLevel(logging.DEBUG)
# and to our GUI
handler2 = LogBoxHandler(self.logbox)
handler2.setLevel(logging.DEBUG)
self.logging_handler2 = LogBoxHandler(self)
self.logging_handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter(
"%(asctime)s - %(levelname)s - %(funcName)s - %(message)s",
datefmt="%Y.%m.%d %H:%M:%S",
)
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
root.addHandler(handler1)
root.addHandler(handler2)
self.logging_handler1.setFormatter(formatter)
self.logging_handler2.setFormatter(formatter)
root.addHandler(self.logging_handler1)
root.addHandler(self.logging_handler2)
self.logger = logging.getLogger(__name__)

def __del__(self):
Expand All @@ -1112,15 +1125,11 @@ def __del__(self):
class LogBoxHandler(logging.StreamHandler):
"""Logging class for the logging textbox at th ebottom of the mainwindow."""

def __init__(self, textctrl):
def __init__(self, event_destination):
logging.StreamHandler.__init__(self)
self.textctrl = textctrl
self.event_destination = event_destination

def emit(self, record):
"""Pokemon exception that hopefully helps getting this working with threads."""
try:
msg = self.format(record)
self.textctrl.WriteText(msg + "\n")
self.flush()
except: # pylint: disable=bare-except
pass
"""Marshal the event over to the main thread."""
msg = self.format(record)
wx.QueueEvent(self.event_destination, LogboxAppendEvent(msg=f"{msg}\n"))
7 changes: 3 additions & 4 deletions unzip_parts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ def unzip_parts(path):
# Open the split file
with open(split_path, "rb") as split_file:
# Read the file data
file_data = split_file.read()

# Append the file data to the original file
db.write(file_data)
while (file_data := split_file.read(1024 * 1024)):
# Append the file data to the original file
db.write(file_data)

# Delete the split file
os.unlink(split_path)
Expand Down

0 comments on commit 16dfd26

Please sign in to comment.