From e51ac2323b7d84e770047b4c89fe3671958cc41b Mon Sep 17 00:00:00 2001 From: cemgungor1 Date: Mon, 25 Nov 2024 18:35:23 +0300 Subject: [PATCH 1/5] feat: new serializer for post to not call api at post request --- backend/docker-compose.yaml | 1 + backend/marketfeed/serializers.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/backend/docker-compose.yaml b/backend/docker-compose.yaml index beedd297..7ee4bca5 100644 --- a/backend/docker-compose.yaml +++ b/backend/docker-compose.yaml @@ -32,6 +32,7 @@ services: sh -c 'python3 manage.py makemigrations && python3 manage.py migrate --noinput && python3 manage.py collectstatic --noinput && + python3 manage.py update_currencies && gunicorn backend.wsgi:application --bind 0.0.0.0:8000' restart: always environment: diff --git a/backend/marketfeed/serializers.py b/backend/marketfeed/serializers.py index 2a2441ce..3b412d4c 100644 --- a/backend/marketfeed/serializers.py +++ b/backend/marketfeed/serializers.py @@ -33,6 +33,22 @@ def __init__(self, *args, **kwargs): self.fields['name'].required = False self.fields['symbol'].required = False +class StockCreateSerializer(serializers.ModelSerializer): + currency = serializers.PrimaryKeyRelatedField(queryset=Currency.objects.all()) + + class Meta: + model = Stock + fields = ['id', 'name', 'symbol', 'currency'] + + def __init__(self, *args, **kwargs): + super(StockCreateSerializer, self).__init__(*args, **kwargs) + + # Get the request method if available + request = self.context.get('request', None) + + if request and request.method == 'POST': + self.fields['currency'].required = True + class TagSerializer(serializers.ModelSerializer): user_id = serializers.PrimaryKeyRelatedField(queryset=User.objects.all()) From f2d3653097ff39f3da023c5a34628f030ec58b1e Mon Sep 17 00:00:00 2001 From: cemgungor1 Date: Mon, 25 Nov 2024 18:36:21 +0300 Subject: [PATCH 2/5] feat: command to add supported currencies to db at each build --- backend/marketfeed/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/update_currencies.py | 36 +++++++++++++++++++ backend/marketfeed/management/currencies.json | 5 +++ backend/marketfeed/views.py | 2 ++ 5 files changed, 43 insertions(+) create mode 100644 backend/marketfeed/management/__init__.py create mode 100644 backend/marketfeed/management/commands/__init__.py create mode 100644 backend/marketfeed/management/commands/update_currencies.py create mode 100644 backend/marketfeed/management/currencies.json diff --git a/backend/marketfeed/management/__init__.py b/backend/marketfeed/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/marketfeed/management/commands/__init__.py b/backend/marketfeed/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/marketfeed/management/commands/update_currencies.py b/backend/marketfeed/management/commands/update_currencies.py new file mode 100644 index 00000000..9aa3c58b --- /dev/null +++ b/backend/marketfeed/management/commands/update_currencies.py @@ -0,0 +1,36 @@ +import json +from django.core.management.base import BaseCommand +from marketfeed.models import Currency +from django.conf import settings +import os + +class Command(BaseCommand): + help = 'Update or Insert the supported currencies to db' + + def handle(self, *args, **kwargs): + # Define the file path (assuming it's inside a 'currency_data' folder) + file_path = os.path.join(settings.BASE_DIR,'marketfeed', 'management', 'currencies.json') + + # Check if the file exists + if not os.path.exists(file_path): + self.stdout.write(self.style.ERROR(f'Currency data file not found: {file_path}')) + return + + with open(file_path, 'r') as file: + currencies_data = json.load(file) + + for currency_data in currencies_data: + code = currency_data.get('code') + name = currency_data.get('name') + + # Get or create the currency + currency, created = Currency.objects.get_or_create( + code=code, + defaults={'name': name} + ) + + # Output the result + if created: + self.stdout.write(self.style.SUCCESS(f'Inserted {currency.code} into the database.')) + else: + self.stdout.write(self.style.SUCCESS(f'{currency.code} already exists in the database.')) diff --git a/backend/marketfeed/management/currencies.json b/backend/marketfeed/management/currencies.json new file mode 100644 index 00000000..99730c8e --- /dev/null +++ b/backend/marketfeed/management/currencies.json @@ -0,0 +1,5 @@ +[ + {"code": "TRY", "name": "Turkish Lira"}, + {"code": "USD", "name": "US Dollar"} + ] + \ No newline at end of file diff --git a/backend/marketfeed/views.py b/backend/marketfeed/views.py index 80e434cf..2b4b2108 100644 --- a/backend/marketfeed/views.py +++ b/backend/marketfeed/views.py @@ -56,6 +56,8 @@ def retrieve(self, request, pk=None): return Response(serializer.data) def create(self, request): + if request.method == 'POST': + self.serializer_class = StockCreateSerializer serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() From 718ab412bc33599f6e710d3d1b2d40508bdf6b26 Mon Sep 17 00:00:00 2001 From: cemgungor1 Date: Mon, 25 Nov 2024 20:12:27 +0300 Subject: [PATCH 3/5] feat: add or update the db with all Turkish Stocks --- .../management/commands/update_stocks.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 backend/marketfeed/management/commands/update_stocks.py diff --git a/backend/marketfeed/management/commands/update_stocks.py b/backend/marketfeed/management/commands/update_stocks.py new file mode 100644 index 00000000..63501d47 --- /dev/null +++ b/backend/marketfeed/management/commands/update_stocks.py @@ -0,0 +1,40 @@ +import json +from django.core.management.base import BaseCommand +from marketfeed.models import Stock, Currency +from django.conf import settings +import requests +import re + +# Search whether the stock name has FON, FONU or BYF in it to pass those: they are not stocks +def notStock(stockName): + return bool(re.search(r'\b(FON|FONU|BYF)\b', stockName, re.IGNORECASE)) + +class Command(BaseCommand): + help = 'Update or Insert the Turkish stock market stocks to db' + + + def handle(self, *args, **kwargs): + # Url to fetch stock list + url = 'https://bigpara.hurriyet.com.tr/api/v1/hisse/list' + try: + response = requests.get(url) + response.raise_for_status() + stocks = response.json().get('data', []) + # name, symbol, currency + currency = Currency.objects.get(code='TRY') + for stock in stocks: + try: + if notStock(stock['ad']): + continue + Stock.objects.update_or_create( + symbol=stock['kod'], + defaults={ + 'name': stock['ad'], + 'currency': currency, + } + ) + except Exception as e: + print(e) + # Output the result + except Exception as e: + print(e) \ No newline at end of file From c634f514a4a86f158088b92f7f023076c39cb611 Mon Sep 17 00:00:00 2001 From: cemgungor1 Date: Thu, 5 Dec 2024 00:12:49 +0300 Subject: [PATCH 4/5] feat: update stocks on build --- backend/docker-compose.yaml | 1 + backend/marketfeed/management/commands/update_stocks.py | 2 -- backend/requirements.txt | 3 ++- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/docker-compose.yaml b/backend/docker-compose.yaml index 7ee4bca5..4cefe877 100644 --- a/backend/docker-compose.yaml +++ b/backend/docker-compose.yaml @@ -33,6 +33,7 @@ services: python3 manage.py migrate --noinput && python3 manage.py collectstatic --noinput && python3 manage.py update_currencies && + python3 manage.py update_stocks && gunicorn backend.wsgi:application --bind 0.0.0.0:8000' restart: always environment: diff --git a/backend/marketfeed/management/commands/update_stocks.py b/backend/marketfeed/management/commands/update_stocks.py index 63501d47..acc6550f 100644 --- a/backend/marketfeed/management/commands/update_stocks.py +++ b/backend/marketfeed/management/commands/update_stocks.py @@ -20,7 +20,6 @@ def handle(self, *args, **kwargs): response = requests.get(url) response.raise_for_status() stocks = response.json().get('data', []) - # name, symbol, currency currency = Currency.objects.get(code='TRY') for stock in stocks: try: @@ -35,6 +34,5 @@ def handle(self, *args, **kwargs): ) except Exception as e: print(e) - # Output the result except Exception as e: print(e) \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt index 07400c88..3094ff28 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -13,4 +13,5 @@ drf-spectacular==0.27.2 django-cors-headers==4.5.0 Pillow feedparser -yfinance \ No newline at end of file +yfinance +requests \ No newline at end of file From c2e7074c924b095bc039ca45e102176c344fcc75 Mon Sep 17 00:00:00 2001 From: cemgungor1 Date: Thu, 5 Dec 2024 00:29:34 +0300 Subject: [PATCH 5/5] fix: merge conflict --- backend/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/requirements.txt b/backend/requirements.txt index 3094ff28..5d1f9204 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -14,4 +14,5 @@ django-cors-headers==4.5.0 Pillow feedparser yfinance -requests \ No newline at end of file +requests +beautifulsoup4 \ No newline at end of file