diff --git a/.gcloudignore b/.gcloudignore index c895b84..c82f389 100644 --- a/.gcloudignore +++ b/.gcloudignore @@ -15,11 +15,14 @@ .github # Quote files (will be pulled from GitHub) -quotes/ +# quotes/ # Python pycache: __pycache__/ # Ignored by the build system /setup.cfg # VSCode settings -.vscode/ \ No newline at end of file +.vscode/ + +# quote submission script +submit_quote.py \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/quote_request.md b/.github/ISSUE_TEMPLATE/quote_request.md index 48fc910..965b396 100644 --- a/.github/ISSUE_TEMPLATE/quote_request.md +++ b/.github/ISSUE_TEMPLATE/quote_request.md @@ -13,7 +13,7 @@ assignees: '' **Quote:** - + **Author:** diff --git a/main.py b/main.py index c525304..71f462c 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,18 @@ from flask import Flask, send_from_directory from flask_restful import Api import random -import requests +# import requests import os +import json app = Flask(__name__) # api = Api(app) -long_quotes = requests.get("https://raw.githubusercontent.com/Marcus5408/orv-quote-api/main/quotes/long_quotes.json").json() -short_quotes = requests.get("https://raw.githubusercontent.com/Marcus5408/orv-quote-api/main/quotes/short_quotes.json").json() +with open('quotes/long_quotes.json', 'r', encoding='utf-8') as f: + long_quotes = json.load(f) + +with open('quotes/short_quotes.json', 'r', encoding='utf-8') as f: + short_quotes = json.load(f) @app.route("/shortquote", methods=["GET"]) def short_quote() -> str: diff --git a/quotes/long_quotes.json b/quotes/long_quotes.json index 6c2df37..f52075e 100644 --- a/quotes/long_quotes.json +++ b/quotes/long_quotes.json @@ -35,7 +35,7 @@ }, { "quote": "She probably knew the truth that this story would never reach the reincarnated Kim Dokjas. That was why, he must never return to Earth. He must never let his companions know of his survival. His absence must become their eternal hope.", - "author": "Han Sooyoung", + "author": "Yoo Joonghyuk", "chapter": 548, "episode": "E5", "episode_name": "The Eternity and Epilogue, III" @@ -46,5 +46,61 @@ "chapter": 551, "episode": "E5", "episode_name": "The Eternity and Epilogue (Complete)" +}, +{ + "quote": "It wasn't the memories related to the 'Ways of Survival'. No, it was of the conversation I had with my mother a long time ago. ⸢\"Why are we rereading the story we know already?\"⸥ There were stories that didn't change even if you read it again. It'd not change, because the one reading didn't change. My mother replied to that question in this manner. ⸢\"Shall we read it together, then?\"⸥", + "author": "Kim Dokja", + "chapter": 445, + "episode": "84", + "episode_name": "1864, I" +}, +{ + "quote": "⸢In that final moment, Uriel reached out towards the sky.⸥ ⸢My Story might come to an end today, but.⸥ ⸢There will be a star that shall never forget this story.⸥", + "author": "Uriel", + "chapter": 511, + "episode": "98", + "episode_name": "Have You Protected All That You Were Supposed to Protect, VI" +}, +{ + "quote": "⸢There are three ways to survive in a ruined world.⸥ ⸢I’ve forgotten a few by now. However, one thing’s for certain.⸥ ⸢And that is, the you reading these words will get to survive.⸥", + "author": "Han Sooyoung", + "chapter": 551, + "episode": "E5", + "episode_name": "The Eternity and Epilogue (Complete)" +}, +{ + "quote": "\"Still, you should leave a mark.\" \"Does that make sense?\" \"There is no apparent meaning.\" \"Then?\" \"It is just important that you left it.\" \"The other party won't know so why?\" \"At least the wall has changed.\" I was speechless for a moment. Jang Hayoung spoke in a resolute voice. \"Then one day, someone might read it.\"", + "author": "Jang Hayoung", + "chapter": 216, + "episode": "41", + "episode_name": "Real Revolutionary, II" +}, +{ + "quote": "Even then, Han Sooyoung wanted to tell him. ⸢To tell him that he was definitely not at fault for this story being born. And to tell him that the things he was about to experience were not his sins.⸥ Because her past 13 years existed solely to say those words to him. ⸢To say that, though you have grown up while reading this story, there's no need for you to become it.⸥", + "author": "Han Sooyoung", + "chapter": 535, + "episode": "E3", + "episode_name": "Author's Words, IV" +}, +{ + "quote": "\"Even before his soul scattered, Kim Dokja was the 'Oldest Dream'. Haven't you ever thought about how strange it was? Why didn't that fool ever dream of his own happiness?\" \"In that case, Kim Dokja's subconsciousness must've thought that this conclusion is the right one.\" An existence who had never imagined his own happiness. The 'Kim Dokja' they knew was such a person. ", + "author": "Yoo Joonghyuk", + "chapter": 551, + "episode": "E5", + "episode_name": "The Eternity and Epilogue (Complete)" +}, +{ + "quote": "The man who came to her 1863rd regression turn. The man who she wanted to see again. The detestable man with his own brand of ass-kissing. The man who lied really easily. The man who she enjoyed being around, since they could lie about something together and snicker among themselves. The man, who didn't remember her. ", + "author": "Han Sooyoung", + "chapter": 535, + "episode": "E3", + "episode_name": "Author's Words, IV" +}, +{ + "quote": "Even if she knew this wouldn't heal her, even if she knew that holding that hand would only inflict her with a greater wound — courage to hold that hand in order to live for one more time. ⸢Some salvations aren't completed by the one giving them out, but by those receiving them.⸥", + "author": "Jung Heewon", + "chapter": 488, + "episode": "93", + "episode_name": "Omniscient Author's Viewpoint, II" } ] \ No newline at end of file diff --git a/quotes/short_quotes.json b/quotes/short_quotes.json index 21ccee3..b0e18d0 100644 --- a/quotes/short_quotes.json +++ b/quotes/short_quotes.json @@ -67,5 +67,26 @@ "chapter": 471, "episode": "89", "episode_name": "Great Apocalypse, V" +}, +{ + "quote": "You are there. I believe in the you of the third round.", + "author": "Kim Dokja", + "chapter": 299, + "episode": "55", + "episode_name": "Reader and Writer, V" +}, +{ + "quote": "⸢This story is for just that one reader.⸥", + "author": "Han Sooyoung", + "chapter": 551, + "episode": "E5", + "episode_name": "The Eternity and Epilogue (Complete)" +}, +{ + "quote": "I, someone of no redeeming quality, could be loved by the others. ", + "author": "Kim Dokja", + "chapter": 513, + "episode": "99", + "episode_name": "The Oldest Dream, II" } -] \ No newline at end of file +] diff --git a/requirements.txt b/requirements.txt index 7666e61..f5dfef3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ flask==2.3.2 flask-restful==0.3.10 gunicorn==21.2.0 -requests==2.31.0 \ No newline at end of file +# requests==2.31.0 diff --git a/submit_quote.py b/submit_quote.py new file mode 100644 index 0000000..26a0581 --- /dev/null +++ b/submit_quote.py @@ -0,0 +1,133 @@ +import os +import json +from tkinter import * +from tkinter import messagebox +from tkinter.ttk import * + +from numpy import add + +root = Tk() +root.title("ORV Quote API - Add Quote") +root.iconbitmap("assets/favicon.ico") +root.minsize(500, 320) +root.geometry("500x320") + +# define fields +heading_label = Label(root, text="Add Quote", font=("TKDefaultFont", 20, "bold")) + +quote_label = Label(root, text="Quote:") +quote_input = Text(root, height=7, wrap="word") +quote_scrollbar = Scrollbar(root, command=quote_input.yview) +quote_input.config(yscrollcommand=quote_scrollbar.set) + +import webbrowser + +def open_wiki(): + webbrowser.open("https://github.com///wiki") + +quote_help_button = Button(root, text="Need Help?", command=lambda: help()) + +def help(): + help_window = Toplevel(root) + help_window.title("Help") + help_window.iconbitmap("assets/favicon.ico") + + help_window_label = Label(help_window, text="Select an option to get help filling out that field.", font=("TKDefaultFont", 20, "bold")) + + tabs = Notebook(help_window) + quote_help = Frame(tabs) + author_help = Frame(tabs) + chapter_help = Frame(tabs) + episode_help = Frame(tabs) + episode_name_help = Frame(tabs) + + tabs.add(quote_help, text="Quote") + tabs.add(author_help, text="Author") + tabs.add(chapter_help, text="Chapter") + tabs.add(episode_help, text="Episode Number") + tabs.add(episode_name_help, text="Episode Name") + + + + text = "NOTE: THIS IS A NECESSARY FIELD. If this field is not filled out, your quote request will not be accepted.\n\nPlease keep quotes reasonably long. This means that you shouldn't quote 2 entire paragraphs, nor should you quote just 2 words. That is, of course, those two words are very prominent, such as \"Get lost, Kim Dokja.\"" + # messagebox.showinfo("Quote Info", text) + +author_label = Label(root, text="Author:") +author_input = Entry(root) + +chapter_label = Label(root, text="Chapter:") +chapter_input = Entry(root) + +episode_label = Label(root, text="Episode Number:") +episode_input = Entry(root) + +episode_name_label = Label(root, text="Episode Name:") +episode_name_input = Entry(root) + +add_quote_button = Button(root, text="Add Quote", command=lambda: add_quote()) + +quote_label.grid(row=0, column=0, columnspan=2, pady=(10, 0), padx=10, sticky="w") +quote_help_button.grid(row=0, column=1, pady=(5, 0), padx=10, sticky="e") +quote_input.grid(row=1, column=0, columnspan=2, pady=(5, 5), padx=(10, 30), sticky="we") + +quote_scrollbar.grid(row=1, column=1, pady=(5, 5), padx=(0, 10), sticky="nse") +quote_input.config(yscrollcommand=quote_scrollbar.set) + +author_label.grid(row=2, column=0, pady=(5,5), padx=(10, 0), sticky="w") +author_input.grid(row=2, column=1, pady=(5,5), padx=(5, 10), sticky="we") + +chapter_label.grid(row=3, column=0, pady=(5,5), padx=(10, 0), sticky="w") +chapter_input.grid(row=3, column=1, pady=(5,5), padx=(5, 10), sticky="we") + +episode_label.grid(row=4, column=0, pady=(5,5), padx=(10, 0), sticky="w") +episode_input.grid(row=4, column=1, pady=(5,5), padx=(5, 10), sticky="we") + +episode_name_label.grid(row=5, column=0, pady=(5,5), padx=(10, 0), sticky="w") +episode_name_input.grid(row=5, column=1, pady=(5,5), padx=(5, 10), sticky="we") + +add_quote_button.grid(row=6, column=0, columnspan=2, pady=(5, 10), padx=10, sticky="we") + +# make column 2 expandable, but column 1 fixed +root.grid_columnconfigure(0, weight=0) +root.grid_columnconfigure(1, weight=1) + +def add_quote(): + # if any fields are empty, show error + quote = { + "quote": quote_input.get("1.0", END), + "author": author_input.get(), + "chapter": int(chapter_input.get()), + "episode": episode_input.get(), + "episode_name": episode_name_input.get() + } + missing_fields = "" + for key in quote: + if quote[key] == "\n" or quote[key] == "": + missing_fields += f"{key}" if missing_fields == "" else f", {key}" + if missing_fields != "": + messagebox.showerror("Error", f"Please fill out the {missing_fields} {'field' if missing_fields.count(',') == 0 else 'fields'}.") + return + # get quote + quote["quote"] = quote["quote"].replace("\n", " ") + # print(quote) + quote_length = "long" if len(quote["quote"]) >= 150 else "short" + if quote_length == "short": + with open("quotes/short_quotes.json", "a") as f: + json.dump(quote, f) + f.write("\n") + else: + with open("quotes/long_quotes.json", "a") as f: + json.dump(quote, f) + f.write("\n") + messagebox.showinfo("Success", "Quote successfully added!") + # clear all fields + quote_input.delete("1.0", END) + author_input.delete(0, END) + chapter_input.delete(0, END) + episode_input.delete(0, END) + episode_name_input.delete(0, END) + + +# run the app +if __name__ == "__main__": + root.mainloop() \ No newline at end of file