Compare commits
49 Commits
php7
...
69debeeffd
| Author | SHA1 | Date | |
|---|---|---|---|
| 69debeeffd | |||
| 266447e03d | |||
| 747043d616 | |||
| be9d6e3687 | |||
| 15abebe9ed | |||
| beaac25180 | |||
| b494d45ed8 | |||
| 41eaf7c6df | |||
| 6ddf932bea | |||
| 93c7f74356 | |||
| 7fc4683cb3 | |||
| 8be72acf26 | |||
| fc32aa6935 | |||
| c37373c083 | |||
| 0ab592ecbc | |||
| 41fa599cd3 | |||
| 7294890f06 | |||
| 0d6e449808 | |||
| 9409a4dbd9 | |||
| a46f286ce2 | |||
| bf016af07c | |||
| 61c7a77431 | |||
| 09e981f94b | |||
| 30dd0c5b8d | |||
| e2684ef05a | |||
| c478be2f3f | |||
| 84b9182937 | |||
| d381fdfbe1 | |||
| f860ce5e5c | |||
| 74d2e3e602 | |||
| 725fb50e03 | |||
| 3e10131f81 | |||
| 677da3892d | |||
| c62211f393 | |||
| 2ec15193a0 | |||
| 32119b6911 | |||
| c7b06c0cba | |||
| 7d108ca032 | |||
| 5283c8aac9 | |||
| df5a21efa7 | |||
| 63aa362100 | |||
| 5d6b9a2f48 | |||
| 700bfb2994 | |||
| c20b900e33 | |||
| 5c96b6b72e | |||
| 026ee3f85d | |||
| dace80dd79 | |||
| f23743adab | |||
| 944758a215 |
@@ -0,0 +1,3 @@
|
||||
RewriteEngine On
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
@@ -1,4 +1,4 @@
|
||||
# GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE.
|
||||
# Scribe uses this file to know when you change something manually in your docs.
|
||||
.scribe/intro.md=5ba4520f0a0f744a7aceda778b683bb0
|
||||
.scribe/intro.md=731671c57601ba874fec492fc1cf37ad
|
||||
.scribe/auth.md=9bee2b1ef8a238b2e58613fa636d5f39
|
||||
@@ -0,0 +1,94 @@
|
||||
## Autogenerated by Scribe. DO NOT MODIFY.
|
||||
|
||||
name: '🪙 Gold'
|
||||
description: ''
|
||||
endpoints:
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/gold-rates
|
||||
metadata:
|
||||
groupName: '🪙 Gold'
|
||||
groupDescription: ''
|
||||
subgroup: 'Fetch Rates'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current gold rates.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"Meta_Data":{"Minutes_Ago":-0.01,"Current_Date":"2025-09-15 17:13:46","Update_Date":"2025-09-15 17:13:46"},"Rates":{"GRA":{"Selling":4858.08,"Type":"Gold","Name":"GRAMALTIN","Change":0.26,"Buying":4857.61},"XU100":{"Selling":10931.75,"Type":"Gold","Name":"XU100","Change":5.4},"DBITCOIN":{"Selling":0,"Type":"Gold","Name":"DBITCOIN","Change":-0.87},"GUMUS":{"Selling":56.07,"Type":"Gold","Name":"GUMUS","Change":-0.12,"Buying":56.03},"BRENT":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":0.99},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":0.45},"HAS":{"Buying":4833.32,"Type":"Gold","Name":"GRAMHASALTIN","Selling":4833.79,"Change":0.26},"CEYREKALTIN":{"Buying":7891.66,"Type":"Gold","Name":"CEYREKALTIN","Selling":8071.59,"Change":0.01},"YARIMALTIN":{"Buying":15734,"Type":"Gold","Name":"YARIMALTIN","Selling":16143.19,"Change":0.01},"TAMALTIN":{"Buying":31566.65,"Type":"Gold","Name":"TAMALTIN","Selling":32187.64,"Change":0.01},"CUMHURIYETALTINI":{"Buying":32651,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":33144,"Change":-0.13},"ATAALTIN":{"Buying":32553.11,"Type":"Gold","Name":"ATAALTIN","Selling":33372.46,"Change":0.01},"14AYARALTIN":{"Buying":2811.4,"Type":"Gold","Name":"14AYARALTIN","Selling":2813.95,"Change":0.01},"18AYARALTIN":{"Buying":3600.57,"Type":"Gold","Name":"18AYARALTIN","Selling":3603.83,"Change":0.01},"YIA":{"Buying":4498.25,"Type":"Gold","Name":"22AYARBILEZIK","Selling":4502.32,"Change":0.01},"IKIBUCUKALTIN":{"Buying":78916.62,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":80172.88,"Change":0.01},"BESLIALTIN":{"Buying":159806.16,"Type":"Gold","Name":"BESLIALTIN","Selling":162912.88,"Change":0.01},"GREMSEALTIN":{"Buying":78916.62,"Type":"Gold","Name":"GREMSEALTIN","Selling":80715.93,"Change":0.01},"RESATALTIN":{"Buying":32553.11,"Type":"Gold","Name":"RESATALTIN","Selling":33372.46,"Change":0.01},"HAMITALTIN":{"Buying":32553.11,"Type":"Gold","Name":"HAMITALTIN","Selling":33372.46,"Change":0.01},"GPL":{"Buying":1849.92,"Type":"Platinum","Name":"GRAMPLATIN","Selling":1854.44,"Change":-0.58},"PAL":{"Buying":1563.23,"Type":"Palladium","Name":"GRAMPALADYUM","Selling":1567.85,"Change":-1.93}}}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: 'api/gold-rates/{goldName}'
|
||||
metadata:
|
||||
groupName: '🪙 Gold'
|
||||
groupDescription: ''
|
||||
subgroup: 'Fetch Rates'
|
||||
subgroupDescription: ''
|
||||
title: 'Get gold rate by name.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters:
|
||||
goldName:
|
||||
name: goldName
|
||||
description: ''
|
||||
required: true
|
||||
example: rerum
|
||||
type: string
|
||||
enumValues: []
|
||||
exampleWasSpecified: false
|
||||
nullable: false
|
||||
custom: []
|
||||
cleanUrlParameters:
|
||||
goldName: rerum
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 404
|
||||
content: '{"error":"Currency not found"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
@@ -0,0 +1,83 @@
|
||||
## Autogenerated by Scribe. DO NOT MODIFY.
|
||||
|
||||
name: Time
|
||||
description: ''
|
||||
endpoints:
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/server-time
|
||||
metadata:
|
||||
groupName: Time
|
||||
groupDescription: ''
|
||||
subgroup: 'Server Info'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current server time.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"server_time":"17:13:46"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/server-date
|
||||
metadata:
|
||||
groupName: Time
|
||||
groupDescription: ''
|
||||
subgroup: 'Server Info'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current server date.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"server_date":"2025-09-15"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
@@ -0,0 +1,92 @@
|
||||
name: '🪙 Gold'
|
||||
description: ''
|
||||
endpoints:
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/gold-rates
|
||||
metadata:
|
||||
groupName: '🪙 Gold'
|
||||
groupDescription: ''
|
||||
subgroup: 'Fetch Rates'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current gold rates.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"Meta_Data":{"Minutes_Ago":-0.01,"Current_Date":"2025-09-15 17:13:46","Update_Date":"2025-09-15 17:13:46"},"Rates":{"GRA":{"Selling":4858.08,"Type":"Gold","Name":"GRAMALTIN","Change":0.26,"Buying":4857.61},"XU100":{"Selling":10931.75,"Type":"Gold","Name":"XU100","Change":5.4},"DBITCOIN":{"Selling":0,"Type":"Gold","Name":"DBITCOIN","Change":-0.87},"GUMUS":{"Selling":56.07,"Type":"Gold","Name":"GUMUS","Change":-0.12,"Buying":56.03},"BRENT":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":0.99},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":0.45},"HAS":{"Buying":4833.32,"Type":"Gold","Name":"GRAMHASALTIN","Selling":4833.79,"Change":0.26},"CEYREKALTIN":{"Buying":7891.66,"Type":"Gold","Name":"CEYREKALTIN","Selling":8071.59,"Change":0.01},"YARIMALTIN":{"Buying":15734,"Type":"Gold","Name":"YARIMALTIN","Selling":16143.19,"Change":0.01},"TAMALTIN":{"Buying":31566.65,"Type":"Gold","Name":"TAMALTIN","Selling":32187.64,"Change":0.01},"CUMHURIYETALTINI":{"Buying":32651,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":33144,"Change":-0.13},"ATAALTIN":{"Buying":32553.11,"Type":"Gold","Name":"ATAALTIN","Selling":33372.46,"Change":0.01},"14AYARALTIN":{"Buying":2811.4,"Type":"Gold","Name":"14AYARALTIN","Selling":2813.95,"Change":0.01},"18AYARALTIN":{"Buying":3600.57,"Type":"Gold","Name":"18AYARALTIN","Selling":3603.83,"Change":0.01},"YIA":{"Buying":4498.25,"Type":"Gold","Name":"22AYARBILEZIK","Selling":4502.32,"Change":0.01},"IKIBUCUKALTIN":{"Buying":78916.62,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":80172.88,"Change":0.01},"BESLIALTIN":{"Buying":159806.16,"Type":"Gold","Name":"BESLIALTIN","Selling":162912.88,"Change":0.01},"GREMSEALTIN":{"Buying":78916.62,"Type":"Gold","Name":"GREMSEALTIN","Selling":80715.93,"Change":0.01},"RESATALTIN":{"Buying":32553.11,"Type":"Gold","Name":"RESATALTIN","Selling":33372.46,"Change":0.01},"HAMITALTIN":{"Buying":32553.11,"Type":"Gold","Name":"HAMITALTIN","Selling":33372.46,"Change":0.01},"GPL":{"Buying":1849.92,"Type":"Platinum","Name":"GRAMPLATIN","Selling":1854.44,"Change":-0.58},"PAL":{"Buying":1563.23,"Type":"Palladium","Name":"GRAMPALADYUM","Selling":1567.85,"Change":-1.93}}}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: 'api/gold-rates/{goldName}'
|
||||
metadata:
|
||||
groupName: '🪙 Gold'
|
||||
groupDescription: ''
|
||||
subgroup: 'Fetch Rates'
|
||||
subgroupDescription: ''
|
||||
title: 'Get gold rate by name.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters:
|
||||
goldName:
|
||||
name: goldName
|
||||
description: ''
|
||||
required: true
|
||||
example: rerum
|
||||
type: string
|
||||
enumValues: []
|
||||
exampleWasSpecified: false
|
||||
nullable: false
|
||||
custom: []
|
||||
cleanUrlParameters:
|
||||
goldName: rerum
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 404
|
||||
content: '{"error":"Currency not found"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
@@ -0,0 +1,81 @@
|
||||
name: Time
|
||||
description: ''
|
||||
endpoints:
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/server-time
|
||||
metadata:
|
||||
groupName: Time
|
||||
groupDescription: ''
|
||||
subgroup: 'Server Info'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current server time.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"server_time":"17:13:46"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
-
|
||||
httpMethods:
|
||||
- GET
|
||||
uri: api/server-date
|
||||
metadata:
|
||||
groupName: Time
|
||||
groupDescription: ''
|
||||
subgroup: 'Server Info'
|
||||
subgroupDescription: ''
|
||||
title: 'Get current server date.'
|
||||
description: ''
|
||||
authenticated: false
|
||||
custom: []
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
urlParameters: []
|
||||
cleanUrlParameters: []
|
||||
queryParameters: []
|
||||
cleanQueryParameters: []
|
||||
bodyParameters: []
|
||||
cleanBodyParameters: []
|
||||
fileParameters: []
|
||||
responses:
|
||||
-
|
||||
status: 200
|
||||
content: '{"server_date":"2025-09-15"}'
|
||||
headers:
|
||||
cache-control: 'no-cache, private'
|
||||
content-type: application/json
|
||||
access-control-allow-origin: '*'
|
||||
description: null
|
||||
custom: []
|
||||
responseFields: []
|
||||
auth: []
|
||||
controller: null
|
||||
method: null
|
||||
route: null
|
||||
custom: []
|
||||
@@ -3,7 +3,7 @@
|
||||
Daily Financial Data: Provides access to real-time financial data updated through the Truncgil API, allowing users to track the daily performance of currency exchange rates and cryptocurrencies.
|
||||
|
||||
<aside>
|
||||
<strong>Base URL</strong>: <code>http://localhost:8000</code>
|
||||
<strong>Base URL</strong>: <code>https://finance.truncgil.com</code>
|
||||
</aside>
|
||||
|
||||
This documentation aims to provide all the information you need to work with our API.
|
||||
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Console\Command;
|
||||
use App\Jobs\FetchCurrencyRates;
|
||||
use App\Jobs\FetchGoldRates;
|
||||
use App\Jobs\MergeCurrencyAndGoldRates;
|
||||
use App\Jobs\FetchCryptoCurrencyRates;
|
||||
|
||||
class RunAllFetchs extends Command
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class RunAllFetchs extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
protected $description = 'This command runs all fetch jobs for currency and gold rates.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
@@ -37,6 +38,11 @@ class RunAllFetchs extends Command
|
||||
$duration = microtime(true) - $start;
|
||||
$results[] = ['FetchCurrencyRates', number_format($duration, 2)];
|
||||
|
||||
$start = microtime(true);
|
||||
FetchCryptoCurrencyRates::dispatchSync();
|
||||
$duration = microtime(true) - $start;
|
||||
$results[] = ['FetchCryptoCurrencyRates', number_format($duration, 2)];
|
||||
|
||||
$start = microtime(true);
|
||||
FetchGoldRates::dispatchSync();
|
||||
$duration = microtime(true) - $start;
|
||||
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use App\Jobs\FetchCurrencyRates;
|
||||
use App\Jobs\FetchGoldRates;
|
||||
use App\Jobs\FetchCryptoCurrencyRates;
|
||||
use App\Jobs\MergeCurrencyAndGoldRates;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
@@ -22,6 +23,7 @@ class Kernel extends ConsoleKernel
|
||||
{
|
||||
$schedule->job(new FetchCurrencyRates())->everyMinute();
|
||||
$schedule->job(new FetchGoldRates())->everyMinute();
|
||||
$schedule->job(new FetchCryptoCurrencyRates())->everyMinute();
|
||||
$schedule->job(new MergeCurrencyAndGoldRates())->everyMinute();
|
||||
}
|
||||
|
||||
@@ -42,6 +44,8 @@ class Kernel extends ConsoleKernel
|
||||
$schedule = app(Schedule::class);
|
||||
$schedule->job(new FetchCurrencyRates())->everyMinute();
|
||||
$schedule->job(new FetchGoldRates())->everyMinute();
|
||||
$schedule->job(new FetchCryptoCurrencyRates())->everyMinute();
|
||||
|
||||
$schedule->job(new MergeCurrencyAndGoldRates())->everyMinute();
|
||||
|
||||
// Diğer job'larınızı buraya ekleyin
|
||||
|
||||
@@ -4,8 +4,11 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\FetchCurrencyRates;
|
||||
use App\Jobs\FetchGoldRates;
|
||||
use App\Jobs\FetchCryptoCurrencyRates;
|
||||
use App\Jobs\MergeCurrencyAndGoldRates;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
|
||||
/**
|
||||
* Class CurrencyController
|
||||
@@ -14,38 +17,77 @@ use Illuminate\Support\Facades\Storage;
|
||||
*/
|
||||
class CurrencyController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches all jobs to fetch currency and gold rates synchronously.
|
||||
* Synchronously fetch all currency, crypto and gold rates.
|
||||
* Rate limited to 2 requests per 30 seconds.
|
||||
* @group Cron Job
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function runAllFetchs()
|
||||
{
|
||||
FetchCurrencyRates::dispatchSync();
|
||||
FetchGoldRates::dispatchSync();
|
||||
MergeCurrencyAndGoldRates::dispatchSync();
|
||||
try {
|
||||
|
||||
FetchCurrencyRates::dispatchSync();
|
||||
FetchGoldRates::dispatchSync();
|
||||
FetchCryptoCurrencyRates::dispatchSync();
|
||||
MergeCurrencyAndGoldRates::dispatchSync();
|
||||
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
'message' => 'All currency, crypto and gold rates have been successfully updated'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'message' => 'Kurlar güncellenirken bir hata oluştu: ' . $e->getMessage()
|
||||
], 429);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all gold and currency rates
|
||||
*
|
||||
* Get all currency, crypto and gold rates.
|
||||
* @group All Rates
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getAllRates()
|
||||
{
|
||||
$jsonFile = 'merged/rates.json';
|
||||
|
||||
// JSON dosyasından oku
|
||||
$jsonFile = 'merged/rates.json';
|
||||
if (Storage::exists($jsonFile)) {
|
||||
return response()->json(
|
||||
json_decode(Storage::get($jsonFile), true)
|
||||
);
|
||||
$data = json_decode(Storage::get($jsonFile), true);
|
||||
$currentDate = now();
|
||||
$updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
|
||||
|
||||
if ($updateDate) {
|
||||
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2);
|
||||
$metaData = [
|
||||
'Minutes_Ago' => $minutesAgo,
|
||||
'Current_Date' => $currentDate->toDateTimeString(),
|
||||
'Update_Date' => $updateDate->toDateTimeString(),
|
||||
];
|
||||
unset($data['Update_Date']);
|
||||
$data = [
|
||||
'Meta_Data' => $metaData,
|
||||
'Rates' => $data
|
||||
];
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Veri bulunamadı'], 404);
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current currency rates
|
||||
*
|
||||
* Get current currency rates.
|
||||
* @group 💵 Currency
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getCurrentRates()
|
||||
@@ -53,17 +95,35 @@ class CurrencyController extends Controller
|
||||
// JSON dosyasından oku
|
||||
$jsonFile = 'currency/today.json';
|
||||
if (Storage::exists($jsonFile)) {
|
||||
return response()->json(
|
||||
json_decode(Storage::get($jsonFile), true)
|
||||
);
|
||||
$data = json_decode(Storage::get($jsonFile), true);
|
||||
$currentDate = now(); // Şu anki tarih
|
||||
$updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
|
||||
|
||||
if ($updateDate) {
|
||||
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2); // Kaç dakika önce alındığı
|
||||
$metaData = [ // Tarih bilgileri için alt dizi
|
||||
'Minutes_Ago' => $minutesAgo,
|
||||
'Current_Date' => $currentDate->toDateTimeString(),
|
||||
'Update_Date' => $updateDate->toDateTimeString(), // Update_Date burada kalacak
|
||||
];
|
||||
unset($data['Update_Date']); // Rates içerisindeki Update_Date elemanını kaldır
|
||||
$data = [
|
||||
'Meta_Data' => $metaData, // Tarih bilgileri alt dizisi
|
||||
'Rates' => $data, // Kur bilgileri alt dizisi
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Veri bulunamadı'], 404);
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current gold rates
|
||||
*
|
||||
* Get current gold rates.
|
||||
* @group 🪙 Gold
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getGoldRates()
|
||||
@@ -71,17 +131,70 @@ class CurrencyController extends Controller
|
||||
// JSON dosyasından oku
|
||||
$jsonFile = 'gold/today.json';
|
||||
if (Storage::exists($jsonFile)) {
|
||||
return response()->json(
|
||||
json_decode(Storage::get($jsonFile), true)
|
||||
);
|
||||
$data = json_decode(Storage::get($jsonFile), true);
|
||||
$currentDate = now(); // Şu anki tarih
|
||||
$updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
|
||||
|
||||
if ($updateDate) {
|
||||
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2); // Kaç dakika önce alındığı
|
||||
$metaData = [ // Tarih bilgileri için alt dizi
|
||||
'Minutes_Ago' => $minutesAgo,
|
||||
'Current_Date' => $currentDate->toDateTimeString(),
|
||||
'Update_Date' => $updateDate->toDateTimeString(), // Update_Date burada kalacak
|
||||
];
|
||||
unset($data['Update_Date']); // Rates içerisindeki Update_Date elemanını kaldır
|
||||
$data = [
|
||||
'Meta_Data' => $metaData, // Tarih bilgileri alt dizisi
|
||||
'Rates' => $data, // Kur bilgileri alt dizisi
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Veri bulunamadı'], 404);
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the currency rate by its name
|
||||
*
|
||||
* Get current crypto rates.
|
||||
* @group ₿ Crypto
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getCryptoCurrencyRates()
|
||||
{
|
||||
$jsonFile = 'crypto/today.json';
|
||||
if (Storage::exists($jsonFile)) {
|
||||
$data = json_decode(Storage::get($jsonFile), true);
|
||||
$currentDate = now();
|
||||
$updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
|
||||
|
||||
if ($updateDate) {
|
||||
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2);
|
||||
$metaData = [
|
||||
'Minutes_Ago' => $minutesAgo,
|
||||
'Current_Date' => $currentDate->toDateTimeString(),
|
||||
'Update_Date' => $updateDate->toDateTimeString(),
|
||||
];
|
||||
unset($data['Update_Date']);
|
||||
$data = [
|
||||
'Meta_Data' => $metaData,
|
||||
'Rates' => $data,
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currency rate by name.
|
||||
* @group 💵 Currency
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @param string $currencyName
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
@@ -101,8 +214,10 @@ class CurrencyController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the gold rate by its name
|
||||
*
|
||||
* Get gold rate by name.
|
||||
* @group 🪙 Gold
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @param string $goldName
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
@@ -120,4 +235,26 @@ class CurrencyController extends Controller
|
||||
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get crypto rate by name.
|
||||
* @group ₿ Crypto
|
||||
* @subgroup Fetch Rates
|
||||
*
|
||||
* @param string $cryptoCurrencyName
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getCryptoCurrencyRateByName($cryptoCurrencyName)
|
||||
{
|
||||
$jsonFile = 'crypto/today.json';
|
||||
if (Storage::exists($jsonFile)) {
|
||||
$data = json_decode(Storage::get($jsonFile), true);
|
||||
if (isset($data[$cryptoCurrencyName])) {
|
||||
return response()->json([$cryptoCurrencyName => $data[$cryptoCurrencyName]]);
|
||||
}
|
||||
return response()->json(['error' => 'Cryptocurrency not found'], 404);
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Data not found'], 404);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* @OA\Info(title="Time and Date API", version="1.0.0")
|
||||
*/
|
||||
class TimeDateController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get current server time.
|
||||
* @group Time
|
||||
* @subgroup Server Info
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/server-time",
|
||||
* summary="Get Server Time",
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Successful response",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="server_time", type="string", example="14:30:00")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getServerTime(): JsonResponse
|
||||
{
|
||||
return response()->json(['server_time' => date('H:i:s')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current server date.
|
||||
* @group Time
|
||||
* @subgroup Server Info
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/server-date",
|
||||
* summary="Get Server Date",
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Successful response",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(property="server_date", type="string", example="2023-10-01")
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getServerDate(): JsonResponse
|
||||
{
|
||||
return response()->json(['server_date' => date('Y-m-d')]);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ class Kernel extends HttpKernel
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\EnsurePasswordIsConfirmed::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'api' => \App\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
'custom.throttle' => \App\Http\Middleware\CustomThrottleRequests::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Cache\RateLimiter;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CustomThrottleRequests
|
||||
{
|
||||
protected $limiter;
|
||||
|
||||
public function __construct(RateLimiter $limiter)
|
||||
{
|
||||
$this->limiter = $limiter;
|
||||
}
|
||||
|
||||
public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1): Response
|
||||
{
|
||||
$key = $request->ip();
|
||||
|
||||
if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
|
||||
return response()->json([
|
||||
'error' => 'Rate limit aşıldı',
|
||||
'message' => 'Bu endpoint 30 dakikada bir kez çağrılabilir.',
|
||||
'retry_after' => $this->limiter->availableIn($key)
|
||||
], 429);
|
||||
}
|
||||
|
||||
$this->limiter->hit($key, $decayMinutes * 60);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Helpers\NumberFormatter;
|
||||
|
||||
class FetchCryptoCurrencyRates implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$data = [];
|
||||
$data['Update_Date'] = now()->format('Y-m-d H:i:s');
|
||||
|
||||
// Kripto para kurları
|
||||
$response = $this->fetchData('https://www.doviz.com/kripto-paralar');
|
||||
// DOM işlemleri için veri çekme
|
||||
$dom = new \DOMDocument();
|
||||
@$dom->loadHTML($response->body());
|
||||
$xpath = new \DOMXPath($dom);
|
||||
|
||||
// Kripto para verilerini içeren tabloyu ID'ye göre bul
|
||||
$rows = $xpath->query("//table[@id='coins']/tbody/tr");
|
||||
foreach ($rows as $row) {
|
||||
$symbol = trim($xpath->evaluate("string(.//td[1]//text()[last()])", $row));
|
||||
// Semboldeki boşlukları temizle ve sadece kripto para sembolünü al
|
||||
$symbol = preg_replace('/^.*\s(\w+)\s*$/', '$1', $symbol);
|
||||
|
||||
// Kripto para ismini al
|
||||
$name = $xpath->evaluate("string(.//td[1]//div[@class='cname'])", $row);
|
||||
|
||||
if (strlen($symbol) > 0) {
|
||||
$priceUSD = $xpath->evaluate("string(.//td[2])", $row);
|
||||
$priceTRY = $xpath->evaluate("string(.//td[3])", $row);
|
||||
$change = $xpath->evaluate("string(.//td[6])", $row);
|
||||
|
||||
// Fiyat verilerini temizle (örn: $3.310,57 -> 3310.57)
|
||||
$priceUSD = str_replace('$', '', $priceUSD);
|
||||
$priceUSD = str_replace('.', '', $priceUSD);
|
||||
$priceUSD = str_replace(',', '.', $priceUSD);
|
||||
|
||||
$priceTRY = str_replace('₺', '', $priceTRY);
|
||||
$priceTRY = str_replace('.', '', $priceTRY);
|
||||
$priceTRY = str_replace(',', '.', $priceTRY);
|
||||
|
||||
$change = str_replace('%', '', $change);
|
||||
$change = str_replace('.', '', $change);
|
||||
$change = str_replace(',', '.', $change);
|
||||
|
||||
$data[$symbol] = [
|
||||
'Name' => trim($name),
|
||||
'USD_Price' => (float)$priceUSD,
|
||||
'TRY_Price' => (float)$priceTRY,
|
||||
'Selling' => (float)$priceTRY,
|
||||
'Change' => (float)$change,
|
||||
'Type' => 'CryptoCurrency'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// JSON dosyasını kaydet
|
||||
Storage::put('crypto/today.json', json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function fetchData($url)
|
||||
{
|
||||
return Http::withHeaders([
|
||||
'User-Agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10',
|
||||
'Accept-Language' => 'en'
|
||||
])->get($url);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class FetchCurrencyRates implements ShouldQueue
|
||||
$data = [];
|
||||
$data['Update_Date'] = now()->format('Y-m-d H:i:s');
|
||||
|
||||
// Döviz kurları
|
||||
// Döviz kurları - ana kaynak
|
||||
$response = $this->fetchData('https://kur.doviz.com');
|
||||
|
||||
// DOM işlemleri için veri çekme
|
||||
@@ -38,19 +38,39 @@ class FetchCurrencyRates implements ShouldQueue
|
||||
if (trim($name) !== '') {
|
||||
if ($name == "JPY") $value = $value / 100;
|
||||
if (strlen($name) === 3) {
|
||||
// Para birimi ismini bul
|
||||
$nameElement = $xpath->query(".//div[@class='cname']", $element->parentNode);
|
||||
if ($nameElement->length > 0) {
|
||||
$data[$name]['Name'] = trim($nameElement->item(0)->nodeValue);
|
||||
}
|
||||
|
||||
if ($type == "bid") $data[$name]['Buying'] = (float)$value;
|
||||
if ($type == "ask") $data[$name]['Selling'] = (float)$value;
|
||||
if ($type == "c") $data[$name]['Change'] = round((float)$value, 2);
|
||||
|
||||
$data[$name]['Type'] = "Currency";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Eğer USD verisi yoksa veya boşsa, TCMB'den veri çek
|
||||
if (!isset($data['USD']) || empty($data['USD']['Buying'])) {
|
||||
\Log::info('USD verisi bulunamadı, TCMB\'den veri çekiliyor...');
|
||||
$tcmbData = $this->fetchFromTCMB();
|
||||
if (!empty($tcmbData)) {
|
||||
\Log::info('TCMB\'den ' . count($tcmbData) . ' kur alındı');
|
||||
$data = array_merge($data, $tcmbData);
|
||||
} else {
|
||||
\Log::error('TCMB\'den veri alınamadı');
|
||||
}
|
||||
}
|
||||
|
||||
// AZN kuru için
|
||||
$aznResponse = $this->fetchData('https://wise.com/tr/currency-converter/azn-to-try-rate?amount=1');
|
||||
preg_match('/(\d+\.\d+)\s+TRY/', $aznResponse->body(), $matches);
|
||||
if (isset($matches[1])) {
|
||||
$data['AZN'] = [
|
||||
'Name' => 'AZERBAYCAN YENİ MANATI',
|
||||
'Buying' => NumberFormatter::commaToDot($matches[1]),
|
||||
'Selling' => NumberFormatter::commaToDot($matches[1]),
|
||||
'Change' => "0.00",
|
||||
@@ -71,4 +91,84 @@ class FetchCurrencyRates implements ShouldQueue
|
||||
'Accept-Language' => 'en'
|
||||
])->get($url);
|
||||
}
|
||||
|
||||
private function fetchFromTCMB()
|
||||
{
|
||||
try {
|
||||
$response = $this->fetchData('https://www.tcmb.gov.tr/kurlar/today.xml');
|
||||
|
||||
if (!$response->successful()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$xml = simplexml_load_string($response->body());
|
||||
if (!$xml) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
// Currency mapping - TCMB'deki isimleri kod olarak kullan
|
||||
$currencyMap = [
|
||||
'USD' => 'US DOLLAR',
|
||||
'EUR' => 'EURO',
|
||||
'GBP' => 'POUND STERLING',
|
||||
'CHF' => 'SWISS FRANK',
|
||||
'JPY' => 'JAPENESE YEN',
|
||||
'CAD' => 'CANADIAN DOLLAR',
|
||||
'AUD' => 'AUSTRALIAN DOLLAR',
|
||||
'SEK' => 'SWEDISH KRONA',
|
||||
'NOK' => 'NORWEGIAN KRONE',
|
||||
'DKK' => 'DANISH KRONE',
|
||||
'RUB' => 'RUSSIAN ROUBLE',
|
||||
'CNY' => 'CHINESE RENMINBI',
|
||||
'SAR' => 'SAUDI RIYAL',
|
||||
'KWD' => 'KUWAITI DINAR',
|
||||
'QAR' => 'QATARI RIAL',
|
||||
'AED' => 'UNITED ARAB EMIRATES DIRHAM',
|
||||
'PKR' => 'PAKISTANI RUPEE',
|
||||
'KRW' => 'SOUTH KOREAN WON',
|
||||
'AZN' => 'AZERBAIJANI NEW MANAT',
|
||||
'BGN' => 'BULGARIAN LEV',
|
||||
'RON' => 'NEW LEU'
|
||||
];
|
||||
|
||||
foreach ($xml->Currency as $currency) {
|
||||
$code = (string)$currency['CurrencyCode'];
|
||||
$unit = (float)$currency->Unit;
|
||||
$name = (string)$currency->CurrencyName;
|
||||
$buying = (float)$currency->BanknoteBuying;
|
||||
$selling = (float)$currency->BanknoteSelling;
|
||||
$forexBuying = (float)$currency->ForexBuying;
|
||||
$forexSelling = (float)$currency->ForexSelling;
|
||||
|
||||
// Birim düzeltmesi (100 yen = 1 birim gibi)
|
||||
if ($unit > 1) {
|
||||
$buying = $buying / $unit;
|
||||
$selling = $selling / $unit;
|
||||
$forexBuying = $forexBuying / $unit;
|
||||
$forexSelling = $forexSelling / $unit;
|
||||
}
|
||||
|
||||
// Forex kurları varsa onları kullan, yoksa banknot kurlarını kullan
|
||||
$finalBuying = $forexBuying > 0 ? $forexBuying : $buying;
|
||||
$finalSelling = $forexSelling > 0 ? $forexSelling : $selling;
|
||||
|
||||
if ($finalBuying > 0 && $finalSelling > 0) {
|
||||
$data[$code] = [
|
||||
'Name' => $name,
|
||||
'Buying' => round($finalBuying, 4),
|
||||
'Selling' => round($finalSelling, 4),
|
||||
'Change' => 0.00,
|
||||
'Type' => 'Currency'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Helpers\NumberFormatter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class FetchGoldRates implements ShouldQueue
|
||||
{
|
||||
@@ -23,30 +24,59 @@ class FetchGoldRates implements ShouldQueue
|
||||
// Altın kurları
|
||||
$goldResponse = $this->fetchData('https://altin.doviz.com');
|
||||
|
||||
|
||||
$domGold = new \DOMDocument();
|
||||
@$domGold->loadHTML($goldResponse->body());
|
||||
|
||||
$xpathGold = new \DOMXPath($domGold);
|
||||
|
||||
// Daha spesifik bir sorgu ile sadece ihtiyacımız olan elementleri seçiyoruz
|
||||
$elementsGold = $xpathGold->query("//*[@data-socket-key]");
|
||||
|
||||
|
||||
// Debug için gelen data-socket-key değerlerini loglamak için
|
||||
$socketKeys = [];
|
||||
|
||||
foreach ($elementsGold as $element) {
|
||||
$attrGold = $element->getAttribute('data-socket-key');
|
||||
$typeGold = $element->getAttribute('data-socket-attr');
|
||||
$valueGold = NumberFormatter::commaToDot($element->nodeValue);
|
||||
|
||||
// Debug için data-socket-key değerlerini topluyoruz
|
||||
if (!in_array($attrGold, $socketKeys)) {
|
||||
$socketKeys[] = $attrGold;
|
||||
}
|
||||
|
||||
if (trim($attrGold) !== '') {
|
||||
|
||||
// Önce orijinal ismi tam olarak koruyalım
|
||||
$nameGold = strtoupper(str_replace("-", "", $attrGold));
|
||||
$fullNameGold = $nameGold;
|
||||
$nameGold = str_replace("14", "OD", $nameGold);
|
||||
$nameGold = str_replace("18", "OS", $nameGold);
|
||||
$nameGold = str_replace("22", "YI", $nameGold);
|
||||
|
||||
// Veri tipi belirlemeleri
|
||||
$metalType = "Gold"; // Varsayılan olarak altın
|
||||
|
||||
// Özel metaller için tür kontrolü
|
||||
if (strpos($nameGold, 'GRAMPALADYUM') !== false) {
|
||||
$metalType = "Palladium";
|
||||
} elseif (strpos($nameGold, 'GRAMPLATIN') !== false) {
|
||||
$metalType = "Platinum";
|
||||
} elseif (strpos($nameGold, 'GRAMGUMUS') !== false) {
|
||||
$metalType = "Silver";
|
||||
}
|
||||
|
||||
// Kısaltma işlemleri
|
||||
$nameGold = str_replace("14AYARBILEZIK", "ODB", $nameGold);
|
||||
$nameGold = str_replace("18AYARBILEZIK", "OSB", $nameGold);
|
||||
$nameGold = str_replace("22AYARBILEZIK", "YIA", $nameGold);
|
||||
$nameGold = str_replace("GRAMALTIN", "GRA", $nameGold);
|
||||
$nameGold = str_replace("GRAMPLATIN", "GPL", $nameGold);
|
||||
$nameGold = str_replace("GRAMHASALTIN", "HAS", $nameGold);
|
||||
$nameGold = strtoupper(substr($nameGold, 0, 3));
|
||||
$nameGold = str_replace("GRAMPALADYUM", "PAL", $nameGold);
|
||||
$nameGold = str_replace("GRAMGUMUS", "GUM", $nameGold);
|
||||
|
||||
// Eğer bir kısaltma yapıldıysa, ilk 3 karakteri al
|
||||
// Aksi takdirde orijinal değeri kullan
|
||||
if ($nameGold != $fullNameGold) {
|
||||
$nameGold = strtoupper(substr($nameGold, 0, 3));
|
||||
}
|
||||
|
||||
$except = ['USD', 'EUR', 'GBP', 'XU1', 'BIT'];
|
||||
if (in_array($nameGold, $except)) {
|
||||
@@ -56,12 +86,14 @@ class FetchGoldRates implements ShouldQueue
|
||||
if ($typeGold == "bid") $data[$nameGold]['Buying'] = (float)$valueGold;
|
||||
if ($typeGold == "ask") $data[$nameGold]['Selling'] = (float)$valueGold;
|
||||
if ($typeGold == "s") $data[$nameGold]['Selling'] = (float)$valueGold;
|
||||
if ($typeGold == "c") $data[$nameGold]['Change'] = round((float)$valueGold,
|
||||
2);
|
||||
$data[$nameGold]['Type'] = "Gold";
|
||||
if ($typeGold == "c") $data[$nameGold]['Change'] = round((float)$valueGold, 2);
|
||||
$data[$nameGold]['Type'] = $metalType;
|
||||
$data[$nameGold]['Name'] = $fullNameGold;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug için socket key'leri loglayalım
|
||||
Log::info('Available data-socket-keys: ' . implode(', ', $socketKeys));
|
||||
|
||||
// JSON dosyasını kaydet
|
||||
Storage::put('gold/today.json', json_encode($data, JSON_UNESCAPED_UNICODE));
|
||||
@@ -72,8 +104,9 @@ class FetchGoldRates implements ShouldQueue
|
||||
private function fetchData($url)
|
||||
{
|
||||
return Http::withHeaders([
|
||||
'User-Agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10',
|
||||
'Accept-Language' => 'en'
|
||||
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
'Accept-Language' => 'tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
|
||||
])->get($url);
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,10 @@ class MergeCurrencyAndGoldRates implements ShouldQueue
|
||||
{
|
||||
$currencyData = $this->getData('currency/today.json');
|
||||
$goldData = $this->getData('gold/today.json');
|
||||
$cryptoCurrencyData = $this->getData('crypto/today.json');
|
||||
|
||||
// Verileri birleştir
|
||||
$mergedData = array_merge($currencyData, $goldData);
|
||||
$mergedData = array_merge($currencyData, $goldData, $cryptoCurrencyData);
|
||||
|
||||
// Birleştirilmiş veriyi dışarıya aktar
|
||||
Storage::put('merged/rates.json', json_encode($mergedData, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
@@ -24,10 +24,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
|
||||
@@ -8519,12 +8519,12 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^8.2"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ INTRO
|
||||
// For example, if your logo is in public/img:
|
||||
// - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs)
|
||||
// - 'logo' => 'img/logo.png' // for `laravel` type
|
||||
'logo' => false,
|
||||
'logo' => 'img/logo-light.svg',
|
||||
|
||||
// Customize the "Last updated" value displayed in the docs by specifying tokens and formats.
|
||||
// Examples:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"USD":{"Name":"US DOLLAR","Buying":39.6792,"Selling":39.7506,"Change":0,"Type":"Currency"},"AUD":{"Name":"AUSTRALIAN DOLLAR","Buying":25.967,"Selling":26.1363,"Change":0,"Type":"Currency"},"DKK":{"Name":"DANISH KRONE","Buying":6.2523,"Selling":6.2831,"Change":0,"Type":"Currency"},"EUR":{"Name":"EURO","Buying":46.7222,"Selling":46.8064,"Change":0,"Type":"Currency"},"GBP":{"Name":"POUND STERLING","Buying":54.1032,"Selling":54.3853,"Change":0,"Type":"Currency"},"CHF":{"Name":"SWISS FRANK","Buying":49.8917,"Selling":50.212,"Change":0,"Type":"Currency"},"SEK":{"Name":"SWEDISH KRONA","Buying":4.1341,"Selling":4.1769,"Change":0,"Type":"Currency"},"CAD":{"Name":"CANADIAN DOLLAR","Buying":29.1614,"Selling":29.293,"Change":0,"Type":"Currency"},"KWD":{"Name":"KUWAITI DINAR","Buying":129.2622,"Selling":130.9536,"Change":0,"Type":"Currency"},"NOK":{"Name":"NORWEGIAN KRONE","Buying":3.9292,"Selling":3.9556,"Change":0,"Type":"Currency"},"SAR":{"Name":"SAUDI RIYAL","Buying":10.5802,"Selling":10.5992,"Change":0,"Type":"Currency"},"JPY":{"Name":"JAPENESE YEN","Buying":0.2742,"Selling":0.276,"Change":0,"Type":"Currency"},"BGN":{"Name":"BULGARIAN LEV","Buying":23.7551,"Selling":24.0659,"Change":0,"Type":"Currency"},"RON":{"Name":"NEW LEU","Buying":9.183,"Selling":9.3032,"Change":0,"Type":"Currency"},"RUB":{"Name":"RUSSIAN ROUBLE","Buying":0.5007,"Selling":0.5073,"Change":0,"Type":"Currency"},"CNY":{"Name":"CHINESE RENMINBI","Buying":5.5081,"Selling":5.5802,"Change":0,"Type":"Currency"},"PKR":{"Name":"PAKISTANI RUPEE","Buying":0.139,"Selling":0.1408,"Change":0,"Type":"Currency"},"QAR":{"Name":"QATARI RIAL","Buying":10.8255,"Selling":10.9671,"Change":0,"Type":"Currency"},"KRW":{"Name":"SOUTH KOREAN WON","Buying":0.0289,"Selling":0.0293,"Change":0,"Type":"Currency"},"AZN":{"Name":"AZERBAIJANI NEW MANAT","Buying":23.2099,"Selling":23.5136,"Change":0,"Type":"Currency"},"AED":{"Name":"UNITED ARAB EMIRATES DIRHAM","Buying":10.7422,"Selling":10.8828,"Change":0,"Type":"Currency"}}
|
||||
@@ -0,0 +1,48 @@
|
||||
version: '3'
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfile
|
||||
image: truncgil-finance-app:latest
|
||||
container_name: truncgil-finance-app
|
||||
restart: always
|
||||
volumes:
|
||||
- .:/var/www
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
web:
|
||||
image: nginx:alpine
|
||||
container_name: truncgil-finance-web
|
||||
restart: always
|
||||
ports:
|
||||
- "8089:80"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
container_name: truncgil-finance-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: truncgil_finance
|
||||
MYSQL_USER: truncgil_finance
|
||||
MYSQL_PASSWORD: "QWEFaca123++"
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
networks:
|
||||
- app-network
|
||||
ports:
|
||||
- "3308:3306"
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
@@ -0,0 +1,73 @@
|
||||
# Laravel için PHP 8.2 resmi imajını kullanıyoruz
|
||||
FROM php:8.2-fpm
|
||||
|
||||
|
||||
# Çalışma dizinini belirleyelim
|
||||
WORKDIR /var/www
|
||||
|
||||
# Gerekli bağımlılıkları yükleyelim
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git \
|
||||
unzip \
|
||||
curl \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
libxml2-dev \
|
||||
zip \
|
||||
cron \
|
||||
&& service cron start && \
|
||||
docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd \
|
||||
&& echo "* * * * * cd /var/www && php /var/www/artisan run-all-fetchs >> /dev/null 2>&1" >> /etc/cron.d/laravel-cron \
|
||||
&& chmod 0644 /etc/cron.d/laravel-cron \
|
||||
&& crontab /etc/cron.d/laravel-cron
|
||||
|
||||
# Composer'ı yükleyelim
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Laravel proje dosyalarını kopyalayalım
|
||||
COPY . .
|
||||
|
||||
|
||||
# Gerekli dizinleri oluşturma
|
||||
RUN mkdir -p /var/www/storage/app/private/scribe
|
||||
|
||||
# Start of Selection
|
||||
RUN set -x && \
|
||||
echo "Dosya izinleri ayarlanıyor..." && \
|
||||
chown -R www-data:www-data /var/www && \
|
||||
echo "chown komutu tamamlandı" && \
|
||||
find /var/www -type d -exec chmod 775 {} \; && \
|
||||
echo "Dizin izinleri ayarlandı" && \
|
||||
find /var/www -type f -exec chmod 664 {} \; && \
|
||||
echo "Dosya izinleri ayarlandı" && \
|
||||
chmod -R 775 /var/www/storage && \
|
||||
echo "Storage izinleri ayarlandı" && \
|
||||
chmod -R 775 /var/www/bootstrap/cache && \
|
||||
echo "Cache izinleri ayarlandı" && \
|
||||
chmod -R 775 /var/www/storage/framework/views && \
|
||||
echo "Views izinleri ayarlandı" && \
|
||||
chmod -R 775 /var/www/public && \
|
||||
echo "Public dizin izinleri ayarlandı"
|
||||
# Laravel uygulamasını başlatma ve loglama
|
||||
|
||||
RUN set -x && \
|
||||
# echo "Laravel kurulum komutları başlatılıyor..." && \
|
||||
# php artisan migrate && \
|
||||
# echo "Migrasyon tamamlandı" && \
|
||||
php artisan key:generate && \
|
||||
echo "Uygulama anahtarı oluşturuldu" && \
|
||||
php artisan config:cache && \
|
||||
echo "Konfigürasyon önbelleğe alındı" && \
|
||||
php artisan route:cache && \
|
||||
echo "Rotalar önbelleğe alındı" && \
|
||||
php artisan view:cache && \
|
||||
echo "Görünümler önbelleğe alındı" && \
|
||||
php artisan storage:link && \
|
||||
echo "Storage sembolik bağlantısı oluşturuldu" && \
|
||||
php artisan scribe:generate && \
|
||||
echo "API dokümantasyonu oluşturuldu" && \
|
||||
echo "Laravel uygulaması başarıyla başlatıldı.";
|
||||
|
||||
|
||||
RUN service cron start && \
|
||||
echo "Cron başlatıldı"
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,65 @@
|
||||
server {
|
||||
listen 80; # 88 yerine 80 kullanın
|
||||
server_name localhost;
|
||||
root /var/www/public;
|
||||
index index.php index.html;
|
||||
|
||||
# Keep-alive ve connection ayarları (bağlantı birikmesini önlemek için)
|
||||
keepalive_timeout 65;
|
||||
keepalive_requests 100;
|
||||
client_max_body_size 20M;
|
||||
client_body_timeout 60s;
|
||||
client_header_timeout 60s;
|
||||
send_timeout 60s;
|
||||
|
||||
# HTTPS için proxy headers
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# Güvenlik başlıkları
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
|
||||
# Ana location
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
# PHP dosyaları için
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
|
||||
# HTTPS için ek parametreler
|
||||
fastcgi_param HTTPS on;
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO https;
|
||||
|
||||
# Timeout ayarları
|
||||
fastcgi_read_timeout 300;
|
||||
fastcgi_connect_timeout 60;
|
||||
fastcgi_send_timeout 300;
|
||||
|
||||
# FastCGI keep-alive ve buffer ayarları (bağlantı birikmesini önlemek için)
|
||||
fastcgi_keep_conn on;
|
||||
fastcgi_buffering on;
|
||||
fastcgi_buffer_size 4k;
|
||||
fastcgi_buffers 8 4k;
|
||||
fastcgi_busy_buffers_size 8k;
|
||||
|
||||
# Connection pool ayarları
|
||||
fastcgi_max_temp_file_size 0;
|
||||
}
|
||||
|
||||
# Gizli dosyaları engelle
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Log dosyalarını engelle
|
||||
location ~ /\.log {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 877 968"><g clip-path="url(#a)"><circle cx="391" cy="391" r="390.5" stroke="#009846" transform="matrix(-1 0 0 1 416 -56)" /><circle cx="468" cy="468" r="467.5" stroke="#009846" opacity=".3" transform="matrix(-1 0 0 1 493 -133)"/><circle cx="558" cy="558" r="557.5" stroke="#009846" opacity=".1" transform="matrix(-1 0 0 1 583 -223)" /><g filter="url(#b)"> <ellipse cx="583" cy="229.5" fill="#009846" rx="583" ry="229.5" transform="matrix(-1 0 0 1 621 -9)" /></g><g filter="url(#c)"><ellipse cx="262" cy="184.5" fill="#fff" rx="262" ry="184.5" transform="matrix(-1 0 0 1 99 42)" /></g></g><defs><filter id="b" width="1614" height="907" x="-769" y="-233" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix" /><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /><feGaussianBlur result="effect1_foregroundBlur_3089_39042" stdDeviation="112" /></filter><filter id="c" width="972" height="817" x="-649" y="-182" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix" /><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /><feGaussianBlur result="effect1_foregroundBlur_3089_39042" stdDeviation="112" /></filter><clipPath id="a"><path fill="#fff" d="M877 0H0v968h877z" /></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "Truncgil Finance API",
|
||||
"short_name": "Truncgil Finance",
|
||||
"theme_color": "#009846",
|
||||
"background_color": "#009846",
|
||||
"display": "browser",
|
||||
"orientation": "portrait",
|
||||
"scope": "https://finance.truncgil.com/",
|
||||
"start_url": "https://finance.truncgil.com/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "img/icons/icon-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "img/icons/icon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
@if($rate)
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
|
||||
<p class="title-text">
|
||||
|
||||
{{$currencyName}}
|
||||
</p>
|
||||
<p class="percent" style="color: {{ ($rate['Change'] ?? 0) > 0 ? 'green' : '#B9101E' }}">
|
||||
{{ $rate['Change'] ?? 0 }}%
|
||||
</p>
|
||||
@if(($rate['Change'] ?? 0) > 0)
|
||||
<svg width="20" height="20" fill="green" style="position: relative; top: -2px;" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"> <path d="M384 576q0-26 19-45t45-19h896q26 0 45 19t19 45-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45z"></path> </svg>
|
||||
@else
|
||||
<svg width="20" height="20" fill="#B9101E" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M384 576q0-26 19-45t45-19h896q26 0 45 19t19 45-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45z"></path> </svg>
|
||||
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="data">
|
||||
<p>
|
||||
|
||||
{{$rate['Selling'] ?? '0.00'}} ₺
|
||||
</p>
|
||||
|
||||
<div class="range">
|
||||
<div class="fill" style="background-color: {{ ($rate['Change'] ?? 0) > 0 ? 'green' : '#B9101E' }};">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@@ -1,21 +1,44 @@
|
||||
<!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>{!! $metadata['title'] !!}</title>
|
||||
<!-- Embed elements Elements via Web Component -->
|
||||
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
|
||||
<script src="https://unpkg.com/@stoplight/elements@9.0.0/web-components.min.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements@9.0.0/styles.min.css">
|
||||
<style>
|
||||
body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
elements-api {
|
||||
--elements-border-radius: 6px;
|
||||
}
|
||||
|
||||
.sl-inline img {
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sl-prose p {
|
||||
font-size: var(--fs-paragraph);
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.sl-text-base {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h4.sl-text-paragraph.sl-leading-snug.sl-font-prose.sl-font-semibold.sl-text-heading {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<elements-api
|
||||
@foreach($htmlAttributes as $attribute => $value)
|
||||
{{-- Attributes specified first override later ones --}}
|
||||
@@ -23,12 +46,23 @@
|
||||
@endforeach
|
||||
apiDescriptionUrl="{!! $metadata['openapi_spec_url'] !!}"
|
||||
router="hash"
|
||||
layout="sidebar"
|
||||
layout="responsive"
|
||||
appearance="auto"
|
||||
hideTryIt="{!! ($tryItOut['enabled'] ?? true) ? '' : 'true'!!}"
|
||||
@if(!empty($metadata['logo']))
|
||||
logo="{!! $metadata['logo'] !!}"
|
||||
@endif
|
||||
/>
|
||||
|
||||
<script>
|
||||
setTimeout(function() {
|
||||
const linkElement = document.querySelector('a.sl-flex.sl-items-center.sl-px-4.sl-py-3.sl-border-t');
|
||||
if (linkElement) {
|
||||
linkElement.href = "https://truncgil.com"; // Yeni URL'yi buraya ekleyin
|
||||
linkElement.innerHTML = '<img src="https://truncgil.com.tr/yatay.svg" width="100" alt="Truncgil Teknoloji">'; // Resim URL'sini ve alternatif metni buraya ekleyin
|
||||
}
|
||||
}, 1000); // 1 saniye gecikme
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Proje dizinine git
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Proje adını tanımlayalım
|
||||
PROJECT_NAME="finance"
|
||||
DB_PORT="3308"
|
||||
|
||||
echo "🚀 '$PROJECT_NAME' projesi kontrol ediliyor..."
|
||||
|
||||
# 1. Port çakışmasını kontrol et ve temizle
|
||||
echo "🔍 Port $DB_PORT kontrol ediliyor..."
|
||||
CONFLICTING_CONTAINER=$(docker ps -q --filter "publish=$DB_PORT")
|
||||
if [ ! -z "$CONFLICTING_CONTAINER" ]; then
|
||||
echo "⚠️ Port $DB_PORT, $(docker ps --filter "id=$CONFLICTING_CONTAINER" --format "{{.Names}}") tarafından kullanılıyor. Temizleniyor..."
|
||||
docker rm -f "$CONFLICTING_CONTAINER"
|
||||
fi
|
||||
|
||||
# 2. İsim çakışmalarını temizle
|
||||
echo "🧹 İsim çakışmaları temizleniyor..."
|
||||
docker rm -f truncgil-finance-app truncgil-finance-web truncgil-finance-db 2>/dev/null
|
||||
|
||||
# 3. Servisleri başlat
|
||||
echo "🆙 Servisler başlatılıyor..."
|
||||
docker compose -p "$PROJECT_NAME" up -d --remove-orphans
|
||||
|
||||
# Durumu göster
|
||||
echo "📊 Mevcut durum ($PROJECT_NAME):"
|
||||
docker compose -p "$PROJECT_NAME" ps
|
||||
|
||||
echo "✅ '$PROJECT_NAME' projesi başarıyla ayağa kaldırıldı!"
|
||||
@@ -3,14 +3,14 @@
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\CurrencyController;
|
||||
use App\Http\Controllers\TimeDateController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//Route::get('/run-all-fetchs', [CurrencyController::class, 'runAllFetchs']);
|
||||
Route::get('/run-all-fetchs', [CurrencyController::class, 'runAllFetchs']);
|
||||
|
||||
Route::get('/today.json', [CurrencyController::class, 'getAllRates']);
|
||||
|
||||
@@ -18,4 +18,12 @@ Route::get('/currency-rates', [CurrencyController::class, 'getCurrentRates']);
|
||||
Route::get('/currency-rates/{currencyName}', [CurrencyController::class, 'getCurrencyRateByName']);
|
||||
|
||||
Route::get('/gold-rates', [CurrencyController::class, 'getGoldRates']);
|
||||
Route::get('/gold-rates/{goldName}', [CurrencyController::class, 'getGoldRateByName']);
|
||||
Route::get('/gold-rates/{goldName}', [CurrencyController::class, 'getGoldRateByName']);
|
||||
|
||||
Route::get('/crypto-currency-rates', [CurrencyController::class, 'getCryptoCurrencyRates']);
|
||||
Route::get('/crypto-currency-rates/{cryptoCurrencyName}', [CurrencyController::class, 'getCryptoCurrencyRateByName']);
|
||||
|
||||
|
||||
Route::get('/server-time', [TimeDateController::class, 'getServerTime']);
|
||||
Route::get('/server-date', [TimeDateController::class, 'getServerDate']);
|
||||
|
||||
|
||||