Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ded552f
setup development environment with Docker Compose
biplala Dec 2, 2024
e0d2c45
refactor/display-Set
Yukkurisiteikitai Dec 3, 2024
c295a6b
set GameMenu&GameKind
Yukkurisiteikitai Dec 3, 2024
d7a5977
setREADME-template
Yukkurisiteikitai Dec 4, 2024
df2a316
perf/mockup-quiz
Yukkurisiteikitai Dec 4, 2024
0864746
peft/game-selectSystem
Yukkurisiteikitai Dec 4, 2024
eea20c8
peft/quiz-question-easy
Yukkurisiteikitai Dec 4, 2024
10f8f0f
perf/setQuiz-Question
Yukkurisiteikitai Dec 4, 2024
7e47750
I Don't know What do division
Yukkurisiteikitai Dec 5, 2024
c0aa97f
implement base of backend application
biplala Dec 5, 2024
0683e3d
setDifferentPoint
Yukkurisiteikitai Dec 5, 2024
e042088
Add intro quiz files (index.html, script.js,style.css)
nozo120 Dec 5, 2024
ec159e0
Add intro quiz frontend
nozo120 Dec 5, 2024
78ce24d
Add intro quiz files (index.html)
nozo120 Dec 5, 2024
18268a3
future/set collision
Yukkurisiteikitai Dec 6, 2024
47f4f20
fix/changeName-FindDifference.js
Yukkurisiteikitai Dec 6, 2024
9b36bf4
bug/canvas-don'tLoadImageFile
Yukkurisiteikitai Dec 6, 2024
17fd7ef
Merge remote-tracking branch 'origin/feature/intro-quiz' into future/…
biplala Dec 6, 2024
bcf46ed
フロントエンドの変更を加えました
nozo120 Dec 7, 2024
b63f04c
define create_quiz
Dec 7, 2024
d13ac05
revise create_quiz
Dec 7, 2024
c5171c8
Load-Division
Yukkurisiteikitai Dec 7, 2024
e5690cb
create_intro
Dec 7, 2024
856a180
フロントエンドの変更を加えました
nozo120 Dec 7, 2024
886691d
set/quiz
Yukkurisiteikitai Dec 7, 2024
f408c9a
set/print-Quiz
Yukkurisiteikitai Dec 7, 2024
90984cb
create_quiz
Dec 7, 2024
cb2dfd0
Merge pull request #1 from tetsushi33/division/gameSystemFile
Yukkurisiteikitai Dec 7, 2024
547dc38
DynamoDBとの繋ぎこみを実装
biplala Dec 7, 2024
dd61c71
フロントエンドの変更を加えました
nozo120 Dec 7, 2024
526b2b7
Merge branch 'develop' into test
Dec 7, 2024
d2f6efe
Merge pull request #2 from tetsushi33/test
biplala Dec 7, 2024
289b2c5
Merge pull request #4 from tetsushi33/feature/intro-quiz
nozo120 Dec 7, 2024
1574875
Merge remote-tracking branch 'origin/develop' into feature/connection…
biplala Dec 7, 2024
29fa499
Merge remote-tracking branch 'origin/develop' into feature/connection…
biplala Dec 7, 2024
824ceeb
Merge pull request #3 from tetsushi33/feature/connection-with-aws-ser…
biplala Dec 7, 2024
066eae5
create_quize() define get_last_id
Dec 7, 2024
2c87794
Merge pull request #5 from tetsushi33/backend
tetsushi33 Dec 7, 2024
9fc3caa
don't set ;
Yukkurisiteikitai Dec 7, 2024
ce2fcb7
フロントエンドの表示デグレを解消
nozo120 Dec 7, 2024
6868981
Merge branch 'develop' of https://github.com/tetsushi33/Mini-Run into…
nozo120 Dec 7, 2024
4c9d897
define play_quiz
Dec 7, 2024
c84b786
define play_quiz
Dec 7, 2024
bb6c7bd
fix/load-Index.html
Yukkurisiteikitai Dec 7, 2024
199cb4c
define play_intro, play_diffshot temp
Dec 7, 2024
7feb843
define play_intro
Dec 7, 2024
3df4d1b
define play_intro
Dec 7, 2024
fbdc62c
add/XMLhttpRequest-GET-quiz-do
Yukkurisiteikitai Dec 7, 2024
4e37ed8
define play_quiz
Dec 7, 2024
faa6ea8
changeCreateD-none
Yukkurisiteikitai Dec 7, 2024
731e36d
define play_quiz
Dec 7, 2024
5960876
フロントエンドの変更を加えました
nozo120 Dec 7, 2024
9411b92
define play_quiz
Dec 7, 2024
2a4c6e7
フロントからのクイズ取得処理を修正
biplala Dec 7, 2024
0cacacb
define play_search_diff, create_search_diff
Dec 7, 2024
c63b660
クイズプレイ画面が動作するよう修正
biplala Dec 7, 2024
af25618
define create_search_diff, play_search_diff, others
Dec 7, 2024
486dc9c
Merge remote-tracking branch 'origin/feature/create_quiz' into releas…
biplala Dec 7, 2024
67df3b4
バグ修正
biplala Dec 7, 2024
d179511
create_quizに'genre': {'S': 'quiz'}
Dec 7, 2024
381b99e
answer_idxを-1、'genre': {'S': 'quiz'}を追加
Dec 7, 2024
c6def86
デグレ修正
biplala Dec 8, 2024
97d5c7d
Merge branch 'develop' of github.com:tetsushi33/Mini-Run into develop
Yukkurisiteikitai Dec 8, 2024
64a31ab
Merge branch 'develop' into merge/quiz-create-play
tetsushi33 Dec 8, 2024
ad1fd88
Merge pull request #8 from tetsushi33/merge/quiz-create-play
tetsushi33 Dec 8, 2024
9155fd3
Merge branch 'develop' into backend-2
tetsushi33 Dec 8, 2024
e263e21
Merge pull request #9 from tetsushi33/backend-2
tetsushi33 Dec 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# log files
*.log.*
*.log

# environment informations and credentials
*.env
*.pyc
./frontend/thinks
*.DS_Store
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
# Mini-Run
aa
# **「暇つぶし革命!遊びながら学び、作って解く新感覚ミニゲーム体験!」**
URL:https://test.croud

## 実行方法
```
docker compose build
docker compose up
```
URL("localhost:5000")に接続

## 使用技術
|kind |version |
|:--|:--:|
|node.js |node:18 |
|Flask |2.2.5 |
|boto3 |1.26.145 |
|gunicorn |20.1.0 |
10 changes: 10 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.10

WORKDIR /app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["flask", "run", "--host=0.0.0.0"]
26 changes: 26 additions & 0 deletions backend/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from flask import Flask
from flask_cors import CORS
import router
from config import config

def create_app():
app = Flask(__name__)

app.config.from_object(config.Config)

app.register_blueprint(router.router)

app.config['JSON_AS_ASCII'] = False #日本語文字化け対策
app.config["JSON_SORT_KEYS"] = False #ソートをそのまま
CORS(
app,
resources = {
r"/api/*": {"origins": ["http://localhost", "http://localhost:3000","http://localhost:8032"]}
}
)

return app

if __name__ == "__main__":
app = create_app()
app.run(host='0.0.0.0', debug=True, port=5001, threaded=True, use_reloader=False)
7 changes: 7 additions & 0 deletions backend/config/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import os
from dataclasses import dataclass

@dataclass
class Config:
DEBUG = os.getenv("DEBUG")
DATABASE_URI= ""
38 changes: 38 additions & 0 deletions backend/config/logging.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"version": 1,
"formatters": {
"default": {
"format": "[%(asctime)s] [%(levelname)s] : %(message)s"
}
},
"loggers": {
"file": {
"handlers": ["file"],
"level": "WARN",
"qualname": "file",
"propagate": "no"
},
"wsgi": {
"handlers": ["wsgi"],
"level": "WARN",
"qualname": "wsgi",
"propagate": "no"
}
},
"handlers": {
"file": {
"class": "logging.handlers.TimedRotatingFileHandler",
"formatter": "default",
"filename": "./logs/application.log"
},
"wsgi": {
"class": "logging.StreamHandler",
"stream": "ext://flask.logging.wsgi_errors_stream",
"formatter": "default"
}
},
"root": {
"level": "WARN",
"handlers": ["file", "wsgi"]
}
}
257 changes: 257 additions & 0 deletions backend/controller/game_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
from flask import make_response, jsonify, request
from engine.dynamo_client import DynamoClient
import hashlib
from engine.s3_client import S3Client
#from werkzeug.utils import secure_filename


class GameController:
def __init__(self):
self.table_name = "minirun_game_table"
self.db_client = DynamoClient(table_name="minirun_game_table")
self.s3_client = S3Client() # S3専用クラスを利用

def get_game_random(self):
response = self.db_client.get_random()
return make_response(jsonify({
'code': 200,
'game': response
}))

def get_last_id(self) -> int:
response = self.db_client.scan(TableName=self.table_name, ProjectionExpression="id")
items = response.get('Items', [])
if not items:
return 0
ids = [int(item['id']['N']) for item in items]
return max(ids)

def create_quiz(self):
# リクエストデータを取得
data = request.get_json()
question = data['question']
selects = data['selects']
answer_idx = data['answer_idx'] - 1
data['answer_idx'] = answer_idx - 1
last_id = self.get_last_id()
data['id'] = last_id + 1

# バリデーションを実装
if not isinstance(question, str) or not question.strip():
return make_response(jsonify({'code': 400, 'message': 'Invalid question'}), 400)
if not isinstance(selects, list) or len(selects) != 4:
return make_response(jsonify({'code': 400, 'message': 'Invalid selects'}), 400)
if not isinstance(answer_idx, int) or not (0 <= answer_idx <= 3):
return make_response(jsonify({'code': 400, 'message': 'Invalid answer_idx'}), 400)

# DBに保存
try:
if self.db_client.create_quiz(data):
return make_response(jsonify({'code': 200, 'message': 'Quiz created successfully'}), 200)
else:
return make_response(jsonify({'code': 500, 'message': 'Failed to create quiz'}), 500)
except Exception as e:
# エラーハンドリングを実装
return make_response(jsonify({'code': 500, 'message': str(e)}), 500)

def create_intro(self):
data = request.get_json()
music_title_answer = data['music_title_answer']
#music_data = data['music_data'] # musicのデータ本体
last_id = self.get_last_id()
data['id'] = last_id + 1

if 'file' not in request.files:
return jsonify({"error": "No file part"}), 400

file = request.files['file']
if file.filename == '':
return jsonify({"error": "No selected file"}), 400
# ファイル名を安全にする
#filename = secure_filename(file.filename)
filename = file.filename
# ファイル名のハッシュを生成
file_hash = hashlib.sha256(filename.encode('utf-8')).hexdigest()

try:
# S3にファイルをアップロード
upload_to_s3(file, file_hash, file.content_type)
# DynamoDBにメタデータを保存
self.db_client.save_file_metadata(data, file_hash, filename)
return jsonify({"message": "File uploaded successfully", "file_hash": file_hash}), 200
except Exception as e:
return jsonify({"error": str(e)}), 500


# バリデーションを実装
if not isinstance(music_title_answer, str) or not music_title_answer.strip():
return make_response(jsonify({'code': 400, 'message': 'Invalid music_title_answer'}), 400)
if not music_data:
return make_response(jsonify({'code': 400, 'message': 'Invalid music_data'}), 400)

# DBに保存
try:
if self.db_client.create_intro(data):
return make_response(jsonify({'code': 200, 'message': 'Intro created successfully'}), 200)
else:
return make_response(jsonify({'code': 500, 'message': 'Failed to create intro'}), 500)
except Exception as e:
return make_response(jsonify({'code': 500, 'message': str(e)}), 500)

def create_search_diff(self):
try:
# フォームデータとファイルを取得
images = request.files.getlist('images') # 画像ファイルのリスト
answer_idx = request.form.get('answer_idx') # 正解の番号(request.filesを操作した後にrequest.get_json()を使用するとエラーが発生する可能性があるらしい)

# バリデーションチェック
if not images or len(images) != 9:
return make_response(jsonify({'code': 400, 'message': 'Invalid images list'}), 400)
if answer_idx is None or not answer_idx.isdigit() or not (0 <= int(answer_idx) - 1 < 9):
return make_response(jsonify({'code': 400, 'message': 'Invalid correct index'}), 400)

answer_idx = int(answer_idx) - 1

# 画像ファイルをS3に保存
image_hashes = []
for image in images:
#filename = secure_filename(image.filename)
filename = image.filename
file_hash = hashlib.sha256(filename.encode('utf-8')).hexdigest()
# S3にアップロード
self.s3_client.upload_fileobj(image, file_hash)
image_hashes.append(file_hash)

# DynamoDBに保存するデータを作成
data_to_save = {
'id': self.get_last_id() + 1, # 新しいID
'genre': 'search_diff', # ジャンルを指定
'image_hashes': image_hashes, # 画像ハッシュリスト
'answer_idx': answer_idx # 正解のインデックス
}

# データベースに保存
if self.db_client.create_search_diff(data_to_save):
return make_response(jsonify({'code': 200, 'message': 'Search diff created successfully'}), 200)
else:
return make_response(jsonify({'code': 500, 'message': 'Failed to create search diff'}), 500)
except Exception as e:
return make_response(jsonify({'code': 500, 'message': str(e)}), 500)


def play_quiz(self):
try:
# データベースからランダムに問題を取得
#response = self.db_client.get_random()
response = self.db_client.get_random_2(genre="quiz")
if response:
quiz_data = {
"question": response.get('question', {}).get('S', ''),
"selects": [select.get('S', '') for select in response.get('selects', {}).get('L', [])],
"answer_idx": int(response.get('answer_idx', {}).get('N', -1))
}
return make_response(jsonify({
'code': 200,
'game_content': quiz_data
}), 200)
else:
return make_response(jsonify({
'code': 404,
'message': 'No quiz found'
}), 404)
except Exception as e:
return make_response(jsonify({
'code': 500,
'message': str(e)
}), 500)

def play_intro(self):
try:
# データベースからランダムに問題を取得
#response = self.db_client.get_random()
response = self.db_client.get_random_2(genre="introdon")
if response:
intro_data = {
"music_title_answer": response.get('music_title_answer', {}).get('S', ''),
#"music_data": response.get('music_data', {}).get('B', '')
}
return make_response(jsonify({
'code': 200,
'game_content': intro_data
}), 200)
else:
return make_response(jsonify({
'code': 404,
'message': 'No intro found'
}), 404)
except Exception as e:
return make_response(jsonify({
'code': 500,
'message': str(e)
}), 500)

def play_search_diff(self):
try:
# データベースからランダムに問題を取得
response = self.db_client.get_random_2(genre="search_diff")
if response:
# ハッシュ値リストを取得
image_hashes = response.get("image_hashes", [])
answer_idx = response.get("answer_idx", -1)
# ハッシュ値を元にS3から画像データを取得
image_data_list = []
for image_hash in image_hashes:
try:
image_data = self.s3_client.get_s3_file_data(image_hash)
image_data_list.append(image_data)
except Exception as s3_error:
print(f"Error getting image data from S3: {e}")
return make_response(jsonify({
'code': 500,
'message': f"Failed to retrieve image for hash: {image_hash}"
}), 500)

search_diff_data = {
"images": image_data_list, # 画像データリスト
"answer_idx": answer_idx
}
return make_response(jsonify({
'code': 200,
'game_content': search_diff_data
}), 200)
else:
return make_response(jsonify({
'code': 404,
'message': 'No search_diff found'
}), 404)
except Exception as e:
return make_response(jsonify({
'code': 500,
'message': str(e)
}), 500)


def play_diffshot(self):
try:
# データベースからランダムに問題を取得
response = self.db_client.get_random()
if response:
diffshot_data = {
"picture_data": response.get('picture_data', {}).get('S', ''),
"picture_data_answer": response.get('picture_data_answer', {}).get('S', ''),
"answer_points": response.get('answer_points', {}).get('L', [])
}
return make_response(jsonify({
'code': 200,
'game_content': diffshot_data
}), 200)
else:
return make_response(jsonify({
'code': 404,
'message': 'No diffshot found'
}), 404)
except Exception as e:
return make_response(jsonify({
'code': 500,
'message': str(e)
}), 500)
Loading