Skip to content

Commit

Permalink
Merge pull request #13 from yihong1120/feature/Added-backend-console-…
Browse files Browse the repository at this point in the history
…interface

Feature/added backend console interface
  • Loading branch information
yihong1120 committed Oct 31, 2023
2 parents 24728ae + 9d14a20 commit 5051aa9
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 33 deletions.
50 changes: 50 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Use Ubuntu 22.04 as the base image
FROM ubuntu:22.04

# Set environment variable to prevent interactive prompts during apt-get commands
ENV DEBIAN_FRONTEND=noninteractive

# Update apt and install required tools
RUN apt-get update && apt-get install -y \
curl \
wget \
lsb-release \
apt-transport-https \
software-properties-common \
gnupg \
python3.11 \
python3-pip

# Add repository and key for Microsoft SQL
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
&& curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list > /etc/apt/sources.list.d/mssql-release.list

# Install Microsoft's MSSQL tools and other necessary packages
RUN apt-get update && \
ACCEPT_EULA=Y apt-get install -y msodbcsql18 && \
ACCEPT_EULA=Y apt-get install -y mssql-tools18 && \
apt-get install -y unixodbc-dev

# Add mssql-tools18 to the system PATH
ENV PATH="$PATH:/opt/mssql-tools18/bin"

# Install Python dependencies
COPY requirements.txt /app/
RUN pip install -r /app/requirements.txt

# Copy your application into the container
COPY . /app/
WORKDIR /app/

# Execute app.py and web server of Django when the container starts
CMD ["sh", "-c", "python app.py && cd chatbo_web && python manage.py runserver 8080"]

# To utilise this Dockerfile, first execute the following command in the directory containing the Dockerfile to construct the container image:
# '''bash
# docker build -t chatbot_app .
# '''

# Subsequently, run:
# '''bash
# docker run -p 8080:8080 chatbot_app
# '''
25 changes: 24 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,36 @@
base_context = config_manager.load_base_context()

async def start(update: Update, context: CallbackContext) -> None:
"""
Start the chatbot for a user.
Args:
update (Update): The update received from Telegram.
context (CallbackContext): The context associated with this update.
"""
user_id = update.message.from_user.id

try:
# Ensure the chat file for this user exists
chat_manager.ensure_chat_file_exists(user_id)
logging.info(f"User {user_id} started the bot.")
await update.message.reply_text('Welcome to the Llama Chatbot! Type your message.')
except Exception as e:
logging.error(f"Error starting chat for user {user_id}: {e}")

async def chat(update: Update, context: CallbackContext) -> None:
"""
Process a chat message from a user.
Args:
update (Update): The update received from Telegram.
context (CallbackContext): The context associated with this update.
"""
user_input = update.message.text
user_id = update.message.from_user.id

try:
# Load the conversation history for this user
convo = chat_manager.load_chat(user_id)

# Add the latest message to the conversation
Expand All @@ -41,6 +57,12 @@ async def chat(update: Update, context: CallbackContext) -> None:
logging.error(f"Error processing chat for user {user_id} with input '{user_input}': {e}")

def main() -> None:
"""
The main function to start the chatbot.
This function sets up logging, initializes the bot with a token,
adds a message handler for text messages, and starts the bot.
"""
# Set up logging
config_manager.setup_logging()

Expand All @@ -49,11 +71,12 @@ def main() -> None:
bot = Bot(token=TOKEN)
app = Application.builder().token(TOKEN).build()

# Add a message handler for text messages (excluding commands)
text_filter = (filters.TEXT & ~filters.COMMAND)
app.add_handler(MessageHandler(text_filter, chat))

logging.info("Bot started and is now polling...")
app.run_polling()

if __name__ == '__main__':
main()
main()
8 changes: 7 additions & 1 deletion chatbo_web/chatbo_web/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'
# STATIC_URL is used to build the URL of the static files
STATIC_URL = '/static/'

# Here we add the directories where Django will search for additional static files
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
Expand Down
Binary file not shown.
Binary file not shown.
11 changes: 8 additions & 3 deletions chatbo_web/chatbot_manager/templates/registration/login.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
{% extends 'base.html' %}

{% load static %} {# 加載靜態文件功能 #}

{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
or <a href="{% url 'register' %}">Register</a>
</form>
{% endblock %}
or
<button id="registerBtn" data-url="{% url 'register' %}" type="button">Register</button>
</form>

<script src="{% static 'chatbot_manager/javascript/register_redirect.js' %}"></script>
{% endblock %}
1 change: 0 additions & 1 deletion chatbo_web/chatbot_manager/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
urlpatterns = [
path('', views.dashboard, name='dashboard'), # 主頁面設為儀表板
path('register/', views.register, name='register'),
# path('login/', auth_views.LoginView.as_view(success_url='/chatbot_manager/'), name='login'),
path('login/', views.home, name='login'),
path('logout/', views.logout_view, name='logout'),
path('view_log_file/<str:log_filename>/', views.view_log_file, name='view_log_file'),
Expand Down
132 changes: 114 additions & 18 deletions chatbo_web/chatbot_manager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,65 @@
from .models import ChatLog
import os, json
import glob
from django.http import HttpRequest

def home(request):
def home(request: HttpRequest) -> HttpResponse:
"""
Home view that redirects authenticated users to the dashboard
and unauthenticated users to the login page.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
if request.user.is_authenticated:
return redirect('dashboard')
else:
return auth_views.LoginView.as_view()(request)

def login_view(request):
def login_view(request: HttpRequest) -> HttpResponse:
"""
Login view that redirects authenticated users to the dashboard
and unauthenticated users to the login page.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
if request.user.is_authenticated:
return redirect('dashboard')
else:
return render(request, 'login.html')

def logout_view(request):
def logout_view(request: HttpRequest) -> HttpResponse:
"""
Logout view that logs out the user and redirects to the homepage.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
# Log out the user.
logout(request)
# Redirect to the homepage.
return redirect('/')

def register(request):
def register(request: HttpRequest) -> HttpResponse:
"""
Registration view that allows unauthenticated users to create a new account.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
Expand All @@ -38,15 +77,33 @@ def register(request):
return render(request, 'register.html', {'form': form})

@login_required
def profile(request):
def profile(request: HttpRequest) -> HttpResponse:
"""
Profile view that displays the profile of the logged in user.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
return render(request, 'profile.html')

@login_required
def dashboard(request):
# 獲取所有 log 檔案
def dashboard(request: HttpRequest) -> HttpResponse:
"""
Dashboard view that displays the dashboard to the logged in user.
Args:
request (HttpRequest): The request object.
Returns:
HttpResponse: The HTTP response.
"""
# Get all log files
log_files = [f for f in os.listdir("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/logs") if f.endswith('.log')]

# 獲取所有 JSON 檔案
# Get all JSON files
json_files = [f for f in os.listdir("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/chat_records") if f.endswith('.json')]

context = {
Expand All @@ -56,7 +113,17 @@ def dashboard(request):
return render(request, 'dashboard.html', context)

@login_required
def download_log_file(request, log_filename):
def download_log_file(request: HttpRequest, log_filename: str) -> HttpResponse:
"""
View to download a log file.
Args:
request (HttpRequest): The request object.
log_filename (str): The name of the log file to download.
Returns:
HttpResponse: The HTTP response.
"""
log_path = os.path.join("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/logs", log_filename)
if os.path.exists(log_path):
with open(log_path, 'rb') as file:
Expand All @@ -66,7 +133,17 @@ def download_log_file(request, log_filename):
return HttpResponseNotFound("Log file not found.")

@login_required
def view_log_file(request, log_filename):
def view_log_file(request: HttpRequest, log_filename: str) -> HttpResponse:
"""
View to display the content of a log file.
Args:
request (HttpRequest): The request object.
log_filename (str): The name of the log file to display.
Returns:
HttpResponse: The HTTP response.
"""
log_path = os.path.join("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/logs", log_filename)
if os.path.exists(log_path):
with open(log_path, 'r') as file:
Expand All @@ -75,26 +152,45 @@ def view_log_file(request, log_filename):
return HttpResponseNotFound("Log file not found.")

@login_required
def view_json_file(request, json_filename):
def view_json_file(request: HttpRequest, json_filename: str) -> HttpResponse:
"""
View to display the content of a JSON file.
Args:
request (HttpRequest): The request object.
json_filename (str): The name of the JSON file to display.
Returns:
HttpResponse: The HTTP response.
"""
json_path = os.path.join("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/chat_records", json_filename)
if os.path.exists(json_path):
with open(json_path, 'r', encoding='utf-8') as file:
json_content = json.load(file) # Using json.load to parse the JSON content
return render(request, 'json_file_content.html', {'json_content': json_content})
return HttpResponseNotFound("JSON file not found.")


@login_required
def download_json_file(request, json_filename):
# 指定 JSON 檔案的完整路徑
def download_json_file(request: HttpRequest, json_filename: str) -> HttpResponse:
"""
View to download a JSON file.
Args:
request (HttpRequest): The request object.
json_filename (str): The name of the JSON file to download.
Returns:
HttpResponse: The HTTP response.
"""
# Specify the full path of the JSON file
json_path = os.path.join("/Users/YiHung/Documents/Side_Projects/Llama2-Telegram-Bot/chat_records", json_filename)

# 檢查文件是否存在
# Check if the file exists
if os.path.exists(json_path):
# 使用 FileResponse 回傳檔案內容
# Use FileResponse to return the file content
response = FileResponse(open(json_path, 'rb'), content_type='application/json')
# 設定回傳的檔頭,告訴瀏覽器這是一個要下載的文件
# Set the response header to tell the browser this is a file to download
response['Content-Disposition'] = f'attachment; filename="{json_filename}"'
return response
else:
return HttpResponseNotFound("JSON file not found.")
return HttpResponseNotFound("JSON file not found.")
Binary file modified chatbo_web/db.sqlite3
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Use JavaScript to handle the click event of the Register button
document.getElementById("registerBtn").addEventListener("click", function() {
location.href = this.getAttribute('data-url');
});
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ diskcache==5.6.3
llama_cpp_python==0.2.11
numpy==1.26.1
typing_extensions==4.8.0
pyodbc==5.0.1
pyodbc==5.0.1
django-recaptcha==3.0.0
Loading

0 comments on commit 5051aa9

Please sign in to comment.