turkiyem 1.9.0 → 1.10.0
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.
- package/README.md +37 -6
- package/package.json +1 -1
- package/src/commands/menu.js +17 -124
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
-
|
|
15
|
+
9 şehrin toplu taşıma verileri, güncel nöbetçi eczaneler, AFAD deprem bilgileri, Open-Meteo hava durumu, TCMB döviz kurları — hepsi tek bir <code>npm</code> paketi içinde.
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
---
|
|
@@ -52,6 +52,7 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
|
|
|
52
52
|
|
|
53
53
|
- 🔎 Tarayıcı açmadan **hat ve durak sorgulama**
|
|
54
54
|
- 📍 Terminal üzerinden **canlı araç takibi** (İstanbul, Bursa)
|
|
55
|
+
- 💊 Anlık **nöbetçi eczane** sorgulama seçenekleri
|
|
55
56
|
- 🌍 **Deprem bildirimleri** renkli uyarılarla
|
|
56
57
|
- ⛅ **Hava durumu** ve **hava kalitesi** API key gerektirmeden
|
|
57
58
|
- 💱 **TCMB döviz kurları** tek komutla
|
|
@@ -71,6 +72,8 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
|
|
|
71
72
|
| **İzmir** | ESHOT (GTFS Açık Veri) | ✅ | ✅ | — | ✅ |
|
|
72
73
|
| **Trabzon** | Trabzon Büyükşehir Belediyesi | ✅ | — | — | ✅ |
|
|
73
74
|
| **Samsun** | Samulaş | ✅ | ✅ | — | ✅ |
|
|
75
|
+
| **Mersin** | Mersin Büyükşehir Belediyesi | ✅ | — | — | ✅ |
|
|
76
|
+
| **Kayseri** | Sadece Nöbetçi Eczane | — | — | — | — |
|
|
74
77
|
|
|
75
78
|
> Yeni şehir entegrasyonları için [yol haritasına](#-yol-haritası) bakın.
|
|
76
79
|
|
|
@@ -78,13 +81,18 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
|
|
|
78
81
|
|
|
79
82
|
## ✨ Özellikler
|
|
80
83
|
|
|
81
|
-
### 🚌 Toplu Taşıma (
|
|
84
|
+
### 🚌 Toplu Taşıma (9 Şehir)
|
|
82
85
|
- Hat numarası veya adıyla arama
|
|
83
86
|
- Durak listesi ve sıralı güzergah görüntüleme
|
|
84
87
|
- Sefer saatleri (gün tipi ve yöne göre)
|
|
85
88
|
- Durak bazlı geçen hat ve zaman sorgulama
|
|
86
89
|
- Birden fazla sonuçta interaktif seçim menüsü
|
|
87
90
|
|
|
91
|
+
### 💊 Sağlık & Nöbetçi Eczane
|
|
92
|
+
- **İzmir** ve **Kayseri** için nöbetçi eczane sorgulama
|
|
93
|
+
- İzmir genel eczane arama ve lokasyon bilgisi
|
|
94
|
+
- Telefon numarası ve harita bağlantısı gösterimi
|
|
95
|
+
|
|
88
96
|
### 📍 Canlı Araç Takibi
|
|
89
97
|
- **İstanbul (IETT):** Anlık araç konumu, yön, yakın durak bilgisi
|
|
90
98
|
- **Bursa (Burulaş):** Plaka, hız, doluluk oranı gösterimi
|
|
@@ -185,6 +193,9 @@ turkiyem sehir adana # Şehri Adana olarak ayarla
|
|
|
185
193
|
turkiyem sehir antalya # Şehri Antalya olarak ayarla
|
|
186
194
|
turkiyem sehir bursa # Şehri Bursa olarak ayarla
|
|
187
195
|
turkiyem sehir izmir # Şehri İzmir olarak ayarla
|
|
196
|
+
turkiyem sehir samsun # Şehri Samsun olarak ayarla
|
|
197
|
+
turkiyem sehir mersin # Şehri Mersin olarak ayarla
|
|
198
|
+
turkiyem sehir kayseri # Şehri Kayseri olarak ayarla
|
|
188
199
|
```
|
|
189
200
|
|
|
190
201
|
> 💡 `hat` ve `durak` komutları her zaman seçili şehre göre çalışır.
|
|
@@ -219,10 +230,26 @@ turkiyem hat 34
|
|
|
219
230
|
# Trabzon — Hat bilgisi + kalkış ve dönüş yönlü sefer saatleri
|
|
220
231
|
turkiyem sehir trabzon
|
|
221
232
|
turkiyem hat 103
|
|
233
|
+
|
|
234
|
+
# Samsun (Samulaş) — Hat bilgisi + duraklar + kalkış saatleri
|
|
235
|
+
turkiyem sehir samsun
|
|
236
|
+
turkiyem hat E1
|
|
237
|
+
|
|
238
|
+
# Mersin — Hat bilgisi + kalkış saatleri
|
|
239
|
+
turkiyem sehir mersin
|
|
240
|
+
turkiyem hat 11M # veya 'merkez' yazarak hat seçimi yapabilirsiniz
|
|
222
241
|
```
|
|
223
242
|
|
|
224
243
|
> Birden fazla eşleşen hat varsa interaktif bir seçim menüsü sunulur.
|
|
225
244
|
|
|
245
|
+
### Sağlık & Nöbetçi Eczane (İzmir / Kayseri)
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
turkiyem eczane nobetci # Seçili şehirdeki tüm nöbetçi eczaneleri listeler
|
|
249
|
+
turkiyem eczane nobetci bornova # Seçili şehirde "bornova" ilçesi için arar
|
|
250
|
+
turkiyem eczane ara yusuf # İzmir'de adı/adresi "yusuf" olan tüm eczaneleri getirir
|
|
251
|
+
```
|
|
252
|
+
|
|
226
253
|
### Durak Sorgulama
|
|
227
254
|
|
|
228
255
|
```bash
|
|
@@ -314,6 +341,10 @@ turkiyem temizle # Cache ve yapılandırmayı sıfırla
|
|
|
314
341
|
| [Burulaş (Bursakart)](https://www.bursakart.com.tr) | Hat / durak / canlı konum | Bursa | Kamu API |
|
|
315
342
|
| [ESHOT GTFS](https://acikveri.bizizmir.com) | Hat / durak / sefer saatleri | İzmir | İzmir Açık Veri Lisansı |
|
|
316
343
|
| [Trabzon Büyükşehir](https://ulasim.trabzon.bel.tr) | Hat / sefer saatleri | Trabzon | Kamu verisi |
|
|
344
|
+
| [Samulaş](https://samulas.com.tr) | Hat / durak / sefer saatleri | Samsun | Kamu verisi |
|
|
345
|
+
| [Mersin Büyükşehir](https://ulasim.mersin.bel.tr) | Hat / sefer saatleri | Mersin | Kamu API |
|
|
346
|
+
| [İzmir BB Açık Veri](https://acikveri.bizizmir.com) | Eczane Bilgileri | İzmir | İzmir Açık Veri Lisansı |
|
|
347
|
+
| [Kayseri BB Açık Veri](https://acikveri.kayseri.bel.tr) | Nöbetçi Eczaneler | Kayseri | Kamu API |
|
|
317
348
|
| [Open-Meteo](https://open-meteo.com) | Hava durumu, hava kalitesi | Tüm dünya | CC BY 4.0 |
|
|
318
349
|
| [TCMB](https://www.tcmb.gov.tr) | Döviz kurları | — | Kamu verisi |
|
|
319
350
|
|
|
@@ -470,11 +501,11 @@ Detaylı yol haritası için [`TODO.md`](./TODO.md) dosyasına bakın.
|
|
|
470
501
|
|---------|-------|
|
|
471
502
|
| Kocaeli GTFS Verileri | 📋 Planlandı |
|
|
472
503
|
| Konya GTFS Verileri | 📋 Planlandı |
|
|
473
|
-
| Mersin Ulaşım Tarifeleri |
|
|
474
|
-
| Samsun Otobüs Bilgileri |
|
|
504
|
+
| Mersin Ulaşım Tarifeleri | ✅ Tamamlandı |
|
|
505
|
+
| Samsun Otobüs Bilgileri | ✅ Tamamlandı |
|
|
475
506
|
| Trabzon Ulaşım Bilgileri | ✅ Tamamlandı |
|
|
476
|
-
| İzmir Nöbetçi Eczane |
|
|
477
|
-
| Kayseri Nöbetçi Eczane |
|
|
507
|
+
| İzmir Nöbetçi Eczane | ✅ Tamamlandı |
|
|
508
|
+
| Kayseri Nöbetçi Eczane | ✅ Tamamlandı |
|
|
478
509
|
| e-Nabız / e-Sağlık | 📋 Planlandı |
|
|
479
510
|
|
|
480
511
|
---
|
package/package.json
CHANGED
package/src/commands/menu.js
CHANGED
|
@@ -2,157 +2,50 @@ import chalk from 'chalk';
|
|
|
2
2
|
import prompts from 'prompts';
|
|
3
3
|
import { printBanner } from '../utils/banner.js';
|
|
4
4
|
import { getCity } from '../utils/config.js';
|
|
5
|
-
import { sehirSec } from './sehir.js';
|
|
6
|
-
import { hatSorgula, hatCanliSorgula } from './hat.js';
|
|
7
|
-
import { depremSon24, deprem7Gun, depremBuyukluk } from './deprem.js';
|
|
8
|
-
import { havaGuncel, havaSaatlik, havaKalitesi } from './hava.js';
|
|
9
|
-
import { dovizKurlari } from './doviz.js';
|
|
10
|
-
import { durakSorgula } from './durak.js';
|
|
11
5
|
|
|
12
6
|
function printSessionHeader() {
|
|
13
7
|
const city = getCity();
|
|
14
8
|
const cityLabel = city ? chalk.green.bold(city) : chalk.yellow('seçilmedi');
|
|
15
9
|
console.log('');
|
|
16
10
|
console.log(chalk.gray('─'.repeat(60)));
|
|
17
|
-
console.log(chalk.gray(` 🏙️ Aktif şehir: ${cityLabel} │ ${chalk.gray('Çıkmak için: Ctrl+C veya "
|
|
11
|
+
console.log(chalk.gray(` 🏙️ Aktif şehir: ${cityLabel} │ ${chalk.gray('Çıkmak için: Ctrl+C veya "exit"')}`));
|
|
18
12
|
console.log(chalk.gray('─'.repeat(60)));
|
|
19
13
|
console.log('');
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
export async function showMenu() {
|
|
23
17
|
printBanner();
|
|
24
|
-
console.log(chalk.white.bold(' 🇹🇷 Sürekli oturum modu —
|
|
18
|
+
console.log(chalk.white.bold(' 🇹🇷 Sürekli oturum modu — Komutları direkt yazabilirsiniz (Örn: hat 500T, deprem son24)\n'));
|
|
19
|
+
console.log(chalk.gray(' Tüm komutları görmek için "help" yazabilirsiniz.\n'));
|
|
25
20
|
|
|
26
21
|
// REPL loop — kullanıcı çıkış seçene kadar devam et
|
|
27
22
|
while (true) {
|
|
28
23
|
printSessionHeader();
|
|
29
24
|
|
|
30
|
-
const
|
|
31
|
-
type: '
|
|
32
|
-
name: '
|
|
33
|
-
message: '
|
|
34
|
-
choices: [
|
|
35
|
-
{ title: '🚌 Toplu Taşıma (Hat Sorgula)', value: 'hat' },
|
|
36
|
-
{ title: '📍 Canlı Araç Takibi', value: 'canli' },
|
|
37
|
-
{ title: '🚏 Durak Sorgula', value: 'durak' },
|
|
38
|
-
{ title: '🌍 Deprem Bilgileri', value: 'deprem' },
|
|
39
|
-
{ title: '⛅ Hava Durumu', value: 'hava' },
|
|
40
|
-
{ title: '💱 Döviz Kurları (TCMB)', value: 'doviz' },
|
|
41
|
-
{ title: '⚙️ Şehir Değiştir', value: 'sehir' },
|
|
42
|
-
{ title: '❌ Çıkış', value: 'exit' }
|
|
43
|
-
]
|
|
25
|
+
const { cmd } = await prompts({
|
|
26
|
+
type: 'text',
|
|
27
|
+
name: 'cmd',
|
|
28
|
+
message: chalk.cyan('turkiyem >')
|
|
44
29
|
});
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
if (!response.action || response.action === 'exit') {
|
|
31
|
+
if (cmd === undefined || cmd.trim().toLowerCase() === 'exit' || cmd.trim().toLowerCase() === 'çıkış') {
|
|
48
32
|
console.log('');
|
|
49
33
|
console.log(chalk.cyan(' Görüşmek üzere! 🇹🇷👋'));
|
|
50
34
|
console.log('');
|
|
51
35
|
break;
|
|
52
36
|
}
|
|
53
37
|
|
|
38
|
+
const args = cmd.trim().split(' ').filter(Boolean);
|
|
39
|
+
|
|
40
|
+
if (args.length === 0) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
54
44
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const { hatNo } = await prompts({
|
|
58
|
-
type: 'text',
|
|
59
|
-
name: 'hatNo',
|
|
60
|
-
message: 'Hat numarasını/adını girin:'
|
|
61
|
-
});
|
|
62
|
-
if (hatNo) await hatSorgula(hatNo);
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
case 'canli': {
|
|
66
|
-
const { hatNo } = await prompts({
|
|
67
|
-
type: 'text',
|
|
68
|
-
name: 'hatNo',
|
|
69
|
-
message: 'Canlı takip için hat numarasını girin:'
|
|
70
|
-
});
|
|
71
|
-
if (hatNo) await hatCanliSorgula(hatNo, {});
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case 'durak': {
|
|
75
|
-
const { stopId } = await prompts({
|
|
76
|
-
type: 'text',
|
|
77
|
-
name: 'stopId',
|
|
78
|
-
message: 'Durak numarasını/adını girin:'
|
|
79
|
-
});
|
|
80
|
-
if (stopId) await durakSorgula(stopId);
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
case 'deprem': {
|
|
84
|
-
const { subAction } = await prompts({
|
|
85
|
-
type: 'select',
|
|
86
|
-
name: 'subAction',
|
|
87
|
-
message: 'Hangi deprem verisi?',
|
|
88
|
-
choices: [
|
|
89
|
-
{ title: '🕐 Son 24 Saat', value: 'son24' },
|
|
90
|
-
{ title: '📅 Son 7 Gün', value: '7gun' },
|
|
91
|
-
{ title: '📊 Büyüklüğe Göre Filtrele', value: 'buyukluk' },
|
|
92
|
-
{ title: '↩ Geri', value: 'back' }
|
|
93
|
-
]
|
|
94
|
-
});
|
|
95
|
-
if (subAction === 'son24') await depremSon24();
|
|
96
|
-
else if (subAction === '7gun') await deprem7Gun();
|
|
97
|
-
else if (subAction === 'buyukluk') {
|
|
98
|
-
const { deger } = await prompts({
|
|
99
|
-
type: 'text',
|
|
100
|
-
name: 'deger',
|
|
101
|
-
message: 'Minimum büyüklük değeri (ör: 4.0):'
|
|
102
|
-
});
|
|
103
|
-
if (deger) await depremBuyukluk(deger);
|
|
104
|
-
}
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
case 'hava': {
|
|
108
|
-
const { subAction } = await prompts({
|
|
109
|
-
type: 'select',
|
|
110
|
-
name: 'subAction',
|
|
111
|
-
message: 'Hangi hava verisi?',
|
|
112
|
-
choices: [
|
|
113
|
-
{ title: '🌡️ Güncel Hava', value: 'guncel' },
|
|
114
|
-
{ title: '⏱️ Saatlik Tahmin', value: 'saatlik' },
|
|
115
|
-
{ title: '🏭 Hava Kalitesi', value: 'kalite' },
|
|
116
|
-
{ title: '↩ Geri', value: 'back' }
|
|
117
|
-
]
|
|
118
|
-
});
|
|
119
|
-
if (subAction === 'back') break;
|
|
120
|
-
const { konum } = await prompts({
|
|
121
|
-
type: 'text',
|
|
122
|
-
name: 'konum',
|
|
123
|
-
message: 'Şehir adı veya koordinat (boş bırakırsan seçili şehir):'
|
|
124
|
-
});
|
|
125
|
-
const loc = konum || undefined;
|
|
126
|
-
if (subAction === 'guncel') await havaGuncel(loc);
|
|
127
|
-
else if (subAction === 'saatlik') await havaSaatlik(loc, 2);
|
|
128
|
-
else if (subAction === 'kalite') await havaKalitesi(loc);
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
case 'doviz':
|
|
132
|
-
await dovizKurlari({ tum: false });
|
|
133
|
-
break;
|
|
134
|
-
case 'sehir': {
|
|
135
|
-
const { sehir } = await prompts({
|
|
136
|
-
type: 'select',
|
|
137
|
-
name: 'sehir',
|
|
138
|
-
message: 'Hangi şehri seçmek istersiniz?',
|
|
139
|
-
choices: [
|
|
140
|
-
{ title: 'Ankara', value: 'ankara' },
|
|
141
|
-
{ title: 'İstanbul', value: 'istanbul' },
|
|
142
|
-
{ title: 'Adana', value: 'adana' },
|
|
143
|
-
{ title: 'Antalya', value: 'antalya' },
|
|
144
|
-
{ title: 'Bursa', value: 'bursa' },
|
|
145
|
-
{ title: 'İzmir', value: 'izmir' },
|
|
146
|
-
{ title: 'Trabzon', value: 'trabzon' },
|
|
147
|
-
{ title: 'Samsun', value: 'samsun' }
|
|
148
|
-
]
|
|
149
|
-
});
|
|
150
|
-
if (sehir) sehirSec(sehir);
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
45
|
+
const { spawnSync } = await import('node:child_process');
|
|
46
|
+
spawnSync(process.argv[0], [process.argv[1], ...args], { stdio: 'inherit' });
|
|
154
47
|
} catch (err) {
|
|
155
|
-
console.log(chalk.red(
|
|
48
|
+
console.log(chalk.red(`\n Komut çalıştırılamadı: ${err.message}`));
|
|
156
49
|
}
|
|
157
50
|
}
|
|
158
51
|
}
|