Browse Source

list of cities and countries read from json files added

master
Mohsen Taba 1 month ago
parent
commit
bad2b88407
  1. 3
      apps/api/urls.py
  2. 3
      apps/api/views/__init__.py
  3. 95
      apps/api/views/api_views.py
  4. 2
      config/urls.py
  5. 86
      utils/country_city_list/generate_city_list.py
  6. 1777382
      utils/country_city_list/large_cities_file.json
  7. 10507
      utils/country_city_list/optimized_cities.json
  8. 26
      utils/country_city_list/optimized_countries.json
  9. 1496
      utils/country_city_list/raw_countries.json

3
apps/api/urls.py

@ -1,6 +1,6 @@
from django.urls import path,include from django.urls import path,include
from .views import HomeView, CountryView, CommentListAPIView
from .views import HomeView, CountryView, CommentListAPIView, CityListView
from .views.api_views import AppVersionListAPIView from .views.api_views import AppVersionListAPIView
@ -8,6 +8,7 @@ from .views.api_views import AppVersionListAPIView
urlpatterns = [ urlpatterns = [
path('', HomeView.as_view()), path('', HomeView.as_view()),
path('countries/', CountryView.as_view()), path('countries/', CountryView.as_view()),
path('cities/', CityListView.as_view(), name='city-list'),
path('comments/', CommentListAPIView.as_view(), name='comment-list'), path('comments/', CommentListAPIView.as_view(), name='comment-list'),
path('app-versions/', AppVersionListAPIView.as_view(), name='appversion-list'), path('app-versions/', AppVersionListAPIView.as_view(), name='appversion-list'),
] ]

3
apps/api/views/__init__.py

@ -1,7 +1,7 @@
# API Views Package # API Views Package
# This package contains all API-related views organized by functionality # This package contains all API-related views organized by functionality
from .api_views import HomeView, CountryView, CommentListAPIView
from .api_views import HomeView, CountryView, CommentListAPIView, CityListView
from .documentation import CustomAPIDocumentationView from .documentation import CustomAPIDocumentationView
from .swagger_views import CustomSwaggerView, SwaggerTokenAuthView, clear_swagger_auth from .swagger_views import CustomSwaggerView, SwaggerTokenAuthView, clear_swagger_auth
from .admin_dashboard import AdminDashboardStatsView from .admin_dashboard import AdminDashboardStatsView
@ -10,6 +10,7 @@ __all__ = [
'HomeView', 'HomeView',
'CountryView', 'CountryView',
'CommentListAPIView', 'CommentListAPIView',
'CityListView',
'CustomAPIDocumentationView', 'CustomAPIDocumentationView',
'CustomSwaggerView', 'CustomSwaggerView',
'SwaggerTokenAuthView', 'SwaggerTokenAuthView',

95
apps/api/views/api_views.py

@ -1,5 +1,6 @@
import random import random
from rest_framework.generics import GenericAPIView, ListAPIView from rest_framework.generics import GenericAPIView, ListAPIView
from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import serializers from rest_framework import serializers
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
@ -15,7 +16,34 @@ from utils.pagination import StandardResultsSetPagination
class HomeSerializer(serializers.Serializer): class HomeSerializer(serializers.Serializer):
token = serializers.CharField() token = serializers.CharField()
from utils.countries import countries
import json
from django.conf import settings
COUNTRIES_FILE_PATH = settings.BASE_DIR / 'utils' / 'country_city_list' / 'optimized_countries.json'
CITIES_FILE_PATH = settings.BASE_DIR / 'utils' / 'country_city_list' / 'optimized_cities.json'
def get_localized_name(translations, target_lang='en'):
if not translations:
return ""
for t in translations:
if t.get('language_code') == target_lang:
return t.get('title')
for t in translations:
if t.get('language_code') == 'en':
return t.get('title')
return translations[0].get('title', '')
def get_localized_cities(cities_data, country_code, target_lang='en'):
country_cities = cities_data.get(country_code.upper())
if not country_cities:
return []
for item in country_cities:
if item.get('language_code') == target_lang:
return item.get('title', [])
for item in country_cities:
if item.get('language_code') == 'en':
return item.get('title', [])
return country_cities[0].get('title', [])
# test class generate token # test class generate token
@ -49,13 +77,72 @@ class HomeView(GenericAPIView):
return Response({'token': "ok", 'build_number': build_number}) return Response({'token': "ok", 'build_number': build_number})
class CountryView(GenericAPIView):
class CountryView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema( @swagger_auto_schema(
operation_description="List of countries with dialing codes and flags",
operation_description="List of optimized countries with codes and names",
responses={200: openapi.Response(description="Countries list")} responses={200: openapi.Response(description="Countries list")}
) )
def get(self, request): def get(self, request):
return Response(countries, status=200)
try:
with open(COUNTRIES_FILE_PATH, 'r', encoding='utf-8') as f:
countries_data = json.load(f)
except Exception as e:
return Response({"error": "Failed to load countries data"}, status=500)
lang = getattr(request, 'LANGUAGE_CODE', 'en')
result = []
for code, translations in countries_data.items():
name = get_localized_name(translations, lang)
result.append({
"code": code,
"name": name
})
# Sort countries alphabetically by name
result.sort(key=lambda x: x["name"])
return Response(result, status=200)
class CityListView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_description="List of cities based on country code",
manual_parameters=[
openapi.Parameter(
name='country_code',
in_=openapi.IN_QUERY,
description='Two-letter country code (e.g. IR, CN, TR)',
type=openapi.TYPE_STRING,
required=True
)
],
responses={
200: openapi.Response(description="List of city names"),
400: openapi.Response(description="Country code is required or invalid")
}
)
def get(self, request):
country_code = request.query_params.get('country_code')
if not country_code:
return Response({"error": "country_code query parameter is required"}, status=400)
try:
with open(CITIES_FILE_PATH, 'r', encoding='utf-8') as f:
cities_data = json.load(f)
except Exception as e:
return Response({"error": "Failed to load cities data"}, status=500)
lang = getattr(request, 'LANGUAGE_CODE', 'en')
cities = get_localized_cities(cities_data, country_code, lang)
if not cities and country_code.upper() not in cities_data:
return Response({"error": f"No cities found or invalid country code: {country_code}"}, status=400)
# Sort cities alphabetically
sorted_cities = sorted(cities)
return Response(sorted_cities, status=200)
class CommentListAPIView(ListAPIView): class CommentListAPIView(ListAPIView):

2
config/urls.py

@ -69,7 +69,7 @@ def oneapi_translate(request):
api_patterns = [ api_patterns = [
path('test/', include('apps.api.urls')),
path('', include('apps.api.urls')),
path('account/', include('apps.account.urls')), path('account/', include('apps.account.urls')),
path('courses/', include('apps.course.urls')), path('courses/', include('apps.course.urls')),

86
utils/country_city_list/generate_city_list.py

@ -0,0 +1,86 @@
import json
# 1. تنظیمات اولیه: کشورهایی که می‌خواهید نگه دارید را اینجا وارد کنید
# می‌توانید کدهای دیگر مثل 'IR', 'RU' و غیره را به این لیست اضافه یا کم کنید
TARGET_COUNTRIES = {'CN', 'TR', 'IR', 'RU',}
# زبان پیش‌فرض
DEFAULT_LANGUAGE = "en"
# مسیر فایل ورودی (فایل حجیم شما) و فایل خروجی
input_file_path = 'large_cities_file.json'
output_file_path = 'optimized_cities.json'
# ۲. مسیر فایل‌ها
inputc_file_path = 'raw_countries.json' # اسم فایل خامی که الان فرستادید
outputc_file_path = 'optimized_countries.json' # اسم فایلی که فقط کشورهای مدنظر را دارد
def process_cities_data():
structured_data = {}
try:
print("در حال خواندن فایل اصلی شهرها...")
with open(input_file_path, 'r', encoding='utf-8-sig') as f:
content = f.read().strip()
cities = json.loads(content)
print("در حال فیلتر و مرتب‌سازی دیتای شهرها...")
for city in cities:
country_code = city.get('country')
city_name = city.get('name')
if country_code in TARGET_COUNTRIES:
# تغییر جدید: اگر کشور وجود نداشت، یک لیست (آرایه) ایجاد می‌کنیم
if country_code not in structured_data:
structured_data[country_code] = [
{
"language_code": DEFAULT_LANGUAGE,
"title": []
}
]
# اضافه کردن شهر به لیست title در اولین زبان (ایندکس 0)
if city_name not in structured_data[country_code][0]["title"]:
structured_data[country_code][0]["title"].append(city_name)
with open(output_file_path, 'w', encoding='utf-8') as f:
json.dump(structured_data, f, ensure_ascii=False, indent=2)
print(f"عملیات شهرها با موفقیت انجام شد! خروجی در: {output_file_path}")
except Exception as e:
print(f"خطا در اسکریپت شهرها: {e}")
def filter_countries_data():
filtered_countries = {}
try:
print("در حال خواندن فایل کشورها...")
with open(inputc_file_path, 'r', encoding='utf-8-sig') as f:
# چون فایل شما الان یک دیکشنری (Object) است، مستقیم آن را لود می‌کنیم
all_countries = json.load(f)
print("در حال استخراج کشورهای مدنظر...")
# بررسی می‌کنیم که کدام کلیدها (کد کشورها) در فایل اصلی وجود دارند
for country_code, country_data in all_countries.items():
# اگر کد کشور داخل لیست ما بود، کل آن بخش را به فایل جدید منتقل می‌کنیم
if country_code in TARGET_COUNTRIES:
filtered_countries[country_code] = country_data
# ذخیره فایل جدید
with open(outputc_file_path, 'w', encoding='utf-8') as f:
json.dump(filtered_countries, f, ensure_ascii=False, indent=2)
print(f"✅ عملیات با موفقیت انجام شد! فایل جداشده در مسیر زیر ساخته شد:\n{outputc_file_path}")
except FileNotFoundError:
print(f"❌ خطا: فایل '{inputc_file_path}' پیدا نشد!")
except json.JSONDecodeError as e:
print(f"❌ خطا در ساختار JSON: {e}")
except Exception as e:
print(f"❌ یک خطای غیرمنتظره رخ داد: {e}")
if __name__ == "__main__":
process_cities_data()
filter_countries_data()

1777382
utils/country_city_list/large_cities_file.json
File diff suppressed because it is too large
View File

10507
utils/country_city_list/optimized_cities.json
File diff suppressed because it is too large
View File

26
utils/country_city_list/optimized_countries.json

@ -0,0 +1,26 @@
{
"CN": [
{
"language_code": "en",
"title": "China"
}
],
"IR": [
{
"language_code": "en",
"title": "Iran (Islamic Republic of)"
}
],
"RU": [
{
"language_code": "en",
"title": "Russian Federation (the)"
}
],
"TR": [
{
"language_code": "en",
"title": "Türkiye"
}
]
}

1496
utils/country_city_list/raw_countries.json
File diff suppressed because it is too large
View File

Loading…
Cancel
Save