FYP-23-S1-21 commited on
Commit
bb19264
·
1 Parent(s): 1fa064d

Upload 10 files

Browse files
BreakdownFeature.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ from flask import g
3
+ from transformers import pipeline
4
+
5
+ # Set up zero-shot classification pipeline
6
+ classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
7
+
8
+ # The main "breakdown" functionality. Performs NLP using zero-shot classification!
9
+ def breakdown(userStory):
10
+
11
+ # The results are stored into a dictionary variable with predefined labels
12
+ processedStory = classifier(userStory, candidate_labels=["developer", "tester", "project manager", "system admin"])
13
+
14
+ # Extract labels and scores
15
+ scores = processedStory['scores']
16
+ labels = processedStory['labels']
17
+
18
+ # As the index of a score is always equal to its associated label,
19
+ # We only need to index of the score to find correct label.
20
+ maxScoreIndex = scores.index(max(scores)) # Gets the index of the highest score/accuracy
21
+ maxLabel = labels[maxScoreIndex] # Gets the associated label name
22
+
23
+ # Return the highest label
24
+ return maxLabel
25
+
26
+ # Function to grab all contents in the "Breakdown" table (except for unique ids)
27
+ def getBreakdownContents():
28
+ db = getattr(g, '_database', None) # Gets the _database attribute from the 'g' object. If it does not exist, returns 'None'
29
+ if db is None:
30
+ db = g._database = sqlite3.connect('Refineverse.db') # If db is None, create a new connection for db and g._database.
31
+ cursor = db.cursor() # Creates a cursor object to handle data
32
+ cursor.execute("SELECT user_story, assignedLabel FROM Breakdown") # The cursor executes the query
33
+ rows = cursor.fetchall() # Stores the results of fetchall() into a variable
34
+ return rows
35
+
36
+ # Function to insert a new row into the "Breakdown" table
37
+ def insertBreakdownRow(user_story, assigned_label):
38
+ with sqlite3.connect('Refineverse.db') as conn: # 'With' will automatically take care of closing and opening the connection
39
+ cursor = conn.cursor()
40
+ cursor.execute("INSERT INTO Breakdown (user_story, assignedLabel) VALUES (?, ?)", (user_story, assigned_label))
41
+ conn.commit()
42
+
CSIT321Project-Info.txt ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **CSIT321 Project FYPS1-21**
2
+ ## Our Refineverse Plugin URL on Hugging Face's Spaces
3
+ https://huggingface.co/spaces/FYP-S1-21/Refineverse_Plugin
4
+
5
+ ## Our Source code Repository:
6
+ https://github.com/Nikosgo/FYP-S1-21-Refineverse.git
7
+
8
+
9
+ ---
10
+
11
+ ## IMPORTANT! Rules to follow during development:
12
+ 1. Only Commit to your own branch/workspace under Source control.(Message..to commit on "your name")
13
+ 2. Please DO NOT push or commit to "Main" branch (very Important)
14
+ 3. Before doing anything with code, always select Pull From "Main" under Source Control
15
+ 4. Make sure you are in your own branch/workspace before doing anything.
16
+
17
+ ---
18
+
19
+ ## SET UP
20
+ 1. Install Vscode
21
+ 2. Install XAMPP https://www.apachefriends.org/download.html
22
+
23
+ ---
24
+
25
+ ## In Vscode, before cloning repository:
26
+ 1. Make sure to install Git https://git-scm.com/downloads (Ignore if Git already installed)
27
+ 2. Install Git Extension Pack, Extension Pack for Java, Jira and Bitbucket(Atlassian Labs).
28
+ 3. Install PHP Extensions.
29
+
30
+ ## In Vscode, cloning repository:
31
+ 1. In New Window, Select "Clone Git Repository..."
32
+ 2. Copy & paste https://github.com/Nikosgo/FYP-S1-21-Refineverse.git in github url option.
33
+ 3. Click and select "Clone From github". Do not select clone from URL!
34
+ 4. Select local repository location as C:\xampp\htdocs (Xampp)
35
+ 5. Prompt to login in to Atlassian Account, Do so.
36
+
37
+ ## Setting Git Credentials and Access:
38
+ 1. Select and Open New Terminal under Terminal Tab.
39
+ 2. Type "cd" command to go root directory of your Git repository.
40
+ 3. Type and run git config --global user.name "your Github username"
41
+ 4. Type and run git config --global user.email "your Github email"
42
+ 5. Type and run git config --global credential.helper wincred to store your Github credentials
43
+ 6. Type and run git config --list to verify verify that your Git configuration is set up correctly
44
+
45
+ ---
46
+
47
+ ## Selecting Your Branch/Workspace
48
+ 1. In left Side panel of screen, select Source Control
49
+ 2. Select the 3 dots next to refresh icon and all the other icons.
50
+ 3. Select Checkout to origin/yourname
51
+
52
+ ---
53
+
54
+ ## To be done each time before any coding to get most updated version of source codes
55
+ 1. In left Side panel of screen, select Source Control
56
+ 2. Select the 3 dots next to refresh icon and all the other icons.
57
+ 3. Under "Pull,Push" select "Pull From..."
58
+ 4. Choose "origin/main"
59
+
60
+ ---
61
+
62
+ ## How to push commit to your codes?
63
+ 1. Under File tab, make sure "Autosave" is checked to automatically save your codes
64
+ 2. Under Source Control, ensure message box shows "Message (Ctrl+Enter to commit on "yourname")
65
+ 3. Below blue commit button, under Changes select the "+" sign to stage changes.
66
+ 4. Write a message for the change and Select blue Commit Button.
67
+ 5. Select Sync Changes to update local repository.
68
+
69
+ ---
70
+
71
+ ## Setting up a Python Virtual Environment (in VS Code)
72
+ To run/debug our project's NLP-related Python code, you must first set up a Python virtual environment.
73
+ Alternatively, you can install the libraries locally on your machine (not recommended).
74
+ **Important!** At the very least you must have Python installed locally on your machine and the Python extension enabled in VS Code.
75
+ The library installation commands listed here are meant for Windows machines. Do find the approriate commands for Linux/Mac yourself.
76
+
77
+ When running the virtual environment, you might run into an error intially when running the activate script due to Window's PowerShell. (Ignore if not using a Windows machine)
78
+ You can rectify this by changing the current execution policy for running scripts.
79
+ 1. Open up Window's PowerShell (not command prompt!) **as an administrator**.
80
+ 2. Use Get-ExecutionPolicy to check the current execution policy.
81
+ 3. If it is "Restricted", set it to either "RemoteSigned" or "Unrestricted" using "Set-ExecutionPolicy RemoteSigned" or "Set-ExecutionPolicy Unrestricted".
82
+ 4. You can change it back after you are done with the virtual environment using "Set-ExecutionPolicy Restricted".
83
+
84
+ Now you can open up VS Code to create the virutal environment.
85
+ 1. In VS Code, use the shortcut "Ctrl+Shift+P" to open up the command palette.
86
+ 2. Search for "Python: Create Environment..." and click it.
87
+ 3. When asked to pick an enviroment type, choose "Venv".
88
+ 4. When asked for a Python installation to use you should only have one option listed which is the Python version installed on your machine locally. Choose that option.
89
+ 5. A notification will appear to show the progress of the environment creation. After creation, a folder will appear in your workplace automatically, and the Python intepreter should be changed automatically.
90
+ 6. Verify if your Python has been changed to the new environment by looking at the bottom-right of your VS Code. It should say something like "Python 3.11.3 ('venv':venv)". If not, click on it and change it to the correct environment.
91
+ 7. Now you can start installing the neccessary libraries by opening a new terminal window in VS Code. Navigate to the Terminal tab and choose "New Terminal". The new environment should be reflected in the terminal.
92
+ 8. Install Pytorch (CPU): Pytorch (CPU): pip3 install torch torchvision torchaudio
93
+ 9. Install Transformers: pip install transformers
94
+ 11. These libraries are the bare minimum for running NLP code using HuggingFace's transformers. You can now try running some test code to verify.
95
+
96
+ To note:
97
+ By default, the virtual enviroment will not be detected as a new change/commit due to the automatically generated .gitignore file.
98
+ Please **do not** attempt to change this and upload your environment to GitHub as it may cause errors!
99
+
100
+ ---
101
+
102
+ ## Managing your Virtual Environment
103
+ As the path of the Python installation used to build the environment is user-specific, it cannot be shared.
104
+ Thus, the virtual environment must be maintained and installed properly by yourself.
105
+ Feel free to rename your virtual environment anything you want.
106
+
107
+ If you wish to install more libraries to test/debug new features (such as Flask or Beautiful Soup) go ahead.
108
+ However, do communicate with the team if a new library is being used to enable team members to run your code as well.
109
+ The final required Python libraries for our project will be included in a requirements.txt file.
110
+ If for some reason you encounter issues such as library conflicts or errors, feel free to remove your environment and follow the steps to create a new one again.
111
+
112
+ ---
113
+
114
+ ## Installing your libraries
115
+ 1. Ensure that you have already setup and activated your virtual environment.
116
+ 2. In the VsCode terminal, type the command "pip install -r requirements.txt" and click enter to allow the system to automatically install all necessary libraries that have been defined in the requirements.txt file in order to run the application.
117
+
118
+ ---
119
+
120
+ ## Creating or Saving a requirements.txt for library installation
121
+ 1. Ensure that you have already setup and activated your virtual environment.
122
+ 2. Delete any existing requirements.txt file as the command does not overwrite the text file.
123
+ 2. In the VsCode terminal, type the command "pip freeze > requirements.txt" and click enter to save all libraries that have already been installed into the requirements.txt file.
GenerationFeature.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re # Python's built-in library for regular expressions (or Regex)
2
+ import sqlite3
3
+ from flask import g
4
+ from transformers import pipeline, set_seed
5
+
6
+ # Main function of the generation feature. Performs text generation!
7
+ def generate(Entered_story):
8
+
9
+ # Check if the input is empty
10
+ if not Entered_story.strip():
11
+ raise ValueError("Empty input!")
12
+
13
+ # Validate that the input is in the correct format
14
+ if not validate_story(Entered_story):
15
+ raise ValueError("Incorrect format!")
16
+
17
+ # Set the pipeline to use the correct NLP type and model
18
+ generator = pipeline('text-generation', model='gpt2')
19
+
20
+ # Take note: The max_length & min_length variables refer to the OUTPUT length!
21
+ set_seed(42)
22
+ generated_text = generator(Entered_story, max_length=30, num_return_sequences=5)
23
+
24
+ generated_text = generated_text[0]['generated_text']
25
+
26
+ return generated_text
27
+
28
+ # User Input Format Validation Function
29
+ def validate_story(Entered_story):
30
+ pattern = r'As a (?P<role>[^,.]+), I want to (?P<goal>[^,.]+)(?:,|.)+\s*so that' #Follows the normal structure, but allows anything after 'so that'
31
+ match = re.search(pattern, Entered_story, flags=re.DOTALL)
32
+ return bool(match)
33
+
34
+ # Function to grab all contents in the "TextGeneration" table (except for unique ids)
35
+ def getTextGenContents():
36
+ db = getattr(g, '_database', None) # Gets the _database attribute from the 'g' object. If it does not exist, returns 'None'
37
+ if db is None:
38
+ db = g._database = sqlite3.connect('Refineverse.db') # If db is None, create a new connection for db and g._database.
39
+ cursor = db.cursor() # Creates a cursor object to handle data
40
+ cursor.execute("SELECT userStory, generatedStory FROM TextGeneration") # The cursor executes the query
41
+ rows = cursor.fetchall() # Stores the results of fetchall() into a variable
42
+ return rows
43
+
44
+ # Function to insert a new row into the "TextGeneration" table
45
+ def insertTextGenRow( Entered_story, generatedStory):
46
+ with sqlite3.connect('Refineverse.db') as conn: # 'With' will automatically take care of closing and opening the connection
47
+ cursor = conn.cursor()
48
+ cursor.execute("INSERT INTO TextGeneration (userStory, generatedStory) VALUES (?, ?)", (Entered_story, generatedStory))
49
+ conn.commit()
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Refineverse Plugin
3
- emoji: 🏃
4
- colorFrom: red
5
- colorTo: indigo
6
- sdk: static
 
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Refineverse
3
+ emoji: 💻
4
+ colorFrom: blue
5
+ colorTo: gray
6
+ sdk: gradio
7
+ python_version: 3.11.3
8
+ app_file: Refineverse.py
9
  pinned: false
10
  ---
11
 
12
+ This is to host our plugin online on Hugging Face.
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
Refineverse.db ADDED
Binary file (24.6 kB). View file
 
Refineverse.py ADDED
@@ -0,0 +1,225 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Plugin will run on this file & Strictly only contains codes for routing between files!
2
+ from flask import Flask, render_template, request, flash, g
3
+ from TextSummarizationFeature import summarize, getTextSumContents, insertTextSumRow
4
+ from BreakdownFeature import breakdown, getBreakdownContents, insertBreakdownRow
5
+ from TranslationFeature import translate_text, switch, getTranslatedContents, insertTranslationRow
6
+ from GenerationFeature import generate, getTextGenContents, insertTextGenRow
7
+
8
+ app = Flask(__name__)
9
+ app.secret_key = 'refineverseAdmin' # Used to encrypt cookies & sessions
10
+
11
+ # Routing to Main Dashboard/homepage file
12
+ @app.route('/')
13
+ def index():
14
+ return render_template('RefineverseDashboardUI.html')
15
+
16
+ # Routing to text summarization file
17
+ @app.route('/text_summarization', methods=["POST", "GET"])
18
+ def text_summarization():
19
+ if request.method == "POST":
20
+ try:
21
+ # Grab the user story text from the textarea in html form
22
+ Entered_story = request.form["input_text"]
23
+
24
+ # The results are stored into a dictionary variable
25
+ summarizedStory = summarize(Entered_story)
26
+
27
+ flash("Your user story has been summarized!") # Displays a success message using flash, which is part of the Flask framework
28
+
29
+ # Insert into TextSummarization table in Refineverse.db
30
+ insertTextSumRow(Entered_story, summarizedStory)
31
+
32
+ # Render and display summarized user story
33
+ return render_template('TextSummarizationUI.html', summarizedStory=summarizedStory)
34
+
35
+ # Exception handling messages for specific errors
36
+ except ValueError as e:
37
+ if str(e) == "Empty input!":
38
+ flash("The input text cannot be empty! Please enter a user story.", 'error')
39
+ return render_template('TextSummarizationUI.html')
40
+ elif str(e) == "Incorrect format!":
41
+ flash("Incorrect user story format! Please enter in the right format.", 'error')
42
+ return render_template('TextSummarizationUI.html')
43
+ elif str(e) == "Invalid length!":
44
+ flash("Your inputted user story is too short to summarize. Please enter a longer story!", 'error')
45
+ return render_template('TextSummarizationUI.html')
46
+ else: # As a final resort, simply print out the error name
47
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
48
+ return render_template('TextSummarizationUI.html')
49
+
50
+ except KeyError:
51
+ flash("Please enter a valid user story!")
52
+ return render_template('TextSummarizationUI.html')
53
+
54
+ # Catch-all exception handling
55
+ except Exception as e:
56
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
57
+ return render_template('TextSummarizationUI.html')
58
+
59
+ else:
60
+ return render_template('TextSummarizationUI.html')
61
+
62
+ # Routing to summarization table file
63
+ @app.route('/summarization_table')
64
+ def summarization_table():
65
+ # Get the summarization data from the database
66
+ summarizations = getTextSumContents()
67
+
68
+ # Render the summarization data as an HTML table
69
+ return render_template('SummarizationTable.html', summarizations=summarizations)
70
+
71
+ # Routing to Project Task Breakdown file
72
+ @app.route("/project_breakdown", methods=["POST", "GET"]) # This tells flask the route to get to the page
73
+ def project_breakdown():
74
+ if request.method == "POST": # POST occurs when submitting a form, as specified in the HTML file
75
+ try:
76
+ # Grab the user story contents
77
+ userStory = request.form["user-story-text"]
78
+
79
+ # The results are stored into a dictionary variable
80
+ processedLabel = breakdown(userStory)
81
+
82
+ # Display success popup message
83
+ flash("Your user story has been allocated as a " + processedLabel + " task!")
84
+
85
+ insertBreakdownRow(userStory, processedLabel) # Inserts data into the Breakdown table
86
+ rows = getBreakdownContents() # Grab all contents inside the Breakdown table
87
+
88
+ return render_template('ProjectBreakdownUI.html', rows=rows)
89
+
90
+ # Exception handling messages for specific errors
91
+ except KeyError:
92
+ flash("Please enter a valid user story!", 'error')
93
+ rows = getBreakdownContents()
94
+ return render_template('ProjectBreakdownUI.html', row=rows)
95
+
96
+ # Catch-all exception handling
97
+ except Exception as e:
98
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
99
+ rows = getBreakdownContents()
100
+ return render_template('ProjectBreakdownUI.html', rows=rows)
101
+
102
+ else: # For "GET" scenarios (loading the page, etc.)
103
+ rows = getBreakdownContents() # To always display the table, we must grab the contents of Breakdown every time the page loads
104
+ return render_template('ProjectBreakdownUI.html', rows=rows)
105
+
106
+ # Routing to Translation file
107
+ @app.route('/language_translation', methods=["POST", "GET"])
108
+ def language_translation():
109
+ if request.method == "POST":
110
+ try:
111
+ # Grab all relevant information for processing
112
+ input_text = request.form['input'] # Grab user text input
113
+
114
+ # Grab source language code
115
+ source_language = request.form['source_language']
116
+
117
+ # Grab target language code
118
+ target_language = request.form['target_language']
119
+
120
+ # Generate translated text using custom translation function
121
+ translatedStory = translate_text(input_text, source_language, target_language)
122
+
123
+ # Display success popup message
124
+ flash("Your user story has been translated to " + switch(target_language) + " !")
125
+
126
+ # Insert into Translation table in Refineverse.db
127
+ insertTranslationRow(input_text, translatedStory)
128
+
129
+ # Display the page
130
+ return render_template('LanguageTranslationUI.html', input_text=input_text, translatedStory=translatedStory)
131
+
132
+ # Exception handling messages for specific errors
133
+ except ValueError as e:
134
+ if str(e) == "Empty input!":
135
+ flash("The input text cannot be empty! Please enter a user story.", 'error')
136
+ return render_template('LanguageTranslationUI.html')
137
+ elif str(e) == "Incorrect format!":
138
+ flash("Unable to translate your user story. Please enter in the correct format.", 'error')
139
+ return render_template('LanguageTranslationUI.html')
140
+ else: # As a final resort, simply print out the error name
141
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
142
+ return render_template('LanguageTranslationUI.html')
143
+
144
+ # Catch-all exception handling
145
+ except Exception as e:
146
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
147
+ return render_template('LanguageTranslationUI.html')
148
+
149
+ else:
150
+ return render_template('LanguageTranslationUI.html')
151
+
152
+ # Routing to translation table file
153
+ @app.route('/translation_table')
154
+ def translation_data():
155
+ # Get the translation data from the database
156
+ translations = getTranslatedContents()
157
+
158
+ # Render the translation data as an HTML table
159
+ return render_template('TranslationTable.html', translations=translations)
160
+
161
+ # Routing to text summarization file
162
+ @app.route('/text_generation', methods=["POST", "GET"])
163
+ def text_generation():
164
+ if request.method == "POST":
165
+ try:
166
+ # Grab the user story text from the textarea in html form
167
+ Entered_story = request.form["input_text"]
168
+
169
+ # The results are stored into a dictionary variable
170
+ generatedStory = generate(Entered_story)
171
+
172
+ # Display a success message for the user
173
+ flash("Your user story has been generated!")
174
+
175
+ # Insert into TextGeneration table in Refineverse.db
176
+ insertTextGenRow(Entered_story, generatedStory)
177
+
178
+ # Render and display summarized user story
179
+ return render_template('TextGenerationUI.html', generatedStory=generatedStory)
180
+
181
+ # Exception handling messages for specific errors
182
+ except ValueError as e:
183
+ if str(e) == "Empty input!":
184
+ flash("The input text cannot be empty! Please enter a user story.", 'error')
185
+ return render_template('TextGenerationUI.html')
186
+ elif str(e) == "Incorrect format!":
187
+ flash("Incorrect user story format! Please enter in the right format.", 'error')
188
+ return render_template('TextGenerationUI.html')
189
+ else: # As a final resort, simply print out the error name
190
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
191
+ return render_template('TextGenerationUI.html')
192
+
193
+ except KeyError:
194
+ flash("Please enter a valid user story!")
195
+ return render_template('TextGenerationUI.html')
196
+
197
+ # Catch-all exception handling
198
+ except Exception as e:
199
+ flash("An error of type '{}' occurred: {}".format(type(e).__name__, str(e)), 'error')
200
+ return render_template('TextGenerationUI.html')
201
+
202
+ else:
203
+ return render_template('TextGenerationUI.html')
204
+
205
+ # Routing to generation table file
206
+ @app.route('/generation_table')
207
+ def generation_table():
208
+ # Get the generation data from the database
209
+ generations = getTextGenContents()
210
+
211
+ # Render the generation data as an HTML table
212
+ return render_template('GenerationTable.html', generations=generations)
213
+
214
+ # Used when the application is torn down
215
+ # Its purpose is to close the database connection if it has not been closed
216
+ @app.teardown_appcontext
217
+ def close_connection(exception):
218
+ db = getattr(g, '_database', None)
219
+ if db is not None:
220
+ db.close() # Closes the database connection
221
+
222
+ # Initialise the app
223
+ if __name__ == '__main__':
224
+ app.run(host="0.0.0.0", port=7860) # For HF hosting
225
+ #app.run(debug=False) # can set to True/False for local testing
TextSummarizationFeature.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re # Python's built-in library for regular expressions (or Regex)
2
+ import sqlite3
3
+ from flask import g
4
+ from transformers import pipeline
5
+
6
+ # Main function of the summarization feature. Performs summarization!
7
+ def summarize(Entered_story):
8
+
9
+ # Check if the input is empty
10
+ if not Entered_story.strip():
11
+ raise ValueError("Empty input!")
12
+
13
+ # Validate that the input is in the correct format
14
+ if not validate_story(Entered_story):
15
+ raise ValueError("Incorrect format!")
16
+
17
+ # Before we do anything, make sure the input is long enough for summarization.
18
+ if len(Entered_story) < 200:
19
+ raise ValueError("Invalid length!")
20
+
21
+ # Set the pipeline to use the correct NLP type and model
22
+ summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
23
+
24
+ # Take note: The max_length & min_length variables refer to the OUTPUT length!
25
+ summary = summarizer(Entered_story, max_length=100, min_length=30, do_sample=False)[0]["summary_text"]
26
+
27
+ return summary
28
+
29
+ # User Input Format Validation Function for English only
30
+ def validate_story(Entered_story):
31
+ pattern = r'As a (?P<role>[^,.]+), I want to (?P<goal>[^,.]+)(,|.)+so that (?P<benefit>.+)'
32
+ match = re.search(pattern, Entered_story, flags=re.DOTALL)
33
+ return bool(match)
34
+
35
+ # Function to grab all contents in the "TextSummarization" table (except for unique ids)
36
+ def getTextSumContents():
37
+ db = getattr(g, '_database', None) # Gets the _database attribute from the 'g' object. If it does not exist, returns 'None'
38
+ if db is None:
39
+ db = g._database = sqlite3.connect('Refineverse.db') # If db is None, create a new connection for db and g._database.
40
+ cursor = db.cursor() # Creates a cursor object to handle data
41
+ cursor.execute("SELECT Entered_story, summary FROM TextSummarization") # The cursor executes the query
42
+ rows = cursor.fetchall() # Stores the results of fetchall() into a variable
43
+ return rows
44
+
45
+ # Function to insert a new row into the "TextSummarization" table
46
+ def insertTextSumRow( Entered_story, summary):
47
+ with sqlite3.connect('Refineverse.db') as conn: # 'With' will automatically take care of closing and opening the connection
48
+ cursor = conn.cursor()
49
+ cursor.execute("INSERT INTO TextSummarization (Entered_story, summary) VALUES (?, ?)", (Entered_story, summary))
50
+ conn.commit()
TranslationFeature.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import sqlite3
3
+ from flask import g
4
+ from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer
5
+
6
+ model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_1.2B") # Setting the model to use
7
+ tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_1.2B") # Setting the tokenizer to use
8
+
9
+ # Main function of the translation feature. Performs translation!
10
+ def translate_text(input_text, source_language, target_language):
11
+
12
+ # Grabs the source language to be used in the tokenizer
13
+ tokenizer.src_lang = source_language
14
+
15
+ # Check if the input is empty
16
+ if not input_text.strip():
17
+ raise ValueError("Empty input!")
18
+
19
+ # Validate that the input is in the correct format
20
+ if not validate_input(input_text):
21
+ raise ValueError("Incorrect format!")
22
+
23
+ # Creates encoded text
24
+ encoded_text = tokenizer(input_text, return_tensors="pt")
25
+
26
+ # Generates new tokens using encoded text from source language
27
+ generated_tokens = model.generate(**encoded_text, forced_bos_token_id=tokenizer.get_lang_id(target_language), max_new_tokens=512)
28
+
29
+ # Decode generated tokens to display translated text
30
+ translated_text = tokenizer.batch_decode(generated_tokens, skip_special_tokens=True)[0]
31
+
32
+ return translated_text
33
+
34
+ # Helper function for displaying appropriate language names in flash messages
35
+ # Note: Python does not have a built-in switch function, so this is just a rough implementation of the logic
36
+ def switch(lang):
37
+ if lang == "en":
38
+ return "English"
39
+ elif lang == "zh":
40
+ return "Chinese"
41
+ elif lang == "ms":
42
+ return "Malay"
43
+ elif lang == "ta":
44
+ return "Tamil"
45
+ elif lang == "th":
46
+ return "Thai"
47
+
48
+ # User Input Format Validation Function for all 4 languages
49
+ def validate_input(input_text):
50
+
51
+ # Pattern for English language
52
+ pattern_en = r'As a (?P<role>[^,.]+), I want to (?P<goal>[^,.]+)(,|.)+so that (?P<benefit>.+)'
53
+
54
+ # Pattern for Chinese language
55
+ pattern_zh = r'作为(?P<role>[^,.]+),我想要(?P<goal>[^,.]+)(,|。)+以便(?P<benefit>.+)'
56
+
57
+ # Pattern for Malay language
58
+ pattern_ms = r'Sebagai(?P<role>[^,.]+), saya mahu(?P<goal>[^,.]+)(,|.)+supaya(?P<benefit>.+)'
59
+
60
+ # Pattern for Tamil language
61
+ pattern_ta = r'என(?P<role>[^,.]+) எனக்கு வேண்டும்(?P<goal>[^,.]+)(,|.)+அதனால்(?P<benefit>.+) பயன்படுத்தி வைக்கும்'
62
+
63
+ # Pattern for Thai language
64
+ pattern_th = r'ในฐานะ(?P<role>[^,.]+) ฉันต้องการ(?P<goal>[^,.]+)(,|.)+เพื่อที่ฉัน(?P<benefit>.+)'
65
+
66
+ # Try each pattern to see if there is a match
67
+ match_en = re.search(pattern_en, input_text, flags=re.DOTALL)
68
+ match_zh = re.search(pattern_zh, input_text, flags=re.DOTALL)
69
+ match_ms = re.search(pattern_ms, input_text, flags=re.DOTALL)
70
+ match_ta = re.search(pattern_ta, input_text, flags=re.DOTALL)
71
+ match_th = re.search(pattern_th, input_text, flags=re.DOTALL)
72
+
73
+ # Return True if at least one pattern matches, otherwise False
74
+ return bool(match_en or match_zh or match_ms or match_ta or match_th)
75
+
76
+ # Function to grab all contents in the "Translation" table (except for unique ids)
77
+ def getTranslatedContents():
78
+ db = getattr(g, '_database', None) # Gets the _database attribute from the 'g' object. If it does not exist, returns 'None'
79
+ if db is None:
80
+ db = g._database = sqlite3.connect('Refineverse.db') # If db is None, create a new connection for db and g._database
81
+ cursor = db.cursor() # Creates a cursor object to handle data
82
+ cursor.execute("SELECT input_text, translated_text FROM Translation") # The cursor executes the query
83
+ rows = cursor.fetchall() # Stores the results of fetchall() into a variable
84
+ return rows
85
+
86
+ # Function to insert a new row into the "Translation" table
87
+ def insertTranslationRow(input_text, translated_text):
88
+ with sqlite3.connect('Refineverse.db') as conn: # 'With' will automatically take care of closing and opening the connection
89
+ cursor = conn.cursor()
90
+ cursor.execute("INSERT INTO Translation (input_text, translated_text) VALUES (?, ?)", (input_text, translated_text))
91
+ conn.commit()
createDatabase.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is used to create an SQLite database.
2
+ # If adding more tables, you should delete the exising databases, or alter the code here to drop the pre-exising tables first.
3
+ import sqlite3
4
+
5
+ # Establishes a connection to the specified DB. If the DB does not exist, it creates a new one.
6
+ connection = sqlite3.connect("Refineverse.db")
7
+ cursor = connection.cursor() # A cursor object that is used to handle data.
8
+
9
+ # Creating the Breakdown table
10
+ cursor.execute('''
11
+ CREATE TABLE IF NOT EXISTS Breakdown (
12
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
13
+ user_story TEXT,
14
+ assignedLabel TEXT
15
+ )
16
+ ''')
17
+
18
+ # Creating the TextSummarization table
19
+ cursor.execute('''
20
+ CREATE TABLE IF NOT EXISTS TextSummarization (
21
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
22
+ Entered_story TEXT,
23
+ summary TEXT
24
+ )
25
+ ''')
26
+
27
+ # Creating the Translation table
28
+ cursor.execute('''
29
+ CREATE TABLE IF NOT EXISTS Translation (
30
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ input_text TEXT,
32
+ translated_text TEXT
33
+ )
34
+ ''')
35
+
36
+ # Creating the TextGeneration table
37
+ cursor.execute('''
38
+ CREATE TABLE IF NOT EXISTS TextGeneration (
39
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
40
+ userStory TEXT,
41
+ generatedStory TEXT
42
+ )
43
+ ''')
44
+
45
+ connection.close() # Closes the connection
requirements.txt ADDED
Binary file (1.17 kB). View file