Compare commits
39 Commits
main
...
7fc4683cb3
| Author | SHA1 | Date | |
|---|---|---|---|
| 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.02,"Current_Date":"2025-01-21 22:46:25","Update_Date":"2025-01-21 22:46:24"},"Rates":{"GRA":{"Selling":3140.98,"Type":"Gold","Name":"GRAMALTIN","Change":1.34,"Buying":3140.64},"GUM":{"Selling":35.28,"Type":"Gold","Name":"GUMUS","Change":0.9,"Buying":35.23},"BRE":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":-0.5},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":1.21},"HAS":{"Buying":3125.34,"Type":"Gold","Name":"GRAMHASALTIN","Selling":3125.77,"Change":1.36},"CEY":{"Buying":4996.08,"Type":"Gold","Name":"CEYREKALTIN","Selling":5109.73,"Change":0.73},"YAR":{"Buying":9960.93,"Type":"Gold","Name":"YARIMALTIN","Selling":10219.46,"Change":0.73},"TAM":{"Buying":19984.31,"Type":"Gold","Name":"TAMALTIN","Selling":20376.41,"Change":0.73},"CUM":{"Buying":20709,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":21022,"Change":0.77},"ATA":{"Buying":20608.82,"Type":"Gold","Name":"ATAALTIN","Selling":21126.46,"Change":0.73},"ODA":{"Buying":1779.85,"Type":"Gold","Name":"14AYARALTIN","Selling":1781.37,"Change":0.73},"OSA":{"Buying":2279.46,"Type":"Gold","Name":"18AYARALTIN","Selling":2281.41,"Change":0.73},"YIA":{"Buying":2847.76,"Type":"Gold","Name":"22AYARBILEZIK","Selling":2850.2,"Change":0.73},"IKI":{"Buying":49960.78,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":50753.51,"Change":0.73},"BES":{"Buying":101170.59,"Type":"Gold","Name":"BESLIALTIN","Selling":103132.13,"Change":0.73},"GRE":{"Buying":49960.78,"Type":"Gold","Name":"GREMSEALTIN","Selling":51097.28,"Change":0.73},"RES":{"Buying":20608.82,"Type":"Gold","Name":"RESATALTIN","Selling":21126.46,"Change":0.73},"HAM":{"Buying":20608.82,"Type":"Gold","Name":"HAMITALTIN","Selling":21126.46,"Change":0.73},"GPL":{"Buying":1081.39,"Type":"Gold","Name":"GRAMPLATIN","Selling":1085.18,"Change":-0.4}}}'
|
||||
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: porro
|
||||
type: string
|
||||
enumValues: []
|
||||
exampleWasSpecified: false
|
||||
nullable: false
|
||||
custom: []
|
||||
cleanUrlParameters:
|
||||
goldName: porro
|
||||
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":"22:46:25"}'
|
||||
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-01-21"}'
|
||||
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.02,"Current_Date":"2025-01-21 22:46:25","Update_Date":"2025-01-21 22:46:24"},"Rates":{"GRA":{"Selling":3140.98,"Type":"Gold","Name":"GRAMALTIN","Change":1.34,"Buying":3140.64},"GUM":{"Selling":35.28,"Type":"Gold","Name":"GUMUS","Change":0.9,"Buying":35.23},"BRE":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":-0.5},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":1.21},"HAS":{"Buying":3125.34,"Type":"Gold","Name":"GRAMHASALTIN","Selling":3125.77,"Change":1.36},"CEY":{"Buying":4996.08,"Type":"Gold","Name":"CEYREKALTIN","Selling":5109.73,"Change":0.73},"YAR":{"Buying":9960.93,"Type":"Gold","Name":"YARIMALTIN","Selling":10219.46,"Change":0.73},"TAM":{"Buying":19984.31,"Type":"Gold","Name":"TAMALTIN","Selling":20376.41,"Change":0.73},"CUM":{"Buying":20709,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":21022,"Change":0.77},"ATA":{"Buying":20608.82,"Type":"Gold","Name":"ATAALTIN","Selling":21126.46,"Change":0.73},"ODA":{"Buying":1779.85,"Type":"Gold","Name":"14AYARALTIN","Selling":1781.37,"Change":0.73},"OSA":{"Buying":2279.46,"Type":"Gold","Name":"18AYARALTIN","Selling":2281.41,"Change":0.73},"YIA":{"Buying":2847.76,"Type":"Gold","Name":"22AYARBILEZIK","Selling":2850.2,"Change":0.73},"IKI":{"Buying":49960.78,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":50753.51,"Change":0.73},"BES":{"Buying":101170.59,"Type":"Gold","Name":"BESLIALTIN","Selling":103132.13,"Change":0.73},"GRE":{"Buying":49960.78,"Type":"Gold","Name":"GREMSEALTIN","Selling":51097.28,"Change":0.73},"RES":{"Buying":20608.82,"Type":"Gold","Name":"RESATALTIN","Selling":21126.46,"Change":0.73},"HAM":{"Buying":20608.82,"Type":"Gold","Name":"HAMITALTIN","Selling":21126.46,"Change":0.73},"GPL":{"Buying":1081.39,"Type":"Gold","Name":"GRAMPLATIN","Selling":1085.18,"Change":-0.4}}}'
|
||||
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: porro
|
||||
type: string
|
||||
enumValues: []
|
||||
exampleWasSpecified: false
|
||||
nullable: false
|
||||
custom: []
|
||||
cleanUrlParameters:
|
||||
goldName: porro
|
||||
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":"22:46:25"}'
|
||||
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-01-21"}'
|
||||
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,37 +17,76 @@ 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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
||||
// 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
|
||||
*/
|
||||
@@ -53,16 +95,34 @@ 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(['error' => 'Veri bulunamadı'], 404);
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@@ -71,16 +131,69 @@ 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(['error' => 'Veri bulunamadı'], 404);
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
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,7 +214,9 @@ 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);
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,16 @@ 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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,9 +24,6 @@ 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')
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ return [
|
||||
'type' => 'external_laravel',
|
||||
|
||||
// See https://scribe.knuckles.wtf/laravel/reference/config#theme for supported options
|
||||
'theme' => 'scalar',
|
||||
'theme' => 'elements',
|
||||
|
||||
'static' => [
|
||||
// HTML documentation, assets and Postman collection will be generated to this folder.
|
||||
@@ -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,45 @@
|
||||
version: '3'
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfile
|
||||
image: truncgil-finance-app:latest
|
||||
container_name: truncgil-finance-app
|
||||
volumes:
|
||||
- .:/var/www
|
||||
networks:
|
||||
- laravel-network
|
||||
|
||||
web:
|
||||
image: nginx:alpine
|
||||
container_name: truncgil-finance-web
|
||||
ports:
|
||||
- "8081:80"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||
networks:
|
||||
- laravel-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:
|
||||
- laravel-network
|
||||
ports:
|
||||
- "3307:3306"
|
||||
|
||||
networks:
|
||||
laravel-network:
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
@@ -0,0 +1,76 @@
|
||||
# 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 \
|
||||
ntp \
|
||||
&& service cron start && \
|
||||
ntpd -gq && \
|
||||
ntpd && \
|
||||
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,24 @@
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
add_header Content-Security-Policy "upgrade-insecure-requests";
|
||||
index index.php index.html;
|
||||
server_name localhost;
|
||||
root /var/www/public;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
include fastcgi_params;
|
||||
fastcgi_pass app:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
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,30 @@
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
|
||||
<p class="title-text">
|
||||
|
||||
{{$currencyName}}
|
||||
</p>
|
||||
<p class="percent" style="color: {{ $rate['Change'] > 0 ? 'green' : '#B9101E' }}">
|
||||
{{ $rate['Change'] }}%
|
||||
</p>
|
||||
@if($rate['Change'] > 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']}} ₺
|
||||
</p>
|
||||
|
||||
<div class="range">
|
||||
<div class="fill" style="background-color: {{ $rate['Change'] > 0 ? 'green' : '#B9101E' }};">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,23 +1,62 @@
|
||||
<!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config -->
|
||||
<!doctype html>
|
||||
<html>
|
||||
<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>Truncgil Finance</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1"/>
|
||||
<!-- Embed elements Elements via Web Component -->
|
||||
<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 {
|
||||
margin: 0;
|
||||
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
|
||||
apiDescriptionUrl="{{ route("scribe.openapi") }}"
|
||||
router="hash"
|
||||
layout="responsive"
|
||||
appearance="auto"
|
||||
hideTryIt=""
|
||||
logo="img/logo-light.svg"
|
||||
/>
|
||||
|
||||
<script
|
||||
id="api-reference"
|
||||
data-url="{{ route("scribe.openapi") }}">
|
||||
<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>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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']);
|
||||
|
||||
@@ -19,3 +19,11 @@ Route::get('/currency-rates/{currencyName}', [CurrencyController::class, 'getCur
|
||||
|
||||
Route::get('/gold-rates', [CurrencyController::class, 'getGoldRates']);
|
||||
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']);
|
||||
|
||||
|
||||