clapp-pm 1.0.20__py3-none-any.whl → 1.0.21__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.
- {clapp_pm-1.0.20.data → clapp_pm-1.0.21.data}/data/version.json +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/METADATA +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/RECORD +10 -8
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/top_level.txt +2 -0
- new_command.py +181 -0
- progress_utils.py +274 -0
- version.py +1 -1
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/WHEEL +0 -0
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/entry_points.txt +0 -0
- {clapp_pm-1.0.20.dist-info → clapp_pm-1.0.21.dist-info}/licenses/LICENSE +0 -0
@@ -12,16 +12,18 @@ list_command.py,sha256=qbeocvrg2eXRklxbYS3audQhYHGXTlMBk_tNh1cMxd0,8391
|
|
12
12
|
main.py,sha256=uf2-LzBBFIwIiyg1kcyZG4J1B9f5U33VHieBXu1uLi8,23889
|
13
13
|
manifest_schema.py,sha256=qR6dIpYL1zwAJmrij05gkgE_urN3qVamoUi2BgR7Lv4,2801
|
14
14
|
manifest_validator.py,sha256=JW0mETHDQCSMhodZ5sntr5KPU8T5LYv4IiVoAp4zOIY,8092
|
15
|
+
new_command.py,sha256=gz1w8zMf-gFITtRQAc9G2WES2akuCwdH7dtuDu9TacU,5926
|
15
16
|
package_registry.py,sha256=Rco15cvz-6lpCEDdCzwGZNCKtvVhlFIsEPy-WFAESMM,4233
|
16
17
|
package_runner.py,sha256=GqLPlQRxh7g3bDgGDSVpmHdeRXaP5f6s8kp8QVnw5LM,5783
|
17
18
|
package_signing.py,sha256=ModMAzLk08rkI6zd8QKhyCH5BFbB-7dy8pwqKYatFQo,4579
|
18
19
|
post_install_hint.py,sha256=wjMPCgRurZiGu6hv_se-XA36KqBCdeYdRCD1q7FrJzQ,4918
|
20
|
+
progress_utils.py,sha256=yiQ2e-jrU8UVt36iOC_pdKx6cuv1YPNCTZNIItbEPPU,8263
|
19
21
|
publish_command.py,sha256=P05AFbu_mxcc1yAiwShN5Yi9PX1o_7TFXD1mowJcqJE,8589
|
20
22
|
remote_registry.py,sha256=rPBIM_ESXUt0br5cARQ4YbzUoTda0G4e1KGzfyYMbpQ,8235
|
21
23
|
smart_search.py,sha256=R5O5CDXqlQc-N-6R6D5k36_-arCB-wnKfmWr5zMYWUI,15741
|
22
24
|
uninstall_command.py,sha256=rQYbZ-XMw8Xxw1fmgGdDaBQmgBGqyJ_rTBZkvEV5HV0,7066
|
23
25
|
validate_command.py,sha256=idaujErzrwuZNT6DYCVTVwZqBDEEi1GTxIXAGBgKMKM,7623
|
24
|
-
version.py,sha256=
|
26
|
+
version.py,sha256=H9_enMWKOmwY_YpwVRxCb26vBaOVq9GK3iQUblkJn68,224
|
25
27
|
version_command.py,sha256=DZuYWtohSeM5PJNYCflBy36_k0vex3tYV2C8ixEA9ho,4259
|
26
28
|
version_manager.py,sha256=fpC7jxhIW1wZhJ9IkVwyqkgJN4mhBjUUbaLefXLDMiM,11423
|
27
29
|
where_command.py,sha256=TcLoXLGmrPSHQuvlceVuuKBsfeadIwz-E0G_5okH14g,6420
|
@@ -60,8 +62,8 @@ clapp-packages-repo/packages/test-app/main.py,sha256=rN4Zo9u53bIVjcUlul059knx6v-
|
|
60
62
|
clapp-packages-repo/packages/test-app/manifest.json,sha256=kJe4sjYdPRNZD5hEeca80jj3lxeEWBMJoZ59RW7tiKI,118
|
61
63
|
clapp-packages-repo/packages/test-app2/main.py,sha256=lHkbjTmehFY4VuYYF2dYiVBH7W0oqHHeY0I5W85iPTY,35
|
62
64
|
clapp-packages-repo/packages/test-app2/manifest.json,sha256=vshXJrtRxBc_ISM6E8KT5BSmveMbjWszenlgxgSN86w,121
|
63
|
-
clapp_pm-1.0.
|
64
|
-
clapp_pm-1.0.
|
65
|
+
clapp_pm-1.0.21.data/data/version.json,sha256=14ypbLPPM7__r9B0nGVxi9y3DQRkDYpd70LvStBPIXQ,239
|
66
|
+
clapp_pm-1.0.21.dist-info/licenses/LICENSE,sha256=_hryv9pKR6udRexceUYuoYCJGmYBz7e-vRuFWmm38UY,1075
|
65
67
|
docs/developer_guide.md,sha256=B-S141TSNy7e8T9KaV6Fr-ZAFhYqqgcwqWijjX0C2Xc,7336
|
66
68
|
templates/dart/manifest.json,sha256=ycVKZxrArzcSoRZ5LKKe8aOerwk5Z-7VX0td86aim0M,267
|
67
69
|
templates/lua/manifest.json,sha256=CRIy0dP6Pr3vH6IV4dObGs4KqqJ_sURsY0wAgK2av7E,262
|
@@ -71,8 +73,8 @@ templates/python/manifest.json,sha256=hjmKqsEkWEBTwxFgm35MkvuwWZ2CQWq9Zo8uHodqHr
|
|
71
73
|
test-app/README.md,sha256=AqVgCZ-cwXBuDHFoJdYkAHAuB6SjSjqXQrjhLu0q7cc,964
|
72
74
|
test-app/main.py,sha256=24IEuyHSuPWJp2-xYhInUNEWqeueGxAO3NBgHkEgLdQ,1562
|
73
75
|
test-app/manifest.json,sha256=MM1nl5Bljrnsik3fwsrgFBchfgwIb2REoBwwzNpFHQU,284
|
74
|
-
clapp_pm-1.0.
|
75
|
-
clapp_pm-1.0.
|
76
|
-
clapp_pm-1.0.
|
77
|
-
clapp_pm-1.0.
|
78
|
-
clapp_pm-1.0.
|
76
|
+
clapp_pm-1.0.21.dist-info/METADATA,sha256=x7XdkEWtZ2OidLL19YVZOzCEY1RPf2ilwr6VuZehWgM,3980
|
77
|
+
clapp_pm-1.0.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
78
|
+
clapp_pm-1.0.21.dist-info/entry_points.txt,sha256=7j-3pQVpQfnaVzUV83g7zlCA30ePlnXkhHLAGGz9xrQ,36
|
79
|
+
clapp_pm-1.0.21.dist-info/top_level.txt,sha256=2FeS-lC1OV3lBqLAHahLU8vcWxlxSDLNJSk-4MmymKk,475
|
80
|
+
clapp_pm-1.0.21.dist-info/RECORD,,
|
new_command.py
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
new_command.py - Yeni Uygulama Oluşturma Komutu
|
4
|
+
|
5
|
+
Bu modül clapp için yeni uygulama şablonları oluşturur.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import os
|
9
|
+
import shutil
|
10
|
+
import json
|
11
|
+
from pathlib import Path
|
12
|
+
from package_runner import get_supported_languages
|
13
|
+
|
14
|
+
def create_new_app(language: str, app_name: str, target_dir: str | None = None) -> tuple[bool, str]:
|
15
|
+
"""
|
16
|
+
Yeni bir clapp uygulaması oluşturur
|
17
|
+
|
18
|
+
Args:
|
19
|
+
language: Programlama dili
|
20
|
+
app_name: Uygulama adı
|
21
|
+
target_dir: Hedef dizin (opsiyonel)
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
(success, message)
|
25
|
+
"""
|
26
|
+
try:
|
27
|
+
# Dil kontrolü
|
28
|
+
if language.lower() not in get_supported_languages():
|
29
|
+
supported = ', '.join(get_supported_languages())
|
30
|
+
return False, f"Desteklenmeyen dil: {language}. Desteklenen diller: {supported}"
|
31
|
+
|
32
|
+
# Uygulama adı kontrolü
|
33
|
+
if not app_name or not app_name.strip():
|
34
|
+
return False, "Uygulama adı boş olamaz"
|
35
|
+
|
36
|
+
app_name = app_name.strip().lower()
|
37
|
+
|
38
|
+
# Geçersiz karakter kontrolü
|
39
|
+
invalid_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|']
|
40
|
+
for char in invalid_chars:
|
41
|
+
if char in app_name:
|
42
|
+
return False, f"Uygulama adında geçersiz karakter: {char}"
|
43
|
+
|
44
|
+
# Hedef dizin belirleme
|
45
|
+
if target_dir:
|
46
|
+
target_path = Path(target_dir) / app_name
|
47
|
+
else:
|
48
|
+
target_path = Path.cwd() / app_name
|
49
|
+
|
50
|
+
# Dizin zaten var mı kontrol et
|
51
|
+
if target_path.exists():
|
52
|
+
return False, f"Dizin zaten mevcut: {target_path}"
|
53
|
+
|
54
|
+
# Şablon dizini
|
55
|
+
template_dir = Path(__file__).parent / "templates" / language.lower()
|
56
|
+
|
57
|
+
if not template_dir.exists():
|
58
|
+
return False, f"Şablon bulunamadı: {language}"
|
59
|
+
|
60
|
+
# Dizini oluştur
|
61
|
+
target_path.mkdir(parents=True, exist_ok=True)
|
62
|
+
|
63
|
+
# Şablon dosyalarını kopyala
|
64
|
+
for item in template_dir.iterdir():
|
65
|
+
if item.is_file():
|
66
|
+
# Dosya adını uygulama adına göre güncelle
|
67
|
+
if item.name == "manifest.json":
|
68
|
+
update_manifest(item, target_path / item.name, app_name, language)
|
69
|
+
else:
|
70
|
+
shutil.copy2(item, target_path / item.name)
|
71
|
+
elif item.is_dir():
|
72
|
+
# Alt dizinleri kopyala
|
73
|
+
shutil.copytree(item, target_path / item.name)
|
74
|
+
|
75
|
+
# Başarı mesajı
|
76
|
+
success_message = f"""
|
77
|
+
✅ Yeni {language} uygulaması oluşturuldu!
|
78
|
+
|
79
|
+
📁 Dizin: {target_path}
|
80
|
+
🚀 Çalıştırmak için:
|
81
|
+
cd {app_name}
|
82
|
+
clapp validate .
|
83
|
+
clapp install .
|
84
|
+
clapp run {app_name}
|
85
|
+
|
86
|
+
📖 Geliştirme için docs/developer_guide.md dosyasını inceleyin.
|
87
|
+
""".strip()
|
88
|
+
|
89
|
+
return True, success_message
|
90
|
+
|
91
|
+
except Exception as e:
|
92
|
+
return False, f"Uygulama oluşturma hatası: {str(e)}"
|
93
|
+
|
94
|
+
def update_manifest(template_path: Path, target_path: Path, app_name: str, language: str):
|
95
|
+
"""
|
96
|
+
Manifest dosyasını uygulama adına göre günceller
|
97
|
+
|
98
|
+
Args:
|
99
|
+
template_path: Şablon manifest dosyası
|
100
|
+
target_path: Hedef manifest dosyası
|
101
|
+
app_name: Uygulama adı
|
102
|
+
language: Programlama dili
|
103
|
+
"""
|
104
|
+
try:
|
105
|
+
# Şablon manifest'i oku
|
106
|
+
with open(template_path, 'r', encoding='utf-8') as f:
|
107
|
+
manifest = json.load(f)
|
108
|
+
|
109
|
+
# Uygulama adını güncelle
|
110
|
+
manifest['name'] = app_name
|
111
|
+
|
112
|
+
# Açıklamayı güncelle
|
113
|
+
if 'description' in manifest:
|
114
|
+
manifest['description'] = manifest['description'].replace(
|
115
|
+
'hello-' + language.lower(), app_name
|
116
|
+
)
|
117
|
+
|
118
|
+
# Hedef dosyaya yaz
|
119
|
+
with open(target_path, 'w', encoding='utf-8') as f:
|
120
|
+
json.dump(manifest, f, indent=2, ensure_ascii=False)
|
121
|
+
|
122
|
+
except Exception as e:
|
123
|
+
print(f"⚠️ Manifest güncelleme hatası: {e}")
|
124
|
+
|
125
|
+
def list_available_templates() -> str:
|
126
|
+
"""
|
127
|
+
Mevcut şablonları listeler
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
Formatlanmış şablon listesi
|
131
|
+
"""
|
132
|
+
templates_dir = Path(__file__).parent / "templates"
|
133
|
+
|
134
|
+
if not templates_dir.exists():
|
135
|
+
return "❌ Şablon dizini bulunamadı"
|
136
|
+
|
137
|
+
result = "📋 Mevcut Şablonlar:\n"
|
138
|
+
result += "=" * 30 + "\n\n"
|
139
|
+
|
140
|
+
for template in sorted(templates_dir.iterdir()):
|
141
|
+
if template.is_dir():
|
142
|
+
# Şablon bilgilerini oku
|
143
|
+
manifest_path = template / "manifest.json"
|
144
|
+
if manifest_path.exists():
|
145
|
+
try:
|
146
|
+
with open(manifest_path, 'r', encoding='utf-8') as f:
|
147
|
+
manifest = json.load(f)
|
148
|
+
|
149
|
+
name = manifest.get('name', template.name)
|
150
|
+
description = manifest.get('description', 'Açıklama yok')
|
151
|
+
language = manifest.get('language', 'unknown')
|
152
|
+
|
153
|
+
result += f"🌐 {language.upper()}\n"
|
154
|
+
result += f" 📝 {description}\n"
|
155
|
+
result += f" 📁 Şablon: {template.name}\n\n"
|
156
|
+
|
157
|
+
except Exception:
|
158
|
+
result += f"🌐 {template.name.upper()}\n"
|
159
|
+
result += f" 📁 Şablon: {template.name}\n\n"
|
160
|
+
|
161
|
+
result += "💡 Kullanım: clapp new <dil> <uygulama-adı>"
|
162
|
+
|
163
|
+
return result
|
164
|
+
|
165
|
+
def handle_new_command(args) -> tuple[bool, str]:
|
166
|
+
"""
|
167
|
+
new komutunu işler
|
168
|
+
|
169
|
+
Args:
|
170
|
+
args: Argümanlar
|
171
|
+
|
172
|
+
Returns:
|
173
|
+
(success, message)
|
174
|
+
"""
|
175
|
+
if args.list:
|
176
|
+
return True, list_available_templates()
|
177
|
+
|
178
|
+
if not args.language or not args.app_name:
|
179
|
+
return False, "Dil ve uygulama adı gerekli. Örnek: clapp new python my-app"
|
180
|
+
|
181
|
+
return create_new_app(args.language, args.app_name, args.target_dir)
|
progress_utils.py
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
progress_utils.py - Progress Bar ve İndirme Hızı Göstergesi
|
4
|
+
|
5
|
+
Bu modül indirme ve yükleme işlemleri için progress bar ve hız göstergesi sağlar.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import sys
|
9
|
+
import time
|
10
|
+
import threading
|
11
|
+
from typing import Optional, Callable
|
12
|
+
from urllib.request import urlopen
|
13
|
+
from urllib.error import URLError
|
14
|
+
|
15
|
+
class ProgressBar:
|
16
|
+
"""Progress bar sınıfı"""
|
17
|
+
|
18
|
+
def __init__(self, total: int, description: str = "İndiriliyor", width: int = 50):
|
19
|
+
self.total = total
|
20
|
+
self.description = description
|
21
|
+
self.width = width
|
22
|
+
self.current = 0
|
23
|
+
self.start_time = time.time()
|
24
|
+
self.last_update = 0
|
25
|
+
self.speed = 0
|
26
|
+
self.lock = threading.Lock()
|
27
|
+
|
28
|
+
def update(self, current: int, speed: Optional[float] = None):
|
29
|
+
"""Progress bar'ı günceller"""
|
30
|
+
with self.lock:
|
31
|
+
self.current = current
|
32
|
+
if speed is not None:
|
33
|
+
self.speed = speed
|
34
|
+
|
35
|
+
# Hız hesaplama
|
36
|
+
if self.current > 0:
|
37
|
+
elapsed = time.time() - self.start_time
|
38
|
+
if elapsed > 0:
|
39
|
+
self.speed = self.current / elapsed
|
40
|
+
|
41
|
+
def display(self):
|
42
|
+
"""Progress bar'ı ekranda gösterir"""
|
43
|
+
if self.total <= 0:
|
44
|
+
return
|
45
|
+
|
46
|
+
percentage = (self.current / self.total) * 100
|
47
|
+
filled_width = int(self.width * self.current // self.total)
|
48
|
+
|
49
|
+
# Progress bar oluştur
|
50
|
+
bar = '█' * filled_width + '░' * (self.width - filled_width)
|
51
|
+
|
52
|
+
# Hız formatı
|
53
|
+
speed_str = self._format_speed(self.speed)
|
54
|
+
|
55
|
+
# Yüzde ve boyut bilgisi
|
56
|
+
current_str = self._format_size(self.current)
|
57
|
+
total_str = self._format_size(self.total)
|
58
|
+
|
59
|
+
# Progress bar çıktısı
|
60
|
+
progress_line = f"\r{self.description}: [{bar}] {percentage:5.1f}% | {current_str}/{total_str} | {speed_str}"
|
61
|
+
|
62
|
+
# Satırı temizle ve yaz
|
63
|
+
sys.stdout.write('\r' + ' ' * (len(progress_line) + 10)) # Temizle
|
64
|
+
sys.stdout.write(progress_line)
|
65
|
+
sys.stdout.flush()
|
66
|
+
|
67
|
+
def finish(self, success: bool = True):
|
68
|
+
"""Progress bar'ı tamamlar"""
|
69
|
+
if success:
|
70
|
+
# Tamamlandı mesajı
|
71
|
+
sys.stdout.write('\r' + ' ' * (self.width + 50)) # Temizle
|
72
|
+
sys.stdout.write(f"\r✅ {self.description} tamamlandı!\n")
|
73
|
+
else:
|
74
|
+
# Hata mesajı
|
75
|
+
sys.stdout.write('\r' + ' ' * (self.width + 50)) # Temizle
|
76
|
+
sys.stdout.write(f"\r❌ {self.description} başarısız!\n")
|
77
|
+
sys.stdout.flush()
|
78
|
+
|
79
|
+
def _format_speed(self, speed: float) -> str:
|
80
|
+
"""Hızı formatlar (B/s, KB/s, MB/s)"""
|
81
|
+
if speed < 1024:
|
82
|
+
return f"{speed:.1f} B/s"
|
83
|
+
elif speed < 1024 * 1024:
|
84
|
+
return f"{speed/1024:.1f} KB/s"
|
85
|
+
else:
|
86
|
+
return f"{speed/(1024*1024):.1f} MB/s"
|
87
|
+
|
88
|
+
def _format_size(self, size: int) -> str:
|
89
|
+
"""Boyutu formatlar (B, KB, MB, GB)"""
|
90
|
+
if size < 1024:
|
91
|
+
return f"{size} B"
|
92
|
+
elif size < 1024 * 1024:
|
93
|
+
return f"{size/1024:.1f} KB"
|
94
|
+
elif size < 1024 * 1024 * 1024:
|
95
|
+
return f"{size/(1024*1024):.1f} MB"
|
96
|
+
else:
|
97
|
+
return f"{size/(1024*1024*1024):.1f} GB"
|
98
|
+
|
99
|
+
|
100
|
+
def download_with_progress(url: str, filename: str, description: str = "İndiriliyor") -> bool:
|
101
|
+
"""
|
102
|
+
Progress bar ile dosya indirir
|
103
|
+
|
104
|
+
Args:
|
105
|
+
url: İndirilecek URL
|
106
|
+
filename: Kaydedilecek dosya adı
|
107
|
+
description: Progress bar açıklaması
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
Başarılı ise True
|
111
|
+
"""
|
112
|
+
try:
|
113
|
+
# URL'den dosya boyutunu al
|
114
|
+
response = urlopen(url)
|
115
|
+
total_size = int(response.headers.get('content-length', 0))
|
116
|
+
response.close()
|
117
|
+
|
118
|
+
# Progress bar oluştur
|
119
|
+
progress = ProgressBar(total_size, description)
|
120
|
+
|
121
|
+
# İndirme işlemi
|
122
|
+
with urlopen(url) as response:
|
123
|
+
with open(filename, 'wb') as file:
|
124
|
+
downloaded = 0
|
125
|
+
chunk_size = 8192
|
126
|
+
|
127
|
+
while True:
|
128
|
+
chunk = response.read(chunk_size)
|
129
|
+
if not chunk:
|
130
|
+
break
|
131
|
+
|
132
|
+
file.write(chunk)
|
133
|
+
downloaded += len(chunk)
|
134
|
+
|
135
|
+
# Progress bar güncelle
|
136
|
+
progress.update(downloaded)
|
137
|
+
progress.display()
|
138
|
+
|
139
|
+
# Kısa bekleme (çok sık güncelleme önlemek için)
|
140
|
+
time.sleep(0.01)
|
141
|
+
|
142
|
+
# Tamamlandı
|
143
|
+
progress.finish(True)
|
144
|
+
return True
|
145
|
+
|
146
|
+
except Exception as e:
|
147
|
+
if 'progress' in locals():
|
148
|
+
progress.finish(False)
|
149
|
+
print(f"❌ İndirme hatası: {e}")
|
150
|
+
return False
|
151
|
+
|
152
|
+
|
153
|
+
def copy_with_progress(src: str, dst: str, description: str = "Kopyalanıyor") -> bool:
|
154
|
+
"""
|
155
|
+
Progress bar ile dosya kopyalar
|
156
|
+
|
157
|
+
Args:
|
158
|
+
src: Kaynak dosya
|
159
|
+
dst: Hedef dosya
|
160
|
+
description: Progress bar açıklaması
|
161
|
+
|
162
|
+
Returns:
|
163
|
+
Başarılı ise True
|
164
|
+
"""
|
165
|
+
import os
|
166
|
+
import shutil
|
167
|
+
|
168
|
+
try:
|
169
|
+
# Dosya boyutunu al
|
170
|
+
total_size = os.path.getsize(src)
|
171
|
+
|
172
|
+
# Progress bar oluştur
|
173
|
+
progress = ProgressBar(total_size, description)
|
174
|
+
|
175
|
+
# Kopyalama işlemi
|
176
|
+
with open(src, 'rb') as src_file:
|
177
|
+
with open(dst, 'wb') as dst_file:
|
178
|
+
copied = 0
|
179
|
+
chunk_size = 8192
|
180
|
+
|
181
|
+
while True:
|
182
|
+
chunk = src_file.read(chunk_size)
|
183
|
+
if not chunk:
|
184
|
+
break
|
185
|
+
|
186
|
+
dst_file.write(chunk)
|
187
|
+
copied += len(chunk)
|
188
|
+
|
189
|
+
# Progress bar güncelle
|
190
|
+
progress.update(copied)
|
191
|
+
progress.display()
|
192
|
+
|
193
|
+
# Kısa bekleme
|
194
|
+
time.sleep(0.001)
|
195
|
+
|
196
|
+
# Tamamlandı
|
197
|
+
progress.finish(True)
|
198
|
+
return True
|
199
|
+
|
200
|
+
except Exception as e:
|
201
|
+
if 'progress' in locals():
|
202
|
+
progress.finish(False)
|
203
|
+
print(f"❌ Kopyalama hatası: {e}")
|
204
|
+
return False
|
205
|
+
|
206
|
+
|
207
|
+
def extract_with_progress(zip_path: str, extract_path: str, description: str = "Çıkarılıyor") -> bool:
|
208
|
+
"""
|
209
|
+
Progress bar ile ZIP dosyası çıkarır
|
210
|
+
|
211
|
+
Args:
|
212
|
+
zip_path: ZIP dosyası yolu
|
213
|
+
extract_path: Çıkarılacak dizin
|
214
|
+
description: Progress bar açıklaması
|
215
|
+
|
216
|
+
Returns:
|
217
|
+
Başarılı ise True
|
218
|
+
"""
|
219
|
+
import zipfile
|
220
|
+
import os
|
221
|
+
|
222
|
+
try:
|
223
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
224
|
+
# Toplam dosya sayısı
|
225
|
+
file_list = zip_ref.filelist
|
226
|
+
total_files = len(file_list)
|
227
|
+
|
228
|
+
if total_files == 0:
|
229
|
+
print(f"❌ ZIP dosyası boş: {zip_path}")
|
230
|
+
return False
|
231
|
+
|
232
|
+
# Progress bar oluştur
|
233
|
+
progress = ProgressBar(total_files, description)
|
234
|
+
|
235
|
+
# Çıkarma işlemi
|
236
|
+
for i, file_info in enumerate(file_list):
|
237
|
+
zip_ref.extract(file_info, extract_path)
|
238
|
+
|
239
|
+
# Progress bar güncelle
|
240
|
+
progress.update(i + 1)
|
241
|
+
progress.display()
|
242
|
+
|
243
|
+
# Kısa bekleme
|
244
|
+
time.sleep(0.01)
|
245
|
+
|
246
|
+
# Tamamlandı
|
247
|
+
progress.finish(True)
|
248
|
+
return True
|
249
|
+
|
250
|
+
except Exception as e:
|
251
|
+
if 'progress' in locals():
|
252
|
+
progress.finish(False)
|
253
|
+
print(f"❌ Çıkarma hatası: {e}")
|
254
|
+
return False
|
255
|
+
|
256
|
+
|
257
|
+
def show_success_message(message: str):
|
258
|
+
"""Başarı mesajı gösterir"""
|
259
|
+
print(f"✅ {message}")
|
260
|
+
|
261
|
+
|
262
|
+
def show_error_message(message: str):
|
263
|
+
"""Hata mesajı gösterir"""
|
264
|
+
print(f"❌ {message}")
|
265
|
+
|
266
|
+
|
267
|
+
def show_info_message(message: str):
|
268
|
+
"""Bilgi mesajı gösterir"""
|
269
|
+
print(f"ℹ️ {message}")
|
270
|
+
|
271
|
+
|
272
|
+
def show_warning_message(message: str):
|
273
|
+
"""Uyarı mesajı gösterir"""
|
274
|
+
print(f"⚠️ {message}")
|
version.py
CHANGED
File without changes
|
File without changes
|
File without changes
|