pilot.linkstec 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pilot.linkstec might be problematic. Click here for more details.
- pilot/__init__.py +0 -0
- pilot/config/__init__.py +0 -0
- pilot/config/config_reader.py +89 -0
- pilot/control/__init__.py +0 -0
- pilot/control/control_interface.py +6 -0
- pilot/control/impl/__init__.py +0 -0
- pilot/control/impl/base_controller.py +29 -0
- pilot/conver/__init__.py +0 -0
- pilot/conver/converfileEncodding.py +77 -0
- pilot/conver/nkf_converter.py +28 -0
- pilot/generater/__init__.py +0 -0
- pilot/generater/vertexai.py +66 -0
- pilot/job/__init__.py +0 -0
- pilot/job/impl/__init__.py +0 -0
- pilot/job/impl/base_job.py +288 -0
- pilot/job/job_interface.py +6 -0
- pilot/splitters/__init__.py +0 -0
- pilot/splitters/cobolsplitter.py +128 -0
- pilot/unit/__init__.py +0 -0
- pilot/unit/impl/__init__.py +0 -0
- pilot/unit/impl/base_unit.py +39 -0
- pilot/unit/unit_interface.py +10 -0
- pilot/util/__init__.py +0 -0
- pilot/util/files.py +45 -0
- pilot_linkstec-0.0.1.dist-info/METADATA +20 -0
- pilot_linkstec-0.0.1.dist-info/RECORD +29 -0
- pilot_linkstec-0.0.1.dist-info/WHEEL +5 -0
- pilot_linkstec-0.0.1.dist-info/licenses/LICENSE +19 -0
- pilot_linkstec-0.0.1.dist-info/top_level.txt +1 -0
pilot/__init__.py
ADDED
|
File without changes
|
pilot/config/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import configparser
|
|
2
|
+
import os
|
|
3
|
+
import inspect
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class ConfigDTO:
|
|
9
|
+
work_space: str
|
|
10
|
+
threads: int
|
|
11
|
+
project: str
|
|
12
|
+
steps: list[str]
|
|
13
|
+
skipsteps: list[str]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ConfigReader:
|
|
18
|
+
def __init__(self, filename = None):
|
|
19
|
+
filepath = None
|
|
20
|
+
if filename is None:
|
|
21
|
+
filepath = self.find_config_path()
|
|
22
|
+
|
|
23
|
+
if filename is not None:
|
|
24
|
+
cwd = os.getcwd()
|
|
25
|
+
filepath = os.path.join(cwd, 'config', filename)
|
|
26
|
+
if not os.path.exists(filepath):
|
|
27
|
+
raise FileNotFoundError(f"Configuration file not found: {filepath}")
|
|
28
|
+
|
|
29
|
+
self.config = configparser.ConfigParser()
|
|
30
|
+
self.config.optionxform = str
|
|
31
|
+
|
|
32
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
33
|
+
content = f.read()
|
|
34
|
+
if not content.lstrip().startswith('['):
|
|
35
|
+
content = '[DEFAULT]\n' + content
|
|
36
|
+
self.config.read_string(content)
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def find_config_path(cls):
|
|
40
|
+
cwd = os.getcwd()
|
|
41
|
+
candidate_path = os.path.join(cwd, 'config', 'control.properties')
|
|
42
|
+
if os.path.exists(candidate_path):
|
|
43
|
+
return candidate_path
|
|
44
|
+
|
|
45
|
+
stack = inspect.stack()
|
|
46
|
+
for frame in stack:
|
|
47
|
+
caller_file = frame.filename
|
|
48
|
+
caller_dir = os.path.dirname(os.path.abspath(caller_file))
|
|
49
|
+
possible_path = os.path.abspath(os.path.join(caller_dir, '..', '..', 'config', 'control.properties'))
|
|
50
|
+
if os.path.exists(possible_path):
|
|
51
|
+
return possible_path
|
|
52
|
+
|
|
53
|
+
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
|
54
|
+
fallback_path = os.path.join(base_dir, 'config', 'control.properties')
|
|
55
|
+
if os.path.exists(fallback_path):
|
|
56
|
+
return fallback_path
|
|
57
|
+
|
|
58
|
+
raise FileNotFoundError("control.properties not found in expected locations")
|
|
59
|
+
|
|
60
|
+
def get(self, section, option, fallback=None, cast_type=str):
|
|
61
|
+
try:
|
|
62
|
+
if cast_type == bool:
|
|
63
|
+
return self.config.getboolean(section, option)
|
|
64
|
+
elif cast_type == int:
|
|
65
|
+
return self.config.getint(section, option)
|
|
66
|
+
elif cast_type == float:
|
|
67
|
+
return self.config.getfloat(section, option)
|
|
68
|
+
else:
|
|
69
|
+
return self.config.get(section, option)
|
|
70
|
+
except (configparser.NoSectionError, configparser.NoOptionError):
|
|
71
|
+
return fallback
|
|
72
|
+
|
|
73
|
+
def get_dto(self) -> ConfigDTO:
|
|
74
|
+
input_path = self.get('DEFAULT', 'input_path', fallback='.')
|
|
75
|
+
work_space = self.get('DEFAULT', 'work_space', fallback='.')
|
|
76
|
+
threads = int(self.get('DEFAULT', 'threads', fallback=1))
|
|
77
|
+
project = self.get('DEFAULT', 'project', fallback='')
|
|
78
|
+
steps_str = self.get('DEFAULT', 'steps', fallback='')
|
|
79
|
+
steps = [s.strip() for s in steps_str.split(',')] if steps_str else []
|
|
80
|
+
skipsteps_str = self.get('DEFAULT', 'skipsteps', fallback='')
|
|
81
|
+
skipsteps = [s.strip() for s in skipsteps_str.split(',')] if skipsteps_str else []
|
|
82
|
+
|
|
83
|
+
return ConfigDTO(
|
|
84
|
+
work_space=work_space,
|
|
85
|
+
threads=threads,
|
|
86
|
+
project=project,
|
|
87
|
+
steps=steps,
|
|
88
|
+
skipsteps=skipsteps
|
|
89
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
2
|
+
|
|
3
|
+
from generater.vertexai import VertexAISingleton
|
|
4
|
+
from src.pilot.control.control_interface import ControlInterface
|
|
5
|
+
from src.pilot.unit.impl.base_unit import BaseUnit
|
|
6
|
+
from src.pilot.config.config_reader import ConfigReader
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseController(ControlInterface):
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
vertexai: VertexAISingleton = VertexAISingleton.get_instance()
|
|
13
|
+
|
|
14
|
+
def _init_unit(self):
|
|
15
|
+
return BaseUnit()
|
|
16
|
+
|
|
17
|
+
def run(self):
|
|
18
|
+
import time
|
|
19
|
+
config_dto = ConfigReader().get_dto()
|
|
20
|
+
def worker():
|
|
21
|
+
unit = self._init_unit()
|
|
22
|
+
unit.run()
|
|
23
|
+
with ThreadPoolExecutor(max_workers=config_dto.threads) as executor:
|
|
24
|
+
futures = []
|
|
25
|
+
for _ in range(config_dto.threads):
|
|
26
|
+
futures.append(executor.submit(worker))
|
|
27
|
+
time.sleep(0.2)
|
|
28
|
+
for future in futures:
|
|
29
|
+
future.result()
|
pilot/conver/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
def nkf_convert(file_path, nkf_args):
|
|
6
|
+
"""
|
|
7
|
+
nkf を使ってファイルの文字コード変換を行う
|
|
8
|
+
|
|
9
|
+
:param file_path: 変換対象のファイルパス
|
|
10
|
+
:param nkf_args: nkf に渡す引数のリスト(例: ['-w'])
|
|
11
|
+
"""
|
|
12
|
+
# nkfコマンドの引数にファイルパスを追加
|
|
13
|
+
#cmd = ['nkf'] + nkf_args + [file_path]
|
|
14
|
+
|
|
15
|
+
cmd = ['nkf32'] + nkf_args + file_path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
# nkfを実行し標準出力を取得
|
|
20
|
+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
|
|
21
|
+
print(f"nkfの実行完了しました: {file_path}")
|
|
22
|
+
except subprocess.CalledProcessError as e:
|
|
23
|
+
print(f"nkfの実行でエラーが発生しました: {e.stderr.decode()}", file=sys.stderr)
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
# nkfの変換結果(バイト列)を返す
|
|
27
|
+
return result.stdout
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
#if __name__ == "__main__":
|
|
31
|
+
# 処理対象のルートフォルダパスを指定(適宜変更してください)
|
|
32
|
+
# root_folder = r"d:\work2\src"
|
|
33
|
+
# nkf_convert(root_folder, ['-v'])
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
#if __name__ == "__main__":
|
|
38
|
+
# if len(sys.argv) < 3:
|
|
39
|
+
# print(f"使い方: python {sys.argv[0]} <ファイルパス> <nkf引数...>", file=sys.stderr)
|
|
40
|
+
# print(f"例: python {sys.argv[0]} test.txt -w --overwrite", file=sys.stderr)
|
|
41
|
+
# sys.exit(1)
|
|
42
|
+
|
|
43
|
+
# file_path = [r"D:\test\CHKCONST.cpy"]
|
|
44
|
+
# nkf_args = ['-w','--overwrite']
|
|
45
|
+
#nkf_args = ['-g']
|
|
46
|
+
# output = nkf_convert(file_path, nkf_args)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
target_dir = r'D:\work\fullsource'
|
|
53
|
+
nkf_args = ['-w', '--overwrite']
|
|
54
|
+
#extensions = (
|
|
55
|
+
# '.cfc', '.cfm', '.cob', '.cobol', '.cpy', '.csh', '.css', '.ctl',
|
|
56
|
+
# '.htm', '.html', '.js', '.sh', '.sql', '.tpl', '.txt'
|
|
57
|
+
#)
|
|
58
|
+
extensions = ('.cnd','.cng','int')
|
|
59
|
+
for root, dirs, files in os.walk(target_dir):
|
|
60
|
+
for file in files:
|
|
61
|
+
if file.lower().endswith(extensions):
|
|
62
|
+
filepath = os.path.join(root, file)
|
|
63
|
+
output = nkf_convert([filepath], nkf_args)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
#if output is not None:
|
|
67
|
+
# 結果を標準出力にバイナリのまま書き出す場合
|
|
68
|
+
# sys.stdout.buffer.write(output)
|
|
69
|
+
|
|
70
|
+
# あるいはUTF-8等に応じてデコードして表示する場合
|
|
71
|
+
# 一旦utf-8デコードを試みる例(必要に応じて変更してください)
|
|
72
|
+
# try:
|
|
73
|
+
# decoded_output = output.decode('utf-8')
|
|
74
|
+
# print(decoded_output)
|
|
75
|
+
# except UnicodeDecodeError:
|
|
76
|
+
# print("utf-8へのデコードに失敗しました。バイナリデータとして出力します。", file=sys.stderr)
|
|
77
|
+
# sys.stdout.buffer.write(output)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
class NkfConverter:
|
|
5
|
+
def __init__(self, nkf_args=None):
|
|
6
|
+
"""
|
|
7
|
+
コンストラクタ
|
|
8
|
+
:param nkf_args: nkf に渡す引数のリスト(例: ['-w', '--overwrite'])
|
|
9
|
+
指定しない場合はデフォルト値を使用
|
|
10
|
+
"""
|
|
11
|
+
if nkf_args is None:
|
|
12
|
+
nkf_args = ['-w', '--overwrite']
|
|
13
|
+
self.nkf_args = nkf_args
|
|
14
|
+
|
|
15
|
+
def convert(self, file_path):
|
|
16
|
+
"""
|
|
17
|
+
nkf を使ってファイルの文字コード変換を行う
|
|
18
|
+
:param file_path: 変換対象のファイルパス
|
|
19
|
+
:return: nkfの変換結果のバイト列、失敗したらNone
|
|
20
|
+
"""
|
|
21
|
+
cmd = ['nkf32'] + self.nkf_args + [file_path]
|
|
22
|
+
try:
|
|
23
|
+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
|
|
24
|
+
print(f"nkfの実行完了しました: {file_path}")
|
|
25
|
+
except subprocess.CalledProcessError as e:
|
|
26
|
+
print(f"nkfの実行でエラーが発生しました: {e.stderr.decode()}", file=sys.stderr)
|
|
27
|
+
return None
|
|
28
|
+
return result.stdout
|
|
File without changes
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Dict, Any, Optional
|
|
3
|
+
|
|
4
|
+
import tiktoken
|
|
5
|
+
from vertexai.preview.generative_models import GenerativeModel, ChatSession
|
|
6
|
+
from transformers import AutoTokenizer
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
class VertexAISingleton:
|
|
10
|
+
_instance: Optional['VertexAISingleton'] = None
|
|
11
|
+
_lock = threading.Lock()
|
|
12
|
+
_tokenizer_cache = {}
|
|
13
|
+
encoding = None
|
|
14
|
+
|
|
15
|
+
def __new__(cls, model_name: str = "gemini-2.5-pro"):
|
|
16
|
+
if cls._instance is None:
|
|
17
|
+
with cls._lock:
|
|
18
|
+
if cls._instance is None:
|
|
19
|
+
cls._instance = super(VertexAISingleton, cls).__new__(cls)
|
|
20
|
+
cls._instance._initialized = False
|
|
21
|
+
return cls._instance
|
|
22
|
+
|
|
23
|
+
def __init__(self, model_name: str = "gemini-2.5-pro"):
|
|
24
|
+
if not self._initialized:
|
|
25
|
+
with self._lock:
|
|
26
|
+
if not self._initialized:
|
|
27
|
+
self.model = GenerativeModel(model_name)
|
|
28
|
+
os.environ["TIKTOKEN_CACHE_DIR"] = r"D:\api"
|
|
29
|
+
self.encoding = tiktoken.get_encoding("cl100k_base")
|
|
30
|
+
self._initialized = True
|
|
31
|
+
|
|
32
|
+
def generate_content(self, prompt: str) -> Dict[str, Any]:
|
|
33
|
+
"""複数スレッドから安全に呼び出し可能"""
|
|
34
|
+
try:
|
|
35
|
+
response = self.model.generate_content(prompt)
|
|
36
|
+
return {
|
|
37
|
+
"prompt": prompt,
|
|
38
|
+
"response": response.text,
|
|
39
|
+
"success": True,
|
|
40
|
+
"error": None
|
|
41
|
+
}
|
|
42
|
+
except Exception as e:
|
|
43
|
+
return {
|
|
44
|
+
"prompt": prompt,
|
|
45
|
+
"response": None,
|
|
46
|
+
"success": False,
|
|
47
|
+
"error": str(e)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
def start_chat(self) -> ChatSession:
|
|
51
|
+
"""新しいチャットセッションを開始"""
|
|
52
|
+
return self.model.start_chat()
|
|
53
|
+
|
|
54
|
+
def count_tokens(self, text: str) -> int:
|
|
55
|
+
"""与えられたテキストのトークン数を返す(bert-base-uncasedのみ使用)"""
|
|
56
|
+
try:
|
|
57
|
+
tokens = self.encoding.encode(text)
|
|
58
|
+
return len(tokens)
|
|
59
|
+
except Exception as e:
|
|
60
|
+
print(f"トークン計算失敗: {e}")
|
|
61
|
+
return 0
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def get_instance(cls, model_name: str = "gemini-2.5-pro") -> 'VertexAISingleton':
|
|
65
|
+
"""インスタンスを取得"""
|
|
66
|
+
return cls(model_name)
|
pilot/job/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
|
|
4
|
+
from pilot.job.job_interface import JobInterface
|
|
5
|
+
from pilot.config.config_reader import ConfigReader
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseJob(JobInterface):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.config_dto = ConfigReader().get_dto()
|
|
11
|
+
self._current_step = None
|
|
12
|
+
self._file_path = None
|
|
13
|
+
self._step_index = None
|
|
14
|
+
self._next_step = None
|
|
15
|
+
self._next_step_file_path = None
|
|
16
|
+
self._content = None
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def current_step(self):
|
|
20
|
+
return self._current_step
|
|
21
|
+
|
|
22
|
+
@current_step.setter
|
|
23
|
+
def current_step(self, value):
|
|
24
|
+
self._current_step = value
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def file_path(self):
|
|
28
|
+
return self._file_path
|
|
29
|
+
|
|
30
|
+
@file_path.setter
|
|
31
|
+
def file_path(self, value):
|
|
32
|
+
self._file_path = value
|
|
33
|
+
self._content = None # ファイルパスが変わったらキャッシュクリア
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def step_index(self):
|
|
37
|
+
return self._step_index
|
|
38
|
+
|
|
39
|
+
@step_index.setter
|
|
40
|
+
def step_index(self, value):
|
|
41
|
+
self._step_index = value
|
|
42
|
+
self._next_step = None # step_indexが変わったらnext_stepをリセット
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def next_step(self):
|
|
46
|
+
if self._next_step is None and self._step_index is not None:
|
|
47
|
+
steps_list = self.config_dto.steps
|
|
48
|
+
if self._step_index + 1 < len(steps_list):
|
|
49
|
+
self._next_step = steps_list[self._step_index + 1]
|
|
50
|
+
else:
|
|
51
|
+
self._next_step = None
|
|
52
|
+
return self._next_step
|
|
53
|
+
|
|
54
|
+
@next_step.setter
|
|
55
|
+
def next_step(self, value):
|
|
56
|
+
self._next_step = value
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def current_trg_file_path(self):
|
|
61
|
+
return self._trg_file_path
|
|
62
|
+
|
|
63
|
+
@current_trg_file_path.setter
|
|
64
|
+
def current_trg_file_path(self, value):
|
|
65
|
+
self._trg_file_path = value
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def run(self):
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def get_file_content(self):
|
|
74
|
+
if self._content is None and self._file_path:
|
|
75
|
+
with open(self._file_path, 'r', encoding='utf-8') as f:
|
|
76
|
+
self._content = f.read()
|
|
77
|
+
return self._content
|
|
78
|
+
|
|
79
|
+
def get_current_step_relative_path(self):
|
|
80
|
+
if not self._file_path:
|
|
81
|
+
return self._file_path
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
base_dir = os.path.join(self.config_dto.work_space, self.current_step)
|
|
85
|
+
return os.path.relpath(self._file_path, base_dir)
|
|
86
|
+
except ValueError:
|
|
87
|
+
return self._file_path
|
|
88
|
+
|
|
89
|
+
def get_current_step_count(self):
|
|
90
|
+
if not self._file_path:
|
|
91
|
+
return self.config_dto.work_space
|
|
92
|
+
try:
|
|
93
|
+
relative_path = self.get_current_step_relative_path()
|
|
94
|
+
return os.path.relpath(self.config_dto.work_space, relative_path)
|
|
95
|
+
except ValueError:
|
|
96
|
+
return self.config_dto.work_space
|
|
97
|
+
|
|
98
|
+
def _copy_file_to_step_dir(self, src_path, base_dir, step_dir):
|
|
99
|
+
"""指定したsrc_pathをbase_dirからの相対パスをごとstep_dir配下にコピーする。
|
|
100
|
+
すでにコピー先に同名ファイルがあればNoneを返し、存在しなければコピー先ファイルパスを返す。
|
|
101
|
+
"""
|
|
102
|
+
if not src_path:
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
rel_path = os.path.relpath(os.path.dirname(src_path), base_dir)
|
|
106
|
+
dest_dir = os.path.join(step_dir, rel_path)
|
|
107
|
+
base_file_name = os.path.basename(src_path)
|
|
108
|
+
dest_file_path = os.path.join(dest_dir, base_file_name)
|
|
109
|
+
|
|
110
|
+
if os.path.exists(dest_file_path):
|
|
111
|
+
self._next_step_file_path = dest_file_path
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
os.makedirs(dest_dir, exist_ok=True)
|
|
115
|
+
shutil.copy(src_path, dest_file_path)
|
|
116
|
+
self._next_step_file_path = dest_file_path
|
|
117
|
+
return dest_file_path
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def copy_current_file_to_next_step(self):
|
|
121
|
+
if not self._file_path or not self.next_step:
|
|
122
|
+
return None
|
|
123
|
+
base_dir = os.path.join(self.config_dto.work_space, self.current_step)
|
|
124
|
+
step_dir = os.path.join(self.config_dto.work_space, self.next_step)
|
|
125
|
+
return self._copy_file_to_step_dir(self._file_path, base_dir, step_dir)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# 共通化メソッド
|
|
129
|
+
def _create_next_step_trigger_file(self, ext):
|
|
130
|
+
if self._next_step_file_path:
|
|
131
|
+
trg_file = self._next_step_file_path + ".trg"
|
|
132
|
+
end_file = self._next_step_file_path + ".end"
|
|
133
|
+
begin_file = self._next_step_file_path + ".begin"
|
|
134
|
+
target_file = self._next_step_file_path + ext
|
|
135
|
+
if not (os.path.exists(trg_file) or os.path.exists(end_file) or os.path.exists(begin_file)):
|
|
136
|
+
open(target_file, 'w', encoding='utf-8').close()
|
|
137
|
+
return trg_file
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
def create_next_step_todo_trg_file(self):
|
|
141
|
+
return self._create_next_step_trigger_file(".trg")
|
|
142
|
+
|
|
143
|
+
def create_next_step_end_trg_file(self):
|
|
144
|
+
return self._create_next_step_trigger_file(".end")
|
|
145
|
+
|
|
146
|
+
def create_next_step_begin_trg_file(self):
|
|
147
|
+
return self._create_next_step_trigger_file(".begin")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def change_current_trg_to_end(self):
|
|
151
|
+
if os.path.exists(self.current_trg_file_path):
|
|
152
|
+
file_path, file_extension = os.path.splitext(self.current_trg_file_path)
|
|
153
|
+
if file_extension == ".trg" or file_extension == ".begin":
|
|
154
|
+
try:
|
|
155
|
+
os.rename(self.current_trg_file_path, file_path + ".end")
|
|
156
|
+
return True
|
|
157
|
+
except Exception:
|
|
158
|
+
# 例外が発生した場合は False を返す
|
|
159
|
+
print("!!!!!!!!!!!!!!!!!!!!change_current_trg_to_end erro")
|
|
160
|
+
return False
|
|
161
|
+
# trgファイルが存在しなければ何もしないので、そのままreturn
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
def change_current_trg_to_begin(self):
|
|
165
|
+
if os.path.exists(self.current_trg_file_path):
|
|
166
|
+
file_path, file_extension = os.path.splitext(self.current_trg_file_path)
|
|
167
|
+
if file_extension == ".trg":
|
|
168
|
+
try:
|
|
169
|
+
os.rename(self.current_trg_file_path, file_path + ".begin")
|
|
170
|
+
self.current_trg_file_path = os.path.join(file_path + ".begin")
|
|
171
|
+
return True
|
|
172
|
+
except Exception:
|
|
173
|
+
# 例外が発生した場合は False を返す
|
|
174
|
+
return False
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
def copy_input_file_to_next_step(self, input_file_path):
|
|
178
|
+
"""
|
|
179
|
+
input_file_pathで指定されたファイルを、next stepフォルダにコピーする。
|
|
180
|
+
コピー先に同名ファイルがあればNone、存在しなければコピー先ファイルパスを返す。
|
|
181
|
+
"""
|
|
182
|
+
if not input_file_path or not self.next_step:
|
|
183
|
+
return None
|
|
184
|
+
base_dir = os.path.join(self.config_dto.work_space, self.current_step)
|
|
185
|
+
step_dir = os.path.join(self.config_dto.work_space, self.next_step)
|
|
186
|
+
return self._copy_file_to_step_dir(input_file_path, base_dir, step_dir)
|
|
187
|
+
|
|
188
|
+
def create_next_step_todo_trg_file_from_input(self, input_file_path):
|
|
189
|
+
"""
|
|
190
|
+
input_file_pathで指定されたファイルをnext stepフォルダにコピーし、.trgファイルを生成する。
|
|
191
|
+
ファイルが既に存在する場合でも.trgファイルの作成を試行する。
|
|
192
|
+
"""
|
|
193
|
+
if not input_file_path or not self.next_step:
|
|
194
|
+
return None
|
|
195
|
+
|
|
196
|
+
# ファイルをコピー(既存の場合はNoneが返される)
|
|
197
|
+
copied_file_path = self.copy_input_file_to_next_step(input_file_path)
|
|
198
|
+
|
|
199
|
+
# コピーが成功しなかった場合でも、対象ファイルパスを取得
|
|
200
|
+
if not copied_file_path:
|
|
201
|
+
base_dir = os.path.join(self.config_dto.work_space, self.current_step)
|
|
202
|
+
step_dir = os.path.join(self.config_dto.work_space, self.next_step)
|
|
203
|
+
rel_path = os.path.relpath(os.path.dirname(input_file_path), base_dir)
|
|
204
|
+
dest_dir = os.path.join(step_dir, rel_path)
|
|
205
|
+
base_file_name = os.path.basename(input_file_path)
|
|
206
|
+
copied_file_path = os.path.join(dest_dir, base_file_name)
|
|
207
|
+
|
|
208
|
+
# .trgファイルを作成
|
|
209
|
+
trg_file = copied_file_path + ".trg"
|
|
210
|
+
end_file = copied_file_path + ".end"
|
|
211
|
+
begin_file = copied_file_path + ".begin"
|
|
212
|
+
|
|
213
|
+
if not (os.path.exists(trg_file) or os.path.exists(end_file) or os.path.exists(begin_file)):
|
|
214
|
+
# 空ファイルとして.trgファイルを生成
|
|
215
|
+
open(trg_file, 'w', encoding='utf-8').close()
|
|
216
|
+
return trg_file
|
|
217
|
+
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
def create_current_step_end_trg_file_from_input(self, input_file_path):
|
|
221
|
+
"""
|
|
222
|
+
input_file_pathで指定されたファイルに対して.endファイルを生成する。
|
|
223
|
+
"""
|
|
224
|
+
if not input_file_path:
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
trg_file = input_file_path + ".trg"
|
|
228
|
+
end_file = input_file_path + ".end"
|
|
229
|
+
begin_file = input_file_path + ".begin"
|
|
230
|
+
|
|
231
|
+
# マーカーファイルが存在しない場合のみ.endファイルを作成
|
|
232
|
+
if not (os.path.exists(trg_file) or os.path.exists(end_file) or os.path.exists(begin_file)):
|
|
233
|
+
# 空ファイルとして.endファイルを生成
|
|
234
|
+
open(end_file, 'w', encoding='utf-8').close()
|
|
235
|
+
return end_file
|
|
236
|
+
return None
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def create_trg_file_in_file_path_dir(self, file_name):
|
|
240
|
+
"""
|
|
241
|
+
file_pathのディレクトリ配下に指定されたファイル名の.trgファイルを作成する。
|
|
242
|
+
既に.trg, .end, .beginファイルが存在する場合は何もしない。
|
|
243
|
+
"""
|
|
244
|
+
if not self._file_path or not file_name:
|
|
245
|
+
return None
|
|
246
|
+
dir_path = os.path.dirname(self._file_path)
|
|
247
|
+
base_path = os.path.join(dir_path, file_name)
|
|
248
|
+
trg_file = base_path + ".trg"
|
|
249
|
+
end_file = base_path + ".end"
|
|
250
|
+
begin_file = base_path + ".begin"
|
|
251
|
+
if not (os.path.exists(trg_file) or os.path.exists(end_file) or os.path.exists(begin_file)):
|
|
252
|
+
# 空ファイルとして.trgファイルを生成
|
|
253
|
+
open(trg_file, 'w', encoding='utf-8').close()
|
|
254
|
+
return trg_file
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
def get_work_space(self):
|
|
258
|
+
"""
|
|
259
|
+
config_dtoからwork_spaceを取得するメソッド
|
|
260
|
+
"""
|
|
261
|
+
return self.config_dto.work_space
|
|
262
|
+
|
|
263
|
+
def copy_file_todo_trg_to_next_step(self, result_file):
|
|
264
|
+
self.create_current_step_end_trg_file_from_input(result_file)
|
|
265
|
+
next_step_file = self.copy_input_file_to_next_step(result_file)
|
|
266
|
+
self.create_next_step_todo_trg_file_from_input(next_step_file)
|
|
267
|
+
|
|
268
|
+
def change_trg_file_to_end_in_file(self, file_name):
|
|
269
|
+
"""
|
|
270
|
+
file_pathのディレクトリ配下に指定されたファイル名の.trgまたは.beginファイルが存在すれば、.endにリネームする。
|
|
271
|
+
成功時 True、失敗時 False を返す。
|
|
272
|
+
"""
|
|
273
|
+
if not self._file_path or not file_name:
|
|
274
|
+
return False
|
|
275
|
+
dir_path = os.path.dirname(self._file_path)
|
|
276
|
+
base_path = os.path.join(dir_path, file_name)
|
|
277
|
+
trg_file = base_path + ".trg"
|
|
278
|
+
begin_file = base_path + ".begin"
|
|
279
|
+
end_file = base_path + ".end"
|
|
280
|
+
# .trgまたは.beginが存在すれば.endにリネーム
|
|
281
|
+
if os.path.exists(begin_file):
|
|
282
|
+
try:
|
|
283
|
+
os.rename(trg_file, end_file)
|
|
284
|
+
return True
|
|
285
|
+
except Exception:
|
|
286
|
+
print(f"change_trg_file_to_end_in_file error: {trg_file}")
|
|
287
|
+
return False
|
|
288
|
+
return False
|
|
File without changes
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import os
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
class CobolSplitter:
|
|
6
|
+
def __init__(self, input_file):
|
|
7
|
+
self.input_file = input_file
|
|
8
|
+
self.identification_div = []
|
|
9
|
+
self.environment_div = []
|
|
10
|
+
self.data_div = []
|
|
11
|
+
self.procedure_div = [] # list of tuples: (line_text, line_number)
|
|
12
|
+
self.paragraphs = {}
|
|
13
|
+
logging.basicConfig(
|
|
14
|
+
level=logging.DEBUG,
|
|
15
|
+
format="%(asctime)s [%(levelname)s] %(message)s"
|
|
16
|
+
)
|
|
17
|
+
logging.debug(f"Initialized CobolSplitter for file: {input_file}")
|
|
18
|
+
@staticmethod
|
|
19
|
+
def normalize_whitespace(s):
|
|
20
|
+
return re.sub(r'\s+', ' ', s).strip().upper()
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def line_starts_with_division(cls, line, division_name):
|
|
24
|
+
line_norm = cls.normalize_whitespace(line)
|
|
25
|
+
division_norm = cls.normalize_whitespace(division_name)
|
|
26
|
+
return line_norm.startswith(division_norm)
|
|
27
|
+
|
|
28
|
+
def read_file(self):
|
|
29
|
+
logging.debug(f"Reading file: {self.input_file}")
|
|
30
|
+
with open(self.input_file, 'r', encoding='utf-8') as f:
|
|
31
|
+
lines = f.readlines()
|
|
32
|
+
|
|
33
|
+
div = None
|
|
34
|
+
for idx, line in enumerate(lines, 1): # 行番号は1始まり
|
|
35
|
+
if self.line_starts_with_division(line, "IDENTIFICATION DIVISION"):
|
|
36
|
+
div = "IDENTIFICATION"
|
|
37
|
+
logging.debug(f"Found IDENTIFICATION DIVISION at line {idx}")
|
|
38
|
+
elif self.line_starts_with_division(line, "ENVIRONMENT DIVISION"):
|
|
39
|
+
div = "ENVIRONMENT"
|
|
40
|
+
logging.debug(f"Found ENVIRONMENT DIVISION at line {idx}")
|
|
41
|
+
elif self.line_starts_with_division(line, "DATA DIVISION"):
|
|
42
|
+
div = "DATA"
|
|
43
|
+
logging.debug(f"Found DATA DIVISION at line {idx}")
|
|
44
|
+
elif self.line_starts_with_division(line, "PROCEDURE DIVISION"):
|
|
45
|
+
div = "PROCEDURE"
|
|
46
|
+
logging.debug(f"Found PROCEDURE DIVISION at line {idx}")
|
|
47
|
+
elif line.strip() == ".":
|
|
48
|
+
div = None
|
|
49
|
+
logging.debug(f"Division end at line {idx}")
|
|
50
|
+
|
|
51
|
+
if div == "IDENTIFICATION":
|
|
52
|
+
self.identification_div.append(line)
|
|
53
|
+
elif div == "ENVIRONMENT":
|
|
54
|
+
self.environment_div.append(line)
|
|
55
|
+
elif div == "DATA":
|
|
56
|
+
self.data_div.append(line)
|
|
57
|
+
elif div == "PROCEDURE":
|
|
58
|
+
self.procedure_div.append( (line, idx) ) # タプルで行テキストと行番号を保持
|
|
59
|
+
else:
|
|
60
|
+
self.identification_div.append(line)
|
|
61
|
+
logging.debug("Finished reading and splitting divisions.")
|
|
62
|
+
|
|
63
|
+
def split_paragraphs(self):
|
|
64
|
+
logging.debug("Splitting PROCEDURE DIVISION into paragraphs.")
|
|
65
|
+
procedure_lines = self.procedure_div[:]
|
|
66
|
+
if procedure_lines and self.line_starts_with_division(procedure_lines[0][0], "PROCEDURE DIVISION"):
|
|
67
|
+
procedure_lines.pop(0)
|
|
68
|
+
|
|
69
|
+
para_header_re = re.compile(r"^\s*([A-Z0-9\-]+)\.\s*$", re.I)
|
|
70
|
+
|
|
71
|
+
current_para = None
|
|
72
|
+
current_lines = []
|
|
73
|
+
|
|
74
|
+
for line, lineno in procedure_lines:
|
|
75
|
+
m = para_header_re.match(line)
|
|
76
|
+
if m:
|
|
77
|
+
if current_para:
|
|
78
|
+
self.paragraphs[current_para] = current_lines
|
|
79
|
+
logging.debug(f"Paragraph '{current_para}' ends at line {lineno}")
|
|
80
|
+
current_para = m.group(1)
|
|
81
|
+
current_lines = [(line, lineno)]
|
|
82
|
+
logging.debug(f"Paragraph '{current_para}' starts at line {lineno}")
|
|
83
|
+
else:
|
|
84
|
+
if current_para:
|
|
85
|
+
current_lines.append((line, lineno))
|
|
86
|
+
else:
|
|
87
|
+
current_para = "MAIN"
|
|
88
|
+
current_lines = [(line, lineno)]
|
|
89
|
+
if current_para:
|
|
90
|
+
self.paragraphs[current_para] = current_lines
|
|
91
|
+
logging.debug(f"Paragraph '{current_para}' ends at last line.")
|
|
92
|
+
logging.debug(f"Total paragraphs found: {len(self.paragraphs)}")
|
|
93
|
+
|
|
94
|
+
def write_files(self):
|
|
95
|
+
logging.debug("Writing split paragraphs to files.")
|
|
96
|
+
created_files = []
|
|
97
|
+
|
|
98
|
+
base_name = os.path.splitext(os.path.basename(self.input_file))[0]
|
|
99
|
+
input_dir = os.path.dirname(self.input_file)
|
|
100
|
+
outdir = os.path.join(input_dir, base_name)
|
|
101
|
+
os.makedirs(outdir, exist_ok=True)
|
|
102
|
+
logging.debug(f"Output directory created: {outdir}")
|
|
103
|
+
|
|
104
|
+
for para, lines_para in self.paragraphs.items():
|
|
105
|
+
# パラグラフの開始行番号を取得
|
|
106
|
+
start_line = lines_para[0][1] if lines_para else 0
|
|
107
|
+
outfname = os.path.join(outdir, f"{base_name}_{para}_{start_line}.cbl")
|
|
108
|
+
|
|
109
|
+
with open(outfname, "w", encoding="utf-8") as f:
|
|
110
|
+
# パラグラフの内容のみを出力(行番号コメントなし)
|
|
111
|
+
for line, lineno in lines_para:
|
|
112
|
+
f.write(line)
|
|
113
|
+
if not line.endswith("\n"):
|
|
114
|
+
f.write("\n")
|
|
115
|
+
|
|
116
|
+
created_files.append(outfname)
|
|
117
|
+
logging.info(f"Created: {outfname}")
|
|
118
|
+
|
|
119
|
+
logging.debug("All paragraph files written.")
|
|
120
|
+
return created_files
|
|
121
|
+
|
|
122
|
+
def run(self):
|
|
123
|
+
logging.info("CobolSplitter run started.")
|
|
124
|
+
self.read_file()
|
|
125
|
+
self.split_paragraphs()
|
|
126
|
+
created_files = self.write_files()
|
|
127
|
+
logging.info("CobolSplitter run finished.")
|
|
128
|
+
return created_files
|
pilot/unit/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from src.pilot.unit.unit_interface import UnitInterface
|
|
4
|
+
from src.pilot.job.impl.base_job import BaseJob
|
|
5
|
+
from src.pilot.config.config_reader import ConfigReader
|
|
6
|
+
|
|
7
|
+
class BaseUnit(UnitInterface):
|
|
8
|
+
config_dto = None
|
|
9
|
+
joblist = []
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.config_dto = ConfigReader().get_dto()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _init_job(self,step):
|
|
16
|
+
return BaseJob()
|
|
17
|
+
|
|
18
|
+
def run(self):
|
|
19
|
+
steps = self.config_dto.steps
|
|
20
|
+
skipsteps = self.config_dto.skipsteps
|
|
21
|
+
for index, step in enumerate(steps):
|
|
22
|
+
if step in skipsteps:
|
|
23
|
+
continue
|
|
24
|
+
self._run_jobs_in_step_dir(self.config_dto.work_space+ "/" +step,step,index)
|
|
25
|
+
|
|
26
|
+
def _run_jobs_in_step_dir(self, current_step_dir, step,index):
|
|
27
|
+
for dirpath, _, filenames in os.walk(current_step_dir):
|
|
28
|
+
for filename in filenames:
|
|
29
|
+
file_path = os.path.join(dirpath, filename)
|
|
30
|
+
job = self._init_job(step)
|
|
31
|
+
job.current_step = step
|
|
32
|
+
job.step_index = index
|
|
33
|
+
job.file_path = file_path
|
|
34
|
+
if self.job_need_run(job,filename,index):
|
|
35
|
+
job.run()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def job_need_run(self, job:BaseJob,filename: str,index):
|
|
39
|
+
return True
|
pilot/util/__init__.py
ADDED
|
File without changes
|
pilot/util/files.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import csv
|
|
3
|
+
|
|
4
|
+
class FileUtil:
|
|
5
|
+
@staticmethod
|
|
6
|
+
def exists(path: str) -> bool:
|
|
7
|
+
return os.path.exists(path)
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def read(path: str, encoding: str = "utf-8") -> str:
|
|
11
|
+
with open(path, "r", encoding=encoding) as f:
|
|
12
|
+
return f.read()
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def write(path: str, data: str, encoding: str = "utf-8") -> None:
|
|
16
|
+
with open(path, "w", encoding=encoding) as f:
|
|
17
|
+
f.write(data)
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def export_files_to_csv(folder: str, csv_path: str) -> None:
|
|
21
|
+
import re
|
|
22
|
+
rows = []
|
|
23
|
+
max_depth = 0
|
|
24
|
+
file_infos = []
|
|
25
|
+
for root, _, files in os.walk(folder):
|
|
26
|
+
for file in files:
|
|
27
|
+
rel_path = os.path.relpath(os.path.join(root, file), folder)
|
|
28
|
+
parts = rel_path.split(os.sep)
|
|
29
|
+
file_infos.append((parts, rel_path, root))
|
|
30
|
+
if len(parts) > max_depth:
|
|
31
|
+
max_depth = len(parts)
|
|
32
|
+
headers = ["No", "file", "ext", "folder_rel_path", "prefix_before_number"] + [f"fold{i + 1}" for i in range(max_depth - 1)]
|
|
33
|
+
for idx, (parts, rel_path, folder_full_path) in enumerate(file_infos, 1):
|
|
34
|
+
file_name = parts[-1]
|
|
35
|
+
ext = os.path.splitext(file_name)[1][1:]
|
|
36
|
+
folders = parts[:-1]
|
|
37
|
+
folder_rel_path = os.path.relpath(folder_full_path, folder)
|
|
38
|
+
match = re.match(r"([^\d]*)(\d.*)?", file_name)
|
|
39
|
+
prefix_before_number = match.group(1) if match and match.group(2) else ""
|
|
40
|
+
row = [idx, file_name, ext, folder_rel_path, prefix_before_number] + folders + [""] * (max_depth - 1 - len(folders))
|
|
41
|
+
rows.append(row)
|
|
42
|
+
with open(csv_path, "w", newline="", encoding="utf-8") as f:
|
|
43
|
+
writer = csv.writer(f)
|
|
44
|
+
writer.writerow(headers)
|
|
45
|
+
writer.writerows(rows)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pilot.linkstec
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: pilot of the ship, a tool for managing and deploying Python projects.
|
|
5
|
+
Author-email: wanglr <wanglr1980@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/nighter1980/pilot
|
|
8
|
+
Project-URL: Issues, https://github.com/nighter1980/pilot/issues
|
|
9
|
+
Keywords: python,project management,deployment
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# pilot
|
|
18
|
+
|
|
19
|
+
This is a simple example package. You can use
|
|
20
|
+
to write your content.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
pilot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
pilot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pilot/config/config_reader.py,sha256=RL9925CIjKyimvcspzmZkPzJUJe6z28cfz5nGhZ3g3k,3308
|
|
4
|
+
pilot/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
pilot/control/control_interface.py,sha256=zGv380oQgAKPAIHDHeFdPYzhj2Ngo2T66NWlNloA7vY,124
|
|
6
|
+
pilot/control/impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
pilot/control/impl/base_controller.py,sha256=wAQTBFk9_bPFnxXiAOw0Au1pGeZvI7uHM2yde9TJTM4,965
|
|
8
|
+
pilot/conver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
pilot/conver/converfileEncodding.py,sha256=UqjcWO0bzkuTRHLEWrWJkeo3p-P7WuYE7jFKveyPekA,2781
|
|
10
|
+
pilot/conver/nkf_converter.py,sha256=JqgThmXcdnTGMsLIHUEwe8sc0VGMqDaKCIQTg-UE3WE,1148
|
|
11
|
+
pilot/generater/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
pilot/generater/vertexai.py,sha256=P56h5Y_frWzBVLgIg_cs1gu3o9rhX8FyeD8EGe6RJZ8,2393
|
|
13
|
+
pilot/job/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
pilot/job/job_interface.py,sha256=LL0hfuFfnKnkpQD99jv1hkaAIAFM-JJPrX3PFxN6O_A,120
|
|
15
|
+
pilot/job/impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
pilot/job/impl/base_job.py,sha256=1ogh6Ge6qH7gOM5I4dV58xu4NH5gK6-9LYzGHk_Woyc,11701
|
|
17
|
+
pilot/splitters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
pilot/splitters/cobolsplitter.py,sha256=oPwxKRjA7TyXWaWV3jdy59lJZy1mRn6yxD9ivqFYCuY,5461
|
|
19
|
+
pilot/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
pilot/unit/unit_interface.py,sha256=fE8N4h_rZU-dWLHy9o0EE3yyErGmRyIuGUDb-zqe7qo,167
|
|
21
|
+
pilot/unit/impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
pilot/unit/impl/base_unit.py,sha256=SiyByVtxflRz91E-LHdjkX9Qrs_0NNNjIXoaDjbF2ww,1276
|
|
23
|
+
pilot/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
pilot/util/files.py,sha256=v9uzfzo3Aq4xgnUIASEZeBJoA2nD9Qz_EA3P-FwzGFQ,1896
|
|
25
|
+
pilot_linkstec-0.0.1.dist-info/licenses/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
|
26
|
+
pilot_linkstec-0.0.1.dist-info/METADATA,sha256=-WkAak-d4m4-LPY0No1WQeyCVih39c_VAXDgzKsrHjE,678
|
|
27
|
+
pilot_linkstec-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
28
|
+
pilot_linkstec-0.0.1.dist-info/top_level.txt,sha256=BijnVJdXnIPxxx3s60M848seL4Z12gNUPod6KPJxK9c,6
|
|
29
|
+
pilot_linkstec-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pilot
|