listpick 0.1.14.4__py3-none-any.whl → 0.1.14.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of listpick might be problematic. Click here for more details.
- listpick/listpick_app.py +97 -13
- listpick/ui/input_field.py +47 -6
- listpick/ui/keys.py +4 -4
- listpick/utils/table_to_list_of_lists.py +111 -43
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/METADATA +1 -1
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/RECORD +10 -10
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/WHEEL +0 -0
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/entry_points.txt +0 -0
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/licenses/LICENSE.txt +0 -0
- {listpick-0.1.14.4.dist-info → listpick-0.1.14.5.dist-info}/top_level.txt +0 -0
listpick/listpick_app.py
CHANGED
|
@@ -20,6 +20,8 @@ import json
|
|
|
20
20
|
import threading
|
|
21
21
|
import string
|
|
22
22
|
import logging
|
|
23
|
+
import tty
|
|
24
|
+
import select
|
|
23
25
|
|
|
24
26
|
from listpick.ui.picker_colours import get_colours, get_help_colours, get_notification_colours, get_theme_count, get_fallback_colours
|
|
25
27
|
from listpick.utils.options_selectors import default_option_input, output_file_option_selector, default_option_selector
|
|
@@ -349,6 +351,65 @@ class Picker:
|
|
|
349
351
|
if not attr_name.startswith('__') and not callable(getattr(self, attr_name)):
|
|
350
352
|
size += sys.getsizeof(getattr(self, attr_name))
|
|
351
353
|
return size
|
|
354
|
+
|
|
355
|
+
def set_config(self, path: str ="~/.config/listpick/config.toml"):
|
|
356
|
+
""" Set config from toml file. """
|
|
357
|
+
config = self.get_config(path)
|
|
358
|
+
self.logger.info(f"function: set_config()")
|
|
359
|
+
if "general" in config:
|
|
360
|
+
for key, val in config["general"].items():
|
|
361
|
+
self.logger.info(f"set_config: key={key}, val={val}.")
|
|
362
|
+
try:
|
|
363
|
+
setattr(self, key, val)
|
|
364
|
+
except Exception as e:
|
|
365
|
+
self.logger.error(f"set_config: key={key}, val={val}. {e}")
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def get_config(self, path: str ="~/.config/listpick/config.toml") -> dict:
|
|
369
|
+
""" Get config from file. """
|
|
370
|
+
self.logger.info(f"function: get_config()")
|
|
371
|
+
import toml
|
|
372
|
+
if os.path.exists(os.path.expanduser(path)):
|
|
373
|
+
with open(os.path.expanduser(path), "r") as f:
|
|
374
|
+
config = toml.load(f)
|
|
375
|
+
return config
|
|
376
|
+
# full_config = self.get_default_config()
|
|
377
|
+
# default_path = "~/.config/listpick/config.toml"
|
|
378
|
+
#
|
|
379
|
+
# CONFIGPATH = default_path
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
# if "general" in config:
|
|
384
|
+
# for key in config["general"]:
|
|
385
|
+
# full_config["general"][key] = config["general"][key]
|
|
386
|
+
# if "appearance" in config:
|
|
387
|
+
# for key in config["appearance"]:
|
|
388
|
+
# full_config["appearance"][key] = config["appearance"][key]
|
|
389
|
+
#
|
|
390
|
+
# return full_config
|
|
391
|
+
|
|
392
|
+
def get_default_config(self) -> dict:
|
|
393
|
+
default_config = {
|
|
394
|
+
"general" : {
|
|
395
|
+
"url": "http://localhost",
|
|
396
|
+
"port": "6800",
|
|
397
|
+
"token": "",
|
|
398
|
+
"startupcmds": ["aria2c"],
|
|
399
|
+
"restartcmds": ["pkill aria2c && sleep 1 && aria2c"],
|
|
400
|
+
"ariaconfigpath": "~/.config/aria2/aria2.conf",
|
|
401
|
+
"paginate": False,
|
|
402
|
+
"refresh_timer": 2,
|
|
403
|
+
"global_stats_timer": 1,
|
|
404
|
+
"terminal_file_manager": "yazi",
|
|
405
|
+
"gui_file_manager": "kitty yazi",
|
|
406
|
+
"launch_command": "xdg-open",
|
|
407
|
+
},
|
|
408
|
+
"appearance":{
|
|
409
|
+
"theme": 0
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return default_config
|
|
352
413
|
|
|
353
414
|
def calculate_section_sizes(self):
|
|
354
415
|
"""
|
|
@@ -2179,10 +2240,14 @@ class Picker:
|
|
|
2179
2240
|
function_data = self.get_function_data()
|
|
2180
2241
|
return [], "", function_data
|
|
2181
2242
|
|
|
2182
|
-
#
|
|
2243
|
+
# Open tty to accept input
|
|
2244
|
+
tty_fd = open_tty()
|
|
2183
2245
|
|
|
2246
|
+
# Main loop
|
|
2184
2247
|
while True:
|
|
2185
|
-
key = self.stdscr.getch()
|
|
2248
|
+
# key = self.stdscr.getch()
|
|
2249
|
+
|
|
2250
|
+
key = get_char(tty_fd, timeout=0.2)
|
|
2186
2251
|
if key != -1:
|
|
2187
2252
|
self.logger.info(f"key={key}")
|
|
2188
2253
|
h, w = self.stdscr.getmaxyx()
|
|
@@ -2421,7 +2486,7 @@ class Picker:
|
|
|
2421
2486
|
formula_auto_complete=False,
|
|
2422
2487
|
function_auto_complete=False,
|
|
2423
2488
|
word_auto_complete=True,
|
|
2424
|
-
auto_complete_words=["ft", "ct", "cv"]
|
|
2489
|
+
auto_complete_words=["ft", "ct", "cv"],
|
|
2425
2490
|
)
|
|
2426
2491
|
if return_val:
|
|
2427
2492
|
self.user_settings = usrtxt
|
|
@@ -3505,6 +3570,24 @@ def unrestrict_curses(stdscr: curses.window) -> None:
|
|
|
3505
3570
|
curses.raw() # Disable control keys (ctrl-c, ctrl-s, ctrl-q, etc.)
|
|
3506
3571
|
curses.curs_set(False)
|
|
3507
3572
|
|
|
3573
|
+
|
|
3574
|
+
def open_tty():
|
|
3575
|
+
""" Return a file descriptor for the tty that we are opening"""
|
|
3576
|
+
tty_fd = os.open('/dev/tty', os.O_RDONLY)
|
|
3577
|
+
tty.setraw(tty_fd)
|
|
3578
|
+
return tty_fd
|
|
3579
|
+
|
|
3580
|
+
def get_char(tty_fd, timeout: float = 0.2) -> int:
|
|
3581
|
+
""" Get character from a tty_fd with a timeout. """
|
|
3582
|
+
rlist, _, _ = select.select([tty_fd], [], [], timeout)
|
|
3583
|
+
if rlist:
|
|
3584
|
+
# key = ord(tty_fd.read(1))
|
|
3585
|
+
key = ord(os.read(tty_fd, 1))
|
|
3586
|
+
# os.system(f"notify-send { key }")
|
|
3587
|
+
else:
|
|
3588
|
+
key = -1
|
|
3589
|
+
return key
|
|
3590
|
+
|
|
3508
3591
|
def main() -> None:
|
|
3509
3592
|
""" Main function when listpick is executed. Deals with command line arguments and starts a Picker. """
|
|
3510
3593
|
args, function_data = parse_arguments()
|
|
@@ -3540,16 +3623,16 @@ def main() -> None:
|
|
|
3540
3623
|
"color": 8,
|
|
3541
3624
|
}
|
|
3542
3625
|
]
|
|
3543
|
-
function_data["cell_cursor"] = True
|
|
3544
|
-
function_data["display_modes"] = True
|
|
3545
|
-
function_data["centre_in_cols"] = True
|
|
3546
|
-
function_data["show_row_header"] = True
|
|
3547
|
-
function_data["keys_dict"] = picker_keys
|
|
3548
|
-
function_data["id_column"] = -1
|
|
3549
|
-
function_data["track_entries_upon_refresh"] = True
|
|
3550
|
-
function_data["centre_in_terminal_vertical"] = True
|
|
3551
|
-
function_data["highlight_full_row"] = True
|
|
3552
|
-
function_data["pin_cursor"] = True
|
|
3626
|
+
# function_data["cell_cursor"] = True
|
|
3627
|
+
# function_data["display_modes"] = True
|
|
3628
|
+
# function_data["centre_in_cols"] = True
|
|
3629
|
+
# function_data["show_row_header"] = True
|
|
3630
|
+
# function_data["keys_dict"] = picker_keys
|
|
3631
|
+
# function_data["id_column"] = -1
|
|
3632
|
+
# function_data["track_entries_upon_refresh"] = True
|
|
3633
|
+
# function_data["centre_in_terminal_vertical"] = True
|
|
3634
|
+
# function_data["highlight_full_row"] = True
|
|
3635
|
+
# function_data["pin_cursor"] = True
|
|
3553
3636
|
# function_data["display_infobox"] = True
|
|
3554
3637
|
# function_data["infobox_items"] = [["1"], ["2"], ["3"]]
|
|
3555
3638
|
# function_data["infobox_title"] = "Title"
|
|
@@ -3572,6 +3655,7 @@ def main() -> None:
|
|
|
3572
3655
|
|
|
3573
3656
|
# app = Picker(stdscr, **function_data)
|
|
3574
3657
|
app = Picker(stdscr)
|
|
3658
|
+
app.set_config("~/.config/listpick/config.toml")
|
|
3575
3659
|
app.set_function_data(function_data)
|
|
3576
3660
|
app.splash_screen("Listpick is loading your data...")
|
|
3577
3661
|
app.load_input_history("~/.config/listpick/cmdhist.json")
|
listpick/ui/input_field.py
CHANGED
|
@@ -16,7 +16,26 @@ from datetime import datetime
|
|
|
16
16
|
import logging
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger('picker_log')
|
|
19
|
-
|
|
19
|
+
import select
|
|
20
|
+
import tty
|
|
21
|
+
|
|
22
|
+
def open_tty():
|
|
23
|
+
""" Return a file descriptor for the tty that we are opening"""
|
|
24
|
+
tty_fd = os.open('/dev/tty', os.O_RDONLY)
|
|
25
|
+
tty.setraw(tty_fd)
|
|
26
|
+
return tty_fd
|
|
27
|
+
|
|
28
|
+
def get_char(tty_fd, timeout: float = 0.2) -> int:
|
|
29
|
+
""" Get character from a tty_fd with a timeout. """
|
|
30
|
+
rlist, _, _ = select.select([tty_fd], [], [], timeout)
|
|
31
|
+
if rlist:
|
|
32
|
+
# key = ord(tty_fd.read(1))
|
|
33
|
+
key = ord(os.read(tty_fd, 1))
|
|
34
|
+
# os.system(f"notify-send { key }")
|
|
35
|
+
else:
|
|
36
|
+
key = -1
|
|
37
|
+
return key
|
|
38
|
+
|
|
20
39
|
def input_field(
|
|
21
40
|
stdscr: curses.window,
|
|
22
41
|
usrtxt:str="",
|
|
@@ -106,6 +125,10 @@ def input_field(
|
|
|
106
125
|
offscreen_x, offscreen_y = False, False
|
|
107
126
|
orig_x, orig_y = x, y
|
|
108
127
|
|
|
128
|
+
# tty_fd = open('/dev/tty')
|
|
129
|
+
# tty_fd = os.open('/dev/tty', os.O_RDONLY)
|
|
130
|
+
# tty.setraw(tty_fd)
|
|
131
|
+
tty_fd = open_tty()
|
|
109
132
|
# Input field loop
|
|
110
133
|
while True:
|
|
111
134
|
|
|
@@ -131,7 +154,7 @@ def input_field(
|
|
|
131
154
|
|
|
132
155
|
# Clear background to end of the input field
|
|
133
156
|
stdscr.addstr(field_y, x(), " "*(max_field_length), curses.color_pair(colours_start+colour_pair_bg))
|
|
134
|
-
stdscr.refresh()
|
|
157
|
+
# stdscr.refresh()
|
|
135
158
|
|
|
136
159
|
if literal:
|
|
137
160
|
field_string_length = len(repr(usrtxt)) + len(field_prefix)
|
|
@@ -206,12 +229,30 @@ def input_field(
|
|
|
206
229
|
pass
|
|
207
230
|
|
|
208
231
|
|
|
209
|
-
|
|
232
|
+
stdscr.refresh()
|
|
233
|
+
# timeout = 0.05
|
|
234
|
+
# rlist, _, _ = select.select([tty_fd], [], [], timeout)
|
|
235
|
+
# if rlist:
|
|
236
|
+
# # key = ord(tty_fd.read(1))
|
|
237
|
+
# key = ord(os.read(tty_fd, 1))
|
|
238
|
+
# os.system(f"notify-send { key }")
|
|
239
|
+
# else:
|
|
240
|
+
# key = -1
|
|
241
|
+
key = get_char(tty_fd, timeout=0.5)
|
|
242
|
+
# key = ord(tty.read(1))
|
|
243
|
+
# key = stdscr.getch()
|
|
210
244
|
|
|
211
245
|
if key in [27, 7]: # ESC/ALT key or Ctrl+g
|
|
212
246
|
# For Alt-key combinations: set nodelay and get the second key
|
|
213
|
-
stdscr.nodelay(True)
|
|
214
|
-
key2 = stdscr.getch()
|
|
247
|
+
# stdscr.nodelay(True)
|
|
248
|
+
# key2 = stdscr.getch()
|
|
249
|
+
# rlist, _, _ = select.select([tty_fd], [], [], timeout)
|
|
250
|
+
# if rlist:
|
|
251
|
+
# key2 = ord(os.read(tty_fd, 1))
|
|
252
|
+
# os.system(f"notify-send 'metakey { key }'")
|
|
253
|
+
# else:
|
|
254
|
+
# key2 = -1
|
|
255
|
+
key2 = get_char(tty_fd, timeout=0.05)
|
|
215
256
|
|
|
216
257
|
if key2 == -1: # ESCAPE key (no key-combination)
|
|
217
258
|
stdscr.nodelay(False)
|
|
@@ -311,7 +352,7 @@ def input_field(
|
|
|
311
352
|
curses.endwin()
|
|
312
353
|
exit()
|
|
313
354
|
|
|
314
|
-
elif key
|
|
355
|
+
elif key in [10, 13]: # Enter/return key
|
|
315
356
|
# Return
|
|
316
357
|
return usrtxt, True
|
|
317
358
|
|
listpick/ui/keys.py
CHANGED
|
@@ -32,7 +32,7 @@ picker_keys = {
|
|
|
32
32
|
"select_none": [ord('M'), 18], # Ctrl-r
|
|
33
33
|
"visual_selection_toggle": [ord('v')],
|
|
34
34
|
"visual_deselection_toggle": [ord('V')],
|
|
35
|
-
"enter": [ord('\n'), curses.KEY_ENTER],
|
|
35
|
+
"enter": [ord('\n'), curses.KEY_ENTER, 13],
|
|
36
36
|
"redraw_screen": [12], # Ctrl-l
|
|
37
37
|
"cycle_sort_method": [ord('s')],
|
|
38
38
|
"cycle_sort_method_reverse": [ord('S')],
|
|
@@ -152,7 +152,7 @@ menu_keys = {
|
|
|
152
152
|
"cursor_top": [ord('g'), curses.KEY_HOME],
|
|
153
153
|
"five_up": [ord('K')],
|
|
154
154
|
"five_down": [ord('J')],
|
|
155
|
-
"enter": [ord('\n'), curses.KEY_ENTER, ord('l')],
|
|
155
|
+
"enter": [ord('\n'), curses.KEY_ENTER, ord('l'), 13],
|
|
156
156
|
"redraw_screen": [12], # Ctrl-l
|
|
157
157
|
"filter_input": [ord('f')],
|
|
158
158
|
"search_input": [ord('/')],
|
|
@@ -183,7 +183,7 @@ options_keys = {
|
|
|
183
183
|
"select_none": [ord('M'), 18], # Ctrl-r
|
|
184
184
|
"visual_selection_toggle": [ord('v')],
|
|
185
185
|
"visual_deselection_toggle": [ord('V')],
|
|
186
|
-
"enter": [ord('\n'), curses.KEY_ENTER, ord('l')],
|
|
186
|
+
"enter": [ord('\n'), curses.KEY_ENTER, ord('l'), 13],
|
|
187
187
|
"redraw_screen": [12], # Ctrl-l
|
|
188
188
|
"cycle_sort_method": [ord('s')],
|
|
189
189
|
"cycle_sort_method_reverse": [ord('S')],
|
|
@@ -213,7 +213,7 @@ edit_menu_keys = {
|
|
|
213
213
|
"cursor_top": [ord('g'), curses.KEY_HOME],
|
|
214
214
|
"five_up": [ord('K')],
|
|
215
215
|
"five_down": [ord('J')],
|
|
216
|
-
"enter": [ord('\n'), curses.KEY_ENTER],
|
|
216
|
+
"enter": [ord('\n'), curses.KEY_ENTER, 13],
|
|
217
217
|
"redraw_screen": [12], # Ctrl-l
|
|
218
218
|
"cycle_sort_method": [ord('s')],
|
|
219
219
|
"cycle_sort_method_reverse": [ord('S')],
|
|
@@ -36,6 +36,102 @@ def strip_whitespace(item: Iterable) -> Iterable:
|
|
|
36
36
|
return item
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
def xlsx_to_list(file_name: str, sheet_number:int = 0, extract_formulae: bool = False):
|
|
40
|
+
import pandas as pd
|
|
41
|
+
from openpyxl import load_workbook
|
|
42
|
+
# wb = load_workbook(filename=input_arg, read_only=True)
|
|
43
|
+
# values or formulae
|
|
44
|
+
if not os.path.exists(file_name):
|
|
45
|
+
return [], [], []
|
|
46
|
+
wb = load_workbook(filename=file_name, read_only=True, data_only=not extract_formulae)
|
|
47
|
+
|
|
48
|
+
if not isinstance(sheet_number, int): sheet_number = 0
|
|
49
|
+
sheet_number = max(0, min(sheet_number, len(wb.sheetnames)-1))
|
|
50
|
+
ws = wb.worksheets[sheet_number]
|
|
51
|
+
|
|
52
|
+
# Read data and formulas from the sheet
|
|
53
|
+
table_data = []
|
|
54
|
+
# table_data = [[cell for cell in row] for row in ws.iter_rows(min_row=1, values_only=False)]
|
|
55
|
+
# table_data = [[cell.value for cell in row] for row in ws.iter_rows(min_row=1, values_only=False)]
|
|
56
|
+
table_data = [[cell if cell != None else "" for cell in row] for row in ws.iter_rows(min_row=1, values_only=True)]
|
|
57
|
+
header = []
|
|
58
|
+
# header = [cell for cell in list(ws.iter_rows(values_only=True))[0]] # Assuming the first row is the header
|
|
59
|
+
header = table_data[0]
|
|
60
|
+
table_data = table_data[1:]
|
|
61
|
+
#
|
|
62
|
+
# for row in ws.iter_rows(min_row=2, values_only=True): # Skip the header row
|
|
63
|
+
# row_data = []
|
|
64
|
+
# for cell in row:
|
|
65
|
+
# if isinstance(cell, str) and '=' in cell: # Check if it's a formula
|
|
66
|
+
# row_data.append(cell)
|
|
67
|
+
# else:
|
|
68
|
+
# row_data.append(str(cell))
|
|
69
|
+
# table_data.append(row_data)
|
|
70
|
+
|
|
71
|
+
return table_data, header, wb.sheetnames
|
|
72
|
+
|
|
73
|
+
def ods_to_list(filename: str, sheet_number: int = 0, extract_formulas: bool = False, first_row_is_header: bool = True):
|
|
74
|
+
from odf.opendocument import load
|
|
75
|
+
from odf import table, text
|
|
76
|
+
|
|
77
|
+
from odf.namespaces import TABLENS
|
|
78
|
+
# Load the ODS file
|
|
79
|
+
doc = load(filename)
|
|
80
|
+
|
|
81
|
+
sheets = doc.spreadsheet.getElementsByType(table.Table)
|
|
82
|
+
sheet_names = [s.attributes.get((TABLENS, 'name')) for s in sheets]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# Get the sheet by index
|
|
86
|
+
sheet = doc.spreadsheet.getElementsByType(table.Table)[sheet_number]
|
|
87
|
+
|
|
88
|
+
data = []
|
|
89
|
+
for row in sheet.getElementsByType(table.TableRow):
|
|
90
|
+
row_data = []
|
|
91
|
+
for cell in row.getElementsByType(table.TableCell):
|
|
92
|
+
if extract_formulas:
|
|
93
|
+
formula = cell.attributes.get((TABLENS, 'formula'))
|
|
94
|
+
if formula is not None:
|
|
95
|
+
row_data.append(formula)
|
|
96
|
+
continue # Skip extracting value if formula found
|
|
97
|
+
|
|
98
|
+
# Extract value (as text) from <text:p> elements
|
|
99
|
+
cell_text = ""
|
|
100
|
+
for p in cell.getElementsByType(text.P):
|
|
101
|
+
cell_text += str(p.firstChild) if p.firstChild is not None else ""
|
|
102
|
+
row_data.append(cell_text)
|
|
103
|
+
data.append(row_data)
|
|
104
|
+
if first_row_is_header and len(data) > 0:
|
|
105
|
+
header = data[0]
|
|
106
|
+
data = data[1:]
|
|
107
|
+
else:
|
|
108
|
+
header = []
|
|
109
|
+
|
|
110
|
+
return data, header, sheet_names
|
|
111
|
+
|
|
112
|
+
def ods_to_list_old(file_name: str, sheet_number:int = 0, extract_formulae: bool = False):
|
|
113
|
+
try:
|
|
114
|
+
import pandas as pd
|
|
115
|
+
ef = pd.ExcelFile(file_name)
|
|
116
|
+
sheets = ef.sheet_names
|
|
117
|
+
sheet_number = max(0, min(sheet_number, len(sheets)-1))
|
|
118
|
+
df = pd.read_excel(file_name, engine='odf', sheet_name=sheet_number)
|
|
119
|
+
# if sheet_number < len(sheets):
|
|
120
|
+
# df = pd.read_excel(input_arg, engine='odf', sheet_name=sheet_number)
|
|
121
|
+
# else:
|
|
122
|
+
# df = pd.read_excel(input_arg, engine='odf')
|
|
123
|
+
table_data = df.values.tolist()
|
|
124
|
+
table_data = [[x if not pd.isna(x) else "" for x in row] for row in table_data]
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
header = list(df.columns)
|
|
128
|
+
except:
|
|
129
|
+
header = []
|
|
130
|
+
return table_data, header, sheets
|
|
131
|
+
except Exception as e:
|
|
132
|
+
print(f"Error loading ODS file: {e}")
|
|
133
|
+
return [], [], []
|
|
134
|
+
|
|
39
135
|
|
|
40
136
|
def table_to_list(
|
|
41
137
|
|
|
@@ -80,7 +176,17 @@ def table_to_list(
|
|
|
80
176
|
reader = csv.reader(f, skipinitialspace=True)
|
|
81
177
|
return [row for row in reader]
|
|
82
178
|
|
|
83
|
-
if
|
|
179
|
+
if input_arg == '--stdin':
|
|
180
|
+
os.system(f"notify-send stdin")
|
|
181
|
+
input_data = sys.stdin.read()
|
|
182
|
+
elif input_arg == '--stdin2':
|
|
183
|
+
os.system(f"notify-send stdin2")
|
|
184
|
+
input_count = int(sys.stdin.readline())
|
|
185
|
+
input_data = "\n".join([sys.stdin.readline() for i in range(input_count)])
|
|
186
|
+
sys.stdin.flush()
|
|
187
|
+
# sys.stdin.close()
|
|
188
|
+
# sys.stdin = open('/dev/tty', 'r')
|
|
189
|
+
elif file_type == 'csv' or delimiter in [',']:
|
|
84
190
|
try:
|
|
85
191
|
if input_arg == '--stdin':
|
|
86
192
|
input_data = sys.stdin.read()
|
|
@@ -141,45 +247,12 @@ def table_to_list(
|
|
|
141
247
|
return [], [], []
|
|
142
248
|
|
|
143
249
|
elif file_type == 'xlsx':
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
sheets = ef.sheet_names
|
|
147
|
-
sheet_number = min(0, max(sheet_number, len(sheets)-1))
|
|
148
|
-
df = pd.read_excel(input_arg, engine='odf', sheet_name=sheet_number)
|
|
149
|
-
# if sheet_number < len(sheets):
|
|
150
|
-
# df = pd.read_excel(input_arg, sheet_name=sheet_number)
|
|
151
|
-
# else:
|
|
152
|
-
# df = pd.read_excel(input_arg)
|
|
153
|
-
table_data = df.values.tolist()
|
|
154
|
-
table_data = [[x if not pd.isna(x) else "" for x in row] for row in table_data]
|
|
155
|
-
try:
|
|
156
|
-
header = list(df.columns)
|
|
157
|
-
except:
|
|
158
|
-
header = []
|
|
159
|
-
return table_data, header, sheets
|
|
250
|
+
extract_formulae = False
|
|
251
|
+
return xlsx_to_list(input_arg, sheet_number, extract_formulae)
|
|
160
252
|
|
|
161
253
|
elif file_type == 'ods':
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
ef = pd.ExcelFile(input_arg)
|
|
165
|
-
sheets = ef.sheet_names
|
|
166
|
-
sheet_number = min(0, max(sheet_number, len(sheets)-1))
|
|
167
|
-
df = pd.read_excel(input_arg, engine='odf', sheet_name=sheet_number)
|
|
168
|
-
# if sheet_number < len(sheets):
|
|
169
|
-
# df = pd.read_excel(input_arg, engine='odf', sheet_name=sheet_number)
|
|
170
|
-
# else:
|
|
171
|
-
# df = pd.read_excel(input_arg, engine='odf')
|
|
172
|
-
table_data = df.values.tolist()
|
|
173
|
-
table_data = [[x if not pd.isna(x) else "" for x in row] for row in table_data]
|
|
174
|
-
|
|
175
|
-
try:
|
|
176
|
-
header = list(df.columns)
|
|
177
|
-
except:
|
|
178
|
-
header = []
|
|
179
|
-
return table_data, header, sheets
|
|
180
|
-
except Exception as e:
|
|
181
|
-
print(f"Error loading ODS file: {e}")
|
|
182
|
-
return [], [], []
|
|
254
|
+
extract_formulae = False
|
|
255
|
+
return ods_to_list(input_arg, sheet_number, extract_formulae)
|
|
183
256
|
elif file_type == 'pkl':
|
|
184
257
|
with open(os.path.expandvars(os.path.expanduser(input_arg)), 'rb') as f:
|
|
185
258
|
loaded_data = pickle.load(f)
|
|
@@ -187,11 +260,6 @@ def table_to_list(
|
|
|
187
260
|
header = loaded_data["header"] if "header" in loaded_data else []
|
|
188
261
|
return items, header, []
|
|
189
262
|
|
|
190
|
-
if input_arg == '--stdin':
|
|
191
|
-
input_data = sys.stdin.read()
|
|
192
|
-
elif input_arg == '--stdin2':
|
|
193
|
-
input_count = int(sys.stdin.readline())
|
|
194
|
-
input_data = "\n".join([sys.stdin.readline() for i in range(input_count)])
|
|
195
263
|
else:
|
|
196
264
|
input_data = read_file_content(input_arg)
|
|
197
265
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
listpick/__init__.py,sha256=ExXc97-bibodH--wlwpQivl0zCNR5D1hvpvrf7OBofU,154
|
|
2
2
|
listpick/__main__.py,sha256=wkCjDdqw093W27yWwnlC3nG_sMRKaIad7hHHWy0RBgY,193
|
|
3
|
-
listpick/listpick_app.py,sha256=
|
|
3
|
+
listpick/listpick_app.py,sha256=Qmrrfx26B9Snew3j277vPlaOc4b2bjGJ2nveuk8STbE,186680
|
|
4
4
|
listpick/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
listpick/ui/build_help.py,sha256=8QtsRosIE2IMagRc_remzmwSWpCurFgLenLL7w1ly94,8949
|
|
6
6
|
listpick/ui/footer.py,sha256=eaGCJlUMuOyoVfBxbqDFBxF7b3w_FMUuzFO1_xWz7xY,14702
|
|
7
7
|
listpick/ui/help_screen.py,sha256=zbfGIgb-IXtATpl4_Sx7nPbsnRXZ7eiMYlCKGS9EFmw,5608
|
|
8
|
-
listpick/ui/input_field.py,sha256=
|
|
9
|
-
listpick/ui/keys.py,sha256=
|
|
8
|
+
listpick/ui/input_field.py,sha256=0OBhU_-IIa_sOcehocfyeVGQ93Wk-C0Waa6dgvaQpnI,31784
|
|
9
|
+
listpick/ui/keys.py,sha256=lhbwgsCr7pIpi10OqFMFOJSTC0nP4vpkQj9GIt787UU,13178
|
|
10
10
|
listpick/ui/pane_stuff.py,sha256=7GXa4UnV_7YmBv-baRi5moN51wYcuS4p0odl5C3m0Tc,169
|
|
11
11
|
listpick/ui/picker_colours.py,sha256=FLOzvkq83orrN2bL0Mw-6RugWOZyuwUjQCrUFMUnKGY,11563
|
|
12
12
|
listpick/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -21,11 +21,11 @@ listpick/utils/picker_log.py,sha256=SW6GmjxpI7YrSf72fSr4O8Ux0fY_OzaSXUgTFdz6Xo4,
|
|
|
21
21
|
listpick/utils/search_and_filter_utils.py,sha256=XxGfkyDVXO9OAKcftPat8IReMTFIuTH-jorxI4o84tg,3239
|
|
22
22
|
listpick/utils/searching.py,sha256=Xk5UIqamNHL2L90z3ACB_Giqdpi9iRKoAJ6pKaqaD7Q,3093
|
|
23
23
|
listpick/utils/sorting.py,sha256=WZZiVlVA3Zkcpwji3U5SNFlQ14zVEk3cZJtQirBkecQ,5329
|
|
24
|
-
listpick/utils/table_to_list_of_lists.py,sha256=
|
|
24
|
+
listpick/utils/table_to_list_of_lists.py,sha256=FbLJpP8v9kPQkVnCFoM1qnq-ZiioyAKF3z7DWhZJGKA,10783
|
|
25
25
|
listpick/utils/utils.py,sha256=McOl9uT3jh7l4TIWeSd8ZGjK_e7r0YZF0Gl20yI6fl0,13873
|
|
26
|
-
listpick-0.1.14.
|
|
27
|
-
listpick-0.1.14.
|
|
28
|
-
listpick-0.1.14.
|
|
29
|
-
listpick-0.1.14.
|
|
30
|
-
listpick-0.1.14.
|
|
31
|
-
listpick-0.1.14.
|
|
26
|
+
listpick-0.1.14.5.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
|
|
27
|
+
listpick-0.1.14.5.dist-info/METADATA,sha256=buxwDKACNAU-7m58shUjUTekCQzWu3UVNgQ6MMPWtT8,8090
|
|
28
|
+
listpick-0.1.14.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
29
|
+
listpick-0.1.14.5.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
|
|
30
|
+
listpick-0.1.14.5.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
|
|
31
|
+
listpick-0.1.14.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|