This commit is contained in:
2020-09-10 17:03:24 +02:00
Unverified
43 changed files with 1062 additions and 880 deletions

11
.idea/GeneratorCSV.iml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.8 (Zadanie 4)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (Zadanie 4)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/GeneratorCSV.iml" filepath="$PROJECT_DIR$/.idea/GeneratorCSV.iml" />
</modules>
</component>
</project>

112
.idea/workspace.xml generated
View File

@@ -1,112 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="f2c161d8-ce90-4812-beb4-a44c9013c541" name="Default Changelist" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="ProjectId" id="1UCu6ZWXUKDrAFKKgXFMJB1R5q3" />
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.generator">
<configuration name="generator" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="GeneratorCSV" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/generator.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="GeneratorCSV" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/test.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.generator" />
<item itemvalue="Python.test" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f2c161d8-ce90-4812-beb4-a44c9013c541" name="Default Changelist" comment="" />
<created>1574872723273</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1574872723273</updated>
<workItem from="1574872724849" duration="19564000" />
<workItem from="1574945757291" duration="32858000" />
<workItem from="1575021304049" duration="1032000" />
<workItem from="1575022913504" duration="500000" />
<workItem from="1575031053599" duration="646000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/GeneratorCSV$test.coverage" NAME="test Coverage Results" MODIFIED="1574890328703" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/GeneratorCSV$generator.coverage" NAME="generator Coverage Results" MODIFIED="1575023380703" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
assets/tab-icons/about.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
assets/tab-icons/format.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

BIN
assets/tab-icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,21 +0,0 @@
1.0
- Pierwsza wersja programu składająca się z 4 części
2.0
- Podstawowy tekstowy interfejs
- Scalenie programu w jeden
- Aktualizacja formatu plików z danymi
- Wstępne przystosowanie do działania w czteroletnim liceum i w trzyletniej szkole branżowej
- Aktualizacja kodowania
3.0
- Wprowadzenie pełnego graficznego interfejsu w środowisku tkinter
- Wstępne obsługiwanie wyjątków
- Przeniesienie modułów do oddzielnego pliku
- Stworzenie pliku 'format.py' ze skryptem przetwarzającym dane - przystosowanie programu do ewentualnych zmian w formacie plików z danymi
- Przeniesienie ukrytych ustawień do pliku 'config.cfg'
3.0.1
- Poprawka błędu - pole 3 i 4 nie mają już przypisanej tej samej zmiennej tekstowej
- Przydzielenie wersji, autorów, tytułu programu i lat pracy do zmiennych globalnych środowiska graficznego

View File

@@ -1 +0,0 @@
Kodowanie: utf-8

12
configs/config.cfg Normal file
View File

@@ -0,0 +1,12 @@
secret(S) = entersecretstringhere
mailOutputCoding(Sc) = utf-8
officeOutputCoding(Sc) = utf-8
domain(S) = losobolew.pl
quota(I) = 500
country(S) = Rzeczypospolita Polska
schoolData(MSAs) = [LO, 4, 0]|[BS, 3, 1]
schoolyearStart(D) = 01.09.* *:*:*
ifHeadlineInMail(B) = 0
headlineInMail(S) = mailHeadline
ifHeadlineInOffice(B) = 0
headlineInOffice(S) = officeHeadline

152
configs/style.cfg Normal file
View File

@@ -0,0 +1,152 @@
windowWidth(I) = 1200
windowHeight(I) = 720
windowWidthResizable(B) = 0
windowHeightResizable(B) = 0
windowMainBG(C) = #21242D
mainIcon(P) = icon.ico
mainMenuBG(C) = #21242D
mainMenuPosition(FAposition) = wn
tabFramesBorderWidth(I) = 0
unselectedTabBG(C) = #21242D
menuTabsBorderWidth(I) = 0
menuTabsPadding(I) = 10
selectedTabBG(C) = #333842
disabledTabBG(C) = #333842
tabFrameBG(C) = #21242D
headerFont(F) = Segoe UI;15
headerBG(C) = #333842
headerTextColor(C) = #C0C0C0
headerPadding(I) = 10
headerTextAnchor(FAanchor) = center
contentTabFrameBG(C) = #21242D
layoutFrameBG(C) = #21242D
label1BG(C) = #21242D
label1TextColor(C) = #C0C0C0
label1Font(F) = Segoe UI;10
label2BG(C) = #21242D
label2TextColor(C) = #C0C0C0
label2Font(F) = Segoe UI;9
label3BG(C) = #21242D
label3TextColor(C) = #C0C0C0
label3Font(F) = Segoe UI;7
label4BG(C) = #21242D
label4TextColor(C) = #C0C0C0
label4Font(F) = Segoe UI;25
combobox1ArrowColor(C) = #C0C0C0
combobox1ButtonColor(C) = #333842
combobox1BorderColor(C) = #21242D
combobox1FieldBackground(C) = #333842
combobox1TextColor(C) = #C0C0C0
combobox1Relief(FArelief) = flat
combobox1BorderWidth(I) = 0
combobox1Padding(I) = 5
combobox1ListBoxBackground(C) = #333842
combobox1ListBoxForeground(C) = #C0C0C0
combobox1ListBoxSelectBackground(C) = #737373
combobox1ListBoxSelectForeground(C) = #FFFFFF
combobox2ArrowColor(C) = #C0C0C0
combobox2ButtonColor(C) = #333842
combobox2BorderColor(C) = #21242D
combobox2FieldBackground(C) = #333842
combobox2TextColor(C) = #C0C0C0
combobox2Relief(FArelief) = flat
combobox2BorderWidth(I) = 0
combobox2Padding(I) = 7
combobox2ListBoxBackground(C) = #333842
combobox2ListBoxForeground(C) = #C0C0C0
combobox2ListBoxSelectBackground(C) = #737373
combobox2ListBoxSelectForeground(C) = #FFFFFF
button1TextAnchor(FAanchor) = center
button1Background(C) = #333842
button1Foreground(C) = #C0C0C0
button1Padding(I) = 4
separator1BG(C) = #21242D
spinbox1ArrowColor(C) = #C0C0C0
spinbox1FieldBackground(C) = #333842
spinbox1Relief(FArelief) = flat
spinbox1BorderWidth(I) = 0
spinbox1TextColor(C) = #C0C0C0
spinbox1ButtonColor(C) = #333842
spinbox1Padding(I) = 7
entry1FieldBackground(C) = #333842
entry1Relief(FArelief) = flat
entry1BorderWidth(I) = 0
entry1Padding(I) = 7
entry1TextColor(C) = #C0C0C0
iconTabIcon(P) = assets/tab-icons/icon.png
tabIconsSize(I) = 30
generateTabIcon(P) = assets/tab-icons/generate.png
headerFill(FAfill) = x
tabFramePadding(I) = 10
contentTabFrameFill(FAfill) = both
contentTabFrameExpand(I) = 1
outsidelayoutFramesPadX(I) = 6
GIFFrameSeparators(I) = 16
generateFilesLabelWidth(I) = 15
generateFilesLabelAnchor(FAanchor) = center
generateInputFilesPadding(I) = 6
generateHorizontalSeparatorPadY(I) = 10
generateOutputFilesPadding(I) = 6
generateStartButtonPadding(I) = 10
generateStartButtonPadY(I) = 6
formatTabIcon(P) = assets/tab-icons/format.png
loadingListPadX(I) = 12
loadingButtonWidth(I) = 15
formatHorizontalSeparatorPadY(I) = 10
formatVerticalSeparatorPadY(I) = 10
EPOSTypeFramePadY(I) = 0
EPOSPersonSeparatorFramePadY(I) = 0
EPOSRowSeparatorFramePadY(I) = 0
EPOSDataSeparatorFramePadY(I) = 7
EPOSLabelWidth(I) = 30
EPOSLabelAnchor(FAanchor) = center
radiobutton1Background(C) = #21242D
radiobutton1TextColor(C) = #C0C0C0
radiobutton1IndicatorBackground(C) = #21242D
checkbutton1Background(C) = #21242D
checkbutton1TextColor(C) = #C0C0C0
checkbutton1IndicatorBackground(C) = #21242D
text1Background(C) = #333842
text1TextColor(C) = #C0C0C0
text1Relief(FArelief) = flat
EPDataLocalizationPadX(I) = 6
EPDataLocalizationPadY(I) = 6
editingPresetButtonsPadY(I) = 6
editingPresetSaveButtonWidth(I) = 25
editingPresetCancelButtonWidth(I) = 25
settingsTabIcon(P) = assets/tab-icons/settings.png
settingsHorizontalSeparatorPadY(I) = 10
settingsVerticalSeparatorPadY(I) = 10
settingsCodeLabelWidth(I) = 35
settingsCodeLabelAnchor(FAanchor) = w
settingsOtherLabelWidth(I) = 35
settingsOtherLabelAnchor(FAanchor) = w
settingsHeadlineLabelWidth(I) = 35
settingsHeadlineLabelAnchor(FAanchor) = w
settingsSchoolDataLabelAnchor(FAanchor) = center
settingsButtonsPadY(I) = 6
settingsButtonSaveWidth(I) = 20
settingsButtonCancelWidth(I) = 15
settingsButtonPDUOWidth(I) = 35
settingsButtonPDUWWidth(I) = 35
settingsButtonZPFWidth(I) = 35
aboutTabIcon(P) = assets/tab-icons/about.png
button2TextAnchor(FAanchor) = center
button2Background(C) = #21242D
button2Padding(I) = 0
aboutLogoButtonImg(P) = assets/icon.png
aboutLogoButtonImgSize(I) = 250
aboutInstructionButtonWidth(I) = 25
aboutOtherInfoFramePadX(I) = 10
ZPFWindowWidth(I) = 500
ZPFWindowHeight(I) = 400
ZPFWindowWidthResizable(B) = 0
ZPFWindowHeightResizable(B) = 0
ZPFWindowMainBG(C) = #21242D
listbox1BG(C) = #333842
listbox1TextColor(C) = #C0C0C0
listbox1Relief(FArelief) = flat
listbox1BorderWidth(I) = 0
listbox1ActiveStyle(FAactivestyle) = none
listbox1HighlightThickness(I) = 0
listbox1SelectBG(C) = #4F4F4F

View File

@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<p id = "about-program-image">
<br>
<br>
<br>
<br>
<img src = '../assets/documentation-page/about-program/icon.png'>
<br>
<br>
<br>
<br>
</p>
<h1>
Generator CSV
</h1>
<p id = "about-program-main-text">
Wersja 4.0 (Build 20254)
</p>
<p id = "about-program-text-centered">
<br>
© styczeń 2019 - wrzesień 2020<br>
<br>
Mateusz Skoczek<br>
<br>
dla ZSP Sobolew<br>
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<hr>
<br>
<h2>Historia wersji</h2>
<p id = 'about-program-changelog-main-version'>Wersja 1.0</p>
<br>
<ul>
<li>Pierwsza wersja programu składająca się z 4 części</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 2.0</p>
<br>
<ul>
<li>Podstawowy tekstowy interfejs</li>
<li>Scalenie programu w jeden</li>
<li>Aktualizacja formatu plików z danymi</li>
<li>Wstępne przystosowanie do działania w czteroletnim liceum i w trzyletniej szkole branżowej</li>
<li>Aktualizacja kodowania</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 3.0</p>
<br>
<ul>
<li>Wprowadzenie pełnego graficznego interfejsu w środowisku tkinter</li>
<li>Wstępne obsługiwanie wyjątków</li>
<li>Przeniesienie modułów do oddzielnego pliku</li>
<li>Stworzenie pliku 'format.py' ze skryptem przetwarzającym dane - przystosowanie programu do ewentualnych zmian w formacie plików z danymi</li>
<li>Przeniesienie ukrytych ustawień do pliku 'config.cfg'</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 3.0.1</p>
<br>
<ul>
<li>Poprawka błędu - pole 3 i 4 nie mają już przypisanej tej samej zmiennej tekstowej</li>
<li>Przydzielenie wersji, autorów, tytułu programu i lat pracy do zmiennych globalnych środowiska graficznego</li>
</ul>
<br>
<br>
<br>
<p id = 'about-program-changelog-main-version'>Wersja 4.0 (work in progress)</p>
<br>
<ul>
<li>Skompliowanie pliku programu do formatu .exe</li>
<li>Przeprojektowanie kodu programu</li>
<li>Nowy interfejs programu</li>
<li>Dodanie ustawień</li>
<li>Dodanie możliwości ręcznego zmieniania wyglądu programu</li>
<li>Wprowadzenie systemu format presetów zamiast pliku 'format.py'</li>
<li>Możliwość zmiany nazwy plików wyjściowych i uniezależnienie ich lokalizacji od siebie</li>
<li>Usunięcie konsoli w tle</li>
<li>Stworzenie strony w HTMLu zawierającej instrukcję, dokumentację, informacje o programie i changelog</li>
<li>Wiele innych mniejszych zmian</li>
</ul>
<br>
<br>
<br>
</body>
</html>

104
documentation/content.css Normal file
View File

@@ -0,0 +1,104 @@
h1 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 35px;
text-align: center;
}
h2 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 25px;
text-align: center;
}
h5 {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 15px;
}
p {
color: #C0C0C0;
font-family: 'Segoe UI';
}
#description-text {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
line-height: 25px;
text-align: center;
}
#description-image {
text-align: center;
}
#about-program-image {
text-align: center;
}
#about-program-main-text {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
line-height: 25px;
text-align: center;
}
#about-program-text-centered {
text-align: center;
}
#about-program-changelog-main-version {
color: #C0C0C0;
font-family: 'Segoe UI';
font-size: 17px;
font-weight: 600;
}
td {
color: #C0C0C0;
font-family: 'Segoe UI';
}
th {
color: #C0C0C0;
font-family: 'Segoe UI';
}
.accordion {
background-color: #333842;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
color: #C0C0C0;
font-size: 18px;
font-family: 'Segoe UI';
}
.active, .accordion:hover {
background-color: #3a3f4b;
}
.panel {
padding: 0 18px;
background-color: #2e313b;
display: none;
overflow: hidden;
}
li {
color: #C0C0C0;
font-family: 'Segoe UI';
}
code {
color: #C0C0C0;
font-size: large;
}

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<p id = "description-text">Program "Generator CSV" służy do przetwarzania plików danymi uczniów/nauczycieli i generowania plików wyjściowych w formacie pozwalającym na import danych na stronie szkoły oraz portal.office.com</p>
<br>
<br>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/generator-csv.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/format-danych.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/ustawienia.png'><br></p>
<p id = "description-image"><img width = '60%' src = '../assets/documentation-page/description/o-programie.png'><br></p>
</body>
</html>

30
documentation/index.html Normal file
View File

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "main.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<div id = "outer">
<header>
<img id = "header-image" src = "../assets/documentation-page/icon.png">
<div id = "header-text">
<p>GENERATOR CSV</p>
</div>
<nav>
<ul id = "menu-ul">
<li id = "menu-li"><a href = "description.html" target = "content">Opis</a></li>
<li id = "menu-li"><a href = "instruction.html" target = "content">Instrukcja</a></li>
<li id = "menu-li"><a href = "program_documentation.html" target = "content">Dokumentacja</a></li>
<li id = "menu-li"><a href = "about_program.html" target = "content">O programie</a></li>
</ul>
</nav>
</header>
<section>
<iframe name = "content" src = "description.html"></iframe>
</section>
</div>
</body>
</html>

View File

@@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<button class="accordion"><b>Tworzenie/edytowanie format presetu dla danego pliku źródłowego</b></button>
<div class="panel">
<p>Dane dla przykładu:</p>
<img src = '../assets/documentation-page/instruction/example-input-data.png'><br>
<p>W praktyce układ danych wygląda tak (* - nieznaczące dla programu dane):</p>
<p>[imię] [nazwisko]<br>[klasa] [szkoła]<br>[login], [haslo*]</p>
<p>Uruchom program i otwórz zakładkę FORMAT DANYCH. W pierwszej kolejności należy nadać nazwę presetowi formatu w polu zaznaczonym poniżej lub wybrać preset już istniejący z listy rozwijanej</p>
<img width = '700px' src = '../assets/documentation-page/instruction/input-name.png'><br>
<p> Aby przejśc do edycji presetu należy wcisnąć przycisk WCZYTAJ</p>
<br>
<h5>Typ osoby</h5>
<p>Wybierz odpowiednią opcję w zależności od tego jakich osób dane znajdują się w pliku wejściowym</p>
<h5>Separator pomiędzy danymi</h5>
<p>W tym polu należy wpisać znaki, które oddzielają zbiór danych pojeńczych osób. Jeżeli zbiór danych odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to "<u>&ltenter&gt&ltenter&gt</u>"</p>
<h5>Separator pomiędzy wierszami</h5>
<p>W tym polu należy wpisać znaki, które oddzielają wiersze. Zazwyczaj jest to jeden znak końca wiersza. Jeżeli wiersze odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to "<b>&ltenter&gt</b>"</p>
<h5>Separatory pomiędzy danymi</h5>
<p>W tym polu należy wpisać znaki, które oddzielają pojedyńcze dane. Każdy kolejny separator musi być zapisany w następnej linijce. Jeżeli dane odziela znak końca wiersza (wciśnięcie ENTER) należy wpisać &ltenter&gt (ilość zależna od ilości znaków końca wiersza). Niedozwolone znaki to litery, cyfry oraz * i \. Dla przykładowych danych będzie to (znaki są podkreślone aby je wyróżnić):<br>"""<br><u>,<br></u><br>"""</p>
<h5>Prawa kolumna - pozycja danych w zbiorze</h5>
<p>W tej sekcji należy dla każdego typu danych ustawić jego położenie w zbiorze. Typy SZKOŁA i KLASA nie są istotne jeżeli w sekcji TYP OSOBY zosła zaznaczona opcja Nauczyciele. Dla przykładowych danych uczniów bedzie to:</p>
<table>
<tr>
<th></th>
<th>Wiersz</th>
<th>Pozycja<br>w wierszu</th>
</tr>
<tr>
<td>Login</td>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>Imię</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>Nazwisko</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Szkoła</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>Klasa</td>
<td>2</td>
<td>1</td>
</tr>
</table>
<h5>Prawa kolumna - Kodowanie</h5>
<p>W tym polu należy wybrać kodowanie pliku wejściowego.</p>
<br>
<p><b>Aby zapisać preset należy wcisnąć przycisk ZAPISZ. Aby anulować tworzenie należy wcisnąć przycisk Anuluj</b></p>
</div>
<button class="accordion"><b>Edycja ustawień ogólnych</b></button>
<div class="panel">
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<br>
<h5>Kodowanie wyjściowe dla pliku poczty</h5>
<p>W tym polu należy wybrać kodowanie, w jakim ma być zapisany plik csv z danymi uczniów do importu w panelu administracyjnym serwisu szkoły</p>
<h5>Kodowanie wyjściowe dla pliku office</h5>
<p>W tym polu należy wybrać kodowanie, w jakim ma być zapisany plik csv z danymi uczniów do importu w panelu administracyjnym serwisu portal.office.com</p>
<h5>Domena (używana w mailu)</h5>
<p>W tym polu należy wpisać domenę serwisu szkoły. Będzie ona używana w mailu każdego uzytkownika. Przykład: jan.kowalski2023a@<b>losobolew.pl</b></p>
<h5>Quota (MB)</h5>
<p>W tym polu należy wpisać ilość miejsca (w megabajtach) przeznaczoną dla każdego użytkownika na przechowywanie maili. Te dane są używane w pliku wyjściowym poczty. Przykład: jan.kowalski2023a@losobolew.pl,1234567u:JK,<b>500</b></p>
<h5>Kraj (zapisany w danych na office)</h5>
<p>W tym polu należy wpisać nazwę kraju zamieszkania użytkowników. Będzie ona wykorzystywana w pliku wyjściowym office oraz widoczna w profilu użytkownika w serwisie office. Przykład: jan.kowalski2023a@losobolew.pl,Jan,Kowalski,Jan Kowalski,uczeń,1b LO,,,,,,,,,<b>Rzeczpospolita Polska</b></p>
<h5>Nagłówek dla pliku wyjściowego poczty</h5>
<p>Jeżeli chcesz aby w pierwszej linii pliku wyjściowego dla poczty znajdował się nagłowek, zaznacz opcję "Umieść w pliku". Zawartość nagłówka można edytować w polu tekstowym po lewej.</p>
<h5>Nagłówek dla pliku wyjściowego office</h5>
<p>Jeżeli chcesz aby w pierwszej linii pliku wyjściowego dla office znajdował się nagłowek, zaznacz opcję "Umieść w pliku". Zawartość nagłówka można edytować w polu tekstowym po lewej.</p>
<h5>Rozpoczęcie roku szkolnego (DD | MM)</h5>
<p>W tych polach należy wpisać datę rozpoczęcia roku szkolnego (z reguły). W pierwszym polu (po lewo) należy wpisać dzień, a w drugim (po prawo) miesiąc. Te dane są używane do obliczania roku w znaczniku klasy (przykłądowy znacznik klasy: 2023a). W przypadku generowania plików na nowy rok szkolny przed jego rozpoczęciem, należy wprowadzić datę dzisiejszą lub wcześniejszą.</p>
<h5>Dane o szkołach</h5>
<p>W tym polu należy wprowadzić dane każdej szkoły w zespole szkół (po jednej szkole w linijce). Wymagane są trzy "kolumny danych". Są one odzielone znakami "<u>|</u>".<br>W pierwszej kolumnie należy wpisać oznaczenie szkoły (dowolne bez spacji, najlepiej jak najkrótsze). Te dane będą używane w znaczniku klasy, jeżeli w trzeciej kolumnie została wybrana opcja "1".<br>W drugiej kolmnie należy wpisać liczbę klas w danej szkole. Te dane używane są do obliczenia roku w znaczniku klasy.<br>W trzeciej kolumnie można wybrać opcję "1" lub "0" (Prawda/Fałsz). Wybierz "1" jeżeli chcesz, aby w znaczniku klasy znajdowało się oznaczenie szkoły (przykład: 2023bs). Wybierz "0" jeżeli chcesz, aby w znaczniku klasy znajdowała się litera klasy (przykład: 2023a).</p>
<br>
<p><b>Aby zapisać ustawienia należy wcisnąć przycisk ZAPISZ. Aby anulować zmiany wciśnij przycisk Anuluj</b></p>
</div>
<button class="accordion"><b>Generowanie plików wyjściowych</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>W pierwszej kolejności należy przygotować pliki wejściowe oraz stworzyć presety formatu dla tych plików, według instrukcji w sekcji "Tworzenie/edytowanie format presetu dla danego pliku źródłowego" (jednego presetu formatu można używac do kilku plików jeżeli pliki mają ten sam format i to samo kodowanie)</p>
<h5>Krok 2</h5>
<p>Przejdź do zakładki GENERATOR CSV. Możesz przetworzyć naraz 4 pliki wejściowe. Dla każdego pliku należy wybrać jego lokalizację (wpisać ją w polu, oznaczonym kolorem czerwonym na poniższym zdjęciu, lub otworzyć okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" i tam wybrać plik. Następnie należy wybrać preset formatu, odpowiedni dla pliku wejściowego, w polu oznaczonym kolorem zielonym na poniższym zdjęciu.</p>
<img width = '700px' src = '../assets/documentation-page/instruction/generate-input-file-settings.png'><br>
<h5>Krok 3</h5>
<p>Wybierz lokalizację zapisu pliku wyjściowego dla serwisu szkoły, wpisując lokalizację wraz z nazwą pliku w polu, oznaczonym kolorem czerwonym na poniższym zdjęciu, lub otwierając okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" obok tego pola i tam wybierając plik.<br>Wybierz lokalizację zapisu pliku wyjściowego dla serwisu portal.office.com, wpisując lokalizację wraz z nazwą pliku w polu, oznaczonym kolorem zielonym na poniższym zdjęciu, lub otwierając okno wyboru lokalizacji za pomocą przycisku "Przeglądaj" obok tego pola i tam wybierając plik.</p>
<img width = '700px' src = '../assets/documentation-page/instruction/generate-output-file-settings.png'><br>
<h5>Krok 4</h5>
<p>Aby rozpocząć generowanie wciśnij przycisk START i potwierdź komunikat. Pliki wyjściowe zostaną zapisane w wybranych lokalizacjach. Przed importem upewnij się że w plikach nie występują błędy.</p>
</div>
<button class="accordion"><b>Usuwanie presetów formatu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Zarządzaj presetami formatu".</p>
<h5>Krok 3</h5>
<p>Zaznacz presety formatu które chcesz usunąć.</p>
<h5>Krok 4</h5>
<p>Naciśnij przycisk "Usuń zaznaczone"</p>
</div>
<button class="accordion"><b>Przywracanie domyślnych ustawień ogólnych programu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Przywróć domyślne ustawienia ogólne". Po potwierdzeniu i ponownym uruchomieniu programu, ustawienia zostaną przywrócone do ustawień fabrycznych.</p>
</div>
<button class="accordion"><b>Przywracanie domyślnego wyglądu programu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Uruchom program i przejdź do zakładki USTAWIENIA.</p>
<h5>Krok 2</h5>
<p>Naciśnij przycisk "Przywróć domyślne ustawienia wyglądu". Po potwierdzeniu i ponownym uruchomieniu programu, wygląd zostanie przywrócony do ustawień fabrycznych.</p>
</div>
<button class="accordion"><b>Zaawansowana edycja ustawień programu i wyglądu</b></button>
<div class="panel">
<h5>Krok 1</h5>
<p>Otwórz menu start i wpisz "%appdata%"</p>
<h5>Krok 2</h5>
<p>Przejdź do folderu "Generator CSV"</p>
<h5>Krok 3</h5>
<p>Za ustawienia programu odpowiedzialny jest plik "config.cfg", a za wygląd plik "style.cfg". Użyj dowolnego edytora plików tekstowych, do edycji tych plików. Więcej informacji o tych plikach znajduje się w Dokumentacji technicznej.<br>Aby przywrócić te pliki do stanu fabrycznego wykonaj kroki z sekcji odpowiednio "Przywracanie domyślnych ustawień ogólnych programu" lub "Przywracanie domyślnego wyglądu programu"</p>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
</body>
</html>

80
documentation/main.css Normal file
View File

@@ -0,0 +1,80 @@
body, html{
background-color: #21242D;
margin: 0px;
height: 100%;
width: 100%;
}
header {
width: 100%;
position: sticky;
}
#header-image {
background-color: #333842;
width: 100px;
height: 100px;
float: left;
padding: 25px;
}
#header-text {
background-color: #333842;
overflow: auto;
line-height: 40px;
font-family: 'Segoe UI';
color: #C0C0C0;
font-size: 30px;
padding: 25px;
}
nav {
width: 100%;
}
#menu-ul {
width: 100%;
height: 50px;
padding: 0;
margin: 0;
list-style: none;
}
#menu-li a {
display: block;
float: left;
text-align: center;
font-family: 'Segoe UI';
margin-right: 0.05%;
margin-left: 0.05%;
font-size: 20px;
width: 24.9%;
line-height: 50px;
text-decoration: none;
color: #C0C0C0;
background-color: #2e313b;
}
#menu-li a:hover {
color: #C0C0C0;
background: #333842;
}
section {
width: 100%;
}
iframe {
float: left;
width: 100%;
border: none;
height: calc(100% - 220px);
overflow: scroll;
position: absolute;
}

View File

@@ -0,0 +1,388 @@
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "content.css">
<meta charset = "utf-8">
<link rel = "shortcut icon" href = "../assets/documentation-page/icon.ico">
<title>Generator CSV</title>
</head>
<body>
<button class="accordion"><b>generator.pyw - WPROWADZENIE</b></button>
<div class="panel">
<p>Aby móc uruchomić aplikację w wersji developerskiej należy pobrać Pythona (wersja zalecana: 3.8.5) oraz wymagane biblioteki (wymienione w sekcji 'generator.pyw - Import bibliotek')</p>
</div>
<button class="accordion"><b>generator.pyw - Import bibliotek</b></button>
<div class="panel">
<p>
<b>Biblioteki główne</b><br>
<br>
W tej sekcji importowane są wszystkie biblioteki niezwiązane z interfejsem graficznych<br>
<ul>
<li>sys (SS) - używana tylko do zamykania programu</li>
<li>os (OS) - odpowiedzialna za polecenia w terminalu</li>
<li>time (TM) - używana do pobierania aktualnej daty i czasu</li>
<li>codecs (CD) - odpowiedzialna za otwieranie i czytanie plików w odpowiednim kodowaniu</li>
<li>pathlib (PT) - używana tylko do pozyskania ścieżki katalogu APPDATA</li>
<li>shutil (SU) - odpowiedzialna za operacje na plikach i folderach</li>
</ul>
</p>
<p>
<br>
<b>Biblioteki interfejsu graficznego</b><br>
<br>
W tej sekcji importowane są wszystkie biblioteki związane z interfejsem graficznym
<br>
<ul>
<li>tkinter (TK) - główne środowisko budowy interfejsu graficznego</li>
<ul>
<li>ttk (TKttk) - biblioteka odpowiedzialna za kontrolki i ich wygląd</li>
<li>messagebox (TKmsb) - biblioteka odpowiedzialna za wyświetlanie komunikatów dialogowych</li>
<li>filedialog (TKfld) - biblioteka odpowiedzialna za wyświetlanie okien wyboru plików</li>
</ul>
<li>PIL (PL), (PLitk), (PLimg) - biblioteka odpowiedzialna za wyświetlanie obrazów</li>
</ul>
</p>
</div>
<button class="accordion"><b>generator.pyw - Główne zmienne globalne</b></button>
<div class="panel">
<p>
<b>Informacje o programie</b><br>
<br>
<code>programName</code> - Zmienna definująca nazwę programu<br>
<code>programVersion</code> - Zmienna definiująca główną wersję programu<br>
<code>programVersionStage</code> - Zmienna definiująca etap rozwoju programu. Wersja stabilna definiowana jest przez pusty string<br>
<code>programVersionBuild</code> - Zmienna definiująca numer buildu programu. Zapisany jest on w formacie '[ostatnie dwie cyfry roku][numer dnia w roku]'<br>
<code>programCustomer</code> - Zmienna definiująca nazwę organizacji zlecającej stworzenie programu<br>
<code>programAuthors</code> - Lista zawierająca nazwy osób rozwijających program.<br>
<code>programToW</code> - Lista zawierająca informacje na temat czasu rozwoju programu. Format: ['miesiąc rozpoczęcia prac', 'rok rozpoczęcia prac', 'aktualny dla rozwoju danej wersji miesiąc', 'aktualny dla rozwoju danej wersji rok']<br>
<br>
<br>
<b>Dozwolone kodowanie plików</b><br>
<br>
<code>allowedCoding</code> - Lista zawierająca wspierane kodowania plików. Są one wyświetlane w rozwijanych listach wyboru kodowania pliku.<br>
<br>
<br>
<b>Dozwolone znaki</b><br>
<br>
<code>allowedCharactersInSeparator</code> - Lista zawierająca znaki które można wpisać w pola dotyczące separatorów osób, linii i danych<br>
<br>
<br>
<b>Katalog APPDATA</b><br>
<br>
<code>appdataPath</code> - zmienna definiująca ścieżkę do folderu %appdata%
</p>
</div>
<button class="accordion"><b>generator.pyw - Okna dialogowe</b></button>
<div class="panel">
<p>
<b>Lista komunikatów</b><br>
<br>
Słownik <code>MSGlist</code> zawiera listę komunikatów. Format: '[kod dialogowy]' : '[komunikat]'. Kod dialogowy składa się z [jednoznakowego znacznika rodzaju okna dialogowego][czterocyfrowego numeru komunikatu]<br>
<br>
<br>
<b><i>Rodzaje okien dialogowych:</i></b>
<ul>
<li>E - komunikaty błędów</li>
<li>I - komunikaty informacyjne</li>
<li>W - komunikaty ostrzegające</li>
<li>A - komunikaty zapytania</li>
</ul>
</p>
<p>
<br>
<b>Funkcja odpowiedzialna za wywoływanie komunikatów dialogowych</b><br>
<br>
Wywoływanie funkcji: <code>MSG(</code>[kod dialogowy]<code>,</code>[<code>True</code> - Zakończ działanie programu po zamknięciu okna dialogowego/<code>False</code> - Kontynuuj działanie programu po zamknięciu okna dialogowego]<code>,</code>[dodatkowe informacje wyświetlane w komunikacie - <b>opcjonalnie</b>]<code>)</code><br>
<br>
<code>
try:<br>
optionalInfo[0]<br>
except:<br>
optionalInfo = ['']<br>
</code>
Sprawdza czy zostały wpisane 'dodatkowe informacje wyświetlane w komunikacie' i jeżeli nie, definiuje listę, w której znajduje się pusty string (ma to na celu uniknięcia błędu podczas próby wywołania dodatkowych informacji przez dalszą część funkcji)<br>
<br>
<code>
if code[0] == 'E/I/W':<br>
TKmsb.showerror/showinfo/showwarning('</code>[tytuł komunikatu]<code>', '%s\n%s' % (MSGlist[code], optionalInfo[0]))<br>
</code>
Wywoływanie danego rodzaju komunikatu na podstawie jednoznakowego znacznika rodzaju okna dialogowego.<br>
<br>
<code>
if terminate:<br>
SS.exit(0)<br>
</code>
Zakończenie działania programu po zamknięciu okna dialogowego, jeżeli została ustawiona opdowiednia opcja.<br>
<br>
<code>
elif code[0] == 'A':<br>
if TKmsb.askokcancel('Pytanie', '%s\n%s' % (MSGlist[code], optionalInfo[0])):<br>
return True<br>
else:<br>
return False<br>
</code>
Funkcja zwraca wartość boolean w przypadku wywołania komunikatu zapytania
</p>
</div>
<button class="accordion"><b>generator.pyw - Sprawdzanie katalogu programu w APPDATA</b></button>
<div class="panel">
<p>
Klasa <code>checkAppdata</code> odpowiedzialna jest za sprawdzenie poprawności i, w razie potrzeby, doprowadzenie go do stanu poprawności.
<br>
<br>
<b>Główna funkcja programu</b><br>
<br>
1. Czy w folderze %appdata% istnieje folder programu (Generator CSV)?<br>
Jeżeli nie istnieje, uruchamiana jest funckja <code>__buildAppdata</code> (odpowiedzialna za zbudowanie całości katalogu programu).<br>
2. Czy w folderze programu istnieje plik 'version' (przechowuje on numer buildu programu, w którym został zbudowany katalog programu)?<br>
Jeżeli nie istnieje, uruchamiane jest okno dialogowe zapytania z pytaniem czy pozwolić na zresetowanie katalogu programu i kontynuować ładowanie programu<br>
3. Czy numer buildu programu w pliku 'version' jest zgodny z numerem buildu zawartym w zmiennej <code>VAR.programVersionBuild</code><br>
Jeżeli nie, uruchamiane jest okno dialogowe zapytania z pytaniem czy pozwolić na zresetowanie katalogu programu i kontynuować ładowanie programu<br>
Jeżeli tak, sprawdzane są poszczególne pliki i foldery które powinny być zawarte w folderze, i jeżeli któryś plik/folder nie znajduje się w folderze, wywołuje się funkcje mające na celu przywrócenie/utworzenie tych plików/folderów (odpowiednio: <code>__restoreCFG</code> dla plików konfiguracyjnych, <code>__createFormatPresetsDir</code> dla folderu przechowującego format presety)<br>
<br>
<br>
<b>Budowanie katalogu programu</b> (<code>__buildAppdata</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za zbudowanie całości katalogu programu w folderze %appdata%.<br>
1. Tworzenie katalogu 'Generator CSV'<br>
2. Tworzenie pliku 'version' i zapisanie w nim numeru buildu.<br>
3. Inicjacja funkcji <code>__restoreCFG</code> (w celu skopiowania pliku 'config.cfg' z głównego katalogu programu do katalogu 'Generator CSV' w folderze %appdata%).<br>
4. Inicjacja funkcji <code>__restoreCFG</code> (w celu skopiowania pliku 'style.cfg' z głównego katalogu programu do katalogu 'Generator CSV' w folderze %appdata%).<br>
5. Inicjacja funkcji <code>__createFormatPresetsDir</code> (w celu stworzenia folderu 'format-presets' przechowującego format presety)<br>
<br>
<br>
<b>Resetowanie katalogu programu</b> (<code>__resetAppdata</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za przywrócenie katalogu programu w folderze %appdata% do stanu podstawowego oraz stworzenie kopii zapasowej starego katalogu.<br>
1. W przypadku gdy w katalogu istnieje jeszcze starsza kopia zapasowa folderu, kopia ta jest usuwana.<br>
2. Nazwa katalogu programu jest zmieniana na taką z dopiskiem '_old'.<br>
3. Inicjacja funkcji <code>__buildAppdata</code> w celu zbudowania nowego katalogu programu<br>
4. Skopiowanie katalogu 'Generator CSV_old' do nowego katalogu 'Generator CSV'<br>
<br>
<br>
<b>Przywracanie plików konfiguracyjnych</b> (<code>__restoreCFG</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za skopiowanie pliku konfiguracyjnego (.cfg) o danej nazwie z głównego katalogu programu do katalogu programu w folderze %appdata%<br>
<br>
<br>
<b>Tworzenie katalogu przechowującego format presety</b> (<code>__createFormatPresetsDir</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za utworzenie folderu 'format-presets', przechowującego format presety, w katalogu programu w folderze %appdata%
</p>
</div>
<button class="accordion"><b>generator.pyw - Ładowanie głównego pliku konfiguracyjnego 'config.cfg'</b></button>
<div class="panel">
<p>
Klasa <code>CFG</code> odpowiedzialna jest za zarządzanie plikiem konfiguracyjnym 'config.cfg'<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'config.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'config.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja funckji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
4. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
5. Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Zapisywanie zmian w pliku</b> (<code>W</code>)<br>
<br>
Funkcja ta jest odpowiedzialna za sprawdzenie, przetworzenie i zapisanie zmian w pliku konfiguracyjnych.<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'config.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'config.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie, dla każdego recordu ze słownika <code>changes</code><br>
4. Nadpisanie zmiennej ze słownika content, wartością <code>var</code>.<br>
5. Zapisanie zawartości słownika <code>content</code> w pliku 'config.cfg'<br>
6. Funkcja zwraca <code>True</code> jeżeli operacja została wykonana pomyślnie lub <code>False</code> jeżeli wystąpił błąd<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFileExist</code> - funkcja sprawdza czy plik istnieje i możliwe jest jego nadpisanie (w przypadku zapisu)<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Ładowanie pliku konfiguracyjnego stylu 'style.cfg'</b></button>
<div class="panel">
<p>
Klasa <code>GUI</code> odpowiedzialna jest za zarządzanie plikiem konfiguracyjnym 'style.cfg'<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFileExist</code> w celu sprawdzenia czy plik 'style.cfg' istnieje<br>
2. Zczytanie i zapisanie wszystkich danych z pliku 'style.cfg' do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja funkcji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
4. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFileExist</code> - funkcja sprawdza czy plik istnieje<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Zarządzanie plikami formatu</b></button>
<div class="panel">
<p>
Klasa <code>FMT</code> odpowiedzialna jest za zarządzanie plikami formatu (.fmt)<br>
<br>
<br>
<b>Odczytywanie pojedyńczej zmiennej z pliku</b> (<code>R</code>)<br>
<br>
Funkcja ta, jest odpowiedzialna za odczytanie zawartości danego recordu i sprawdzenie jego poprawności<br>
1. Inicjacja funkcji <code>__checkIfFolderExist</code> w celu sprawdzenia czy folder 'format-presets' istnieje<br>
2. Sprawdzenie czy podany plik formatu (<code>preset</code>) znajduje się w folderze 'format-presets' (funkcja <code>getList</code> zwraca listę plików formatu w folderze 'format-presets')<br>
Jeżeli nie, wartość zmiennej jest wybierana ze słownika <code>content</code> (zawierającego podstawowe wartości zmiennych)<br>
Jeżeli tak:
3. Zczytanie i zapisanie wszystkich danych z wybranego pliku formatu do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
4. Inicjacja funkcji <code>__checkIfRecordExist</code> w celu sprawdzenia czy w słowniku <code>content</code> znajduje się żądany record<br>
5. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie<br>
Funkcja zwraca wartość zmiennej.<br>
<br>
<br>
<b>Zapisywanie zmian w pliku</b> (<code>W</code>)<br>
<br>
Funkcja ta jest odpowiedzialna za sprawdzenie, przetworzenie i zapisanie zmian w pliku konfiguracyjnych.<br>
1. Inicjacja funkcji <code>__checkIfFolderExist</code> w celu sprawdzenia czy folder 'format-presets' istnieje<br>
2. Sprawdzenie czy podany plik formatu (<code>preset</code>) znajduje się w folderze 'format-presets' (funkcja <code>getList</code> zwraca listę plików formatu w folderze 'format-presets')<br>
Jeżeli nie, tworzony jest słownik <code>content</code> z zawartością podstawową
Jeżeli tak: Zczytanie i zapisanie wszystkich danych z wybranego pliku formatu do słownika <code>content</code> w formacie: 'nazwa zmiennej' : ['zmienna', 'typ zmiennej']<br>
3. Inicjacja, odpowiedniej dla typu zmiennej, funkcji mającej na celu sprawdzenie jej poprawności i jej przetworzenie, dla każdego recordu ze słownika <code>changes</code><br>
4. Nadpisanie zmiennej ze słownika content, wartością <code>var</code>.<br>
5. Zapisanie zawartości słownika <code>content</code> w pliku 'config.cfg'<br>
6. Funkcja zwraca <code>True</code> jeżeli operacja została wykonana pomyślnie lub <code>False</code> jeżeli wystąpił błąd<br>
<br>
<br>
<b>Funkcja zwracająca listę presetów</b> (<code>getList</code>)<br>
<br>
Funkcja ta odpowiedzialna jest za stworzenie listy plików .fmt w folderze 'format-presets' oraz za jej zwrócenie.<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b><br>
<br>
<code>__checkIfFolderExist</code> - funkcja sprawdza czy folder 'format-presets' istnieje (inicjuje <code>checkAppdata</code>)<br>
<code>__checkIfRecordExist</code> - funkcja sprawdza czy <code>record</code> istnieje w słowniku <code>content</code><br>
<br>
<br>
<b>Funkcje sprawdzające poprawność recordu</b><br>
<br>
Funkcje te odpowiadają za sprawdzenie poprawności zmiennej i w razie potrzeby przetwarzają ją na pożądaną formę.
</p>
</div>
<button class="accordion"><b>generator.pyw - Przetwarzanie plików</b></button>
<div class="panel">
<p>
Klasa <code>dataProcess</code> odpowiedzialna za przetwarzanie plików wejściowych i generowanie plików wyjściowych<br>
<br>
<br>
<b>Główna funkcja klasy</b> (<code>start</code>)<br>
<br>
Funkcja ta odpowiedzialna za zainicjowanie kolejnych funkcji w odpowiedniej kolejności oraz zwrócenie informacji o błędach lub pomyślnym wykonaniu polecenia<br>
1. Inicjacja funkcji <code>__checkIfAtLeastOneInputFileIsFilled</code> w celu sprawdzenia czy przynajmniej jedno pole plików wejściowych zostało wypełnione<br>
2. Inicjacja funkcji <code>__checkIfInputFilesIsReadable</code> w celu sprawdzenia czy pliki wejściowe, do których ścieżki zostały podane, są możliwe do odczytania<br>
3. Inicjacja funkcji <code>__checkIfInputFilesFormatPresetsExist</code> w celu sprawdzenia czy format presety, które zostały wybrane, istnieją<br>
4. Inicjacja funkcji <code>__getData</code> w celu zebrania danych z plików wejściowych<br>
5. Dla każdego zbioru danych - <code>for x in data</code> (dla każdej osoby), inicjacja funkcji <code>__checkLogin</code>, <code>__checkFname</code>, <code>__checkLname</code>, oraz dla uczniów <code>__checkSchool</code>, <code>__checkClass</code>, w celu sprawdzenia poprawności danych<br>
6. Inicjacja funkcji <code>__processData</code> w celu przetworzenia danych w linie gotowe do zapisania w plikach wyjściowych<br>
7. Inicjacja funkcji <code>__checkIfCreatingOutputFilesIsPossible</code> w celu sprawdzenia czy możliwe jest utworzenie plików wyjściowych<br>
8. Inicjacja funkcji <code>__saveData</code> w celu zapisania danych w plikach wyjściowych<br>
Funkcja zwraca listę zawierającą zmienne boolean potwierdzające w którym momencie zakończyło się wykonywanie funkcji (z powodu błędu lub pomyślnego ukończenia operacji)<br>
<br>
<br>
<b>Funkcje sprawdzające istnienie</b>
<br>
<code>__checkIfAtLeastOneInputFileIsFilled</code> - sprawdza czy przynajmniej jedno pole plików wejściowych zostało wypełnione oraz zwraca dane z wypełnionych pól<br>
<code>__checkIfInputFilesIsReadable</code> - sprawdza czy pliki wejściowe są możliwe do odczytania<br>
<code>__checkIfInputFilesFormatPresetsExist</code> - sprawdza czy wybrane format presety istnieją<br>
<code>__checkIfCreatingOutputFilesIsPossible</code> - sprawdza czy utworzenie plików wyjściowych jest możliwe<br>
<br>
<br>
<b>Funkcje sprawdzające poprawność</b>
<br>
Funkcje te sprawdzają poprawność określonych typów danych.
<br>
<br>
<b>Wyodrębnienie danych z plików</b> (<code>__getData</code>)<br>
<br>
Funkcja odpowiedzialna jest za wyodrębnienie danych z pliku (<code>path</code>) na podstawie określonego format presetu (<code>format</code>)
Dla każdego zbioru ścieżek plików wejściowych i format presetów (<code>for x in input</code>):<br>
1. Pobranie danych z pliku formatu (za pomocą funkcji <code>FMT.R</code>)<br>
2. Pobranie zawartości z pliku wyjściowego i podzielenie ich na zbiory danych pojedyńczych osób (<code>.split(personseparator)</code>)<br>
Dla każdego zbioru danych pojedyńczych osób (<code>for x in file</code>):<br>
3. Dzielenie zbioru danych na linie (<code>x.split(linesSeparator)</code>)<br>
4. Dla każdej linii: dzielenie danych na pojedyńcze segmenty separatorami z listy <code>dataSeparators</code><br>
5. Wyodrębnienie wymaganych danych ze zbioru<br>
6. Dodanie danych pojedyńczej osoby do listy <code>data</code><br>
<br>
<br>
<b>Przetworzenie danych</b> (<code>__processData</code>)<br>
<br>
Funkcja odpowiedzialna jest za przetworzenie danych w linie gotowe do zapisania w plikach wyjściowych<br>
Funkcja zwraca listę <code>[mailData, officeData]</code><br>
<br>
<br>
<b>Zapisanie danych</b> (<code>__saveData</code>)<br>
<br>
Funkcja odpowiedzialna jest za zapisanie danych w plikach wyjściowych dla poczty i dla office
</p>
</div>
<button class="accordion"><b>generator.pyw - GUI</b></button>
<div class="panel">
<p>
Klasa <code>GUI</code> odpowiada za interfejs programu<br>
<br>
<br>
<b>1. Główna funkcja programu</b><br>
<br>
- Stworzenie okna<br>
- Inicjacja styli kontrolek<br>
- Kontrolki<br>
<br>
<br>
<b>Akcje przycisków</b><br>
<br>
Funkcje inicjowane przez naciśnięcie przycisków
</p>
</div>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
</script>
</body>
</html>

141
format.py
View File

@@ -1,141 +0,0 @@
# Oznaczenia zmiennych:
# K - Klasa
# N - Nazwisko
# I - Imie
# L - Login do librusa
import codecs as cd
def SprawdzKlasa(K):
if len(K.split(' ')) != 2: # Wywołuje błąd jeżeli napis nie dzieli się w pożądanym formacie
blad = int('x') #
for x in range(0,10): #
if K[1:].find(str(x)) != -1: # Wywołuje bląd jeżeli w nazwie klasy (poza numerem klasy) znajduje się liczba
blad = int('x') #
numery_niedozwolone = [0,9,8,7,6,5,4] # Określa numery klas które nie istnieją
for x in numery_niedozwolone: #
if K[0] == str(x): # Wywołuje błąd jeżeli numer klasy jest równy numerowi niedozwolonemu
blad = int('x') #
szkoly = ['BS', 'LO'] # Określa istniejące szkoly
if K.split(' ')[1] not in szkoly: # Wywołuje błąd jeżeli szkola nie należy do szkół istniejących
blad = int('x') #
oddzialy = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'w', 'y', 'z'] # Określa istniejące oddzialy
if K[1] not in oddzialy: # Wywołuje błąd jeżeli oddział nie należy do oddziałów istniejących
blad = int('x') #
def SprawdzNazwisko(N):
for a in N:
for x in range(0,10): #
if a.find(str(x)) != -1: # Wywoluje blad jeżeli nazwisko zawiera liczbę
blad = int('x') #
def SprawdzImie(I):
for x in range(0,10): #
if I.find(str(x)) != -1: # Wywoluje blad jeżeli imie zawiera liczbę
blad = int('x') #
def SprawdzLogin(L, CzyUczen):
if CzyUczen and L[-1] != 'u': # Wywoluje blad jeżeli login ucznia nie zawiera na końcu 'u'
blad = int('x') #
if CzyUczen: #
blad = int(L[:-1]) # Wywoluje blad jeżeli login (-'u' dla ucznia) nie jest liczbą
else: #
blad = int(L) #
def przetworz(dane):
dane = dane.split('\n\n') # dzielenie danych na pojedyńcze osoby
przetworzone = [] # tworzenie kontenera na przetworzone dane
for osoba in dane: #
try: #
x = int(osoba[0]) #
except ValueError: # Sprawdza czy osoba jest nauczycielem czy uczniem
CzyUczen = False #
else: #
CzyUczen = True #
# Dla uczniów
if CzyUczen:
K = osoba.split(', ')[0].split(' ')[:2]
K = K[0] + ' ' + K[1]
N = osoba.split(', ')[0].split(' ')[2:]
I = osoba.split(', ')[1].split(' ')[0]
L = osoba.split(', ')[1].split(' ')[2]
# Sprawdzenie poprawności
SprawdzKlasa(K)
SprawdzNazwisko(N)
SprawdzImie(I)
SprawdzLogin(L, CzyUczen)
dane = [K, N, I, L, CzyUczen]
przetworzone.append(dane)
# Dla nauczycieli
else:
N = osoba.split(', ')[0].split(' ')
I = osoba.split(', ')[1].split(' ')[-4]
L = osoba.split(', ')[1].split(' ')[-2]
# Sprawdzenie poprawnosci
SprawdzNazwisko(N)
SprawdzImie(I)
SprawdzLogin(L, CzyUczen)
dane = [N, I, L, CzyUczen]
przetworzone.append(dane)
return przetworzone
# Legenda do części dokumentacji poniżej:
# X - Dane nieznaczące
# Q - Pusta linia
# Format danych dla uczniów:
# <Klasa> <Nazwisko>, <Imie> <X> <Login do librusa> <X>
# <Q>
# Przykład:
# 1a BS Nowak, Adam <NieznaczaceDane> 1234567u <NieznaczaceDane>
#
# Format danych dla nauczycieli:
# <Nazwisko>, <Imie> <X> <Login do Librusa> <X>
# <Q>
# Przykład:
# Nowak, Adam <NieznaczaceDane> 1234567 <NieznaczaceDane>
#
# Inne:
# - skrypt akceptuje prefix 'ks.', nieuwzględnia go w przetwarzaniu
# - skrypt akceptuje nazwiska holenderskie (typu 'van X', 'van der X' itp.) i uwzględnia je w przetwarzaniu
# - skrypt nie akceptuje nazwisk złożonych (np. Nowak-Kowalska)
# - skrypt wymaga kodowania ANSI

BIN
generator.exe Normal file

Binary file not shown.

View File

@@ -1,415 +0,0 @@
# GeneratorCSV
# Wersja 3.0.1
# by Mateusz Skoczek
# luty 2019 - grudzień 2019
# dla ZSP Sobolew
## Defincja błędów ##############################################################################
# E001 - Brak pliku składowego
E001x00 = "Brak pliku formatu 'moduly.py'.\nPrzywróć plik. (E001x00)"
E001x01 = "Brak pliku formatu 'format.py'.\nPrzywróć plik. (E001x01)"
E001x02 = "Brak pliku konfiguracyjnego 'config.cfg'.\nPrzywróć plik. (E001x02)"
E001x03 = "Brak pliku 'instrukcja.txt'.\nPrzywróć plik. (E001x03)"
# E002 - Błąd pliku składowego
E002x02 = "Nieokreślony błąd pliku konfiguracyjnego 'config.cfg'.\nPrzywróć domyślny plik lub popraw ustawienia. (E002x02)"
E002x021 = "Błąd pliku konfiguracyjnego 'config.cfg'.\nPodane kodowanie nie jest obsługiwane\nPrzywróć domyślny plik lub popraw ustawienia. (E002x021)"
# E003 - Błąd lokalizacji plików I/O
E003x01 = "Nie podano lokalizacji plików do importu. (E003x01)"
E003x02 = "Nie podano lokalizacji zapisu wygenerowanych plików. (E003x02)"
E003x111 = "Plik podany w sciezce 1 nie istnieje (E003x111)"
E003x112 = "Plik podany w sciezce 2 nie istnieje (E003x112)"
E003x113 = "Plik podany w sciezce 3 nie istnieje (E003x113)"
E003x114 = "Plik podany w sciezce 4 nie istnieje (E003x114)"
#_______________________________________________________________________________________________#
## Import bibliotek zewnętrznych ################################################################
import tkinter as tk
import codecs as cd
import os
import time as tm
import sys as ss
# Definicja składowych biblioteki interfejsu graficznego
from tkinter import filedialog as TKfld
from tkinter import messagebox as TKmsb
#_______________________________________________________________________________________________#
## Weryfikacja istnienia plików składowych programu #############################################
try:
x = open('moduly.py')
except FileNotFoundError:
Message = 'Wystąpił błąd!\n' + E001x00
tk.showerror('Błąd', Message)
ss.exit(0)
try:
x = open('format.py')
except FileNotFoundError:
Message = 'Wystąpił błąd!\n' + E001x01
tk.showerror('Błąd', Message)
ss.exit(0)
#_______________________________________________________________________________________________#
## Import modułów programu ######################################################################
# Import modułów składowych programu
from moduly import ErrorDialog as MDerr
from moduly import FileCheck as MDfck
from moduly import PolishLetterRemover as MDplr
from moduly import ClassTagCreator as MDctc
# Import skryptu przetwarzającego dane
import format as ft
#_______________________________________________________________________________________________#
## Weryfikacja istnienia plików składowych ######################################################
MDfck('format.py', E001x01)
MDfck('config.cfg', E001x02)
MDfck('instrukcja.txt', E001x03)
#_______________________________________________________________________________________________#
## Wczytywanie pliku konfiguracyjnego ###########################################################
try:
with open('config.cfg', 'r') as config:
config = config.read().split('\n')
Kodowanie = str(config[0].strip('Kodowanie: '))
TypyKodowania = ['utf-8', 'cp1252', 'iso-8859-1']
if Kodowanie not in TypyKodowania:
MDerr(E002x021)
except:
MDerr(E002x02)
#_______________________________________________________________________________________________#
## Inicjacja skryptu przetwarzającego dane ######################################################
def Main():
if TKmsb.askokcancel('Ostrzeżenie', "Czy na pewno chcesz rozpocząć generowanie?\nProgram utworzy w podanej lokalizacji pliki 'email.csv' i 'office.csv'.\nJeżeli w podanej lokalizacji istnieją pliki o takich nazwach zostaną one nadpisane."):
sciezka1 = Pole1.get()
sciezka1_puste = True
sciezka2 = Pole2.get()
sciezka2_puste = True
sciezka3 = Pole3.get()
sciezka3_puste = True
sciezka4 = Pole3.get()
sciezka4_puste = True
sciezkaExport = PoleExport.get()
sciezkaExport_puste = True
if sciezka1 != '':
sciezka1_puste = False
if sciezka2 != '':
sciezka2_puste = False
if sciezka3 != '':
sciezka3_puste = False
if sciezka4 != '':
sciezka4_puste = False
if sciezkaExport != '':
sciezkaExport_puste = False
if sciezka1_puste and sciezka2_puste and sciezka3_puste and sciezka4_puste:
MDerr(E003x01)
if sciezkaExport_puste:
MDerr(E003x02)
KontenerDanych = []
if not sciezka1_puste:
try:
x = open(sciezka1)
except FileNotFoundError:
MDerr(E003x111)
else:
with open(sciezka1, 'r') as plik1:
KontenerDanych += ft.przetworz(plik1.read())
if not sciezka2_puste:
try:
x = open(sciezka2)
except FileNotFoundError:
MDerr(E003x112)
else:
with open(sciezka2, 'r') as plik2:
KontenerDanych += ft.przetworz(plik2.read())
if not sciezka3_puste:
try:
x = open(sciezka3)
except FileNotFoundError:
MDerr(E003x113)
else:
with open(sciezka3, 'r') as plik3:
KontenerDanych += ft.przetworz(plik3.read())
if not sciezka4_puste:
try:
x = open(sciezka4)
except FileNotFoundError:
MDerr(E003x114)
else:
with open(sciezka4, 'r') as plik4:
KontenerDanych += ft.przetworz(plik4.read())
KontenerEmail = []
KontenerOffice = []
for osoba in KontenerDanych:
if osoba[-1]:
Klasa = osoba[0]
Imie = osoba[2]
Inicjaly = Imie[0]
Nazwisko = ''
NazwiskoDoEmaila = ''
for x in osoba[1]:
Nazwisko += x + ' '
NazwiskoDoEmaila += ('.' + x)
Inicjaly += x[0]
Nazwisko = Nazwisko[:-1]
ZnacznikKlasy = MDctc(Klasa)
Login = osoba[3]
Adres = MDplr(Imie).lower() + MDplr(NazwiskoDoEmaila).lower() + ZnacznikKlasy + '@losobolew.pl'
Email = Adres + ',' + Login + ':' + MDplr(Inicjaly) + ',500'
Office = Adres + ',' + Imie + ',' + Nazwisko + ',' + Imie + ' ' + Nazwisko + ',uczeń,' + Klasa + ',,,,,,,,,Rzeczypospolita Polska'
KontenerEmail.append(Email)
KontenerOffice.append(Office)
else:
Imie = osoba[1]
Inicjaly = Imie[0]
Nazwisko = ''
NazwiskoDoEmaila = ''
for x in osoba[0]:
Nazwisko += x + ' '
NazwiskoDoEmaila += ('.' + x)
Inicjaly += x[0]
Nazwisko = Nazwisko[:-1]
Login = osoba[2]
Adres = MDplr(Imie).lower() + MDplr(NazwiskoDoEmaila).lower() + '@losobolew.pl'
Email = Adres + ',' + Login + ':' + MDplr(Inicjaly) + ',500'
Office = Adres + ',' + Imie + ',' + Nazwisko + ',' + Imie + ' ' + Nazwisko + ',nauczyciel,,,,,,,,,,Rzeczpospolita Polska'
KontenerEmail.append(Email)
KontenerOffice.append(Office)
sciezkaEmail = sciezkaExport + '/email.csv'
sciezkaOffice = sciezkaExport + '/office.csv'
with cd.open(sciezkaEmail, 'w', Kodowanie) as plikEmail:
for x in KontenerEmail:
plikEmail.writelines(x + '\n')
plikEmail.close()
with cd.open(sciezkaOffice, 'w', Kodowanie) as plikOffice:
for x in KontenerOffice:
plikOffice.writelines(x + '\n')
plikOffice.close()
TKmsb.showinfo('Zakończono', 'Operacja zakończona pomyślnie')
ss.exit(0)
else:
ss.exit(0)
#_______________________________________________________________________________________________#
## Inicjacja okna ###############################################################################
# Zmienne globalne środowiska graficznego
SzerokoscOpisu = 17
SzerokoscPola = 91
TytulProgramu = 'GeneratorCSV'
Autorzy = 'Mateusz Skoczek'
Wersja = '3.0.1'
Lata = '2019'
# Tworzenie okna
OknoGlowne = tk.Tk()
OknoGlowne.title(TytulProgramu)
OknoGlowne.resizable(width = False, height = False)
# Nazwa programu
Tytul = tk.Label(OknoGlowne, text = TytulProgramu, font = ('Segoe UI Semilight', 20), borderwidth = 7, justify = 'center', bg = 'Gainsboro', width = 47)
Tytul.grid(row = 0)
# Tworzenie frame dla ścieżek plików do importu
Ramka1 = tk.LabelFrame(OknoGlowne, text = 'Pliki do importu zawierające dane')
Ramka1.grid(row = 1)
# Ścieżka pliku do importu 1
wiersz1 = 0
text1 = tk.StringVar()
OpisPola1 = tk.Label(Ramka1, text = 'Plik z danymi (1)', justify = 'left', width = SzerokoscOpisu)
OpisPola1.grid(row = wiersz1, column = 0)
Pole1 = tk.Entry(Ramka1, textvariable = text1, width = SzerokoscPola)
Pole1.grid(row = wiersz1, column = 1)
def Browse1_Dialog():
Browse1.filename = TKfld.askopenfilename(initialdir="/", title="Wybierz plik", filetypes=(("Pliki txt", "*.txt"), ("Wszystkie pliki", "*.*")))
Pole1.delete(0, 'end')
Pole1.insert(0, Browse1.filename)
Browse1 = tk.Button(Ramka1, text = '...', command = Browse1_Dialog, background = 'silver', relief = 'flat')
Browse1.grid(row = wiersz1, column = 2, padx = 5, pady = 3)
# Ścieżka pliku do importu 2
wiersz2 = 1
text2 = tk.StringVar()
OpisPola2 = tk.Label(Ramka1, text = 'Plik z danymi (2)', justify = 'left', width = SzerokoscOpisu)
OpisPola2.grid(row = wiersz2, column = 0)
Pole2 = tk.Entry(Ramka1, textvariable = text2, width = SzerokoscPola)
Pole2.grid(row = wiersz2, column = 1)
def Browse2_Dialog():
Browse2.filename = TKfld.askopenfilename(initialdir="/", title="Wybierz plik", filetypes=(("Pliki txt", "*.txt"), ("Wszystkie pliki", "*.*")))
Pole2.delete(0, 'end')
Pole2.insert(0, Browse2.filename)
Browse2 = tk.Button(Ramka1, text = '...', command = Browse2_Dialog, background = 'silver', relief = 'flat')
Browse2.grid(row = wiersz2, column = 2, padx = 5, pady = 3)
# Ścieżka pliku do importu 3
wiersz3 = 2
text3 = tk.StringVar()
OpisPola3 = tk.Label(Ramka1, text = 'Plik z danymi (3)', justify = 'left', width = SzerokoscOpisu)
OpisPola3.grid(row = wiersz3, column = 0)
Pole3 = tk.Entry(Ramka1, textvariable = text3, width = SzerokoscPola)
Pole3.grid(row = wiersz3, column = 1)
def Browse3_Dialog():
Browse3.filename = TKfld.askopenfilename(initialdir="/", title="Wybierz plik", filetypes=(("Pliki txt", "*.txt"), ("Wszystkie pliki", "*.*")))
Pole3.delete(0, 'end')
Pole3.insert(0, Browse3.filename)
Browse3 = tk.Button(Ramka1, text = '...', command = Browse3_Dialog, background = 'silver', relief = 'flat')
Browse3.grid(row = wiersz3, column = 2, padx = 5, pady = 3)
# Ścieżka pliku do importu 4
wiersz4 = 3
text4 = tk.StringVar()
OpisPola4 = tk.Label(Ramka1, text = 'Plik z danymi (4)', justify = 'left', width = SzerokoscOpisu)
OpisPola4.grid(row = wiersz4, column = 0)
Pole4 = tk.Entry(Ramka1, textvariable = text4, width = SzerokoscPola)
Pole4.grid(row = wiersz4, column = 1)
def Browse4_Dialog():
Browse4.filename = TKfld.askopenfilename(initialdir="/", title="Wybierz plik", filetypes=(("Pliki txt", "*.txt"), ("Wszystkie pliki", "*.*")))
Pole4.delete(0, 'end')
Pole4.insert(0, Browse4.filename)
Browse4 = tk.Button(Ramka1, text = '...', command = Browse4_Dialog, background = 'silver', relief = 'flat')
Browse4.grid(row = wiersz4, column = 2, padx = 5, pady = 3)
# Tworzenie frame dla plików export
Ramka2 = tk.LabelFrame(OknoGlowne, text = 'Ustawienia eksportu')
Ramka2.grid(row = 2)
# Ścieżka folderu do zapisu wygenerowanych plików
text4 = tk.StringVar()
OpisPolaExport = tk.Label(Ramka2, text = 'Lokalizacja', justify = 'left', width = SzerokoscOpisu)
OpisPolaExport.grid(row = 0, column = 0)
PoleExport = tk.Entry(Ramka2, textvariable = text4, width = SzerokoscPola)
PoleExport.grid(row = 0, column = 1)
def BrowseExport_Dialog():
BrowseExport.filename = TKfld.askdirectory()
PoleExport.delete(0, 'end')
PoleExport.insert(0, BrowseExport.filename)
BrowseExport = tk.Button(Ramka2, text = '...', command = BrowseExport_Dialog, background = 'silver', relief = 'flat')
BrowseExport.grid(row = 0, column = 2, padx = 5, pady = 3)
# Przycisk START
Przycisk = tk.Button(OknoGlowne, text = 'START', justify = 'center', width = 50, command = Main, relief = 'flat', background = 'silver')
Przycisk.grid(row = 3, pady = 15)
# Pasek dolny
PasekDolny = tk.LabelFrame(OknoGlowne, bd = 0, background = 'Gainsboro')
PasekDolny.grid(row = 4)
info = TytulProgramu + ' ' + Wersja + ' | © ' + Autorzy + ' '+ Lata + ' dla ZSP Sobolew'
InfoLabel = tk.Label(PasekDolny, text = info, justify = 'left', width = 93, anchor = 'w', background = 'Gainsboro')
InfoLabel.grid(row= 0, column = 0)
def InfoOpen():
try:
x = open('instrukcja.txt')
except FileNotFoundError:
MDerr(E001x03)
else:
os.system("notepad instrukcja.txt")
Przycisk = tk.Button(PasekDolny, text = 'Instrukcja', justify = 'center', foreground = 'blue', relief = 'flat', command = InfoOpen, background = 'Gainsboro')
Przycisk.grid(row = 0, column = 1)
tk.mainloop()
#_______________________________________________________________________________________________#

BIN
icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View File

@@ -1,107 +0,0 @@
Program tworzy pliki .csv potrzebne do stworzenia kont uczniów i nauczycieli na szkolnej poczcie i Office 365.
Obecnie program obsługuje tylko 4 pliki z danymi. Program tworzy pliki 'email.csv' do eksportu dla szkolnej poczty oraz 'office.csv' do eksportu dla kont office.
Obecna wersja: 3.0
Autorzy: Mateusz Skoczek
dla ZSP Sobolew
luty 2019 - grudzień 2019
Format domyślny plików z danymi:
Legenda:
X - Dane nieznaczące
Q - Pusta linia
Uczniowie:
# <Klasa> <Nazwisko>, <Imie> <X> <Login do librusa> <X>
# <Q>
# Przykład:
# 1a BS Nowak, Adam <NieznaczaceDane> 1234567u <NieznaczaceDane>
#
Nauczyciele:
# <Nazwisko>, <Imie> <X> <Login do Librusa> <X>
# <Q>
# Przykład:
# Nowak, Adam <NieznaczaceDane> 1234567 <NieznaczaceDane>
#
Format można edytować w pliku 'format.py'. Więcej info na dole.
Format domyślny pliku 'office.csv':
Uczniowie:
# <email>,<imie>,<nazwisko>,<imie nazwisko>,uczeń,<klasa>,,,,,,,,,Rzeczpospolita Polska
# Przykład:
# adam.nowak@losobolew.pl,Adam,Nowak,Adam Nowak,uczeń,1a BS,,,,,,,,,Rzeczpospolita Polska
Nauczyciele:
# <email>,<imie>,<nazwisko>,<imie nazwisko>,nauczyciel,,,,,,,,,,Rzeczpospolita Polska
# Przykład:
# adam.nowak@losobolew.pl,Adam,Nowak,Adam Nowak,nauczyciel,,,,,,,,,,Rzeczpospolita Polska
Format domyślny pliku 'email.csv':
Uczniowie:
# <email>,<haslo>,500
|
v
# <imie>.<nazwisko><znacznikklasy:rokukonczeniaszkoly + literaklasy/bs>@losobolew.pl,<loginlibrusa>:<inicjaly>,500
# Przykład:
# adam.nowak2021bs@losobolew.pl,1234567u,500
Nauczyciele:
# <email>,<haslo>,500
|
v
# <imie>.<nazwisko>@losobolew.pl,<loginlibrusa>:<inicjaly>,500
# Przykład:
# adam.nowak@losobolew.pl,1234567,500
Dalsze pojęcia:
błąd programu - błąd programu objawiający się komunikatem
krytyczny błąd programu - nieoczekiwany błąd programu nieobjawiający się komunikatem
Pliki:
changelog.txt
Informacje o zmianach w poszczególnych wersjach programu.
generator.py
Główny plik programu. Jakiekolwiek naruszenie jego zawartości może spowodować krytyczny błąd programu.
instrukcja.txt
Plik z instrukcją użytkowania. Usunięcie tego pliku spowoduje błąd programu.
config.cfg
Plik zawiera ukryte ustawienia programu. Można go edytować, ale należy robić to z rozwagą. Usunięcie go spowoduje błąd programu.
1: Obsługiwane kodowania: 'utf-8', 'cp1252', 'iso-8859-1'
moduly.py
Plik zawierający moduły niezbędne do działania programu. Usunięcie pliku spowoduje błąd programu. Naruszenie jego zawartości może spowodować krytyczny błąd programu.
format.py
Plik ten jest skryptem przetwarzającym dane. W razie zmiany formatu pliku z danymi należy go edytować, lecz nie powinna tego robić osoba początkująca, gdyż błędny kod może spowodować krytyczny błąd programu lub niepożądane wyniki. Usunięcie pliku spowoduje błąd programu.

View File

@@ -1,51 +0,0 @@
import sys as ss
import time as tm
from tkinter import messagebox as TKmsb
def ErrorDialog(KodBledu):
Message = 'Wystąpił błąd!\n' + KodBledu
TKmsb.showerror('Błąd', Message)
ss.exit(0)
def FileCheck(Plik, KodBledu):
try:
x = open(Plik)
except FileNotFoundError:
ErrorDialog(KodBledu)
def PolishLetterRemover(text):
text1 = text.replace('ę', 'e')
text2 = text1.replace('ó', 'o')
text3 = text2.replace('ą', 'a')
text4 = text3.replace('ś', 's')
text5 = text4.replace('ł', 'l')
text6 = text5.replace('ż', 'z')
text7 = text6.replace('ź', 'z')
text8 = text7.replace('ć', 'c')
text9 = text8.replace('ń', 'n')
text10 = text9.replace('Ę', 'E')
text11 = text10.replace('Ó', 'O')
text12 = text11.replace('Ą', 'A')
text13 = text12.replace('Ś', 'S')
text14 = text13.replace('Ł', 'L')
text15 = text14.replace('Ż', 'Z')
text16 = text15.replace('Ź', 'Z')
text17 = text16.replace('Ć', 'C')
text = text17.replace('Ń', 'N')
return text
def ClassTagCreator(Klasa):
czas = tm.localtime()
miesiac = czas[1]
if miesiac >= 9:
rokpodst = czas[0]
else:
rokpodst = czas[0] - 1
nrklasy = int(Klasa[0])
literaklasy = Klasa[1]
szkola = Klasa.split(' ')[1]
if szkola == 'BS':
znacznik = str((4 - nrklasy) + rokpodst) + szkola
else:
znacznik = str((5 - nrklasy) + rokpodst) + literaklasy
return znacznik