mit neuen venv und exe-Files
This commit is contained in:
BIN
venv3_12/Lib/site-packages/auto_py_to_exe/web/Nunito-Light.ttf
Normal file
BIN
venv3_12/Lib/site-packages/auto_py_to_exe/web/Nunito-Light.ttf
Normal file
Binary file not shown.
Binary file not shown.
184
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/general.css
Normal file
184
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/general.css
Normal file
@@ -0,0 +1,184 @@
|
||||
@font-face {
|
||||
font-family: 'Nunito';
|
||||
src: url('../Nunito-Light.ttf');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Vazirmatn';
|
||||
src: url('../Vazirmatn-Light.ttf');
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: #fbfbfb;
|
||||
--primary: #458bc6;
|
||||
--primary-darker: #1c79c7;
|
||||
--primary-transparent: #1c79c71a;
|
||||
--error: red;
|
||||
--unselected: lightgrey;
|
||||
--disabled: #808080;
|
||||
--text: #000000;
|
||||
|
||||
--title: #666666;
|
||||
--warning-background: #fff3cd;
|
||||
--warning-border: #a0987c;
|
||||
--warning-text: #000000;
|
||||
|
||||
--border-radius: 4px;
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
--background: #15131e;
|
||||
--unselected: #5f5f5f;
|
||||
--text: #ffffff;
|
||||
|
||||
--title: #e2e2e2;
|
||||
--warning-background: #ffdc6d;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background);
|
||||
font-family: 'Vazirmatn', 'Nunito', Helvetica, Arial, sans-serif;
|
||||
font-weight: 100;
|
||||
margin: 0 18px 10px 18px;
|
||||
}
|
||||
|
||||
.mid {
|
||||
/* Global center alignment */
|
||||
margin: auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
/* Headers */
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
font-size: 25px;
|
||||
margin: 10px 0 2px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 17px;
|
||||
margin: 10px 0 4px 0;
|
||||
}
|
||||
|
||||
.sub_header {
|
||||
/* Headers in tabs */
|
||||
font-size: 17px;
|
||||
margin: 10px 2px 4px 2px;
|
||||
}
|
||||
|
||||
h2 > small {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* Generic inputs */
|
||||
|
||||
button,
|
||||
input,
|
||||
select {
|
||||
border: 1px solid var(--primary);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 4px;
|
||||
|
||||
font-family: 'Vazirmatn', 'Nunito', Helvetica, Arial, sans-serif;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
select option {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none; /* Don't show outline so you can see the colour change */
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
border-radius: var(--border-radius);
|
||||
background: transparent;
|
||||
padding: 3px 8px;
|
||||
transition: border 0.3s, background 0.3s;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
button:not(.selected):not(.unselected):hover {
|
||||
/* Apply hovers to non-state buttons */
|
||||
background: var(--primary-transparent);
|
||||
}
|
||||
|
||||
button.selected,
|
||||
button.unselected:hover {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
button.unselected {
|
||||
border-color: var(--unselected);
|
||||
color: var(--unselected);
|
||||
}
|
||||
|
||||
button.large {
|
||||
border-width: 3px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* Info icon */
|
||||
|
||||
.info_icon {
|
||||
/* Information icon */
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAq0lEQVR4XnWQywrDIBBF82P+WPtXebiSbJKtq0jAtVAEwW0WIZ16p04aWjpwcbge5tU0Nfq+V13XteV9QDVX8i/Qrei5LAtt28ZCXuADf9dKxzzPhEgpsRDwKqwatCiiaZrIe09aazLGMOicAwi1qIh5xGAw50z7vtM4juyB+QFDCFzNWnt6DEpr0bquPMIwDKcnrXkZMWOMrAv0XqZufhf4C/ycR6JW/nvwF51vE+IcomqCAAAAAElFTkSuQmCC) -0px -0px
|
||||
no-repeat;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
overflow: hidden;
|
||||
margin-left: 0.25em;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Small notes */
|
||||
|
||||
.note {
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
|
||||
/* Filepath-browse layout */
|
||||
|
||||
.filepath-browse-layout {
|
||||
display: grid;
|
||||
grid-gap: 4px;
|
||||
grid-template-columns: 1fr 120px;
|
||||
}
|
||||
|
||||
/* Icon-specific */
|
||||
|
||||
#icon-invalid-warning {
|
||||
font-size: 14px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
/* Utils */
|
||||
|
||||
.noselect {
|
||||
/* Don't select tab text */
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none;
|
||||
}
|
||||
363
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/main.css
Normal file
363
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/main.css
Normal file
@@ -0,0 +1,363 @@
|
||||
/* Header */
|
||||
|
||||
#header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
#header .title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#header .title img {
|
||||
height: 41px;
|
||||
}
|
||||
|
||||
#header .title h1 {
|
||||
font-weight: 100;
|
||||
font-size: 30px;
|
||||
color: var(--title);
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
|
||||
#header .title > a {
|
||||
display: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header .title > a:hover {
|
||||
-webkit-mask-image: linear-gradient(-75deg, rgb(0, 0, 0) 30%, rgba(0, 0, 0, 0.5) 50%, rgb(0, 0, 0) 70%);
|
||||
-webkit-mask-size: 200%;
|
||||
animation: shine 2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@-webkit-keyframes shine {
|
||||
from {
|
||||
-webkit-mask-position: 150%;
|
||||
}
|
||||
to {
|
||||
-webkit-mask-position: -50%;
|
||||
}
|
||||
}
|
||||
|
||||
#header .extra-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#header .extra-links a {
|
||||
filter: grayscale(1);
|
||||
transition: filter 0.3s;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#header .extra-links a span {
|
||||
font-size: 15px;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
#header .extra-links a:hover {
|
||||
filter: grayscale(0);
|
||||
}
|
||||
|
||||
#header .extra-links a img {
|
||||
height: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
#header .extra-links a:not(:first-child) img {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#header .ui-config {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
#header .ui-config [for='language-selection'] {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
#header .ui-config #language-selection {
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
#header .ui-config #theme-toggle {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
#language-selection {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
/* Warnings */
|
||||
|
||||
#warnings {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#warnings > div {
|
||||
background: var(--warning-background);
|
||||
border: 1px solid var(--warning-border);
|
||||
border-radius: var(--border-radius);
|
||||
margin: 10px 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#warnings > div > p {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#warnings > div > p,
|
||||
#warnings > div > p a {
|
||||
color: var(--warning-text);
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
|
||||
div[id*='section'] {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
div[id*='section'] .header {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div[id*='section'] .header img {
|
||||
height: 30px;
|
||||
transition: transform 0.4s;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
div[id*='section'] .header h2 {
|
||||
display: inline;
|
||||
margin: 0 0 0 15px;
|
||||
}
|
||||
|
||||
div[id*='section'] .content {
|
||||
display: none; /* Hide sections by default */
|
||||
margin: 5px 10px 0 10px;
|
||||
}
|
||||
|
||||
/* Additional Files */
|
||||
|
||||
#datas-add-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-gap: 5px;
|
||||
}
|
||||
|
||||
/* Advanced tab */
|
||||
|
||||
.option-container {
|
||||
/* Option containers */
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.option-container > span {
|
||||
/* Option name */
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.option-container.multiple-input > img {
|
||||
height: 23px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.option-container.multiple-input > div {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.option-container.multiple-input > div > div,
|
||||
#datas-list > div {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-gap: 4px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.option-container.multiple-input > div > div.dual-value,
|
||||
#datas-list > div {
|
||||
grid-template-columns: 1fr 1fr auto;
|
||||
}
|
||||
|
||||
.option-container.multiple-input > div > div > img,
|
||||
#datas-list > div > img {
|
||||
height: 100%;
|
||||
padding: 2px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.option-container.input {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 5px;
|
||||
}
|
||||
|
||||
.option-container.input.with-browse {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
/* Current Command */
|
||||
|
||||
#current-command textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Output */
|
||||
|
||||
#output {
|
||||
display: none; /* Hidden by default */
|
||||
}
|
||||
|
||||
#output.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#output textarea {
|
||||
width: 100%;
|
||||
white-space: pre;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#output textarea.failure {
|
||||
border-color: var(--error);
|
||||
}
|
||||
|
||||
/* Common issues link formatting */
|
||||
|
||||
#common-issue-link {
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
display: none; /* Default to not shown */
|
||||
}
|
||||
|
||||
#common-issue-link.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#common-issue-link a {
|
||||
text-decoration: none;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
#common-issue-link a:hover {
|
||||
color: var(--primary-darker);
|
||||
}
|
||||
|
||||
/* Package / Open Output Folder Buttons */
|
||||
|
||||
#package-button-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
#package-button,
|
||||
#open-output-folder-button {
|
||||
width: 100%;
|
||||
background-color: var(--primary);
|
||||
border: 1px solid var(--primary);
|
||||
font-size: 15px;
|
||||
color: white;
|
||||
height: 38px;
|
||||
padding: 0 30px;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
letter-spacing: 0.1rem;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
#package-button:hover,
|
||||
#open-output-folder-button:hover {
|
||||
background-color: var(--primary-darker);
|
||||
}
|
||||
|
||||
#package-button:disabled {
|
||||
background-color: var(--disabled);
|
||||
border-color: var(--disabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#open-output-folder-button {
|
||||
display: none; /* Default to not shown */
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
#open-output-folder-button.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Loading spinner (from https://projects.lukehaas.me/css-loaders/) */
|
||||
|
||||
.loading-spinner-wrapper {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgb(0 0 0 / 75%);
|
||||
}
|
||||
|
||||
.loading-label {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loading-spinner,
|
||||
.loading-spinner:after {
|
||||
border-radius: 50%;
|
||||
width: 8em;
|
||||
height: 8em;
|
||||
}
|
||||
.loading-spinner {
|
||||
margin: 60px auto;
|
||||
font-size: 10px;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
border-top: 1.1em solid rgba(256, 256, 256, 0.2);
|
||||
border-right: 1.1em solid rgba(256, 256, 256, 0.2);
|
||||
border-bottom: 1.1em solid rgba(256, 256, 256, 0.2);
|
||||
border-left: 1.1em solid #ffffff;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
}
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
62
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/modal.css
Normal file
62
venv3_12/Lib/site-packages/auto_py_to_exe/web/css/modal.css
Normal file
@@ -0,0 +1,62 @@
|
||||
:root {
|
||||
--modal-offset: 0;
|
||||
--modal-padding: 200px;
|
||||
--modal-fallback-color: rgba(0, 0, 0, 0.4);
|
||||
--modal-coverage-area: 100%;
|
||||
}
|
||||
|
||||
.modal-coverage {
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
padding-top: var(--modal-padding);
|
||||
left: var(--modal-offset);
|
||||
top: var(--modal-offset);
|
||||
width: var(--modal-coverage-area);
|
||||
height: var(--modal-coverage-area);
|
||||
overflow: auto;
|
||||
background-color: var(--modal-fallback-color);
|
||||
}
|
||||
|
||||
.modal-coverage-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--background);
|
||||
margin: auto;
|
||||
padding: 16px;
|
||||
border: 2px solid var(--primary);
|
||||
border-radius: var(--border-radius);
|
||||
width: 80%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
color: var(--primary);
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.close-btn:hover,
|
||||
.close-btn:focus {
|
||||
color: var(--primary-darker);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-section {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.modal-btn {
|
||||
margin-right: 4px;
|
||||
}
|
||||
BIN
venv3_12/Lib/site-packages/auto_py_to_exe/web/favicon.ico
Normal file
BIN
venv3_12/Lib/site-packages/auto_py_to_exe/web/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
style="color: #458BC6;">
|
||||
<path fill="currentColor"
|
||||
d="M232.5 163.5l122.8 122.8c4.7 4.7 4.7 12.3 0 17l-22.6 22.6c-4.7 4.7-12.3 4.7-17 0L224 234.2l-91.7 91.7c-4.7 4.7-12.3 4.7-17 0l-22.6-22.6c-4.7-4.7-4.7-12.3 0-17l122.8-122.8c4.7-4.7 12.3-4.7 17 0zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 540 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><path fill="currentColor" d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"/></svg>
|
||||
|
After Width: | Height: | Size: 416 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
style="color: green;">
|
||||
<path fill="currentColor"
|
||||
d="M352 240v32c0 6.6-5.4 12-12 12h-88v88c0 6.6-5.4 12-12 12h-32c-6.6 0-12-5.4-12-12v-88h-88c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h88v-88c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v88h88c6.6 0 12 5.4 12 12zm96-160v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 549 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
style="color: red;">
|
||||
<path fill="currentColor"
|
||||
d="M108 284c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h232c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12H108zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-48 346V86c0-3.3-2.7-6-6-6H54c-3.3 0-6 2.7-6 6v340c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 444 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512" style="color: white;"><path fill="currentColor" d="M256 160c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm246.4 80.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.4-94.8c-6.4-12.8-24.6-12.8-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4c-12.8 6.4-12.8 24.6 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.4-33.5 47.3 94.7c6.4 12.8 24.6 12.8 31 0l47.3-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3c13-6.5 13-24.7.2-31.1zm-155.9 106c-49.9 49.9-131.1 49.9-181 0-49.9-49.9-49.9-131.1 0-181 49.9-49.9 131.1-49.9 181 0 49.9 49.9 49.9 131.1 0 181z"/></svg>
|
||||
|
After Width: | Height: | Size: 722 B |
280
venv3_12/Lib/site-packages/auto_py_to_exe/web/index.html
Normal file
280
venv3_12/Lib/site-packages/auto_py_to_exe/web/index.html
Normal file
@@ -0,0 +1,280 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Auto Py To Exe</title>
|
||||
<script>
|
||||
// Provided for type checking
|
||||
window.eel = {
|
||||
initialise: () => ({
|
||||
filename: null,
|
||||
options: [],
|
||||
suppliedUiConfiguration: {},
|
||||
warnings: [],
|
||||
pathSeparator: '',
|
||||
defaultOutputFolder: '',
|
||||
languageHint: '',
|
||||
}),
|
||||
does_file_exist: (path) => false,
|
||||
does_folder_exist: (path) => false,
|
||||
ask_file: (file_type) => '',
|
||||
ask_files: () => [],
|
||||
ask_folder: () => '',
|
||||
is_file_an_ico: (file_path) => null,
|
||||
convert_path_to_absolute: (path) => '',
|
||||
open_output_in_explorer: (output_directory, input_filename, is_one_file) => {},
|
||||
will_packaging_overwrite_existing: (file_path, manual_name, one_file, output_folder) => true,
|
||||
package: (command, non_pyinstaller_options) => {},
|
||||
import_configuration: () => {},
|
||||
export_configuration: (configuration) => {},
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" src="/eel.js"></script>
|
||||
<script type="text/javascript" src="/js/constants.js"></script>
|
||||
<script type="text/javascript" src="/js/i18n.js"></script>
|
||||
<script type="text/javascript" src="/js/initialise.js"></script>
|
||||
<script type="text/javascript" src="/js/configuration.js"></script>
|
||||
<script type="text/javascript" src="/js/staticEvents.js"></script>
|
||||
<script type="text/javascript" src="/js/interface.js"></script>
|
||||
<script type="text/javascript" src="/js/utils.js"></script>
|
||||
<script type="text/javascript" src="/js/modal.js"></script>
|
||||
<script type="text/javascript" src="/js/messages.js"></script>
|
||||
<script type="text/javascript" src="/js/packaging.js"></script>
|
||||
<script type="text/javascript" src="/js/importExport.js"></script>
|
||||
<link rel="stylesheet" href="/css/general.css" />
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
<link rel="stylesheet" href="/css/modal.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="mid">
|
||||
<div id="header">
|
||||
<div class="title">
|
||||
<a href="https://github.com/brentvollebregt/auto-py-to-exe" target="_blank"><img src="/favicon.ico" /></a>
|
||||
<a href="https://github.com/brentvollebregt/auto-py-to-exe" target="_blank"><h1>Auto Py to Exe</h1></a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="extra-links">
|
||||
<a href="https://github.com/brentvollebregt/auto-py-to-exe" target="_blank">
|
||||
<span>GitHub</span>
|
||||
<img src="https://github.githubassets.com/favicons/favicon.png" alt="GitHub favicon" />
|
||||
</a>
|
||||
<a
|
||||
href="https://nitratine.net/blog/post/issues-when-using-auto-py-to-exe/?utm_source=auto_py_to_exe&utm_medium=application_link&utm_campaign=auto_py_to_exe_help&utm_content=top"
|
||||
target="_blank"
|
||||
>
|
||||
<span data-i18n="ui.links.helpPost">Help Post</span>
|
||||
<img src="https://nitratine.net/static/img/favicon-384x384.png" alt="Nitratine favicon" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="ui-config">
|
||||
<label for="language-selection">
|
||||
<small data-i18n="ui.title.language">Language</small><small>:</small>
|
||||
</label>
|
||||
<select id="language-selection"></select>
|
||||
|
||||
<span id="theme-toggle">
|
||||
<img src="img/sun.svg" id="on-dark-theme-button" style="display: none" />
|
||||
<img src="img/moon.svg" id="on-light-theme-button" style="display: inline" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="warnings"></div>
|
||||
|
||||
<div>
|
||||
<h2 data-i18n="ui.title.scriptLocation">Script Location</h2>
|
||||
<div class="filepath-browse-layout">
|
||||
<input
|
||||
id="entry-script"
|
||||
placeholder="Path to file"
|
||||
required
|
||||
data-i18n_placeholder="ui.placeholders.pathToFile"
|
||||
/>
|
||||
<button id="entry-script-search" data-i18n="ui.button.browse">Browse</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>
|
||||
<span data-i18n="ui.title.oneFile">Onefile</span>
|
||||
<small>(--onedir / --onefile)</small>
|
||||
</h2>
|
||||
<div>
|
||||
<button id="one-directory-button" class="large" data-i18n="ui.button.oneDirectory">One Directory</button>
|
||||
<button id="one-file-button" class="large" data-i18n="ui.button.oneFile">One File</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>
|
||||
<span data-i18n="ui.title.consoleWindow">Console Window</span>
|
||||
<small>(--console / --windowed)</small>
|
||||
</h2>
|
||||
<div>
|
||||
<button id="console-based-button" class="large" data-i18n="ui.button.consoleBased">Console Based</button>
|
||||
<button id="window-based-button" class="large" data-i18n="ui.button.windowBased">
|
||||
Window Based (hide the console)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section-icon">
|
||||
<div class="header noselect" onclick="expandSection('icon')">
|
||||
<img src="img/chevron-square-up.svg" alt="Icon Section Chevron" />
|
||||
<h2>
|
||||
<span data-i18n="ui.title.icon">Icon</span>
|
||||
<small>(--icon)</small>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="filepath-browse-layout">
|
||||
<input id="icon-path" placeholder=".ico file" data-i18n_placeholder="ui.placeholders.icoFile" />
|
||||
<button id="icon-path-search" data-i18n="ui.button.browse">Browse</button>
|
||||
</div>
|
||||
<div>
|
||||
<span id="icon-invalid-warning" style="display: none">
|
||||
⚠️
|
||||
<span data-i18n="ui.notes.invalidIcoFormatWarning">Warning: this file is not a valid .ico file</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section-additional-files">
|
||||
<div class="header noselect" onclick="expandSection('additional-files')">
|
||||
<img src="img/chevron-square-up.svg" alt="Additional Files Section Chevron" />
|
||||
<h2>
|
||||
<span data-i18n="ui.title.additionalFiles">Additional Files</span>
|
||||
<small>(--add-data)</small>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div id="datas-add-buttons">
|
||||
<button id="additional-files-add-files-button" data-i18n="ui.button.addFiles">Add Files</button>
|
||||
<button id="additional-files-add-folder" data-i18n="ui.button.addFolder">Add Folder</button>
|
||||
<button id="additional-files-add-blank" data-i18n="ui.button.addBlank">Add Blank</button>
|
||||
</div>
|
||||
<div id="datas-list"></div>
|
||||
<p
|
||||
id="onefileAdditionalFilesNote"
|
||||
class="note"
|
||||
style="display: none"
|
||||
data-i18n="ui.notes.oneFileAdditionalFilesNote"
|
||||
>
|
||||
Be careful when using additional files with onefile mode;
|
||||
<a href="https://stackoverflow.com/a/13790741/" style="text-decoration: none">read this</a>
|
||||
and update your code to work with PyInstaller.
|
||||
</p>
|
||||
<p class="note" data-i18n="ui.notes.rootDirectory">
|
||||
If you want to put files in the root directory, put a period (.) in the destination.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="section-advanced">
|
||||
<div class="header noselect" onclick="expandSection('advanced')">
|
||||
<img src="img/chevron-square-up.svg" alt="Advanced Section Chevron" />
|
||||
<h2 data-i18n="ui.title.advanced">Advanced</h2>
|
||||
</div>
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
|
||||
<div id="section-settings">
|
||||
<div class="header noselect" onclick="expandSection('settings')">
|
||||
<img src="img/chevron-square-up.svg" alt="Advanced Section Chevron" />
|
||||
<h2 data-i18n="ui.title.settings">Settings</h2>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div>
|
||||
<h3 data-i18n="ui.title.specificOptions">auto-py-to-exe Specific Options</h3>
|
||||
<div class="option-container input">
|
||||
<span>
|
||||
<span data-i18n="ui.title.outputDirectory">Output Directory</span>
|
||||
<span
|
||||
title="The directory to put the output in. Will be created if it doesn't exist"
|
||||
class="info_icon"
|
||||
data-i18n_title="ui.helpText.outputDirectory"
|
||||
></span>
|
||||
</span>
|
||||
<div class="filepath-browse-layout">
|
||||
<input
|
||||
id="output-directory"
|
||||
placeholder="DIRECTORY"
|
||||
data-i18n_placeholder="ui.placeholders.directory"
|
||||
/>
|
||||
<button id="output-directory-search" data-i18n="ui.button.browse">Browse</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-container switch">
|
||||
<span>
|
||||
<span data-i18n="ui.title.increaseRecursionLimit">Increase Recursion Limit</span>
|
||||
<span
|
||||
title="Having this enabled will set the recursion limit to 5000 using sys.setrecursionlimit(5000)."
|
||||
class="info_icon"
|
||||
data-i18n_title="ui.helpText.increaseRecursionLimit"
|
||||
></span>
|
||||
</span>
|
||||
<button id="recursion-limit-switch" data-i18n="ui.button.enable">Enable</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 data-i18n="ui.title.manuallyProvideOptions">Manually Provide Options</h3>
|
||||
<div class="option-container input">
|
||||
<span>
|
||||
<span data-i18n="ui.title.manualArgumentInput">Manual Argument Input</span>
|
||||
<span
|
||||
title="Inject raw text into the generated command."
|
||||
class="info_icon"
|
||||
data-i18n_title="ui.helpText.manualArgumentInput"
|
||||
></span>
|
||||
</span>
|
||||
<input id="raw-arguments" placeholder="ARGUMENTS" data-i18n_placeholder="ui.placeholders.arguments" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 data-i18n="ui.title.configuration">Configuration</h3>
|
||||
<button id="configuration-import" data-i18n="ui.button.importConfig">Import Config From JSON File</button>
|
||||
<button id="configuration-export" data-i18n="ui.button.exportConfig">Export Config To JSON File</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="current-command">
|
||||
<h2 data-i18n="ui.title.currentCommand">Current Command</h2>
|
||||
<textarea readonly></textarea>
|
||||
</div>
|
||||
|
||||
<div id="output">
|
||||
<h2 data-i18n="ui.title.output">Output</h2>
|
||||
<textarea readonly></textarea>
|
||||
</div>
|
||||
|
||||
<div id="common-issue-link" data-i18n="ui.notes.somethingWrongWithOutput">
|
||||
Something wrong with your exe? Read
|
||||
<a
|
||||
href="https://nitratine.net/blog/post/issues-when-using-auto-py-to-exe/?utm_source=auto_py_to_exe&utm_medium=application_link&utm_campaign=auto_py_to_exe_help&utm_content=bottom"
|
||||
target="_blank"
|
||||
>
|
||||
this post on how to fix common issues
|
||||
</a>
|
||||
for possible solutions.
|
||||
</div>
|
||||
|
||||
<div id="package-button-wrapper">
|
||||
<button id="package-button" data-i18n="ui.button.convert">Convert .py to .exe</button>
|
||||
<button id="open-output-folder-button" data-i18n="ui.button.openOutputFolder">Open Output Folder</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-area" class="modal-coverage modal-coverage-hidden"></div>
|
||||
|
||||
<div id="spinner-root" class="loading-spinner-wrapper">
|
||||
<div>
|
||||
<div class="loading-spinner"></div>
|
||||
<span class="loading-label">Initializing...</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Handle configuration modifications
|
||||
*/
|
||||
|
||||
const configurationGetters = []; // Each function in this should either return null or [option.dest, value]
|
||||
const configurationSetters = {}; // dest: fn(value) => void, used to set option values
|
||||
const configurationCleaners = []; // Each function in this should clear a dest value
|
||||
|
||||
// Get option-value pairs [[option, value], ...]
|
||||
const getCurrentConfiguration = async (skipTransformations = false) => {
|
||||
const currentConfiguration = [
|
||||
{
|
||||
optionDest: 'noconfirm',
|
||||
value: true,
|
||||
},
|
||||
];
|
||||
|
||||
// Call all functions to get data
|
||||
configurationGetters.forEach((getter) => {
|
||||
const optionValuePair = getter();
|
||||
if (optionValuePair !== null) {
|
||||
currentConfiguration.push({
|
||||
optionDest: optionValuePair[0],
|
||||
value: optionValuePair[1],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (skipTransformations) {
|
||||
return currentConfiguration;
|
||||
}
|
||||
|
||||
// Convert all relative paths to absolute paths
|
||||
for (const c of currentConfiguration) {
|
||||
const option = options.find((o) => o.dest === c.optionDest);
|
||||
if (option === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
[OPTION_INPUT_VALUE_FILE, OPTION_INPUT_VALUE_DIRECTORY].some((v) => option.allowedInputValues.includes(v)) ||
|
||||
option.dest === 'filenames'
|
||||
) {
|
||||
c.value = await convertPathToAbsolute(c.value);
|
||||
}
|
||||
if (
|
||||
[OPTION_INPUT_VALUE_DOUBLE_FILE_DEST, OPTION_INPUT_VALUE_DOUBLE_DIRECTORY_DEST].some((v) =>
|
||||
option.allowedInputValues.includes(v)
|
||||
)
|
||||
) {
|
||||
const [src, dest] = c.value.split(pathSeparator);
|
||||
c.value = `${await convertPathToAbsolute(src)}${pathSeparator}${dest}`;
|
||||
}
|
||||
}
|
||||
|
||||
return currentConfiguration;
|
||||
};
|
||||
|
||||
const getNonPyinstallerConfiguration = () => {
|
||||
return {
|
||||
outputDirectory: document.getElementById('output-directory').value,
|
||||
increaseRecursionLimit: !document.getElementById('recursion-limit-switch').classList.contains('unselected'),
|
||||
manualArguments: document.getElementById('raw-arguments').value,
|
||||
};
|
||||
};
|
||||
|
||||
const getCurrentCommand = async () => {
|
||||
const currentConfiguration = await getCurrentConfiguration();
|
||||
|
||||
// Match configuration values with the correct flags
|
||||
const optionsAndValues = currentConfiguration
|
||||
.filter((c) => c.optionDest !== 'filenames')
|
||||
.map((c) => {
|
||||
// Identify the options
|
||||
const option = options.find((o) => o.dest === c.optionDest);
|
||||
|
||||
if (option.nargs === 0) {
|
||||
// For switches, there are some switches for false switches that we can use
|
||||
const potentialOption = options.find((o) => o.dest === c.optionDest && o.const === c.value);
|
||||
if (potentialOption !== undefined) {
|
||||
return chooseOptionString(potentialOption.option_strings);
|
||||
} else {
|
||||
return null; // If there is no alternate option, skip it as it won't be required
|
||||
}
|
||||
} else {
|
||||
const optionFlag = chooseOptionString(option.option_strings);
|
||||
return `${optionFlag} "${c.value}"`;
|
||||
}
|
||||
})
|
||||
.filter((x) => x !== null);
|
||||
|
||||
// Identify the entry script provided
|
||||
const entryScriptConfig = currentConfiguration.find((c) => c.optionDest === 'filenames');
|
||||
const entryScript = entryScriptConfig === undefined ? '' : entryScriptConfig.value;
|
||||
|
||||
return `pyinstaller ${optionsAndValues.join(' ')} ${
|
||||
getNonPyinstallerConfiguration().manualArguments
|
||||
} "${entryScript}"`;
|
||||
};
|
||||
|
||||
const updateCurrentCommandDisplay = async () => {
|
||||
document.querySelector('#current-command textarea').value = await getCurrentCommand();
|
||||
};
|
||||
|
||||
const isCommandDefault = async () => {
|
||||
return (await getCurrentCommand()) === 'pyinstaller --noconfirm --onedir --console ""';
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
const options_ignored = ['help'];
|
||||
const options_static = ['filenames', 'onefile', 'console', 'icon_file', 'datas'];
|
||||
const options_overridden = ['specpath', 'distpath', 'workpath', 'noconfirm'];
|
||||
|
||||
const options_inputTypeFile = [
|
||||
'runtime_hooks',
|
||||
'version_file',
|
||||
'manifest',
|
||||
'resources',
|
||||
'splash',
|
||||
'entitlements_file',
|
||||
'icon_file',
|
||||
];
|
||||
const options_inputTypeDirectory = ['upx_dir', 'pathex', 'hookspath'];
|
||||
const options_inputTypeDoubleFileDest = ['datas', 'binaries'];
|
||||
const options_inputTypeDoubleDirectoryDest = ['datas'];
|
||||
|
||||
const advancedSections = [
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.generalOptions',
|
||||
options: ['name', 'contents_directory', 'upx_dir', 'clean_build', 'loglevel'],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.whatToBundleWhereToSearch',
|
||||
options: [
|
||||
'binaries',
|
||||
'pathex',
|
||||
'hiddenimports',
|
||||
'collect_submodules',
|
||||
'collect_data',
|
||||
'collect_binaries',
|
||||
'collect_all',
|
||||
'copy_metadata',
|
||||
'recursive_copy_metadata',
|
||||
'splash',
|
||||
'hookspath',
|
||||
'runtime_hooks',
|
||||
'excludes',
|
||||
'key',
|
||||
],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.howToGenerate',
|
||||
options: ['debug', 'optimize', 'python_options', 'strip', 'noupx', 'upx_exclude'],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.windowsAndMacOsXSpecificOptions',
|
||||
options: ['hide_console', 'disable_windowed_traceback'],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.windowsSpecificOptions',
|
||||
options: ['version_file', 'manifest', 'embed_manifest', 'resources', 'uac_admin', 'uac_uiaccess'],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.macOsxSpecificOptions',
|
||||
options: ['argv_emulation', 'bundle_identifier', 'target_arch', 'codesign_identity', 'entitlements_file'],
|
||||
},
|
||||
{
|
||||
titleI18nPath: 'dynamic.title.rarelyUsedSpecialOptions',
|
||||
options: ['runtime_tmpdir', 'bootloader_ignore_signals'],
|
||||
},
|
||||
];
|
||||
|
||||
// String constants
|
||||
OPTION_IGNORED = 'OPTION_IGNORED';
|
||||
OPTION_STATIC = 'OPTION_STATIC';
|
||||
OPTION_OVERRIDDEN = 'OPTION_OVERRIDDEN';
|
||||
OPTION_SHOW = 'OPTION_SHOW';
|
||||
|
||||
OPTION_INPUT_TYPE_SWITCH = 'OPTION_INPUT_TYPE_SWITCH';
|
||||
OPTION_INPUT_TYPE_DROPDOWN = 'OPTION_INPUT_TYPE_DROPDOWN';
|
||||
OPTION_INPUT_TYPE_INPUT = 'OPTION_INPUT_TYPE_INPUT';
|
||||
OPTION_INPUT_TYPE_MULTIPLE_INPUT = 'OPTION_INPUT_TYPE_MULTIPLE_INPUT';
|
||||
OPTION_INPUT_TYPE_DOUBLE_MULTIPLE_INPUT = 'OPTION_INPUT_TYPE_DOUBLE_MULTIPLE_INPUT';
|
||||
|
||||
OPTION_INPUT_VALUE_TEXT = 'OPTION_INPUT_VALUE_TEXT';
|
||||
OPTION_INPUT_VALUE_FILE = 'OPTION_INPUT_VALUE_FILE';
|
||||
OPTION_INPUT_VALUE_DIRECTORY = 'OPTION_INPUT_VALUE_DIRECTORY';
|
||||
OPTION_INPUT_VALUE_DOUBLE_FILE_DEST = 'OPTION_INPUT_VALUE_DOUBLE_FILE_DEST';
|
||||
OPTION_INPUT_VALUE_DOUBLE_DIRECTORY_DEST = 'OPTION_INPUT_VALUE_DOUBLE_DIRECTORY_DEST';
|
||||
|
||||
PACKAGING_STATE_READY = 'PACKAGING_STATE_READY';
|
||||
PACKAGING_STATE_PACKAGING = 'PACKAGING_STATE_PACKAGING';
|
||||
PACKAGING_STATE_COMPLETE = 'PACKAGING_STATE_COMPLETE';
|
||||
2344
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/i18n.js
Normal file
2344
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/i18n.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
const importConfiguration = (configuration) => {
|
||||
// TODO Check for version to support older versions
|
||||
|
||||
// Re-init UI by clearing everything (copy the array first as it will be mutated during the iteration)
|
||||
[...configurationCleaners].forEach((cleaner) => cleaner());
|
||||
|
||||
if ('pyinstallerOptions' in configuration) {
|
||||
configuration.pyinstallerOptions.forEach(({ optionDest, value }) => {
|
||||
if (configurationSetters.hasOwnProperty(optionDest)) {
|
||||
configurationSetters[optionDest](value);
|
||||
} else {
|
||||
// TODO Warn user?
|
||||
// TODO noconfirm is expected to come here
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// setup nonPyinstallerOptions
|
||||
if ('nonPyinstallerOptions' in configuration) {
|
||||
if ('increaseRecursionLimit' in configuration.nonPyinstallerOptions) {
|
||||
recursionLimitToggle(configuration.nonPyinstallerOptions.increaseRecursionLimit);
|
||||
}
|
||||
if ('manualArguments' in configuration.nonPyinstallerOptions) {
|
||||
document.getElementById('raw-arguments').value = configuration.nonPyinstallerOptions.manualArguments;
|
||||
}
|
||||
if ('outputDirectory' in configuration.nonPyinstallerOptions) {
|
||||
document.getElementById('output-directory').value = configuration.nonPyinstallerOptions.outputDirectory;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _collectDataToExport = async () => {
|
||||
const nonPyinstallerConfiguration = getNonPyinstallerConfiguration();
|
||||
delete nonPyinstallerConfiguration.outputDirectory; // This does not need to be saved in the config
|
||||
|
||||
return {
|
||||
version: 'auto-py-to-exe-configuration_v1',
|
||||
pyinstallerOptions: await getCurrentConfiguration(true),
|
||||
nonPyinstallerOptions: nonPyinstallerConfiguration,
|
||||
};
|
||||
};
|
||||
|
||||
const onConfigurationImport = async () => {
|
||||
if (!(await isCommandDefault())) {
|
||||
const response = await displayModal(
|
||||
getTranslation('dynamic.modal.configModalTitle'),
|
||||
getTranslation('dynamic.modal.configModalDescription'),
|
||||
[
|
||||
getTranslation('dynamic.modal.configModalConfirmButton'),
|
||||
getTranslation('dynamic.modal.configModalCancelButton'),
|
||||
]
|
||||
);
|
||||
|
||||
if (response !== getTranslation('dynamic.modal.configModalConfirmButton')) return;
|
||||
}
|
||||
|
||||
const data = await eel.import_configuration()();
|
||||
if (data !== null) {
|
||||
importConfiguration(data);
|
||||
}
|
||||
};
|
||||
|
||||
const onConfigurationExport = async () => {
|
||||
const data = await _collectDataToExport();
|
||||
await eel.export_configuration(data)();
|
||||
};
|
||||
109
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/initialise.js
Normal file
109
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/initialise.js
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Handle the initialisation of the ui
|
||||
*/
|
||||
|
||||
let options = [];
|
||||
|
||||
let pathSeparator = '';
|
||||
|
||||
const buildUpOptions = (providedOptions) => {
|
||||
return providedOptions.map((option) => {
|
||||
const name = option.dest;
|
||||
|
||||
let placement = OPTION_SHOW;
|
||||
if (options_ignored.indexOf(name) !== -1) {
|
||||
placement = OPTION_IGNORED;
|
||||
} else if (options_static.indexOf(name) !== -1) {
|
||||
placement = OPTION_STATIC;
|
||||
} else if (options_overridden.indexOf(name) !== -1) {
|
||||
placement = OPTION_OVERRIDDEN;
|
||||
}
|
||||
|
||||
let inputType = OPTION_INPUT_TYPE_INPUT;
|
||||
if (option.nargs === 0) {
|
||||
inputType = OPTION_INPUT_TYPE_SWITCH;
|
||||
} else if (option.choices !== null) {
|
||||
inputType = OPTION_INPUT_TYPE_DROPDOWN;
|
||||
} else if (option.dest === 'datas' || option.dest === 'binaries') {
|
||||
inputType = OPTION_INPUT_TYPE_DOUBLE_MULTIPLE_INPUT;
|
||||
} else if (option.default !== null || option.dest === 'upx_exclude') {
|
||||
inputType = OPTION_INPUT_TYPE_MULTIPLE_INPUT;
|
||||
}
|
||||
|
||||
const allowedInputValues = [];
|
||||
if (options_inputTypeFile.indexOf(name) !== -1) {
|
||||
allowedInputValues.push(OPTION_INPUT_VALUE_FILE);
|
||||
}
|
||||
if (options_inputTypeDirectory.indexOf(name) !== -1) {
|
||||
allowedInputValues.push(OPTION_INPUT_VALUE_DIRECTORY);
|
||||
}
|
||||
if (options_inputTypeDoubleFileDest.indexOf(name) !== -1) {
|
||||
allowedInputValues.push(OPTION_INPUT_VALUE_DOUBLE_FILE_DEST);
|
||||
}
|
||||
if (options_inputTypeDoubleDirectoryDest.indexOf(name) !== -1) {
|
||||
allowedInputValues.push(OPTION_INPUT_VALUE_DOUBLE_DIRECTORY_DEST);
|
||||
}
|
||||
if (allowedInputValues.length === 0) {
|
||||
allowedInputValues.push(OPTION_INPUT_VALUE_TEXT);
|
||||
}
|
||||
|
||||
return {
|
||||
...option,
|
||||
placement,
|
||||
inputType,
|
||||
allowedInputValues,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Get initialisation data from the server and setup the ui
|
||||
window.addEventListener('load', async () => {
|
||||
// Get initialisation data from Python
|
||||
console.log('Getting initialisation data');
|
||||
const initialisationData = await eel.initialise()();
|
||||
console.log('Received initialisation data');
|
||||
options = buildUpOptions(initialisationData.options);
|
||||
pathSeparator = initialisationData.pathSeparator;
|
||||
|
||||
// Setup user's default color scheme
|
||||
setupTheme();
|
||||
|
||||
// Setup ui events (for static content) and setup initial state
|
||||
setupEvents();
|
||||
|
||||
// Setup language selection
|
||||
setupLanguageSelection();
|
||||
|
||||
// Setup advanced section (for dynamic content)
|
||||
constructAdvancedSection(options);
|
||||
|
||||
// Setup json config file is supplied
|
||||
if (initialisationData.suppliedUiConfiguration !== null) {
|
||||
importConfiguration(initialisationData.suppliedUiConfiguration);
|
||||
}
|
||||
|
||||
// Set the output directory to the default if it hasn't already been set by `initialisationData.suppliedUiConfiguration`
|
||||
if (document.getElementById('output-directory').value === '') {
|
||||
document.getElementById('output-directory').value = initialisationData.defaultOutputFolder;
|
||||
}
|
||||
|
||||
// If a file is provided, put it in the script location
|
||||
if (initialisationData.filename !== null) {
|
||||
configurationSetters['filenames'](initialisationData.filename);
|
||||
}
|
||||
|
||||
// Display any warnings provided
|
||||
setupWarnings(initialisationData.warnings);
|
||||
|
||||
// Update the current command when setup is complete
|
||||
await updateCurrentCommandDisplay();
|
||||
|
||||
// Try to translate to the default browser language
|
||||
translate(initialisationData.languageHint);
|
||||
|
||||
// If the server stops, close the UI
|
||||
window.eel._websocket.addEventListener('close', (e) => window.close());
|
||||
|
||||
console.log('Application initialised');
|
||||
document.getElementById('spinner-root').style.display = 'none';
|
||||
});
|
||||
462
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/interface.js
Normal file
462
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/interface.js
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
Handle visual events
|
||||
*/
|
||||
|
||||
// Expand a section (typically triggered by clicking on a section heading)
|
||||
const expandSection = (sectionName) => {
|
||||
const root = document.getElementById(`section-${sectionName}`);
|
||||
const chevron = root.querySelector('.header img');
|
||||
const content = root.querySelector(`.content`);
|
||||
|
||||
if (root.getAttribute('data-expanded') === null) {
|
||||
// Show the section
|
||||
chevron.style.transform = 'rotate(0deg)';
|
||||
content.style.display = 'block';
|
||||
root.setAttribute('data-expanded', '');
|
||||
} else {
|
||||
// Hide the section
|
||||
chevron.style.transform = 'rotate(180deg)';
|
||||
content.style.display = 'none';
|
||||
root.removeAttribute('data-expanded');
|
||||
}
|
||||
};
|
||||
|
||||
// Colour an input based on the "allowed" arguments. Returns whether the field is valid or not
|
||||
const colourInput = async (inputNode, allowedToBeEmpty, allowedToBeFile, allowedToBeADirectory) => {
|
||||
const { value } = inputNode;
|
||||
if (
|
||||
(allowedToBeEmpty && value === '') ||
|
||||
(!allowedToBeEmpty && value !== '' && !allowedToBeFile && !allowedToBeADirectory) ||
|
||||
(allowedToBeFile && (await doesFileExist(value))) ||
|
||||
(allowedToBeADirectory && (await doesFolderExist(value)))
|
||||
) {
|
||||
inputNode.style.border = '';
|
||||
return true;
|
||||
} else {
|
||||
inputNode.style.border = '1px solid rgb(244, 67, 54)';
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const addDoubleInputForSrcDst = (
|
||||
parentNode,
|
||||
optionDest,
|
||||
source,
|
||||
destination,
|
||||
sourceCanBeFile,
|
||||
sourceCanBeDirectory
|
||||
) => {
|
||||
// Construct visible inputs
|
||||
const wrapper = document.createElement('div');
|
||||
parentNode.appendChild(wrapper);
|
||||
const sourceInput = document.createElement('input');
|
||||
wrapper.appendChild(sourceInput);
|
||||
const destinationInput = document.createElement('input');
|
||||
wrapper.appendChild(destinationInput);
|
||||
const removeButton = document.createElement('img');
|
||||
wrapper.appendChild(removeButton);
|
||||
|
||||
wrapper.classList.add('dual-value');
|
||||
|
||||
sourceInput.value = source;
|
||||
sourceInput.addEventListener('input', (event) => {
|
||||
colourInput(sourceInput, false, sourceCanBeFile, sourceCanBeDirectory);
|
||||
void updateCurrentCommandDisplay();
|
||||
});
|
||||
colourInput(sourceInput, false, sourceCanBeFile, sourceCanBeDirectory);
|
||||
|
||||
destinationInput.value = destination;
|
||||
destinationInput.addEventListener('input', (event) => {
|
||||
void updateCurrentCommandDisplay();
|
||||
});
|
||||
|
||||
// Add configurationGetter
|
||||
const configurationGetter = () => [optionDest, `${sourceInput.value}${pathSeparator}${destinationInput.value}`];
|
||||
configurationGetters.push(configurationGetter);
|
||||
|
||||
// Setup removal
|
||||
const onRemove = () => {
|
||||
wrapper.remove();
|
||||
const configurationGetterIndex = configurationGetters.indexOf(configurationGetter);
|
||||
configurationGetters.splice(configurationGetterIndex, 1);
|
||||
const configurationCleanerIndex = configurationCleaners.indexOf(onRemove);
|
||||
configurationCleaners.splice(configurationCleanerIndex, 1);
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
removeButton.src = 'img/remove.svg';
|
||||
removeButton.addEventListener('click', onRemove);
|
||||
configurationCleaners.push(onRemove);
|
||||
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
const _createSubSectionInAdvanced = (title, i18nPath, options) => {
|
||||
const parent = document.querySelector('#section-advanced .content');
|
||||
|
||||
// The div wrapping the whole section
|
||||
const subSectionNode = document.createElement('div');
|
||||
parent.appendChild(subSectionNode);
|
||||
|
||||
// Setup title
|
||||
const subSectionTitleNode = document.createElement('h3');
|
||||
subSectionTitleNode.textContent = title;
|
||||
subSectionTitleNode.classList.add('noselect');
|
||||
subSectionTitleNode.dataset.i18n = i18nPath;
|
||||
subSectionNode.appendChild(subSectionTitleNode);
|
||||
|
||||
// Setup options
|
||||
options.forEach((o) => {
|
||||
// Container for option
|
||||
const container = document.createElement('div');
|
||||
subSectionNode.appendChild(container);
|
||||
container.classList.add('option-container');
|
||||
|
||||
// Option title / name
|
||||
const optionNode = document.createElement('span');
|
||||
container.appendChild(optionNode);
|
||||
optionNode.textContent = chooseOptionString(o.option_strings);
|
||||
|
||||
// Help icon
|
||||
const helpNode = document.createElement('span');
|
||||
optionNode.appendChild(helpNode); // Put the icon inside the option text
|
||||
helpNode.title = o.help.replace(/R\|/, '');
|
||||
helpNode.classList.add('info_icon');
|
||||
|
||||
if (o.inputType === OPTION_INPUT_TYPE_SWITCH) {
|
||||
container.classList.add('switch');
|
||||
|
||||
// Add button (take note of the target argument state using `const`)
|
||||
const enableButton = document.createElement('button');
|
||||
container.appendChild(enableButton);
|
||||
if (o.const === true) {
|
||||
enableButton.dataset.i18n = 'dynamic.button.enable';
|
||||
} else if (o.const === false) {
|
||||
enableButton.dataset.i18n = 'dynamic.button.disable';
|
||||
} else {
|
||||
throw new Error('Unknown o.const value: ' + JSON.stringify(o));
|
||||
}
|
||||
enableButton.textContent = getTranslation(enableButton.dataset.i18n);
|
||||
enableButton.classList.add('unselected');
|
||||
|
||||
// Function used to set the value of the switch
|
||||
const setValue = (enabled) => {
|
||||
if (enabled) {
|
||||
enableButton.classList.remove('unselected');
|
||||
enableButton.classList.add('selected');
|
||||
} else {
|
||||
enableButton.classList.add('unselected');
|
||||
enableButton.classList.remove('selected');
|
||||
}
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
// When clicked, toggle the value
|
||||
enableButton.addEventListener('click', () => {
|
||||
setValue(!enableButton.classList.contains('selected'));
|
||||
});
|
||||
|
||||
// Add configurationGetter
|
||||
const configurationGetter = () => [o.dest, !enableButton.classList.contains('unselected')];
|
||||
configurationGetters.push(configurationGetter);
|
||||
|
||||
// Add configurationSetter
|
||||
configurationSetters[o.dest] = setValue;
|
||||
|
||||
// Add configurationCleaner
|
||||
configurationCleaners.push(() => setValue(false));
|
||||
|
||||
// Allow a default value of `true` to come through
|
||||
if (o.default === true) {
|
||||
setValue(true);
|
||||
}
|
||||
} else if (o.inputType === OPTION_INPUT_TYPE_DROPDOWN) {
|
||||
container.classList.add('choice');
|
||||
|
||||
// Add dropdown
|
||||
const selectNode = document.createElement('select');
|
||||
container.appendChild(selectNode);
|
||||
selectNode.addEventListener('change', (event) => {
|
||||
void updateCurrentCommandDisplay();
|
||||
});
|
||||
|
||||
// Add options (including default '')
|
||||
const defaultOptionNode = document.createElement('option');
|
||||
selectNode.appendChild(defaultOptionNode);
|
||||
defaultOptionNode.textContent = '';
|
||||
|
||||
const choices = Array.isArray(o.choices) ? o.choices : Object.keys(o.choices);
|
||||
choices.map((choice) => {
|
||||
const optionNode = document.createElement('option');
|
||||
selectNode.appendChild(optionNode);
|
||||
optionNode.textContent = choice;
|
||||
optionNode.value = choice;
|
||||
});
|
||||
|
||||
// Add configurationGetter
|
||||
const configurationGetter = () => {
|
||||
const value = selectNode.value;
|
||||
return value === '' ? null : [o.dest, value];
|
||||
};
|
||||
configurationGetters.push(configurationGetter);
|
||||
|
||||
// Add configurationSetter
|
||||
configurationSetters[o.dest] = (value) => {
|
||||
if (choices.indexOf(value) !== 1) {
|
||||
selectNode.value = value;
|
||||
} else {
|
||||
selectNode.value = '';
|
||||
}
|
||||
selectNode.dispatchEvent(new Event('change'));
|
||||
};
|
||||
|
||||
// Add configurationCleaner
|
||||
configurationCleaners.push(() => {
|
||||
selectNode.value = '';
|
||||
selectNode.dispatchEvent(new Event('change'));
|
||||
});
|
||||
} else if (o.inputType === OPTION_INPUT_TYPE_INPUT) {
|
||||
container.classList.add('input');
|
||||
|
||||
const isOptionFileBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_FILE) !== -1;
|
||||
const isOptionDirectoryBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_DIRECTORY) !== -1;
|
||||
|
||||
// Add input node
|
||||
const inputNode = document.createElement('input');
|
||||
container.appendChild(inputNode);
|
||||
inputNode.placeholder = o.metavar || 'VALUE';
|
||||
inputNode.addEventListener('input', (event) => {
|
||||
void updateCurrentCommandDisplay();
|
||||
|
||||
if (isOptionFileBased || isOptionDirectoryBased) {
|
||||
colourInput(inputNode, true, isOptionFileBased, isOptionDirectoryBased);
|
||||
}
|
||||
});
|
||||
|
||||
// Show browse button if required (only file or folder - not both)
|
||||
if (isOptionFileBased || isOptionDirectoryBased) {
|
||||
container.classList.add('with-browse');
|
||||
const searchButton = document.createElement('button');
|
||||
container.appendChild(searchButton);
|
||||
searchButton.dataset.i18n = isOptionFileBased
|
||||
? 'dynamic.button.browseForFile'
|
||||
: 'dynamic.button.browseForFolder';
|
||||
searchButton.textContent = getTranslation(searchButton.dataset.i18n);
|
||||
searchButton.addEventListener('click', async () => {
|
||||
const value = isOptionFileBased ? await askForFile(null) : await askForFolder();
|
||||
if (value !== null) {
|
||||
inputNode.value = value;
|
||||
inputNode.dispatchEvent(new Event('input'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add configurationGetter
|
||||
const configurationGetter = () => {
|
||||
const value = inputNode.value;
|
||||
return value === '' ? null : [o.dest, value];
|
||||
};
|
||||
configurationGetters.push(configurationGetter);
|
||||
|
||||
// Add configurationSetter
|
||||
configurationSetters[o.dest] = (value) => {
|
||||
inputNode.value = value;
|
||||
inputNode.dispatchEvent(new Event('input'));
|
||||
};
|
||||
|
||||
// Add configurationCleaner
|
||||
configurationCleaners.push(() => {
|
||||
inputNode.value = '';
|
||||
inputNode.dispatchEvent(new Event('input'));
|
||||
});
|
||||
} else if (o.inputType === OPTION_INPUT_TYPE_MULTIPLE_INPUT) {
|
||||
container.classList.add('multiple-input');
|
||||
|
||||
const isOptionFileBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_FILE) !== -1;
|
||||
const isOptionDirectoryBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_DIRECTORY) !== -1;
|
||||
|
||||
// Add button to add an entry
|
||||
const addButton = document.createElement('img');
|
||||
container.appendChild(addButton);
|
||||
addButton.src = 'img/plus.svg';
|
||||
|
||||
// Container to hold the values
|
||||
const valuesContainer = document.createElement('div');
|
||||
container.appendChild(valuesContainer);
|
||||
|
||||
const addValue = (value) => {
|
||||
// Container to hold the pair
|
||||
const valueContainer = document.createElement('div');
|
||||
valuesContainer.appendChild(valueContainer);
|
||||
|
||||
// Value input
|
||||
const inputNode = document.createElement('input');
|
||||
valueContainer.appendChild(inputNode);
|
||||
inputNode.value = value;
|
||||
inputNode.placeholder = o.metavar || 'VALUE';
|
||||
colourInput(inputNode, false, isOptionFileBased, isOptionDirectoryBased);
|
||||
inputNode.addEventListener('input', (event) => {
|
||||
colourInput(inputNode, false, isOptionFileBased, isOptionDirectoryBased);
|
||||
void updateCurrentCommandDisplay();
|
||||
});
|
||||
|
||||
// Add configurationGetter
|
||||
const configurationGetter = () => [o.dest, inputNode.value];
|
||||
configurationGetters.push(configurationGetter);
|
||||
|
||||
// Remove button
|
||||
const removeButtonNode = document.createElement('img');
|
||||
removeButtonNode.src = 'img/remove.svg';
|
||||
valueContainer.appendChild(removeButtonNode);
|
||||
const onRemove = () => {
|
||||
valueContainer.remove();
|
||||
const configurationGetterIndex = configurationGetters.indexOf(configurationGetter);
|
||||
configurationGetters.splice(configurationGetterIndex, 1);
|
||||
const configurationCleanerIndex = configurationCleaners.indexOf(onRemove);
|
||||
configurationCleaners.splice(configurationCleanerIndex, 1);
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
removeButtonNode.addEventListener('click', onRemove);
|
||||
|
||||
// Add configurationCleaner
|
||||
configurationCleaners.push(onRemove);
|
||||
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
// Event to add a new input pair
|
||||
addButton.addEventListener('click', async () => {
|
||||
// Get initial value
|
||||
let initialValue = '';
|
||||
if (isOptionFileBased || isOptionDirectoryBased) {
|
||||
initialValue = isOptionFileBased ? await askForFile(null) : await askForFolder();
|
||||
if (initialValue === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
addValue(initialValue);
|
||||
});
|
||||
|
||||
// Add configurationSetter
|
||||
configurationSetters[o.dest] = (value) => {
|
||||
addValue(value);
|
||||
};
|
||||
} else if (o.inputType === OPTION_INPUT_TYPE_DOUBLE_MULTIPLE_INPUT) {
|
||||
container.classList.add('multiple-input');
|
||||
|
||||
const isOptionFileBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_DOUBLE_FILE_DEST) !== -1;
|
||||
const isOptionDirectoryBased = o.allowedInputValues.indexOf(OPTION_INPUT_VALUE_DOUBLE_DIRECTORY_DEST) !== -1;
|
||||
|
||||
// Add button to add an entry
|
||||
const addButton = document.createElement('img');
|
||||
container.appendChild(addButton);
|
||||
addButton.src = 'img/plus.svg';
|
||||
|
||||
// Container to hold the value pairs
|
||||
const valuesContainer = document.createElement('div');
|
||||
container.appendChild(valuesContainer);
|
||||
|
||||
addButton.addEventListener('click', async () => {
|
||||
// Get initial value
|
||||
let initialValue = '';
|
||||
if (isOptionFileBased || isOptionDirectoryBased) {
|
||||
initialValue = isOptionFileBased ? await askForFile(null) : await askForFolder();
|
||||
if (initialValue === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addDoubleInputForSrcDst(valuesContainer, o.dest, initialValue, '.', true, false);
|
||||
});
|
||||
|
||||
// Add configurationSetter
|
||||
configurationSetters[o.dest] = (value) => {
|
||||
const [val1, val2] = value.split(pathSeparator);
|
||||
addDoubleInputForSrcDst(valuesContainer, o.dest, val1, val2, true, false);
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const constructAdvancedSection = () => {
|
||||
// Setup pre-defined sections
|
||||
advancedSections.forEach((section) =>
|
||||
_createSubSectionInAdvanced(
|
||||
getTranslation(section.titleI18nPath),
|
||||
section.titleI18nPath,
|
||||
options.filter((o) => section.options.indexOf(o.dest) !== -1)
|
||||
)
|
||||
);
|
||||
|
||||
// Setup extra arguments
|
||||
const usedSectionOptions = flatMap(advancedSections.map((s) => s.options));
|
||||
const extraOptions = options.filter(
|
||||
(option) =>
|
||||
usedSectionOptions.indexOf(option.dest) === -1 &&
|
||||
option.placement !== OPTION_IGNORED &&
|
||||
option.placement !== OPTION_STATIC &&
|
||||
option.placement !== OPTION_OVERRIDDEN
|
||||
);
|
||||
if (extraOptions.length > 0) {
|
||||
_createSubSectionInAdvanced(getTranslation('dynamic.title.other'), 'dynamic.title.other', extraOptions);
|
||||
}
|
||||
};
|
||||
|
||||
const setupWarnings = (warnings) => {
|
||||
if (warnings.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const warningsRootNode = document.getElementById('warnings');
|
||||
|
||||
warnings.forEach((warningContent) => {
|
||||
// Create wrapper
|
||||
const wrapperNode = document.createElement('div');
|
||||
warningsRootNode.appendChild(wrapperNode);
|
||||
|
||||
// Create message
|
||||
const messageNode = document.createElement('p');
|
||||
wrapperNode.appendChild(messageNode);
|
||||
messageNode.innerHTML = warningContent;
|
||||
});
|
||||
};
|
||||
|
||||
const setupLanguageSelection = () => {
|
||||
const languageSelectNode = document.getElementById('language-selection');
|
||||
languageSelectNode.addEventListener('change', (event) => {
|
||||
translate(event.target.value);
|
||||
});
|
||||
supportedLanguages.forEach((language) => {
|
||||
const option = document.createElement('option');
|
||||
option.innerText = language.name;
|
||||
option.value = language.code;
|
||||
languageSelectNode.appendChild(option);
|
||||
});
|
||||
languageSelectNode.value = currentLanguage;
|
||||
};
|
||||
|
||||
// Toggle theme (triggered by clicking moon or sun)
|
||||
const _toggleTheme = () => {
|
||||
const root = document.querySelector('body');
|
||||
const onDarkThemeButton = document.querySelector('#on-dark-theme-button');
|
||||
const onLightThemeButton = document.querySelector('#on-light-theme-button');
|
||||
|
||||
if (root.classList.contains('dark-theme')) {
|
||||
onLightThemeButton.style.display = 'inline';
|
||||
onDarkThemeButton.style.display = 'none';
|
||||
} else {
|
||||
// dark
|
||||
onLightThemeButton.style.display = 'none';
|
||||
onDarkThemeButton.style.display = 'inline';
|
||||
}
|
||||
|
||||
root.classList.toggle('dark-theme');
|
||||
};
|
||||
|
||||
// Check if user's default color scheme is dark
|
||||
const setupTheme = () => {
|
||||
document.getElementById('theme-toggle').addEventListener('click', _toggleTheme);
|
||||
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
_toggleTheme();
|
||||
}
|
||||
};
|
||||
19
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/messages.js
Normal file
19
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/messages.js
Normal file
@@ -0,0 +1,19 @@
|
||||
eel.expose(putMessageInOutput);
|
||||
function putMessageInOutput(message) {
|
||||
const outputNode = document.querySelector('#output textarea');
|
||||
outputNode.value += message; // Add the message
|
||||
if (!message.endsWith('\n')) {
|
||||
outputNode.value += '\n'; // If there was no new line, add one
|
||||
}
|
||||
|
||||
// Set the correct height to fit all the output and then scroll to the bottom
|
||||
outputNode.style.height = 'auto';
|
||||
outputNode.style.height = outputNode.scrollHeight + 10 + 'px';
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
}
|
||||
|
||||
eel.expose(signalPackagingComplete);
|
||||
function signalPackagingComplete(successful) {
|
||||
setPackagingComplete(successful);
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
}
|
||||
105
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/modal.js
Normal file
105
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/modal.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Renders the native JS modal over the window.
|
||||
* Returns selected option from **buttonOptions** list.
|
||||
*
|
||||
* Input:
|
||||
* - title: string
|
||||
* - description: string
|
||||
* - [optional] buttonOptions: string[] = ['Yes', 'No']
|
||||
* - [optional]: closeEvent: string = 'Close'
|
||||
*
|
||||
* Returns:
|
||||
* - Promise<string>
|
||||
*/
|
||||
const displayModal = (title, description, buttonOptions = ['Yes', 'No'], closeEvent = 'Close') => {
|
||||
const buildHeader = (_title) => {
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('modal-section', 'modal-header');
|
||||
|
||||
const closeButton = document.createElement('span');
|
||||
closeButton.classList.add('close-btn');
|
||||
closeButton.innerHTML = '×';
|
||||
header.appendChild(closeButton);
|
||||
|
||||
const titleElement = document.createElement('h2');
|
||||
titleElement.innerText = _title;
|
||||
header.appendChild(titleElement);
|
||||
|
||||
return {
|
||||
header: header,
|
||||
closeButton: closeButton,
|
||||
};
|
||||
};
|
||||
|
||||
const buildBody = (_description) => {
|
||||
const modalBody = document.createElement('div');
|
||||
modalBody.classList.add('modal-section');
|
||||
|
||||
const descriptionElement = document.createElement('a');
|
||||
descriptionElement.innerText = _description;
|
||||
modalBody.appendChild(descriptionElement);
|
||||
|
||||
return {
|
||||
body: modalBody,
|
||||
};
|
||||
};
|
||||
|
||||
const buildFooter = () => {
|
||||
const footerButtons = [];
|
||||
const footer = document.createElement('div');
|
||||
footer.classList.add('modal-section', 'modal-footer');
|
||||
|
||||
for (const label of buttonOptions) {
|
||||
const footerButton = document.createElement('button');
|
||||
footerButton.classList.add('modal-btn');
|
||||
footerButton.innerText = label;
|
||||
footer.appendChild(footerButton);
|
||||
footerButtons.push(footerButton);
|
||||
}
|
||||
|
||||
return {
|
||||
footer: footer,
|
||||
footerButtons: footerButtons,
|
||||
};
|
||||
};
|
||||
|
||||
const modalArea = document.getElementById('modal-area');
|
||||
modalArea.classList.remove('modal-coverage-hidden');
|
||||
|
||||
const headerElement = buildHeader(title);
|
||||
const bodyElement = buildBody(description);
|
||||
const footerElement = buildFooter();
|
||||
const footerButtons = footerElement.footerButtons;
|
||||
|
||||
const clearEventListeners = () => {
|
||||
headerElement.closeButton.removeEventListener('click', (_) => {});
|
||||
footerButtons.forEach((button) => button.removeEventListener('click', (_) => {}));
|
||||
};
|
||||
|
||||
const modalContent = document.createElement('div');
|
||||
modalContent.classList.add('modal-content');
|
||||
|
||||
modalContent.appendChild(headerElement.header);
|
||||
modalContent.appendChild(bodyElement.body);
|
||||
modalContent.appendChild(footerElement.footer);
|
||||
|
||||
modalArea.appendChild(modalContent);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
headerElement.closeButton.addEventListener('click', (_) => {
|
||||
clearEventListeners();
|
||||
modalArea.removeChild(modalContent);
|
||||
modalArea.classList.add('modal-coverage-hidden');
|
||||
resolve(closeEvent);
|
||||
});
|
||||
|
||||
for (const [label, button] of zip(buttonOptions, footerButtons)) {
|
||||
button.addEventListener('click', (_) => {
|
||||
clearEventListeners();
|
||||
modalArea.removeChild(modalContent);
|
||||
modalArea.classList.add('modal-coverage-hidden');
|
||||
resolve(label);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
let packagingState = PACKAGING_STATE_READY;
|
||||
|
||||
const setPackagingState = (newState) => {
|
||||
packagingState = newState;
|
||||
|
||||
const outputSectionNode = document.getElementById('output');
|
||||
const outputTextAreaNode = outputSectionNode.querySelector('textarea');
|
||||
const convertButtonNode = document.getElementById('package-button');
|
||||
const openOutputButtonNode = document.getElementById('open-output-folder-button');
|
||||
const commonIssueLinkNode = document.getElementById('common-issue-link');
|
||||
|
||||
switch (newState) {
|
||||
case PACKAGING_STATE_READY:
|
||||
// Clear output
|
||||
outputSectionNode.classList.remove('show');
|
||||
outputTextAreaNode.value = '';
|
||||
outputTextAreaNode.rows = 0;
|
||||
outputTextAreaNode.classList.remove('failure');
|
||||
// Set the main button back to initial value
|
||||
convertButtonNode.dataset.i18n = 'ui.button.convert';
|
||||
convertButtonNode.innerHTML = getTranslation(convertButtonNode.dataset.i18n);
|
||||
// Hide open folder button
|
||||
openOutputButtonNode.classList.remove('show');
|
||||
// Hide common issue link
|
||||
commonIssueLinkNode.classList.remove('show');
|
||||
return;
|
||||
case PACKAGING_STATE_PACKAGING:
|
||||
// Disable convert button
|
||||
convertButtonNode.disabled = true;
|
||||
convertButtonNode.dataset.i18n = 'dynamic.button.converting';
|
||||
convertButtonNode.innerHTML = getTranslation(convertButtonNode.dataset.i18n);
|
||||
// Show output
|
||||
outputSectionNode.classList.add('show');
|
||||
return;
|
||||
case PACKAGING_STATE_COMPLETE:
|
||||
// Re-enable convert button and re-purpose it
|
||||
convertButtonNode.disabled = false;
|
||||
convertButtonNode.dataset.i18n = 'dynamic.button.clearOutput';
|
||||
convertButtonNode.innerHTML = getTranslation(convertButtonNode.dataset.i18n);
|
||||
// Show open folder button (beside "Clear Output" button)
|
||||
openOutputButtonNode.classList.add('show');
|
||||
// Show common issue link
|
||||
commonIssueLinkNode.classList.add('show');
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const startPackaging = async () => {
|
||||
eel.package(await getCurrentCommand(), getNonPyinstallerConfiguration())();
|
||||
setPackagingState(PACKAGING_STATE_PACKAGING);
|
||||
};
|
||||
|
||||
const setPackagingComplete = (successful) => {
|
||||
setPackagingState(PACKAGING_STATE_COMPLETE);
|
||||
|
||||
// Show red border around output on failure
|
||||
if (!successful) {
|
||||
const outputTextAreaNode = document.querySelector('#output textarea');
|
||||
outputTextAreaNode.classList.add('failure');
|
||||
}
|
||||
};
|
||||
261
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/staticEvents.js
Normal file
261
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/staticEvents.js
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
Handle user events
|
||||
*/
|
||||
|
||||
// Top level inputs
|
||||
|
||||
const scriptLocationChange = async (event) => {
|
||||
colourInput(event.target, false, true, false);
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
const scriptLocationSearch = async (event) => {
|
||||
const entryScriptNode = document.getElementById('entry-script');
|
||||
const value = await askForFile('python');
|
||||
if (value !== null) {
|
||||
entryScriptNode.value = value;
|
||||
await scriptLocationChange({ target: entryScriptNode });
|
||||
}
|
||||
};
|
||||
|
||||
const oneFileOptionChange = (option) => (event) => {
|
||||
const onefileAdditionalFilesNote = document.getElementById('onefileAdditionalFilesNote');
|
||||
onefileAdditionalFilesNote.style.display = option === 'one-file' ? 'block' : 'none'; // Show the note if one-file is being used
|
||||
const oneFileButton = document.getElementById('one-file-button');
|
||||
oneFileButton.classList.add(option === 'one-file' ? 'selected' : 'unselected');
|
||||
oneFileButton.classList.remove(option !== 'one-file' ? 'selected' : 'unselected');
|
||||
const oneDirectoryButton = document.getElementById('one-directory-button');
|
||||
oneDirectoryButton.classList.add(option === 'one-directory' ? 'selected' : 'unselected');
|
||||
oneDirectoryButton.classList.remove(option !== 'one-directory' ? 'selected' : 'unselected');
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
const consoleWindowOptionChange = (option) => (event) => {
|
||||
const consoleButton = document.getElementById('console-based-button');
|
||||
consoleButton.classList.add(option === 'console' ? 'selected' : 'unselected');
|
||||
consoleButton.classList.remove(option !== 'console' ? 'selected' : 'unselected');
|
||||
const windowButton = document.getElementById('window-based-button');
|
||||
windowButton.classList.add(option === 'window' ? 'selected' : 'unselected');
|
||||
windowButton.classList.remove(option !== 'window' ? 'selected' : 'unselected');
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
const iconLocationChange = async (event) => {
|
||||
const valid = await colourInput(event.target, true, true, false);
|
||||
void updateCurrentCommandDisplay();
|
||||
|
||||
// If valid and a value exists, show the message if the file is not an ico file
|
||||
const warningElement = document.getElementById('icon-invalid-warning');
|
||||
if (valid && event.target.value !== '') {
|
||||
const isIcoFile = await isFileAnIco(event.target.value);
|
||||
warningElement.style.display = isIcoFile === false ? 'block' : 'none'; // isIcoFile is boolean | null
|
||||
} else {
|
||||
warningElement.style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
const iconLocationSearch = async (event) => {
|
||||
const iconPathNode = document.getElementById('icon-path');
|
||||
const value = await askForFile('icon');
|
||||
if (value !== null) {
|
||||
iconPathNode.value = value;
|
||||
await iconLocationChange({ target: iconPathNode });
|
||||
}
|
||||
};
|
||||
|
||||
const additionalFilesAddFiles = async (event) => {
|
||||
const files = await askForFiles();
|
||||
if (files !== null) {
|
||||
const datasListNode = document.getElementById('datas-list');
|
||||
files.forEach((file) => {
|
||||
addDoubleInputForSrcDst(datasListNode, 'datas', file, '.', true, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const additionalFilesAddFolder = async (event) => {
|
||||
const folder = await askForFolder();
|
||||
if (folder !== '') {
|
||||
const datasListNode = document.getElementById('datas-list');
|
||||
const destinationFolder = folder.split(/[/\\]/);
|
||||
addDoubleInputForSrcDst(
|
||||
datasListNode,
|
||||
'datas',
|
||||
folder,
|
||||
`${destinationFolder[destinationFolder.length - 1]}/`,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const additionalFilesAddBlank = (event) => {
|
||||
const datasListNode = document.getElementById('datas-list');
|
||||
addDoubleInputForSrcDst(datasListNode, 'datas', '', '.', true, true);
|
||||
};
|
||||
|
||||
// Settings section events
|
||||
|
||||
const outputDirectorySearch = async (event) => {
|
||||
const folder = await askForFolder();
|
||||
if (folder !== '') {
|
||||
const outputDirectoryInput = document.getElementById('output-directory');
|
||||
outputDirectoryInput.value = folder;
|
||||
}
|
||||
};
|
||||
|
||||
const recursionLimitToggle = (enabled) => {
|
||||
const button = document.getElementById('recursion-limit-switch');
|
||||
if (enabled) {
|
||||
button.classList.add('selected');
|
||||
button.classList.remove('unselected');
|
||||
} else {
|
||||
button.classList.remove('selected');
|
||||
button.classList.add('unselected');
|
||||
}
|
||||
};
|
||||
|
||||
const rawArgumentsChange = (event) => {
|
||||
void updateCurrentCommandDisplay();
|
||||
};
|
||||
|
||||
const packageScript = async (event) => {
|
||||
if (packagingState === PACKAGING_STATE_PACKAGING) {
|
||||
// Do not do anything while packaging
|
||||
return;
|
||||
}
|
||||
if (packagingState === PACKAGING_STATE_COMPLETE) {
|
||||
// This is now the clear output button
|
||||
setPackagingState(PACKAGING_STATE_READY);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre-checks
|
||||
const currentConfiguration = await getCurrentConfiguration();
|
||||
const entryScript = currentConfiguration.find((c) => c.optionDest === 'filenames').value;
|
||||
|
||||
if (entryScript === '') {
|
||||
alert(getTranslation('nonDom.alert.noScriptsLocationProvided'));
|
||||
return;
|
||||
}
|
||||
|
||||
const willOverwrite = await eel.will_packaging_overwrite_existing(
|
||||
entryScript,
|
||||
currentConfiguration.find((c) => c.optionDest === 'name')?.value,
|
||||
currentConfiguration.find((c) => c.optionDest === 'onefile').value,
|
||||
getNonPyinstallerConfiguration().outputDirectory
|
||||
)();
|
||||
if (willOverwrite && !confirm(getTranslation('nonDom.alert.overwritePreviousOutput'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If checks have passed, package the script
|
||||
await startPackaging();
|
||||
};
|
||||
|
||||
const openOutputFolder = async (event) => {
|
||||
const currentConfiguration = await getCurrentConfiguration();
|
||||
const entryScript = currentConfiguration.find((c) => c.optionDest === 'filenames').value;
|
||||
const isOneFile = currentConfiguration.find((c) => c.optionDest === 'onefile').value;
|
||||
eel.open_output_in_explorer(getNonPyinstallerConfiguration().outputDirectory, entryScript, isOneFile)();
|
||||
};
|
||||
|
||||
const setupEvents = () => {
|
||||
// Script location
|
||||
document.getElementById('entry-script').addEventListener('input', scriptLocationChange);
|
||||
document.getElementById('entry-script-search').addEventListener('click', scriptLocationSearch);
|
||||
|
||||
// Output bundle type
|
||||
document.getElementById('one-directory-button').addEventListener('click', oneFileOptionChange('one-directory'));
|
||||
document.getElementById('one-file-button').addEventListener('click', oneFileOptionChange('one-file'));
|
||||
|
||||
// Console switch
|
||||
document.getElementById('console-based-button').addEventListener('click', consoleWindowOptionChange('console'));
|
||||
document.getElementById('window-based-button').addEventListener('click', consoleWindowOptionChange('window'));
|
||||
|
||||
// Icon
|
||||
document.getElementById('icon-path').addEventListener('input', iconLocationChange);
|
||||
document.getElementById('icon-path-search').addEventListener('click', iconLocationSearch);
|
||||
|
||||
// Additional files
|
||||
document.getElementById('additional-files-add-files-button').addEventListener('click', additionalFilesAddFiles);
|
||||
document.getElementById('additional-files-add-folder').addEventListener('click', additionalFilesAddFolder);
|
||||
document.getElementById('additional-files-add-blank').addEventListener('click', additionalFilesAddBlank);
|
||||
|
||||
// Settings
|
||||
document.getElementById('output-directory-search').addEventListener('click', outputDirectorySearch);
|
||||
document
|
||||
.getElementById('recursion-limit-switch')
|
||||
.addEventListener('click', (e) => recursionLimitToggle(e.target.classList.contains('unselected')));
|
||||
document.getElementById('raw-arguments').addEventListener('input', rawArgumentsChange);
|
||||
document.getElementById('configuration-import').addEventListener('click', () => onConfigurationImport());
|
||||
document.getElementById('configuration-export').addEventListener('click', () => onConfigurationExport());
|
||||
|
||||
// Build buttons
|
||||
document.getElementById('package-button').addEventListener('click', packageScript);
|
||||
document.getElementById('open-output-folder-button').addEventListener('click', openOutputFolder);
|
||||
|
||||
// Add configurationGetters
|
||||
const getEntryScript = () => ['filenames', document.getElementById('entry-script').value];
|
||||
const getOnefile = () => [
|
||||
'onefile',
|
||||
document.getElementById('one-directory-button').classList.contains('unselected'),
|
||||
];
|
||||
const getConsole = () => ['console', document.getElementById('window-based-button').classList.contains('unselected')];
|
||||
const getIcon = () => {
|
||||
const path = document.getElementById('icon-path').value;
|
||||
return path === '' ? null : ['icon_file', path];
|
||||
};
|
||||
configurationGetters.push(getEntryScript);
|
||||
configurationGetters.push(getOnefile);
|
||||
configurationGetters.push(getConsole);
|
||||
configurationGetters.push(getIcon);
|
||||
|
||||
// Add configurationSetters
|
||||
const setEntryScript = (value) => {
|
||||
document.getElementById('entry-script').value = value;
|
||||
scriptLocationChange({ target: document.getElementById('entry-script') });
|
||||
};
|
||||
const setOnefile = (value) => {
|
||||
if (value) {
|
||||
document.getElementById('one-directory-button').classList.add('unselected');
|
||||
document.getElementById('one-file-button').classList.remove('unselected');
|
||||
} else {
|
||||
document.getElementById('one-directory-button').classList.remove('unselected');
|
||||
document.getElementById('one-file-button').classList.add('unselected');
|
||||
}
|
||||
};
|
||||
const setConsole = (value) => {
|
||||
if (value) {
|
||||
document.getElementById('console-based-button').classList.remove('unselected');
|
||||
document.getElementById('window-based-button').classList.add('unselected');
|
||||
} else {
|
||||
document.getElementById('console-based-button').classList.add('unselected');
|
||||
document.getElementById('window-based-button').classList.remove('unselected');
|
||||
}
|
||||
};
|
||||
const setAdditionalFile = (value) => {
|
||||
const datasListNode = document.getElementById('datas-list');
|
||||
const [val1, val2] = value.split(pathSeparator);
|
||||
addDoubleInputForSrcDst(datasListNode, 'datas', val1, val2, true, true);
|
||||
};
|
||||
const setIcon = (value) => {
|
||||
document.getElementById('icon-path').value = value;
|
||||
document.getElementById('icon-path').dispatchEvent(new Event('input'));
|
||||
};
|
||||
configurationSetters['filenames'] = setEntryScript;
|
||||
configurationSetters['onefile'] = setOnefile;
|
||||
configurationSetters['console'] = setConsole;
|
||||
configurationSetters['datas'] = setAdditionalFile;
|
||||
configurationSetters['icon_file'] = setIcon;
|
||||
|
||||
configurationCleaners.push(() => setEntryScript('')); // filenames
|
||||
configurationCleaners.push(() => setOnefile(false)); // onefile
|
||||
configurationCleaners.push(() => setConsole(true)); // console
|
||||
configurationCleaners.push(() => setIcon('')); // icon_file
|
||||
|
||||
// Soft initialise (to trigger any required initial events)
|
||||
setEntryScript('');
|
||||
setOnefile(false);
|
||||
setConsole(true);
|
||||
};
|
||||
50
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/utils.js
Normal file
50
venv3_12/Lib/site-packages/auto_py_to_exe/web/js/utils.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Util functions
|
||||
*/
|
||||
|
||||
const flatMap = (xs) => xs.reduce((x, y) => x.concat(y), []); // Not all browsers have Array.flatMap
|
||||
|
||||
/*
|
||||
* Equivalent of Python zip(*args) function. Usage:
|
||||
*
|
||||
* for (let [var1, ..., varN] of zip(arr1, ..., arrN)) {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
const zip = (...arrays) => [...arrays[0]].map((_, index) => arrays.map((arr) => arr[index]));
|
||||
|
||||
const doesFileExist = async (path) => {
|
||||
return await eel.does_file_exist(path)();
|
||||
};
|
||||
|
||||
const doesFolderExist = async (path) => {
|
||||
return await eel.does_folder_exist(path)();
|
||||
};
|
||||
|
||||
const askForFile = async (fileType) => {
|
||||
return await eel.ask_file(fileType)();
|
||||
};
|
||||
|
||||
const askForFiles = async () => {
|
||||
return await eel.ask_files()();
|
||||
};
|
||||
|
||||
const askForFolder = async () => {
|
||||
return await eel.ask_folder()();
|
||||
};
|
||||
|
||||
const isFileAnIco = async (file_path) => {
|
||||
return await eel.is_file_an_ico(file_path)();
|
||||
};
|
||||
|
||||
const convertPathToAbsolute = async (path) => {
|
||||
return await eel.convert_path_to_absolute(path)();
|
||||
};
|
||||
|
||||
const chooseOptionString = (optionStrings) => {
|
||||
// Try not to use compressed flags
|
||||
if (optionStrings[0].length === 2 && optionStrings.length > 1) {
|
||||
return optionStrings[1];
|
||||
}
|
||||
return optionStrings[0];
|
||||
};
|
||||
Reference in New Issue
Block a user