12-12-2019, 17:45
.py
^ mozna skopiowac calosc i wkleic
Kod:
#Importowanie wymaganych rzeczy - korzystanie z tzw. modułów tudzież bibliotek (skompilowane wersje .pyc, działają szybciej)
from time import sleep, gmtime, strftime
import time
from random import randint
import sys
import os
import argparse
#wyswietlenie początkowego komunikatu :
print("\n = = = eNeMeL konsolidator ! = = = \n")
#obsługa argumentów z interfejsu wiersza poleceń
parser = argparse.ArgumentParser(description="Patchowanie GRF ~ w NML ~ z plików pnml do jednego pliku NML. Jeśli nie podano żadnych argumentów, program zapętli się i poprosi o dane wejściowe do skompilowania pliku. OSTRZEŻENIE! To NIE kompiluje się do pliku .grf, a tylko łata składowe pliki .pnml do pliku .nml, aby można było skompilować z NMLC!")
parser.add_argument("-o", "--output", type=str, help='Plik do wyjśca , zapisanie do pliku. Podanie nazwy pliku tylko, nie w cudzysłowie ( np.: output.nml ) ' )
parser.add_argument("-f", "--plik", type=str, help="Plik nagłówka do odczytania. Podanie nazwy pliku ze ścieżką w cudzysłowie.")
parser.add_argument("-b", "--backup", type=int, help="1 lub 0, aby potwierdzić, czy program utworzy kopię zapasową w przypadku zastąpienia pliku wyjściowego.", choices=[0,1])
args = parser.parse_args()
#Sprawdzanie, czy którykolwiek z argumentów ma jakąkolwiek wartość, która nie jest "None"
used_args = False
arguments = vars(args)
for argument in arguments:
if not used_args and arguments[argument] != None:
used_args = True
#Definiowanie funkcji ogólnego przeznaczenia ( usuniecie rozszerzenia nazwy pliku )
def rm_file_extension(file_name):
found_file_extension = False
end_point = len(file_name)-1
#Znajdowanie ostatniego miejsca po kropce w nazwie nagłówka pliku
for pos in range(len(file_name)-1,-1,-1):
if file_name[pos] == "." and not found_file_extension:
end_point = pos
found_file_extension = True
return file_name[:end_point]
#Funkcja tworzenia kopii zapasowej, która -najpierw- tworzy kopię zapasową pliku wyjściowego (jeśli już istnieje)
def backup(name):
if name in os.listdir():
if not ("backups" in os.listdir()):
os.mkdir("backups")
os.rename(name, "backups/" + rm_file_extension(name) + "-" + strftime("%H-%M-%S-%Y-%m-%d", gmtime())+".nml")
#Znany błąd drukowania
def print_error(cause, place, action):
print("\nWystąpił błąd!")
print("Przyczyna : ", cause)
print("Znalezione w : ", place)
print("Jak ulepszyć : ", action)
#Nieznany błąd drukowania
def print_general_error(cause):
print("\nWystąpił błąd!")
print("Przyczyna : ", cause)
print("Najprawdopodobniej był to błąd wewnętrzny.\n")
#Definiowanie klasy, która zapisuje do pliku wyjściowego
class writer:
"""Interfejs zapisujący do pliku wyjściowego"""
output_text = ""
def __init__(self):
output = arguments["output"]
self.output = open(output, "w")
def write_line(self, line):
self.output.write(str(line) + "\n")
def close(self):
self.output.close()
#Definiowanie głównej klasy czytajacej
class reader:
"""Klasa, która czyta z pliku i robi z nim różne rzeczy"""
list_of_definitions = {}
total_list_of_errors = []
faulty_definitions = []
def __init__(self, file_name, *parent_variables):
try:
self.current_line = 0
self.errors_made = 0
self.file_name = file_name
self.input = ""
self.input = open(self.file_name, "r")
except (OSError, FileNotFoundError) as inst:
self.errors_made += 1
if parent_variables:
self.total_list_of_errors.append([inst, "Linia " + str(parent_variables[2]) + " ze " + str(parent_variables[0]) + ": " + str(parent_variables[1]), "Sprawdź, czy wiersz kodu jest poprawny"])
else:
self.total_list_of_errors.append([inst, "Wkład bezpośrdni/Argument", "Upewnij się, że podałeś prawidłową nazwę pliku"])
def read_line(self):
line_read = self.input.readline()
return line_read.replace("\n","")
def close(self):
if str(type(self.input)) == "<class '_io.TextIOWrapper'>":
self.input.close()
if len(self.total_list_of_errors):
if len(self.total_list_of_errors) == 1:
print("\nWystąpił 1 błąd w tej poprawce")
else:
print("\nNapotkany", len(self.total_list_of_errors), "errors w patch'u .")
for error in self.total_list_of_errors:
if len(error) == 1:
print_general_error(error[0])
else:
print_error(error[0], error[1], error[2])
def main(self):
#Główna funkcja, która czyta plik i zapisuje go w pliku wyjściowym
#Generowanie listy każdego wiersza kodu w pliku docelowym, a następnie usuwanie nowych znaków wiersza
lines = [line.replace("\n","") for line in self.input]
#Główna pętla - zapętlenia przez każdą linię kodu
self.line_counter = 0
for line in lines:
self.line_counter += 1
do_write = True
#Jeśli wiersz zaczyna się od polecenia „#include”, to tworzy kolejną instancję, która najpierw czyta i zapisuje ten plik
if line.lower()[:8] == "#include":
self.subreader = reader(line.replace('"', '')[9:], self.file_name, line, self.line_counter)
self.subreader.main()
if self.subreader.errors_made == 1:
print("Załatać", line.replace('"', '')[9:], "z 1 error!")
elif self.subreader.errors_made > 1:
print("Załatać", line.replace('"', '')[9:], "z", self.subreader.errors_made, "errors!")
else:
print("Łatane", line.replace('"', '')[9:], "z bez errors.")
do_write = False
elif line.lower()[:7] == "#define":
new_line = line[8:]
#Znajdowanie końca nazwy definicji
def_name = ""
found_def_name = False
for letter in new_line:
if letter == " " and not found_def_name:
new_line = new_line.replace(def_name + " ", "")
if len(new_line) > 0:
print("Wykonano ustanowioną definicję", def_name, "o wartości", new_line)
self.list_of_definitions[def_name] = new_line
elif len(def_name) > 1:
self.total_list_of_errors.append(["Nieprawidłowa definicja !", "Linia" + str(self.line_counter) + " ze " + self.file_name + ": " + line, "Do sprawdzenia wartość definicji"])
found_def_name = True
def_name += letter
do_write = False
else:
#Sprawdzanie ustanowionych definicji
for definition in self.list_of_definitions:
if definition in line:
line = line.replace(definition, self.list_of_definitions[definition])
#Jeśli zostanie znaleziona definicja uznana za wadliwą, wysyła błąd
for definition in self.faulty_definitions:
if definition in line:
self.errors_made +=1
self.total_list_of_errors.append(["Użyto niepoprawnej definicji !", "Linia " + str(self.line_counter) + " ze " + self.file_name + ": " + line, "Sprawdź wartość definicji"])
if do_write:
output.write_line(line)
#Definiowanie innych funkcji ogólnych
#Jeśli dane wyjściowe nie są zdefiniowane, ale plik nagłówkowy jest, to zostanie zdefiniowany tak samo jak dane wejściowe
if arguments["plik"] != None and arguments["output"] == None:
arguments["output"] = rm_file_extension(arguments["plik"])+".nml"
#Tworzenie kopii zapasowej, jeśli kopia zapasowa jest ustawiona na 1
if arguments["backup"] != None and str(arguments["backup"]) != "0" :
print("Próba wykonania kopii zapasowej", arguments["output"])
backup(arguments["output"])
#Wyświetlanie podanych argumentów użytkownikowi
for argument in arguments:
if arguments[argument] != None:
print(argument.capitalize(), ":", arguments[argument])
#Sprawdzanie, czy używane są argumenty
if used_args:
#Sprawdzenie, czy podano argument „plik”, ponieważ program nie może bez niego kontynuować
if arguments["plik"] != None:
try:
#Główna sekwencja, która otwiera pliki, a następnie zapisuje na wyjściu
output = writer()
header = reader(arguments["plik"])
header.main()
output.close()
header.close()
#Wyświetlanie komunikatów po łataniu
if len(header.list_of_definitions) > 0:
print("\nLista ustanowionych definicji używanych w tym pliku:")
for definition in header.list_of_definitions:
print(definition, header.list_of_definitions[definition])
#Wyłapanie wszelkich innyh zgłoszonych błędów
except Exception as inst:
print_general_error(str(inst) + " z " + str(type(inst)))
else:
print("\nNie podano pliku wejściowego!")
else:
print("\nAby wyjść z programu, wpisz 'exit'\n")
#Wprowadzenie w pętlę, którą można przerwać za pomocą Ctrl + C lub polecenia
while True:
try:
print("\n = = = = = = = = = = = = = = = = = \n")
#Uzyskiwanie informacji od użytkowników
arguments["plik"] = input("Plik wejściowy: ")
#Jeśli typ użytkownika zakończy działanie, program się zakończy
if arguments["plik"].lower() == "exit":
raise KeyboardInterrupt
#Tworzenie pliku wyjściowego na podstawie nazwy pliku wejściowego
arguments["output"] = rm_file_extension(arguments["plik"])+".nml"
#Główna sekwencja, która otwiera pliki, a następnie zapisuje na wyjściu
output = writer()
header = reader(arguments["plik"])
header.main()
output.close()
header.close()
#Wyświetlanie komunikatów po łataniu
if len(header.list_of_definitions) > 0:
print("\nLista ustanowionych definicji używanych w tym pliku:")
for definition in header.list_of_definitions:
print(definition, header.list_of_definitions[definition])
#Jeśli polecenie zostanie wprowadzone lub zostanie naciśnięty klawisz Ctrl + C, program zostanie zakończony
except KeyboardInterrupt:
print("\nWyjście z programu!")
break
#Wyłapanie wszelkich innych zgłaszanych błędów (#Wyjątek jako inst)
except SyntaxError:#Exception as inst:
print_general_error(str(inst) + " z " + str(type(inst)))
#input("\nNaciśnięcie enter, by kontynuować\n")![OpenTTD #Polska - Polskie forum gry OpenTTD [ARCHIWUM] OpenTTD #Polska - Polskie forum gry OpenTTD [ARCHIWUM]](https://forum.openttd.pl/images/logo.png)
