wellnpm 2.0.10 → 2.0.11

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.
@@ -0,0 +1,82 @@
1
+ import os
2
+
3
+ try:
4
+ from pyaxmlparser import APK
5
+ except ImportError:
6
+ APK = None
7
+
8
+ # --- FUNCTION: APK AUDIT (VERSI RINGAN) ---
9
+ def audit_apk(laluan_apk):
10
+ """Fungsi untuk memeriksa kebenaran (permissions) menggunakan pyaxmlparser"""
11
+ if not APK:
12
+ print("[Ralat] Pakej 'pyaxmlparser' tidak ditemui. Sila jalankan: pip install pyaxmlparser")
13
+ return
14
+
15
+ # Jika pengguna hanya taip nama fail, semak di folder semasa
16
+ if not os.path.exists(laluan_apk):
17
+ # Cuba semak di folder downloads termux jika laluan penuh tidak diberikan
18
+ laluan_cuba = f"/data/data/com.termux/files/home/downloads/{laluan_apk}"
19
+ if os.path.exists(laluan_cuba):
20
+ laluan_apk = laluan_cuba
21
+ else:
22
+ print("[Ralat] Fail APK tidak ditemui. Pastikan nama fail atau laluan (path) betul.")
23
+ return
24
+
25
+ print(f"\n[-] Menganalisis Fail: {os.path.basename(laluan_apk)}...")
26
+ try:
27
+ a = APK(laluan_apk)
28
+ kebenaran = a.permissions
29
+
30
+ print("\n" + "="*50)
31
+ print(f"📊 HASIL AUDIT UNTUK: {a.package}")
32
+ print("="*50)
33
+ print(f"Versi Aplikasi: {a.version_name}")
34
+ print(f"Jumlah Kebenaran Diminta: {len(kebenaran) if kebenaran else 0}")
35
+ print("-"*50)
36
+
37
+ # Senarai kebenaran yang sering dianggap sensitif
38
+ kebenaran_berisiko = [
39
+ "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE",
40
+ "ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION",
41
+ "READ_CONTACTS", "RECORD_AUDIO", "CAMERA", "READ_PHONE_STATE",
42
+ "REQUEST_INSTALL_PACKAGES", "INTERNET"
43
+ ]
44
+
45
+ if kebenaran:
46
+ print("[+] Senarai Kebenaran Yang Dikesan:")
47
+ for perm in kebenaran:
48
+ nama_pendek = perm.split(".")[-1]
49
+ if nama_pendek in kebenaran_berisiko:
50
+ print(f" ⚠️ {perm} (SENSITIF/RISIKO)")
51
+ else:
52
+ print(f" ✅ {perm}")
53
+ else:
54
+ print("[-] Tiada kebenaran dikesan atau fail tidak dapat dibaca.")
55
+
56
+ except Exception as e:
57
+ print(f"[Ralat] Gagal menganalisis APK: {e}")
58
+
59
+ # --- MENU UTAMA ---
60
+ def menu():
61
+ while True:
62
+ print("\n" + "="*50)
63
+ print("🛡️ DUOGUARD LIGHT - AUDIT SIBER APK 🛡️")
64
+ print("="*50)
65
+ print("1. Audit Keselamatan Fail APK")
66
+ print("2. Keluar")
67
+ print("="*50)
68
+
69
+ pilihan = input("Masukkan pilihan anda (1/2): ").strip()
70
+
71
+ if pilihan == "1":
72
+ laluan = input("\nMasukkan nama fail atau laluan fail .apk anda: ").strip()
73
+ laluan = laluan.strip("'\"")
74
+ audit_apk(laluan)
75
+ elif pilihan == "2":
76
+ print("\nTerima kasih kerana menggunakan DuoGuard. Sentiasa waspada!")
77
+ break
78
+ else:
79
+ print("[Ralat] Pilihan tidak sah.")
80
+
81
+ if __name__ == "__main__":
82
+ menu()
@@ -0,0 +1,3 @@
1
+ http://pautan-mencurigakan-1.com
2
+ https://pautan-mencurigakan-2.net
3
+ http://laman-web-biasa.com
@@ -0,0 +1,67 @@
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ from datetime import datetime
4
+ import sqlite3
5
+
6
+ app = FastAPI()
7
+
8
+ # Model data untuk memvalidasi data yang dihantar oleh telefon
9
+ class DataGPS(BaseModel):
10
+ id_pemandu: str
11
+ nama: str
12
+ latitude: float
13
+ longitude: float
14
+ status: str
15
+
16
+ # Fungsi untuk tetapkan pangkalan data SQLite semasa server bermula
17
+ def siapkan_db():
18
+ conn = sqlite3.connect("logistik.db")
19
+ cursor = conn.cursor()
20
+ cursor.execute("""
21
+ CREATE TABLE IF NOT EXISTS lokasi_pemandu (
22
+ id_pemandu TEXT PRIMARY KEY,
23
+ nama TEXT,
24
+ latitude REAL,
25
+ longitude REAL,
26
+ status TEXT,
27
+ timestamp TEXT
28
+ )
29
+ """)
30
+ conn.commit()
31
+ conn.close()
32
+
33
+ siapkan_db()
34
+
35
+ @app.get("/")
36
+ def laman_utama():
37
+ return {"mesej": "Server Logistik Python Berjalan Lancar!"}
38
+
39
+ # Endpoint untuk terima data dari telefon pemandu
40
+ @app.post("/kemaskini-lokasi")
41
+ def kemaskini_lokasi(data: DataGPS):
42
+ try:
43
+ conn = sqlite3.connect("logistik.db")
44
+ cursor = conn.cursor()
45
+
46
+ # Simpan atau kemaskini data pemandu (Jika ID sama, ia akan overwrite data lama)
47
+ masa_sekarang = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
48
+ cursor.execute("""
49
+ INSERT INTO lokasi_pemandu (id_pemandu, nama, latitude, longitude, status, timestamp)
50
+ VALUES (?, ?, ?, ?, ?, ?)
51
+ ON CONFLICT(id_pemandu) DO UPDATE SET
52
+ latitude=excluded.latitude,
53
+ longitude=excluded.longitude,
54
+ status=excluded.status,
55
+ timestamp=excluded.timestamp
56
+ """, (data.id_pemandu, data.nama, data.latitude, data.longitude, data.status, masa_sekarang))
57
+
58
+ conn.commit()
59
+ conn.close()
60
+ return {"status": "sukses", "mesej": f"Lokasi {data.nama} berjaya dikemaskini."}
61
+ except Exception as e:
62
+ raise HTTPException(status_code=500, detail=str(e))
63
+
64
+ if __name__ == "__main__":
65
+ import uvicorn
66
+ # Jalankan server pada port 8000
67
+ uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -0,0 +1,74 @@
1
+ from fastapi import FastAPI
2
+ from pydantic import BaseModel
3
+ import json
4
+ import os
5
+
6
+ app = FastAPI()
7
+
8
+ # Fail data untuk simpan status 10 pemandu
9
+ DATA_FILE = "pemandu_data.json"
10
+
11
+ class StatusPemandu(BaseModel):
12
+ id_pemandu: str
13
+ nama_pemandu: str
14
+ no_simkad: str # Keperluan 4
15
+ barang_dihantar: str # Keperluan 3
16
+ barang_diserahkan: str # Keperluan 3
17
+ latitude: float # Keperluan 1 & 2
18
+ longitude: float # Keperluan 1 & 2
19
+ status: str
20
+
21
+ def muat_data():
22
+ if os.path.exists(DATA_FILE):
23
+ with open(DATA_FILE, "r") as f:
24
+ return json.load(f)
25
+ return {}
26
+
27
+ def simpan_data(data):
28
+ with open(DATA_FILE, "w") as f:
29
+ json.dump(data, f, indent=4)
30
+
31
+ # Fungsi menghasilkan fail HTML Peta tanpa perlukan Streamlit
32
+ def kemaskini_peta_html(data_pemandu):
33
+ html_content = """
34
+ <html>
35
+ <head>
36
+ <title>HQ Monitor Logistik</title>
37
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
38
+ <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
39
+ <meta http-equiv="refresh" content="10"> <style> #map { height: 100vh; wight: 100%; } body { margin: 0; } </style>
40
+ </head>
41
+ <body>
42
+ <div id="map"></div>
43
+ <script>
44
+ var map = L.map('map').setView([4.2105, 101.9758], 6); // Fokus peta Malaysia
45
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
46
+ """
47
+
48
+ for pid, p in data_pemandu.items():
49
+ html_content += f"""
50
+ L.marker([{p['latitude']}, {p['longitude']}]).addTo(map)
51
+ .bindPopup("<b>{p['nama_pemandu']} ({p['no_simkad']})</b><br>Barang Dibawa: {p['barang_dihantar']}<br>Diserahkan: {p['barang_diserahkan']}<br>Status: {p['status']}");
52
+ """
53
+
54
+ html_content += """
55
+ </script>
56
+ </body>
57
+ </html>
58
+ """
59
+ with open("peta_logistik.html", "w") as f:
60
+ f.write(html_content)
61
+
62
+ @app.post("/kemaskini")
63
+ def kemaskini(data: StatusPemandu):
64
+ semua_pemandu = muat_data()
65
+ semua_pemandu[data.id_pemandu] = data.dict()
66
+ simpan_data(semua_pemandu)
67
+
68
+ # Auto-jana fail peta baru setiap kali pemandu hantar data
69
+ kemaskini_peta_html(semua_pemandu)
70
+ return {"status": "Berjaya dikemaskini"}
71
+
72
+ if __name__ == "__main__":
73
+ import uvicorn
74
+ uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -0,0 +1,29 @@
1
+ # texlive.profile written on Wed Jun 24 09:08:54 2026 UTC
2
+ # It will NOT be updated and reflects only the
3
+ # installation profile at installation time.
4
+ selected_scheme scheme-full
5
+ TEXDIR /data/data/com.termux/files/usr/share/texlive/2026
6
+ TEXMFCONFIG ~/.texlive2026/texmf-config
7
+ TEXMFHOME ~/texmf
8
+ TEXMFLOCAL /data/data/com.termux/files/usr/share/texlive/texmf-local
9
+ TEXMFSYSCONFIG /data/data/com.termux/files/usr/share/texlive/2026/texmf-config
10
+ TEXMFSYSVAR /data/data/com.termux/files/usr/share/texlive/2026/texmf-var
11
+ TEXMFVAR ~/.texlive2026/texmf-var
12
+ instopt_adjustpath 1
13
+ instopt_adjustrepo 1
14
+ instopt_letter 0
15
+ instopt_portable 0
16
+ instopt_write18_restricted 1
17
+ tlpdbopt_autobackup 1
18
+ tlpdbopt_backupdir tlpkg/backups
19
+ tlpdbopt_create_formats 1
20
+ tlpdbopt_desktop_integration 1
21
+ tlpdbopt_file_assocs 1
22
+ tlpdbopt_generate_updmap 0
23
+ tlpdbopt_install_docfiles 0
24
+ tlpdbopt_install_srcfiles 0
25
+ tlpdbopt_post_code 1
26
+ tlpdbopt_sys_bin /data/data/com.termux/files/usr/bin
27
+ tlpdbopt_sys_info /data/data/com.termux/files/usr/share/info
28
+ tlpdbopt_sys_man /data/data/com.termux/files/usr/share/man
29
+ tlpdbopt_w32_multi_user 1
package/loan/hutang.py ADDED
@@ -0,0 +1,175 @@
1
+ from datetime import datetime
2
+
3
+ # Pangkalan data utama untuk rekod pelanggan dan sejarah bayaran
4
+ pangkalan_data_penghutang = []
5
+
6
+ def kira_ansuran_minimum(pokok, kadar_tahunan, total_bulan):
7
+ """Mengira ansuran bulanan tetap berdasarkan jumlah BULAN"""
8
+ kadar_bulanan = (kadar_tahunan / 100) / 12
9
+ if kadar_bulanan == 0:
10
+ return pokok / total_bulan
11
+ # Formula Amortisasi Standard menggunakan total_bulan terus
12
+ ansuran = pokok * (kadar_bulanan * (1 + kadar_bulanan)**total_bulan) / ((1 + kadar_bulanan)**total_bulan - 1)
13
+ return ansuran
14
+
15
+ def simulasi_dan_rekod_bayaran(pokok, kadar_tahunan, total_bulan, bayaran_pilihan):
16
+ kadar_bulanan = (kadar_tahunan / 100) / 12
17
+ baki = pokok
18
+ bulan_berjalan = 0
19
+ jumlah_faedah_dibayar = 0
20
+ log_bayaran = []
21
+
22
+ while baki > 0:
23
+ bulan_berjalan += 1
24
+ faedah_bulan_ini = baki * kadar_bulanan
25
+ jumlah_faedah_dibayar += faedah_bulan_ini
26
+
27
+ if baki + faedah_bulan_ini <= bayaran_pilihan:
28
+ bayaran_sebenar = baki + faedah_bulan_ini
29
+ pokok_dipotong = baki
30
+ baki = 0
31
+ else:
32
+ bayaran_sebenar = bayaran_pilihan
33
+ pokok_dipotong = bayaran_pilihan - faedah_bulan_ini
34
+ baki -= pokok_dipotong
35
+
36
+ log_bayaran.append({
37
+ "bulan": bulan_berjalan,
38
+ "bayaran": bayaran_sebenar,
39
+ "faedah": faedah_bulan_ini,
40
+ "pokok_terpotong": pokok_dipotong,
41
+ "baki_akhir": baki
42
+ })
43
+
44
+ return bulan_berjalan, jumlah_faedah_dibayar, log_bayaran
45
+
46
+ def tambah_rekod_penghutang():
47
+ print("\n" + "="*45)
48
+ print(" INPUT MAKLUMAT PENGHUTANG BAHARU ")
49
+ print("="*45)
50
+
51
+ nama = input("Masukkan Nama Penghutang: ").strip().upper()
52
+ pokok = float(input("Masukkan Jumlah Pinjaman (RM): "))
53
+ kadar = float(input("Masukkan Kadar Faedah Tahunan (%): "))
54
+
55
+ # SEKARANG INPUT DALAM BULAN
56
+ total_bulan_asal = int(input("Masukkan Tempoh Pinjaman (Bulan) (Contoh: 60): "))
57
+
58
+ ansuran_min = kira_ansuran_minimum(pokok, kadar, total_bulan_asal)
59
+ print(f"\n[INFO]: Ansuran minimum wajib: RM{ansuran_min:.2f} sebulan.")
60
+
61
+ while True:
62
+ bayaran_pilihan = float(input(f"Masukkan bayaran bulanan (RM{ansuran_min:.2f} ke atas): "))
63
+ if bayaran_pilihan >= round(ansuran_min, 2):
64
+ break
65
+ print(f"[AMARAN]: Bayaran tidak boleh kurang dari RM{ansuran_min:.2f}!")
66
+
67
+ ekstra_ke_principal = bayaran_pilihan - ansuran_min
68
+
69
+ waktu_sekarang = datetime.now()
70
+ tarikh_terkini = waktu_sekarang.strftime("%d/%m/%Y")
71
+
72
+ # Jalankan simulasi
73
+ bulan_sebenar, total_faedah, sejarah_transaksi = simulasi_dan_rekod_bayaran(pokok, kadar, total_bulan_asal, bayaran_pilihan)
74
+
75
+ status_jadual = f"{bulan_sebenar} daripada {total_bulan_asal} Bulan"
76
+
77
+ rekod = {
78
+ "nama": nama,
79
+ "jumlah": pokok,
80
+ "tarikh": tarikh_terkini,
81
+ "status_jadual": status_jadual,
82
+ "ansuran_dibayar": bayaran_pilihan,
83
+ "sejarah_bayaran": sejarah_transaksi,
84
+ "total_faedah_hangus": total_faedah
85
+ }
86
+ pangkalan_data_penghutang.append(rekod)
87
+ print(f"\n[SUKSES]: Rekod {nama} disimpan! Kontrak {total_bulan_asal} bulan, selesai dalam {bulan_sebenar} bulan.")
88
+
89
+ def paparkan_semua_rekod():
90
+ print("\n" + "="*95)
91
+ print(f"{'RINGKASAN PANGKALAN DATA PENGHUTANG (VERSI BULAN)':^95}")
92
+ print("="*95)
93
+ print(f"{'Nama Penghutang':<18} | {'Jumlah (RM)':<12} | {'Bayaran/Bln':<12} | {'Tarikh':<11} | {'Jadual Masa Berjalan':<20}")
94
+ print("-" * 95)
95
+
96
+ if not pangkalan_data_penghutang:
97
+ print(f"{'[Tiada Rekod Disimpan Lagi]':^95}")
98
+ else:
99
+ for r in pangkalan_data_penghutang:
100
+ print(f"{r['nama']:<18} | RM{r['jumlah']:<10,.2f} | RM{r['ansuran_dibayar']:<10,.2f} | {r['tarikh']:<11} | {r['status_jadual']:<20}")
101
+ print("="*95)
102
+
103
+ def paparkan_sejarah_terperinci():
104
+ print("\n" + "="*45)
105
+ print(" AUDIT SEJARAH BAYARAN LENGKAP ")
106
+ print("="*45)
107
+ if not pangkalan_data_penghutang:
108
+ print("[SISTEM]: Pangkalan data kosong.")
109
+ return
110
+
111
+ nama_cari = input("Masukkan nama penghutang untuk diaudit: ").strip().upper()
112
+
113
+ dijumpai = False
114
+ for r in pangkalan_data_penghutang:
115
+ if r['nama'] == nama_cari:
116
+ dijumpai = True
117
+ print(f"\n>> PEMILIK REKOD: {r['nama']}")
118
+ print(f">> TOTAL FAEDAH DIBAYAR KEPADA BANK: RM{r['total_faedah_hangus']:.2f}")
119
+ print("-" * 75)
120
+ print(f"{'Bln':<5} | {'Jumlah Bayaran':<15} | {'Potong Faedah':<15} | {'Potong Pokok':<15} | {'Baki Pokok':<15}")
121
+ print("-" * 75)
122
+
123
+ for log in r['sejarah_bayaran']:
124
+ print(f"{log['bulan']:<5} | RM{log['bayaran']:<12.2f} | RM{log['faedah']:<12.2f} | RM{log['pokok_terpotong']:<12.2f} | RM{log['baki_akhir']:<12.2f}")
125
+ print("-" * 75)
126
+ break
127
+
128
+ if not dijumpai:
129
+ print(f"\n[RALAT]: Nama '{nama_cari}' tidak dijumpai.")
130
+
131
+ def padam_rekod_penghutang():
132
+ print("\n" + "="*45)
133
+ print(" PADAM REKOD PELANGGAN ")
134
+ print("="*45)
135
+ if not pangkalan_data_penghutang:
136
+ print("[SISTEM]: Pangkalan data kosong.")
137
+ return
138
+
139
+ nama_padam = input("Masukkan nama untuk dipadam: ").strip().upper()
140
+
141
+ dijumpai = False
142
+ for r in pangkalan_data_penghutang:
143
+ if r['nama'] == nama_padam:
144
+ pangkalan_data_penghutang.remove(r)
145
+ print(f"\n[SUKSES]: Rekod '{nama_padam}' dipadam.")
146
+ dijumpai = True
147
+ break
148
+
149
+ if not dijumpai:
150
+ print(f"\n[RALAT]: Nama '{nama_padam}' tidak wujud.")
151
+
152
+ # --- MENU UTAMA SISTEM ---
153
+ while True:
154
+ print("\n=== MENU UTAMA SISTEM PINJAMAN BIJAK ===")
155
+ print("1. Tambah & Semak Rekod Penghutang")
156
+ print("2. Lihat Ringkasan Semua Penghutang")
157
+ print("3. Audit Sejarah Bayaran Terperinci Pelanggan")
158
+ print("4. Padam Rekod Pelanggan")
159
+ print("5. Keluar Sistem")
160
+
161
+ pilihan = input("Pilih menu (1/2/3/4/5): ").strip()
162
+
163
+ if pilihan == "1":
164
+ tambah_rekod_penghutang()
165
+ elif pilihan == "2":
166
+ paparkan_semua_rekod()
167
+ elif pilihan == "3":
168
+ paparkan_sejarah_terperinci()
169
+ elif pilihan == "4":
170
+ padam_rekod_penghutang()
171
+ elif pilihan == "5":
172
+ print("\nTerima kasih! Sistem ditutup.")
173
+ break
174
+ else:
175
+ print("\n[RALAT]: Pilihan tidak sah.")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wellnpm",
3
- "version": "2.0.10",
3
+ "version": "2.0.11",
4
4
  "description": "A brief description of your package",
5
5
  "main": "launch",
6
6
  "scripts": {