clapp-pm 1.0.0__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.
remote_registry.py ADDED
@@ -0,0 +1,285 @@
1
+ import json
2
+ import urllib.request
3
+ import urllib.parse
4
+ from typing import List, Dict, Optional
5
+
6
+ # Uzak paket deposu URL'si
7
+ REMOTE_PACKAGES_URL = "https://raw.githubusercontent.com/mburakmmm/clapp-packages/main/packages.json"
8
+
9
+ def fetch_remote_packages() -> List[Dict]:
10
+ """
11
+ Uzak paket deposundan paket listesini indirir.
12
+
13
+ Returns:
14
+ list: Paket listesi (dict formatında)
15
+ """
16
+ try:
17
+ print("Uzak paket deposu kontrol ediliyor...")
18
+
19
+ # HTTP isteği gönder
20
+ with urllib.request.urlopen(REMOTE_PACKAGES_URL) as response:
21
+ data = response.read().decode('utf-8')
22
+
23
+ # JSON'u parse et
24
+ packages = json.loads(data)
25
+
26
+ print(f"✅ {len(packages)} paket bulundu")
27
+ return packages
28
+
29
+ except urllib.error.URLError as e:
30
+ print(f"❌ Ağ hatası: {e}")
31
+ return []
32
+ except json.JSONDecodeError as e:
33
+ print(f"❌ JSON parse hatası: {e}")
34
+ return []
35
+ except Exception as e:
36
+ print(f"❌ Beklenmeyen hata: {e}")
37
+ return []
38
+
39
+ def get_package_info(app_name: str) -> Optional[Dict]:
40
+ """
41
+ Belirtilen uygulama için uzak paket bilgilerini döndürür.
42
+
43
+ Args:
44
+ app_name (str): Uygulama adı
45
+
46
+ Returns:
47
+ dict or None: Paket bilgileri veya None
48
+ """
49
+ packages = fetch_remote_packages()
50
+
51
+ for package in packages:
52
+ if package.get('name') == app_name:
53
+ return package
54
+
55
+ return None
56
+
57
+ def search_packages(query: str) -> List[Dict]:
58
+ """
59
+ Paket deposunda arama yapar.
60
+
61
+ Args:
62
+ query (str): Arama terimi
63
+
64
+ Returns:
65
+ list: Eşleşen paketler
66
+ """
67
+ packages = fetch_remote_packages()
68
+ results = []
69
+
70
+ query_lower = query.lower()
71
+
72
+ for package in packages:
73
+ # İsim, açıklama ve dilde arama yap
74
+ name = package.get('name', '').lower()
75
+ description = package.get('description', '').lower()
76
+ language = package.get('language', '').lower()
77
+
78
+ if (query_lower in name or
79
+ query_lower in description or
80
+ query_lower in language):
81
+ results.append(package)
82
+
83
+ return results
84
+
85
+ def get_packages_by_language(language: str) -> List[Dict]:
86
+ """
87
+ Belirtilen dildeki paketleri döndürür.
88
+
89
+ Args:
90
+ language (str): Programlama dili
91
+
92
+ Returns:
93
+ list: Belirtilen dildeki paketler
94
+ """
95
+ packages = fetch_remote_packages()
96
+ filtered_packages = []
97
+
98
+ for package in packages:
99
+ if package.get('language', '').lower() == language.lower():
100
+ filtered_packages.append(package)
101
+
102
+ return filtered_packages
103
+
104
+ def list_remote_packages(show_details=False) -> str:
105
+ """
106
+ Uzak paket deposundaki paketleri listeler.
107
+
108
+ Args:
109
+ show_details (bool): Detayları göster
110
+
111
+ Returns:
112
+ str: Formatlanmış paket listesi
113
+ """
114
+ packages = fetch_remote_packages()
115
+
116
+ if not packages:
117
+ return "❌ Uzak paket deposuna erişilemedi veya paket bulunamadı"
118
+
119
+ output = f"🌐 Uzak Paket Deposu ({len(packages)} paket)\n"
120
+ output += "=" * 50 + "\n"
121
+
122
+ # Dillere göre grupla
123
+ by_language = {}
124
+ for package in packages:
125
+ language = package.get('language', 'unknown')
126
+ if language not in by_language:
127
+ by_language[language] = []
128
+ by_language[language].append(package)
129
+
130
+ for language, lang_packages in sorted(by_language.items()):
131
+ output += f"\n📚 {language.upper()} ({len(lang_packages)} paket):\n"
132
+
133
+ for package in sorted(lang_packages, key=lambda x: x.get('name', '')):
134
+ name = package.get('name', 'Bilinmiyor')
135
+ version = package.get('version', '0.0.0')
136
+ description = package.get('description', 'Açıklama yok')
137
+
138
+ output += f" 📦 {name} (v{version})\n"
139
+
140
+ if show_details:
141
+ output += f" Açıklama: {description}\n"
142
+ output += f" İndirme: {package.get('download_url', 'Yok')}\n"
143
+
144
+ if package.get('dependencies'):
145
+ deps = ', '.join(package['dependencies'])
146
+ output += f" Bağımlılıklar: {deps}\n"
147
+
148
+ return output
149
+
150
+ def validate_package_url(url: str) -> bool:
151
+ """
152
+ Paket URL'sinin geçerli olup olmadığını kontrol eder.
153
+
154
+ Args:
155
+ url (str): Kontrol edilecek URL
156
+
157
+ Returns:
158
+ bool: Geçerliyse True
159
+ """
160
+ try:
161
+ # URL formatını kontrol et
162
+ parsed = urllib.parse.urlparse(url)
163
+ if not parsed.scheme or not parsed.netloc:
164
+ return False
165
+
166
+ # HTTP HEAD isteği gönder
167
+ request = urllib.request.Request(url, method='HEAD')
168
+ with urllib.request.urlopen(request) as response:
169
+ return response.status == 200
170
+
171
+ except Exception:
172
+ return False
173
+
174
+ def get_package_statistics() -> Dict:
175
+ """
176
+ Paket deposu istatistiklerini döndürür.
177
+
178
+ Returns:
179
+ dict: İstatistik bilgileri
180
+ """
181
+ packages = fetch_remote_packages()
182
+
183
+ stats = {
184
+ "total_packages": len(packages),
185
+ "languages": {},
186
+ "with_dependencies": 0,
187
+ "without_dependencies": 0,
188
+ "total_dependencies": 0
189
+ }
190
+
191
+ for package in packages:
192
+ # Dil istatistikleri
193
+ language = package.get('language', 'unknown')
194
+ stats["languages"][language] = stats["languages"].get(language, 0) + 1
195
+
196
+ # Bağımlılık istatistikleri
197
+ dependencies = package.get('dependencies', [])
198
+ if dependencies:
199
+ stats["with_dependencies"] += 1
200
+ stats["total_dependencies"] += len(dependencies)
201
+ else:
202
+ stats["without_dependencies"] += 1
203
+
204
+ return stats
205
+
206
+ def get_statistics_report() -> str:
207
+ """
208
+ İstatistik raporunu döndürür.
209
+
210
+ Returns:
211
+ str: Formatlanmış istatistik raporu
212
+ """
213
+ stats = get_package_statistics()
214
+
215
+ if stats["total_packages"] == 0:
216
+ return "❌ Paket deposu verisi alınamadı"
217
+
218
+ report = "📊 Paket Deposu İstatistikleri\n"
219
+ report += "=" * 40 + "\n"
220
+
221
+ report += f"📦 Toplam Paket: {stats['total_packages']}\n"
222
+ report += f"🔗 Bağımlılığa Sahip: {stats['with_dependencies']}\n"
223
+ report += f"🆓 Bağımlılıksız: {stats['without_dependencies']}\n"
224
+ report += f"📊 Toplam Bağımlılık: {stats['total_dependencies']}\n\n"
225
+
226
+ # Dil dağılımı
227
+ report += "💻 Dil Dağılımı:\n"
228
+ for language, count in sorted(stats["languages"].items()):
229
+ percentage = (count / stats["total_packages"]) * 100
230
+ report += f" {language}: {count} paket (%{percentage:.1f})\n"
231
+
232
+ return report
233
+
234
+ def check_remote_connectivity() -> bool:
235
+ """
236
+ Uzak paket deposuna bağlantıyı kontrol eder.
237
+
238
+ Returns:
239
+ bool: Bağlantı varsa True
240
+ """
241
+ try:
242
+ request = urllib.request.Request(REMOTE_PACKAGES_URL, method='HEAD')
243
+ with urllib.request.urlopen(request, timeout=5) as response:
244
+ return response.status == 200
245
+ except Exception:
246
+ return False
247
+
248
+ def get_package_versions(app_name: str) -> List[str]:
249
+ """
250
+ Paketin mevcut sürümlerini döndürür (şu an sadece mevcut sürüm).
251
+
252
+ Args:
253
+ app_name (str): Uygulama adı
254
+
255
+ Returns:
256
+ list: Sürüm listesi
257
+ """
258
+ package = get_package_info(app_name)
259
+
260
+ if package:
261
+ return [package.get('version', '0.0.0')]
262
+
263
+ return []
264
+
265
+ if __name__ == "__main__":
266
+ # Test için örnek kullanım
267
+ print("Remote Registry Test")
268
+ print("=" * 30)
269
+
270
+ # Bağlantı testi
271
+ if check_remote_connectivity():
272
+ print("✅ Uzak paket deposuna bağlantı başarılı")
273
+
274
+ # Paket listesi
275
+ print("\nPaket listesi:")
276
+ print(list_remote_packages())
277
+
278
+ # İstatistikler
279
+ print("\nİstatistikler:")
280
+ print(get_statistics_report())
281
+
282
+ else:
283
+ print("❌ Uzak paket deposuna bağlantı kurulamadı")
284
+
285
+ print("\nTest tamamlandı.")
validate_command.py ADDED
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ validate_command.py - Uygulama doğrulama modülü
4
+
5
+ Bu modül `clapp validate <folder>` komutunu destekler ve
6
+ uygulama klasörlerinin doğru yapıda olup olmadığını kontrol eder.
7
+ """
8
+
9
+ import os
10
+ import json
11
+ from pathlib import Path
12
+ from manifest_validator import validate_manifest_verbose
13
+
14
+ def validate_app_folder(folder_path):
15
+ """Uygulama klasörünü doğrular"""
16
+ folder = Path(folder_path)
17
+
18
+ print(f"🔍 '{folder_path}' klasörü doğrulanıyor...")
19
+ print("=" * 50)
20
+
21
+ # Klasörün var olup olmadığını kontrol et
22
+ if not folder.exists():
23
+ print(f"❌ Klasör bulunamadı: {folder_path}")
24
+ return False
25
+
26
+ if not folder.is_dir():
27
+ print(f"❌ Belirtilen yol bir klasör değil: {folder_path}")
28
+ return False
29
+
30
+ errors = []
31
+ warnings = []
32
+
33
+ # 1. manifest.json kontrolü
34
+ manifest_path = folder / "manifest.json"
35
+ if not manifest_path.exists():
36
+ errors.append("manifest.json dosyası bulunamadı")
37
+ else:
38
+ print("✅ manifest.json dosyası mevcut")
39
+
40
+ # Manifest içeriğini kontrol et
41
+ try:
42
+ with open(manifest_path, 'r', encoding='utf-8') as f:
43
+ manifest_data = json.load(f)
44
+
45
+ # Manifest'i doğrula
46
+ is_valid, validation_errors = validate_manifest_verbose(manifest_data)
47
+
48
+ if is_valid:
49
+ print("✅ manifest.json geçerli")
50
+ else:
51
+ print("❌ manifest.json geçersiz:")
52
+ for error in validation_errors:
53
+ print(f" • {error}")
54
+ errors.append(f"Manifest hatası: {error}")
55
+
56
+ # Giriş dosyası kontrolü
57
+ if "entry" in manifest_data:
58
+ entry_file = folder / manifest_data["entry"]
59
+ if entry_file.exists():
60
+ print(f"✅ Giriş dosyası mevcut: {manifest_data['entry']}")
61
+ else:
62
+ error_msg = f"Giriş dosyası bulunamadı: {manifest_data['entry']}"
63
+ print(f"❌ {error_msg}")
64
+ errors.append(error_msg)
65
+
66
+ # Dil kontrolü
67
+ if "language" in manifest_data:
68
+ language = manifest_data["language"].lower()
69
+ if language in ["python", "lua"]:
70
+ print(f"✅ Desteklenen dil: {language}")
71
+ else:
72
+ warning_msg = f"Desteklenmeyen dil: {language}"
73
+ print(f"⚠️ {warning_msg}")
74
+ warnings.append(warning_msg)
75
+
76
+ except json.JSONDecodeError as e:
77
+ error_msg = f"manifest.json JSON formatı geçersiz: {str(e)}"
78
+ print(f"❌ {error_msg}")
79
+ errors.append(error_msg)
80
+ except Exception as e:
81
+ error_msg = f"manifest.json okunamadı: {str(e)}"
82
+ print(f"❌ {error_msg}")
83
+ errors.append(error_msg)
84
+
85
+ # 2. Klasör içeriği kontrolü
86
+ files = list(folder.iterdir())
87
+ if not files:
88
+ warnings.append("Klasör boş")
89
+ print("⚠️ Klasör boş")
90
+ else:
91
+ print(f"✅ Klasör içeriği: {len(files)} öğe")
92
+
93
+ # 3. Önerilen dosya yapısı kontrolü
94
+ recommended_files = ["manifest.json", "README.md", "requirements.txt"]
95
+ missing_recommended = []
96
+
97
+ for rec_file in recommended_files:
98
+ if not (folder / rec_file).exists():
99
+ missing_recommended.append(rec_file)
100
+
101
+ if missing_recommended:
102
+ print("💡 Önerilen dosyalar eksik:")
103
+ for missing in missing_recommended:
104
+ print(f" • {missing}")
105
+
106
+ # 4. Dosya boyutu kontrolü
107
+ try:
108
+ total_size = 0
109
+ file_count = 0
110
+
111
+ for file_path in folder.rglob("*"):
112
+ if file_path.is_file():
113
+ file_count += 1
114
+ total_size += file_path.stat().st_size
115
+
116
+ print(f"📊 İstatistikler: {file_count} dosya, {format_size(total_size)}")
117
+
118
+ # Büyük dosyalar için uyarı
119
+ if total_size > 100 * 1024 * 1024: # 100MB
120
+ warnings.append(f"Büyük uygulama boyutu: {format_size(total_size)}")
121
+
122
+ except Exception as e:
123
+ warnings.append(f"Dosya boyutu hesaplanamadı: {str(e)}")
124
+
125
+ # Sonuçları göster
126
+ print("\n" + "=" * 50)
127
+ print("📋 Doğrulama Sonuçları:")
128
+
129
+ if not errors and not warnings:
130
+ print("🎉 Mükemmel! Uygulama klasörü tamamen geçerli.")
131
+ print("✅ Kurulum için hazır.")
132
+ elif not errors:
133
+ print("✅ Uygulama klasörü geçerli.")
134
+ if warnings:
135
+ print("⚠️ Bazı uyarılar var:")
136
+ for warning in warnings:
137
+ print(f" • {warning}")
138
+ else:
139
+ print("❌ Uygulama klasörü geçersiz.")
140
+ print("🔧 Düzeltilmesi gereken hatalar:")
141
+ for error in errors:
142
+ print(f" • {error}")
143
+
144
+ if warnings:
145
+ print("⚠️ Ek uyarılar:")
146
+ for warning in warnings:
147
+ print(f" • {warning}")
148
+
149
+ # Öneriler
150
+ if errors or warnings:
151
+ print("\n💡 Öneriler:")
152
+ if not manifest_path.exists():
153
+ print("• manifest.json dosyası oluşturun")
154
+ print("• Örnek: clapp init komutu ile başlayabilirsiniz")
155
+
156
+ if missing_recommended:
157
+ print("• Önerilen dosyaları ekleyin:")
158
+ for missing in missing_recommended:
159
+ if missing == "README.md":
160
+ print(f" - {missing}: Uygulama açıklaması")
161
+ elif missing == "requirements.txt":
162
+ print(f" - {missing}: Python bağımlılıkları (Python uygulamaları için)")
163
+
164
+ if warnings:
165
+ print("• Uyarıları gözden geçirin ve gerekirse düzeltin")
166
+
167
+ print(f"\n🔧 Daha fazla yardım için: clapp doctor")
168
+
169
+ return len(errors) == 0
170
+
171
+ def format_size(size_bytes):
172
+ """Dosya boyutunu formatlar"""
173
+ if size_bytes == 0:
174
+ return "0 B"
175
+
176
+ for unit in ['B', 'KB', 'MB', 'GB']:
177
+ if size_bytes < 1024.0:
178
+ return f"{size_bytes:.1f} {unit}"
179
+ size_bytes /= 1024.0
180
+
181
+ return f"{size_bytes:.1f} TB"
182
+
183
+ def validate_multiple_folders(folder_paths):
184
+ """Birden fazla klasörü doğrular"""
185
+ results = []
186
+
187
+ for folder_path in folder_paths:
188
+ print(f"\n{'='*60}")
189
+ result = validate_app_folder(folder_path)
190
+ results.append((folder_path, result))
191
+
192
+ # Özet
193
+ print(f"\n{'='*60}")
194
+ print("📊 Toplu Doğrulama Özeti:")
195
+
196
+ valid_count = sum(1 for _, result in results if result)
197
+ invalid_count = len(results) - valid_count
198
+
199
+ print(f"✅ Geçerli: {valid_count}")
200
+ print(f"❌ Geçersiz: {invalid_count}")
201
+
202
+ if invalid_count > 0:
203
+ print("\n❌ Geçersiz klasörler:")
204
+ for folder_path, result in results:
205
+ if not result:
206
+ print(f" • {folder_path}")
207
+
208
+ return invalid_count == 0
209
+
210
+ if __name__ == "__main__":
211
+ import sys
212
+
213
+ if len(sys.argv) < 2:
214
+ print("Kullanım: python validate_command.py <klasör_yolu>")
215
+ print("Örnek: python validate_command.py apps/my-app")
216
+ sys.exit(1)
217
+
218
+ folder_paths = sys.argv[1:]
219
+
220
+ if len(folder_paths) == 1:
221
+ success = validate_app_folder(folder_paths[0])
222
+ sys.exit(0 if success else 1)
223
+ else:
224
+ success = validate_multiple_folders(folder_paths)
225
+ sys.exit(0 if success else 1)
version_command.py ADDED
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ version_command.py - Sürüm bilgisi modülü
4
+
5
+ Bu modül `clapp version` komutunu destekler ve
6
+ clapp'in sürüm bilgilerini gösterir.
7
+ """
8
+
9
+ import sys
10
+ import platform
11
+ import json
12
+ from pathlib import Path
13
+
14
+ def get_version_info():
15
+ """Sürüm bilgilerini toplar"""
16
+ # version.json dosyasından sürüm bilgisini oku
17
+ version_file = Path("version.json")
18
+
19
+ if version_file.exists():
20
+ try:
21
+ with open(version_file, 'r', encoding='utf-8') as f:
22
+ version_data = json.load(f)
23
+
24
+ app_name = version_data.get("name", "clapp")
25
+ version = version_data.get("version", "1.0.0")
26
+ author = version_data.get("author", "Bilinmiyor")
27
+
28
+ except Exception:
29
+ app_name = "clapp"
30
+ version = "1.0.0"
31
+ author = "Bilinmiyor"
32
+ else:
33
+ app_name = "clapp"
34
+ version = "1.0.0"
35
+ author = "Bilinmiyor"
36
+
37
+ # Sistem bilgileri
38
+ python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
39
+ system_info = platform.system()
40
+ machine = platform.machine()
41
+
42
+ return {
43
+ "app_name": app_name,
44
+ "version": version,
45
+ "author": author,
46
+ "python_version": python_version,
47
+ "system": system_info,
48
+ "machine": machine,
49
+ "platform": f"{system_info} {platform.release()}"
50
+ }
51
+
52
+ def print_version(format_type="default"):
53
+ """Sürüm bilgisini yazdırır"""
54
+ info = get_version_info()
55
+
56
+ if format_type == "short":
57
+ print(info["version"])
58
+ elif format_type == "json":
59
+ import json
60
+ output = {
61
+ "version": info["version"],
62
+ "python": info["python_version"],
63
+ "os": info["system"],
64
+ "machine": info["machine"]
65
+ }
66
+ print(json.dumps(output, indent=2))
67
+ else: # default
68
+ print(f"🚀 {info['app_name']} v{info['version']}")
69
+ print(f"🐍 Python {info['python_version']}")
70
+ print(f"💻 Platform: {info['platform']} ({info['machine']})")
71
+ print(f"👨‍💻 Yazar: {info['author']}")
72
+
73
+ def print_detailed_version():
74
+ """Detaylı sürüm bilgisini yazdırır"""
75
+ info = get_version_info()
76
+
77
+ print("📋 clapp Detaylı Sürüm Bilgileri")
78
+ print("=" * 50)
79
+
80
+ # Temel bilgiler
81
+ print("🚀 Uygulama Bilgileri:")
82
+ print(f" Ad: {info['app_name']}")
83
+ print(f" Sürüm: {info['version']}")
84
+ print(f" Yazar: {info['author']}")
85
+ print()
86
+
87
+ # Python bilgileri
88
+ print("🐍 Python Bilgileri:")
89
+ print(f" Sürüm: {info['python_version']}")
90
+ print(f" Çalıştırılabilir: {sys.executable}")
91
+ print(f" Prefix: {sys.prefix}")
92
+ print()
93
+
94
+ # Platform bilgileri
95
+ print("💻 Platform Bilgileri:")
96
+ print(f" İşletim Sistemi: {info['system']}")
97
+ print(f" Sürüm: {platform.release()}")
98
+ print(f" Mimari: {info['machine']}")
99
+ print(f" İşlemci: {platform.processor()}")
100
+ print()
101
+
102
+ # Modül bilgileri
103
+ print("📦 Modül Bilgileri:")
104
+ try:
105
+ import flet
106
+ print(f" Flet: v{flet.__version__}")
107
+ except ImportError:
108
+ print(" Flet: Yüklü değil")
109
+
110
+ # Ek bilgiler
111
+ print()
112
+ print("📁 Dizin Bilgileri:")
113
+ print(f" Çalışma Dizini: {Path.cwd()}")
114
+
115
+ # apps/ dizini kontrolü
116
+ apps_dir = Path("apps")
117
+ if apps_dir.exists():
118
+ app_count = len([d for d in apps_dir.iterdir() if d.is_dir()])
119
+ print(f" Apps Dizini: {apps_dir.resolve()} ({app_count} uygulama)")
120
+ else:
121
+ print(" Apps Dizini: Bulunamadı")
122
+
123
+ def check_latest_version():
124
+ """En son sürümü kontrol eder (placeholder)"""
125
+ print("🔍 En son sürüm kontrol ediliyor...")
126
+ print("⚠️ Bu özellik henüz mevcut değil.")
127
+ print("📞 Manuel kontrol için: https://github.com/user/clapp")
128
+
129
+ if __name__ == "__main__":
130
+ import sys
131
+
132
+ if len(sys.argv) > 1:
133
+ arg = sys.argv[1]
134
+ if arg == "--short":
135
+ print_version("short")
136
+ elif arg == "--json":
137
+ print_version("json")
138
+ elif arg == "--detailed":
139
+ print_detailed_version()
140
+ elif arg == "--latest":
141
+ check_latest_version()
142
+ else:
143
+ print_version("default")
144
+ else:
145
+ print_version("default")