Skip to content

Commit b55c5b5

Browse files
authored
Merge pull request #61 from WhiteHyun/feature/scripts
문제 자동 생성 스크립트 구현
2 parents e819d57 + 4f3b2da commit b55c5b5

File tree

5 files changed

+299
-0
lines changed

5 files changed

+299
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.idea/
22
.vscode/
33
.DS_Store
4+
.env

scripts/common.bash

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env bash
2+
3+
source scripts/languages.bash
4+
5+
# Load environment variables from .env file
6+
function load_env_vars() {
7+
if [ -f .env ]; then
8+
# shellcheck disable=SC2046
9+
export echo $(sed <.env 's/#.*//g' | xargs | envsubst)
10+
11+
# Check if required variables are set and not equal to default values
12+
if [ "$NICKNAME" = "your_nickname" ] || [ "$LANGUAGE" = "choose_your_language" ]; then
13+
echo "Error: Required environment variables are set to default values."
14+
echo "Please update NICKNAME and LANGUAGE in the .env file with appropriate values."
15+
exit 1
16+
fi
17+
18+
# Check if the specified language is valid
19+
20+
if [[ ! "${!language_extensions[@]}" =~ $LANGUAGE ]]; then
21+
echo "Error: Invalid language specified in the .env file."
22+
echo "Please set LANGUAGE to one of the following valid languages:"
23+
echo "${!language_extensions[@]}"
24+
exit 1
25+
fi
26+
fi
27+
}
28+
29+
# Check if Bash version meets the minimum requirement
30+
function check_bash_version() {
31+
local required_version=$1
32+
local bash_version
33+
bash_version=$(bash --version | head -n1 | awk '{print $4}' | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/')
34+
35+
if [[ $bash_version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
36+
local major=${BASH_REMATCH[1]}
37+
local minor=${BASH_REMATCH[2]}
38+
local patch=${BASH_REMATCH[3]}
39+
40+
IFS='.' read -r -a required_parts <<<"$required_version"
41+
local required_major=${required_parts[0]}
42+
local required_minor=${required_parts[1]}
43+
local required_patch=${required_parts[2]}
44+
45+
if ((major > required_major || (\
46+
major == required_major && minor > required_minor) || (\
47+
major == required_major && minor == required_minor && patch >= required_patch))); then
48+
return 0
49+
else
50+
return 1
51+
fi
52+
else
53+
return 1
54+
fi
55+
}
56+
57+
# Check if a command is installed
58+
function check_command() {
59+
local command="$1"
60+
if ! command -v "$command" &>/dev/null; then
61+
echo "The $command command is not installed."
62+
read -r -p "Do you want to install $command? (Y/n): " install_command
63+
case "$install_command" in
64+
[nN] | [nN][oO])
65+
echo "Installation of $command has been rejected. Exiting the script."
66+
exit 1
67+
;;
68+
*)
69+
echo "Proceeding with the installation of $command..."
70+
brew install "$command"
71+
;;
72+
esac
73+
fi
74+
}
75+
76+
# Generates the solution code template with question details and author information
77+
function make_solution_code() {
78+
local question_id=$1
79+
local question_name=$2
80+
local question_url=$3
81+
local code=$4
82+
local comment=${language_comments[$LANGUAGE]}
83+
local nickname
84+
if [ -n "$NICKNAME" ]; then
85+
nickname=$NICKNAME
86+
else
87+
nickname=Unknown
88+
fi
89+
local content
90+
content=$(
91+
cat <<EOF
92+
${comment}
93+
${comment}$question_id. $question_name
94+
${comment}$question_url
95+
${comment}Dale-Study
96+
${comment}
97+
${comment}Created by $nickname on $(date "+%Y/%m/%d").
98+
${comment}
99+
100+
$code
101+
102+
EOF
103+
)
104+
echo "$content"
105+
}
106+
107+
# Saves the solution code to a file in the appropriate directory based on the question slug and author's nickname
108+
function save_file() {
109+
local DIR
110+
local title_slug="$1"
111+
local content="$2"
112+
local nickname
113+
local language_extension
114+
local solution_folder
115+
local solution_file
116+
117+
if [ -n "$NICKNAME" ]; then
118+
nickname=$NICKNAME
119+
else
120+
nickname=Unknown
121+
fi
122+
123+
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
124+
language_extension=${language_extensions[$LANGUAGE]}
125+
126+
solution_folder="$DIR/../$title_slug"
127+
mkdir -p "$solution_folder"
128+
129+
solution_file="$solution_folder/$nickname.$language_extension"
130+
echo "$content" >"$solution_file"
131+
echo "File creation completed"
132+
}

scripts/languages.bash

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env bash
2+
3+
declare -A language_extensions=(
4+
["cpp"]="cpp"
5+
["java"]="java"
6+
["python"]="py"
7+
["python3"]="py"
8+
["c"]="c"
9+
["csharp"]="cs"
10+
["javascript"]="js"
11+
["typescript"]="ts"
12+
["php"]="php"
13+
["swift"]="swift"
14+
["kotlin"]="kt"
15+
["dart"]="dart"
16+
["go"]="go"
17+
["ruby"]="rb"
18+
["scala"]="scala"
19+
["rust"]="rs"
20+
["racket"]="rkt"
21+
["erlang"]="erl"
22+
["elixir"]="ex"
23+
)
24+
25+
declare -A language_comments=(
26+
["cpp"]="// "
27+
["java"]="// "
28+
["python"]="# "
29+
["python3"]="# "
30+
["c"]="// "
31+
["csharp"]="// "
32+
["javascript"]="// "
33+
["typescript"]="// "
34+
["php"]="// "
35+
["swift"]="// "
36+
["kotlin"]="// "
37+
["dart"]="// "
38+
["go"]="// "
39+
["ruby"]="# "
40+
["scala"]="// "
41+
["rust"]="// "
42+
["racket"]="; "
43+
["erlang"]="% "
44+
["elixir"]="# "
45+
)

scripts/leetcode.bash

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env bash
2+
3+
source scripts/common.bash
4+
source scripts/leetcode_helper.bash
5+
6+
function main() {
7+
load_env_vars
8+
9+
# Check if required commands are installed
10+
check_command "jq"
11+
check_command "bash"
12+
check_command "brew"
13+
14+
# Set the required Bash version
15+
local required_bash_version="4.0.0"
16+
17+
# Check Bash version and proceed with installation if necessary
18+
if check_bash_version "$required_bash_version"; then
19+
echo "Bash version meets the minimum requirement (>= $required_bash_version). Skipping installation."
20+
else
21+
echo "Bash version does not meet the minimum requirement (>= $required_bash_version). Proceeding with installation using Homebrew..."
22+
# Add your Homebrew installation commands here
23+
brew update
24+
brew install bash
25+
fi
26+
27+
# Check if the problem title-slug or URL is provided
28+
if [ "$#" -eq 1 ]; then
29+
input="$1"
30+
if [[ "$input" == *"https://leetcode.com/problems/"* ]]; then
31+
# If the input is a LeetCode URL
32+
problem_slug=$(extract_problem_name "$input")
33+
else
34+
# If the input is already a title-slug
35+
problem_slug="$input"
36+
fi
37+
else
38+
echo "Please provide the LeetCode problem title-slug or URL."
39+
exit 1
40+
fi
41+
42+
echo "Problem Slug: $problem_slug"
43+
44+
# GraphQL query to fetch problem details
45+
query=$(make_query "$problem_slug")
46+
47+
echo "Requesting problem details from LeetCode GraphQL API..."
48+
49+
# Send a POST request to the LeetCode GraphQL API
50+
response=$(request "$query")
51+
52+
# Check if the response contains valid data
53+
if ! echo -E "$response" | jq -e '.data.question' >/dev/null 2>&1; then
54+
echo -E "$response"
55+
echo "Failed to receive a valid response from the LeetCode API. Exiting the script."
56+
exit 1
57+
fi
58+
59+
echo "Received problem details response from LeetCode."
60+
61+
# Create the file
62+
63+
create_file "$response"
64+
}
65+
66+
# Call the main function
67+
main "$@"

scripts/leetcode_helper.bash

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
3+
# Extract the title-slug from the LeetCode URL
4+
function extract_problem_name() {
5+
local url="$1"
6+
echo "$url" | sed -n 's/.*\/problems\/\([^/]*\)\/.*/\1/p'
7+
}
8+
9+
# Generates the GraphQL query to fetch problem details based on the provided title-slug
10+
function make_query() {
11+
local question_slug=$1
12+
# shellcheck disable=SC2016
13+
local query='{
14+
"query": "query selectProblem($titleSlug: String!) { question(titleSlug: $titleSlug) { questionFrontendId title titleSlug codeSnippets { langSlug code } } }",
15+
"variables": {
16+
"titleSlug": "'"$question_slug"'"
17+
}
18+
}'
19+
echo "$query"
20+
}
21+
22+
# Sends a POST request to the LeetCode GraphQL API with the generated query
23+
function request() {
24+
local query="$1"
25+
local response
26+
response=$(curl -s -X POST -H "Content-Type: application/json" --data "$query" https://leetcode.com/graphql)
27+
echo -E "$response"
28+
}
29+
30+
# Creates a file for the LeetCode problem
31+
#
32+
# Parses the JSON response from the LeetCode API, extracts relevant problem details,
33+
# generates the solution code template using the `make_solution_code()` function,
34+
# and saves the file using the `save_file()` function.
35+
function create_file() {
36+
local json_data="$1"
37+
local question_id
38+
local title
39+
local title_slug
40+
local code_snippet
41+
local content
42+
43+
question_id=$(echo -E "$json_data" | jq -r '.data.question.questionFrontendId')
44+
title=$(echo -E "$json_data" | jq -r '.data.question.title')
45+
title_slug=$(echo -E "$json_data" | jq -r '.data.question.titleSlug')
46+
47+
# Generate the code snippet
48+
code_snippet=$(echo -E "$json_data" | jq -r ".data.question.codeSnippets[] | select(.langSlug == \"$LANGUAGE\") | .code")
49+
50+
# Generate the entire code
51+
content=$(make_solution_code "$question_id" "$title" "https://leetcode.com/problems/$title_slug/description/" "$code_snippet")
52+
53+
save_file "$title_slug" "$content"
54+
}

0 commit comments

Comments
 (0)