Skip to content

Commit

Permalink
[v1.0.0] Merge pull request #25 from KageRyo/develop
Browse files Browse the repository at this point in the history
Update to v1.1.0
  • Loading branch information
KageRyo authored Aug 1, 2024
2 parents a9d85ea + 03b20d3 commit 8f64e59
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 19 deletions.
5 changes: 3 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ RUN apt-get update && apt-get install -y \
git \
vim \
curl \
wget
wget \
redis-server

COPY . .

CMD ["bash"]
CMD service redis-server start && python manage.py runserver 0.0.0.0:8000
24 changes: 23 additions & 1 deletion RyoURL/RyoURL/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# 建立專案的根目錄路徑
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# 快速開發設定 - 不適用於生產環境
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
Expand Down Expand Up @@ -97,6 +96,29 @@
}
}

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'root': {
'handlers': ['console'],
'level': 'DEBUG',
},
}

# Password validation
# 密碼驗證
Expand Down
2 changes: 0 additions & 2 deletions RyoURL/shortURL/api.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import random
import string
import datetime
import requests

from typing import List, Optional
from pydantic import HttpUrl, AnyUrl

from ninja import NinjaAPI, Schema
from ninja.responses import Response
from ninja.renderers import JSONRenderer
from django.shortcuts import get_object_or_404
from django.core.serializers.json import DjangoJSONEncoder
Expand Down
76 changes: 62 additions & 14 deletions RyoURL/shortURL/views.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,68 @@
from django.shortcuts import get_object_or_404, redirect
import logging
from django.core.cache import cache
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.http import HttpResponse
from django.http import HttpResponse, HttpResponsePermanentRedirect
from django.db.models import F
from .models import Url

# 將短網址導向原網址的函式
def redirectShortUrl(request, short_string):
url = get_object_or_404(Url, short_string=short_string)
# 檢查短網址是否已過期
# logging 的設定
logger = logging.getLogger(__name__)

# 檢查短網址是否過期的函式
def is_url_expired(url):
if url.expire_date and url.expire_date < timezone.now():
url.delete()
return HttpResponse("此短網址已過期並已被刪除。", status=404)
try:
url.delete()
return True
except Exception as e:
logger.error(f'刪除過期URL時發生錯誤: {e}')
return False

# 更新資料庫中的訪問次數的函式
def update_visit_count(visit_count, url):
Url.objects.filter(id=url.id).update(visit_count=F('visit_count') + visit_count)
logger.debug(f'訪問次數儲存進資料庫: {visit_count}')

# 處理訪問次數與快取的函式
def handle_visit_count(url):
# 處理快取
cache_key = f'visit_count_{url.id}' # 設定快取的鍵
visit_count = cache.get(cache_key) # 從快取中取得訪問次數
if visit_count is None: # 如果快取中沒有訪問次數,那就從資料庫拿
visit_count = url.visit_count
logger.debug(f'在快取中找不到訪問次數,從資料庫拿: {visit_count}')

# 增加訪問次數
cache.set(cache_key, visit_count, timeout=60*60*24) # 初始化快取,設定快取時間為 24 小時
visit_count = cache.incr(cache_key) # 訪問次數加 1
logger.debug(f'目前快取中的訪問次數: {visit_count}')

# 更新訪問次數
url.visit_count += 1
url.save()
# 每 10 次訪問更新資料庫
if visit_count % 10 == 0:
update_visit_count(visit_count, url)

# 處理快取過期的處理(每日至少儲存至資料庫一次)
daily_update_key = f'daily_update_{url.id}'
if not cache.get(daily_update_key):
cache.set(daily_update_key, True, timeout=60*60*24) # 快取 24 小時過期
Url.objects.filter(id=url.id).update(visit_count=F('visit_count') + (visit_count % 10))
logger.debug(f'每日訪問次數儲存進資料庫: {visit_count}')

# 將短網址導向原網址的函式
def redirectShortUrl(request, short_string):
try:
url = get_object_or_404(Url, short_string=short_string)
if is_url_expired(url): # 檢查短網址是否過期
return HttpResponse("此短網址已過期並已被刪除。", status=410) # 410 Gone
handle_visit_count(url) # 處理訪問次數

# 將使用者重新導向至原網址
return HttpResponsePermanentRedirect(url.orign_url)

# 進行重定向
return redirect(url.orign_url)
except Url.DoesNotExist:
logger.warning(f'短網址不存在: {short_string}')
return HttpResponse("此短網址不存在。", status=404)
except Exception as e:
logger.error(f'發生錯誤: {e}', exc_info=True)
return HttpResponse("發生錯誤,請稍後再試。", status=500)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Django==4.2
django-ninja
django-cors-headers
django-redis

# 工具
python-dotenv
Expand Down

0 comments on commit 8f64e59

Please sign in to comment.