-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileTreeCreator.py
More file actions
317 lines (270 loc) · 14.3 KB
/
Copy pathFileTreeCreator.py
File metadata and controls
317 lines (270 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================================================
FILE TREE CREATOR FOR WEBSITE
===========================================================
Description:
Web sitesi veya dosya sistemi dokümantasyonu için belirtilen dizinden başlayarak tüm alt
dizin ve dosyaları özyinelemeli olarak tarayan, dosya ve klasör yapısını JSON formatında
dışa aktaran Python aracı. Dosya boyutu, tarih, göreli yol ve tam URL bilgilerini toplar.
Author:
Mefamex (info@mefamex.com) (https://mefamex.com)
Features:
- Belirtilen ana dizinden başlayarak tüm alt dizin ve dosyaları özyinelemeli tarama
- Her dosya ve klasör için kapsamlı bilgi toplama (isim, yol, URL, boyut, tarih)
- Dizin ve dosya yapısını ağaç şeklinde JSON formatında dışa aktarma
- Hariç tutulacak klasör ve dosyaları filtreleme imkanı
- Her dosya ve klasör için tam URL oluşturma
- Özelleştirilebilir çıktı dizini ve dosya adı
- Web sitesi dokümantasyonu için optimize edilmiş yapı
Modules:
- os : Dosya ve dizin işlemleri için kullanılır
- json : JSON dosyası oluşturmak ve okumak için kullanılır
- datetime: Dosya tarih bilgilerini almak için kullanılır
- pathlib : Dosya ve dizin yollarını yönetmek için kullanılır
- typing : Tip ipuçları için kullanılır
Classes:
- Walker_file: Tek bir dosyanın bilgilerini tutar ve JSON'a dönüştürür
- Walker_path: Bir dizinin bilgilerini, alt dizinlerini ve içindeki dosyaları tutar
- FileTreeCreator: Ana sınıf - dizinleri tarar, verileri toplar ve JSON çıktısı üretir
Functions:
- Walker_file.to_dict() : Walker_file nesnesini sözlüğe çevirir
- Walker_path.to_dict() : Walker_path nesnesini sözlüğe çevirir
- FileTreeCreator.walker(root) : Dizinleri ve dosyaları özyinelemeli olarak tarar
- FileTreeCreator.print_file_tree(): Oluşturulan dosya ağacını ekrana yazdırır
- FileTreeCreator.save_file_tree() : Dosya ağacını JSON dosyasına kaydeder
Usage:
1. Ana dizini ve çıktı dizinini belirleyin.
2. Gerekirse hariç tutulacak dizin ve dosya adlarını girin.
3. Scripti çalıştırın: `python FileTreeCreator.py`
4. Sonuç olarak belirtilen dizinde `file_tree.json` dosyası oluşacaktır.
Requirements:
- Python 3.8 veya üstü
- Dependencies:
- os (built-in)
- json (built-in)
- datetime (built-in)
- pathlib (built-in)
- typing (built-in)
Installation:
1. Tek dosya olarak kullanım:
- Bu dosyayı projenize kopyalayın
- Python -> from FileTreeCreator import FileTreeCreator
- cmd -> python FileTreeCreator.py
Documentation:
- Detaylı kullanım örnekleri: `README.md`
- API dokümantasyonu: Kod içi docstring'ler
License:
MIT Lisansı (https://opensource.org/licenses/MIT)
Changelog:
- 1.0.0 (2025-05-04): İlk sürüm
- 1.0.1 (2025-05-03): Dosya yolu (relative_path) ile oluşan hata giderildi
- 1.0.2 (2025-06-09): Dosya yolu (relative_path) ile oluşan hata giderildi
- 1.0.3 (2025-07-14): Değişken türleri düzenlendi
- 1.0.4 (2025-07-18): Modül dokümantasyonu düzenlendi, full_url değişkeni güncellendi
- 1.0.5 (2025-07-20): Modül dokümantasyonu, metadatalar güncellendi, gereksiz kodlar kaldırıldı
Contributors: None
Contact:
- Email: info@mefamex.com
- Website: https://mefamex.com
- GitHub: https://github.com/Mefamex/Python_Code_Snippets
Additional Information:
Bu modül özellikle web sitesi dokümantasyonu ve dosya sistemi görselleştirmesi için
tasarlanmıştır. JSON çıktısı web uygulamalarında kolayca kullanılabilir formattadır.
Notes:
- Bu modül web sitesi dosya ağacı oluşturmak için optimize edilmiştir
- BASE_URL değişkeni ile tam URL'ler otomatik olarak oluşturulur
- Filtreleme sistemi ile istenmeyen dosya/klasörler hariç tutulabilir
- Çıktı JSON formatı web uygulamaları için uygundur
Disclaimer and Legal Notice:
Bu yazılım, herhangi bir garanti olmaksızın "olduğu gibi" sağlanmaktadır.
Yazar, bu yazılımın kullanımı sonucunda oluşabilecek zararlardan sorumlu değildir.
Kullanıcılar, yazılımı kendi sorumlulukları altında kullanmalıdır.
MIT Lisansı kapsamında açık kaynak olarak dağıtılır ve kullanıcılar lisans
koşullarına uymakla yükümlüdür. Yazılımın değiştirilmesi, dağıtılması veya
kullanılması lisans koşullarına uygun olmalıdır.
===========================================================
"""
__version__ = "1.0.5"
__author__ = "Mefamex"
__email__ = "info@mefamex.com"
__license__ = "MIT"
__status__ = "STABLE"
__project_name__ = "file-tree-creator"
__url__ = "https://mefamex.com"
__url_github__ = "https://github.com/Mefamex/Python_Code_Snippets"
__copyright__ = "Copyright (c) 2025 Mefamex"
__description__ = "Web sitesi veya dosya sistemi için dizin yapısını JSON formatında dışa aktaran Python aracı"
__date__ = "2025-05-04"
__date_modify__ = "2025-07-20"
__python_version__ = ">=3.8"
__dependencies__ = {
"os": "built-in",
"json": "built-in",
"datetime": "built-in",
"pathlib": "built-in",
"typing": "built-in"
}
#============================ IMPORTS =========================================
import os, json, datetime
from pathlib import Path
from typing import Optional
#==============================================================================
#============================ CONSTANTS =======================================
BASE_URL = "https://mefamex.com"
#==============================================================================
#============================ DATA CLASSES ====================================
class Walker_file:
def __init__(self, name: str, path: str, url: str, relative_path : str):
self.name : str = name
self.path : str = path
self.url : str = url
self.size : int = os.path.getsize(path) if os.path.isfile(path) else 0
self.date : str = datetime.datetime.fromtimestamp(os.path.getmtime(path)).strftime("%Y-%m-%d") if os.path.isfile(path) else "2000-01-01"
self.relative_path : str = relative_path
self.full_url = lambda : BASE_URL + "/" + self.url if self.url else ""
def to_dict(self):
result = {
"name": self.name,
"url" : self.url,
"size": self.size,
"date": self.date,
"full_url" : self.full_url(),
"relative_path" : self.relative_path,
}
if hasattr(self, 'path') and self.path: result["path"] = self.path
return result
class Walker_path:
def __init__(self, name: str, path: str, url: str, date: str, relative_path : str):
self.name : str = name
self.path : str = path
self.url : str = url
self.size : int = 0
self.date : str = date # format = YYYY-MM-DD
self.relative_path : str = relative_path
self.full_url = lambda : BASE_URL + "/" + self.url if self.url else None
self.folder : list[Walker_path] = []
self.files : list[Walker_file] = []
def to_dict(self):
result = {
"name": self.name,
"url" : self.url,
"size": self.size,
"date": self.date,
"relative_path" : self.relative_path,
"full_url" : self.full_url(),
"folder" : [child.to_dict() for child in self.folder],
"files" : [file.to_dict() for file in self.files],
}
if hasattr(self, 'path') and self.path: result["path"] = self.path
return result
#==============================================================================
#============================ MAIN CLASS ======================================
class FileTreeCreator:
def __init__(self, base_dir: Path = Path.cwd(), output_dir: Path = Path.cwd(), output_file: Path = Path("file_tree.json"), passDirs: list= [], passFiles : list= []) -> None:
# check base_dir
self.base_dir : Path = Path(base_dir)
if not self.base_dir.exists(): raise FileNotFoundError(f"Base directory '{self.base_dir}' does not exist.")
print(f"Base directory: '{self.base_dir}'")
# check output_dir
self.output_dir : Path = Path(output_dir)
if not self.output_dir.exists():
try:
self.output_dir.mkdir(parents=True, exist_ok=True)
print(f"Output directory '{self.output_dir}' created.")
except Exception as e:
raise OSError(f"Could not create output directory '{self.output_dir}': {e}")
else: print(f"Output directory already exists: '{self.output_dir}' ")
if not isinstance(passDirs, list): raise TypeError("passDirs must be a list.")
self.passDirs : list = passDirs if passDirs else []
self.passFiles : list = passFiles if passFiles else []
self.output_file : Path = self.output_dir / output_file
self.file_tree : dict = {}
self.walker(base_dir)
# self.print_file_tree()
self.save_file_tree()
def walker(self, root : Path) -> Optional[Walker_path] :
# get directories and files in the root directory
with os.scandir(root) as entries: dirs = [entry.name for entry in entries if entry.is_dir()]
with os.scandir(root) as entries: files = [entry.name for entry in entries if entry.is_file()]
# Skip directories that should be ignored
relative_path = os.path.relpath(root, self.base_dir)
# Skip directories based on various conditions
if (any(dir in str(root) for dir in self.passDirs) or not os.path.isdir(root) or os.path.islink(root) or any(part.startswith(".") for part in Path(root).parts) ) or any(dir in str(root) for dir in self.passDirs):
print(f"Skipped directory: {root}")
return None
# create a new Walker_path object for the current directory
name = os.path.basename(root)
path = os.path.abspath(root)
print(path)
url = f"{relative_path.replace(os.sep, '/')}"
date = datetime.datetime.fromtimestamp(os.path.getmtime(path)).strftime("%Y-%m-%d")
relative_path = os.path.relpath(path, self.base_dir)
walker_path = Walker_path(name=name, path = path, url= url, date = date,relative_path= relative_path)
self.file_tree[name] = walker_path
# process each file in the directory
files = ["index.html"] + [f for f in files if f != "index.html"] if "index.html" in files else files
for file in files:
if any(file.startswith(pf) for pf in self.passFiles):
print(f"Skipped file: {file}")
continue
name = file
path = os.path.join(root, file)
relative_path = os.path.relpath(path, self.base_dir)
url = f"{relative_path.replace(os.sep, '/')}"
if date > walker_path.date or walker_path.date is None: walker_path.date = date
walker_path.files.append(Walker_file(name, path, url, relative_path))
walker_path.size += os.path.getsize(path) if os.path.isfile(path) else 0
for dir in dirs:
dir_path : Path = Path(os.path.join(root, dir))
if os.path.isdir(dir_path):
child = self.walker(dir_path)
if child:
walker_path.folder.append(child)
walker_path.size += child.size
if child.date > walker_path.date or walker_path.date is None: walker_path.date = child.date
print(f"+++++++++++ Processed directory: {root}")
return walker_path
def print_file_tree(self) -> None :
for name, file in self.file_tree.items():
deep = len(file.relative_path.split(os.sep))
print("===="*deep+"===============================")
print(f"{" | "*deep}Name : {file.name}")
print(f"{" | "*deep}Path : {file.path}")
print(f"{" | "*deep}URL : {file.url}")
print(f"{" | "*deep}Date : {file.date}")
print(f"{" | "*deep}Relative Path: {file.relative_path}")
print(f"{" | "*deep}Full URL : {file.full_url}")
print(f"{" | "*deep}Files ({len(file.files)}): {[file.name for file in file.files]}")
print(f"{" | "*deep}folder ({len(file.folder)}): {[child.name for child in file.folder]}")
print("===="*deep+"===============================")
first_item = self.file_tree.get(next(iter(self.file_tree.keys())))
if first_item is not None: print(json.dumps(first_item.to_dict(), indent=4, ensure_ascii=False))
else: print("No file tree data available.")
def save_file_tree(self) -> None:
first_key = next(iter(self.file_tree.keys()))
first_level = self.file_tree.get(first_key)
def delpath(obj):
if hasattr(obj, 'path'): del obj.path
if hasattr(obj, 'files'):
for file in obj.files: del file.path
if hasattr(obj, 'folder'):
for child in obj.folder: delpath(child)
delpath(first_level)
if first_level is not None:
first_level.name = BASE_URL
json_data = first_level.to_dict()
with open(self.output_file, "w", encoding="utf-8") as f: json.dump(json_data, f, indent=4, ensure_ascii=False)
print(f"File tree saved to {self.output_file}")
else: print("No file tree data available to save.")
#==============================================================================
#============================ MAIN EXECUTION ==================================
if __name__ == "__main__":
base_dir = Path(os.getcwd())
passDirs = ["sweetmonstermia" ]
passFiles =["yandex_" ]
output_dir = Path(os.path.join(base_dir, "py", "Filetree"))
output_file = Path("file_tree.json")
FileTreeCreator(base_dir=base_dir, output_dir=output_dir, output_file=output_file, passDirs=passDirs, passFiles=passFiles)
#==============================================================================