├── readme_en
└── README.md
├── .github
└── workflows
│ ├── main.yml
│ └── Auto_Comment.yml
├── assets
├── image.png
├── icon_128.png
├── loading.png
└── logoauto.png
├── readme_vn
├── img.png
├── img_1.png
├── img_2.png
├── img_3.png
├── img_4.png
├── img_5.png
├── img_6.png
├── img_7.png
├── img_8.png
└── README.md
├── content
└── content.js
├── background_script
├── apicallpack.json
├── api.js
├── helpui.js
└── background.js
├── README.md
├── popup
├── popup.js
├── popup.html
├── active_page.js
├── setting_table.css
└── popup.css
├── manifest.json
└── privacy-policy.txt
/readme_en/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/assets/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/assets/image.png
--------------------------------------------------------------------------------
/readme_vn/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img.png
--------------------------------------------------------------------------------
/assets/icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/assets/icon_128.png
--------------------------------------------------------------------------------
/assets/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/assets/loading.png
--------------------------------------------------------------------------------
/assets/logoauto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/assets/logoauto.png
--------------------------------------------------------------------------------
/readme_vn/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_1.png
--------------------------------------------------------------------------------
/readme_vn/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_2.png
--------------------------------------------------------------------------------
/readme_vn/img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_3.png
--------------------------------------------------------------------------------
/readme_vn/img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_4.png
--------------------------------------------------------------------------------
/readme_vn/img_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_5.png
--------------------------------------------------------------------------------
/readme_vn/img_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_6.png
--------------------------------------------------------------------------------
/readme_vn/img_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_7.png
--------------------------------------------------------------------------------
/readme_vn/img_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/khengyun/autonext/HEAD/readme_vn/img_8.png
--------------------------------------------------------------------------------
/content/content.js:
--------------------------------------------------------------------------------
1 | console.log("content script is running")
2 | // Listen for messages from the content script
3 |
4 | function sendmess(params) {
5 | console.log(params)
6 | chrome.runtime.sendMessage(
7 | params
8 | )}
9 |
10 |
11 |
12 | function logMessage(message) {
13 | console.log(message)
14 | token = localStorage.getItem("token")
15 | console.log(`this is token: ${token}`)
16 | sendmess({type: "content_to_background", data: token})
17 | }
18 |
19 | chrome.runtime.onMessage.addListener(
20 | (request, sender, sendResponse) => {
21 | logMessage(request)
22 | }
23 | );
--------------------------------------------------------------------------------
/readme_vn/README.md:
--------------------------------------------------------------------------------
1 | # Hướng Dẫn Sử Dụng Dành Cho nextauto
2 |
3 | ## Bước 0 ( Tải file nguồn )
4 |
5 | > ### [Ấn vào đây để tải file nguồn](https://github.com/khengyun/autonext/archive/refs/tags/v3.4.5.zip)
6 |
7 | - ### Sau khi tải về => tiến hành giải nén
8 |
9 | - ### Sau khi giải nén sẽ có 1 folder nextauto như này
10 | 
11 | - ### LƯU Ý : Tùy Phiên Bản Tên File Sẽ Khác Nhau
12 |
13 | # Bước cuối
14 | - ## Xem video để cài đặt
15 | - ## Trang chủ edunext như cuối video thì đã cài thành công
16 |
17 | https://user-images.githubusercontent.com/78076796/211687272-7b09ddda-e15e-44d5-b2e9-26efe7d5fd42.mp4
18 |
19 |
--------------------------------------------------------------------------------
/background_script/apicallpack.json:
--------------------------------------------------------------------------------
1 | {
2 | "token_check": "https://fugw-edunext.fpt.edu.vn/api/auth/token",
3 | "get_grade": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/grade/get-grade",
4 | "grade_teammates": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/grade/grade-teammates",
5 | "list_group": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/group/list-group?classroomSessionId=",
6 | "course_detail": [
7 | "https://fugw-edunext.fpt.edu.vn:8443/api/v1/course/course-detail?id=",
8 | "¤tPage=1&pageSize=100&statusClickAll=false"
9 | ],
10 | "class_info": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/class/class-info?id=",
11 | "semester": [
12 | "https://fugw-edunext.fpt.edu.vn:8443/api/v1/class/home/student?id=",
13 | "&semesterName="
14 | ],
15 | "round": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/round/get?privateCqId=",
16 | "grading_group": "https://fugw-edunext.fpt.edu.vn:8443/api/v1/grade/grading-group"
17 | }
--------------------------------------------------------------------------------
/.github/workflows/Auto_Comment.yml:
--------------------------------------------------------------------------------
1 | name: Auto Comment
2 | on: [issues, pull_request]
3 | jobs:
4 | run:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: wow-actions/auto-comment@v1
8 | with:
9 | GITHUB_TOKEN: ${{ secrets.TOKEN_Assignees }}
10 | issuesOpened: |
11 | 👋 @{{ author }}
12 | Thank you for raising an issue. We will will investigate into the matter and get back to you as soon as possible.
13 | Please make sure you have given us as much context as possible.
14 |
15 | pullRequestOpened: |
16 | 👋 @{{ author }}
17 | Thank you for raising your pull request.
18 | Please make sure you have followed our contributing guidelines. We will review it as soon as possible
19 | - name: 'Auto-assign issue'
20 | uses: pozil/auto-assign-issue@v1
21 | with:
22 | assignees: Carl-Johnsons
23 | numOfAssignee: 1
24 | allowSelfAssign: false
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # autonext
2 | #### [NEW: Đã cập nhật phù hợp Edunext mới ]
3 | - This automatic grading tool on edunext is intended for fpt university students
4 | - Công cụ chấm điểm tự động trên edunext này dành cho sinh viên fbip
5 |
6 | > The tool is now available on the Chrome Store:
7 | > - https://chrome.google.com/webstore/detail/autonext/boflhmepcnacopclkkedcgoemjglankf?hl=en
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | https://github.com/khengyun/autonext/assets/78076796/fdf435f4-d5c8-49d0-8f12-4bd5f14d9475
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | # User Manual
26 |
27 | | 1. [Hướng Dẫn Sử Dụng](https://github.com/khengyun/nextauto/tree/main/readme_vn#readme) |
28 | |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
29 | | 2. **[User Manual](https://github.com/khengyun/nextauto/tree/main/readme_vn#readme)** |
30 | | **Feature [ (Latest)](https://github.com/khengyun/autonext/releases/latest) ** - Presentation Grading - Group Members Grading |
31 |
32 | # License
33 | MIT © [khengyun](https://github.com/khengyun)
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/popup/popup.js:
--------------------------------------------------------------------------------
1 | const version = chrome.runtime.getManifest().version;
2 | const elmColors = document.getElementsByName("apply_button");
3 | document.getElementById("version").innerText = `v${version}`;
4 |
5 | var USER_INFOR = {};
6 | // receive mess from background
7 |
8 | function localStorageAction(params) {
9 | if (params.type == "get") {
10 | return localStorage.getItem(params.key);
11 | }
12 | if (params.type == "set") {
13 | localStorage.setItem(params.key, JSON.stringify(params.value));
14 | }
15 | }
16 |
17 | chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
18 | if (request.type === "background") {
19 | console.log(request.message);
20 | USER_INFOR = request.message;
21 |
22 | //save to local storage
23 | localStorageAction({ type: "set", key: "user_infor", value: USER_INFOR });
24 | loadLocaltoPopup();
25 |
26 | }
27 | });
28 |
29 | function loadLocaltoPopup(){
30 | if (JSON.parse(localStorage.getItem("user_infor"))) {
31 | USER_INFOR = JSON.parse(
32 | localStorageAction({
33 | type: "get",
34 | key: "user_infor",
35 | })
36 | );
37 |
38 | document.getElementById(
39 | "container"
40 | ).innerHTML = `
Email: ${USER_INFOR.email}
41 | Name: ${USER_INFOR.name}
42 | RollNumber: ${USER_INFOR.rollNumber}
43 |
`;
44 | } else {
45 | document.getElementById("container").innerHTML =
46 | '';
47 | }
48 | }
49 |
50 | document.addEventListener("DOMContentLoaded", function () {
51 | loadLocaltoPopup();
52 | });
53 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "khengyun",
3 | "short_name": "AutoNext",
4 | "name": "AutoNext",
5 | "description": "This automatic grading tool on edunext\n__Hovilo__",
6 | "icons": {
7 | "128": "assets/logoauto.png"
8 | },
9 | "version": "3.5.3",
10 | "manifest_version": 3,
11 | "permissions": [
12 | "webRequest",
13 | "storage",
14 | "tabs",
15 | "scripting",
16 | "https://*.fpt.edu.vn/*"
17 | ],
18 | "host_permissions": ["https://*.fpt.edu.vn/*"],
19 | "web_accessible_resources": [
20 | {
21 | "resources": [
22 | "background_script/*.js",
23 | "assets/*.png",
24 | "popup/*.js",
25 | "popup/*.html",
26 | "popup/*.css"
27 | ],
28 | "matches": ["https://*.fpt.edu.vn/*"],
29 | "use_dynamic_url": true
30 | }
31 | ],
32 | "background": {
33 | "service_worker": "background_script/background.js"
34 | },
35 | "content_scripts": [
36 | {
37 | "matches": ["*://*/*"],
38 | "js": ["content/content.js"],
39 | "all_frames": true,
40 | "run_at": "document_start"
41 | }
42 | ],
43 | "action": {
44 | "default_icon": {
45 | "16": "assets/logoauto.png",
46 | "24": "assets/logoauto.png",
47 | "32": "assets/logoauto.png",
48 | "48": "assets/logoauto.png",
49 | "128": "assets/logoauto.png",
50 | "512": "assets/logoauto.png"
51 | },
52 | "default_title": "AutoNext",
53 | "default_popup": "popup/popup.html"
54 | },
55 | "content_security_policy": {
56 | "extension_pages": "script-src 'self' ; object-src 'self'",
57 | "sandbox": "sandbox allow-scripts; script-src 'self' 'https://apis.google.com/' 'https://www.gstatic.com/' 'https://*.firebaseio.com' 'https://www.googleapis.com' 'https://ajax.googleapis.com'; object-src 'self'"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/background_script/api.js:
--------------------------------------------------------------------------------
1 | var TOKEN = ""
2 | var PORT = 8443;
3 | var NEW_PORT = ""
4 | var USER_INFOR = {};
5 | var USER_SUBJECTS = [];
6 | var USER_CLASS = [];
7 | var USER_COURSE = [];
8 | var API = {};
9 |
10 |
11 | function post_api(input_get_data) {
12 | return new Promise((resolve, reject) => {
13 | const url = input_get_data.url;
14 | const options = {
15 | method: "POST",
16 | headers: {
17 | "Content-Type": "application/json",
18 | "Authorization": `${TOKEN}`,
19 | },
20 | body: input_get_data.body ? JSON.stringify(input_get_data.body) : null,
21 | };
22 |
23 | fetch(url, options)
24 | .then((response) => {
25 | if (!response.ok) {
26 | throw new Error("Network response was not ok");
27 | }
28 | return response.json();
29 | })
30 | .then((data) => {
31 | resolve(data);
32 | })
33 | .catch((error) => {
34 | console.error("There was a problem with the fetch operation:", error);
35 | reject(error);
36 | });
37 | });
38 | }
39 |
40 |
41 |
42 | function get_api(input_get_data) {
43 | return new Promise((resolve, reject) => {
44 |
45 | var myHeaders = new Headers();
46 | myHeaders.append("Content-Type", "application/json");
47 | myHeaders.append("Authorization", `${TOKEN}`);
48 | var requestOptions = {
49 | method: 'GET',
50 | headers: myHeaders,
51 | redirect: 'follow'
52 | };
53 | fetch(input_get_data.url, requestOptions)
54 | .then(response => {
55 | if (!response.ok) {
56 | throw new Error(`Error when load ${input_get_data.url}`);
57 | }
58 | return response.json();
59 | })
60 | .then(data => {
61 | resolve(data);
62 | })
63 | .catch(error => {
64 | reject(`Error when load ${input_get_data.url}`);
65 | });
66 | });
67 | }
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/popup/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | AutoNext
10 |
16 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | version
53 |
54 |
55 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/privacy-policy.txt:
--------------------------------------------------------------------------------
1 | # Privacy Policy
2 |
3 |
4 | ## What is a Privacy Policy
5 | Privacy Policy is a description of what we do with personal data. The important things to describe in the policy are how you and our website or app collect, use, store, and share or disclose information about people. Providing a privacy policy also helps users understand what happens to information about users.
6 |
7 | **Note:** The Privacy Policy is not the same as the Terms and Conditions agreement. Terms and conditions are agreements where we include rules and guidelines that users must agree to in order to use our website or application.
8 |
9 | ## How we use your Personal Data
10 |
11 | We absolutely do not use any of your personal data. which includes
12 | * First and last name
13 | * Email address
14 | * Billing and shipping address
15 | * Credit card information
16 | * And so on
17 |
18 |
19 | ## When is a Privacy Policy required
20 |
21 | ## When to get a Privacy Policy
22 |
23 | A Privacy Policy is required by law if we collect your personal data. One should be provided where your website or app does anything with personal data. The privacy policy lets you know what rights you have and we will also tell you what data we will use about you for our program.
24 |
25 |
26 | ## How this Privacy Policy works
27 | This Privacy Statement describes the personal data we collect and/or process (which may include collecting, organizing, structuring, storing, using).
28 |
29 | ## Disclaimer
30 |
31 | We disclaim responsibility for the user's use of the tool not for the intended purpose.
32 |
33 | This Privacy Policy is not legal advice and is not a substitute for an actual live attorney. We do not use user information on our server at all, all data is stored on the user's machine.
34 |
35 | You should also know that this Privacy Policy Template is provided under a sample supply from google
36 |
37 |
38 | ## License
39 |
40 | This Privacy Policy is licensed under the [MIT License, version 3 (MIT license)](https://github.com/khengyun/autonext/blob/main/LICENSE.txt) and is distributed free of charge.
41 |
42 |
43 | ## Author
44 |
45 | Arthur Garegnyan
46 |
47 | * Email: khaangnguyeen@gmail.com
48 |
49 | * GitHub: [https://github.com/ArthurGareginyan/](https://github.com/khengyun)
50 |
51 | * Facebook: [https://www.facebook.com/niraitoo](https://www.facebook.com/niraitoo)
52 |
53 |
--------------------------------------------------------------------------------
/popup/active_page.js:
--------------------------------------------------------------------------------
1 |
2 | function check_version(data) {
3 | let local_version = version
4 | let github_version = data.tag_name.replace('v', '')
5 |
6 | if (local_version !== github_version) {
7 | let download_link = `https://github.com/khengyun/autonext/archive/refs/tags/${data.tag_name}.zip`
8 |
9 | let text = ' version is no longer supported, click
here to download the new_version
'
10 | .replace('!!!', `${download_link}`)
11 | .replace('new_version',`v${github_version}`)
12 | .replace('version',`v${local_version}`)
13 |
14 |
15 | document.getElementById("version").innerHTML = text;
16 | document.getElementById("version").style.position = 'static';
17 | }
18 | }
19 |
20 |
21 | chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
22 |
23 | //call api check version
24 | let repo_api = "https://api.github.com/repos/khengyun/autonext/releases/latest";
25 | fetch(repo_api).then(res => res.json()).then(jsonData => {
26 |
27 | check_version(jsonData)
28 |
29 | })
30 |
31 | let url = tabs[0].url;
32 | console.log(tabs)
33 | if (url == 'https://fu-edunext.fpt.edu.vn/login') {
34 | localStorageAction({type: "set", key: "user_infor", value: null});
35 | document.getElementById('container').innerHTML = ''
36 | }
37 |
38 | else {
39 |
40 | chrome.runtime.sendMessage({
41 | type: "popup_to_background"
42 | })
43 |
44 |
45 | // if (JSON.parse(localStorage.getItem("user_infor"))) {
46 | // USER_INFOR = JSON.parse(localStorageAction({
47 | // type: "get",
48 | // key: "user_infor",
49 | // }))
50 |
51 | // document.getElementById(
52 | // "container"
53 | // ).innerHTML = `Email: ${USER_INFOR.email}
54 | // Name: ${USER_INFOR.name}
55 | // RollNumber: ${USER_INFOR.rollNumber}
56 | //
`;
57 | // } else {
58 | // document.getElementById("container").innerHTML = ''
59 | // ;
60 | // }
61 | }
62 |
63 |
64 | });
65 |
66 |
--------------------------------------------------------------------------------
/popup/setting_table.css:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | /*css button*/
5 |
6 | .switch {
7 | position: relative;
8 | display: inline-block;
9 | width: 60px;
10 | height: 34px;
11 | }
12 |
13 | .switch input {
14 | opacity: 0;
15 | width: 0;
16 | height: 0;
17 | }
18 |
19 | .slider {
20 | position: absolute;
21 | cursor: pointer;
22 | top: 0;
23 | left: 0;
24 | right: 0;
25 | bottom: 0;
26 | background-color: #f67412;
27 | -webkit-transition: .4s;
28 | transition: .4s;
29 | }
30 |
31 | .slider:before {
32 | position: absolute;
33 | content: "";
34 | height: 26px;
35 | width: 26px;
36 | left: 4px;
37 | bottom: 4px;
38 | background-color: white;
39 | -webkit-transition: .4s;
40 | transition: .4s;
41 | }
42 |
43 | input:checked + .slider {
44 | background-color: #1db128;
45 | }
46 |
47 | input:focus + .slider {
48 | box-shadow: 0 0 1px #2196F3;
49 | }
50 |
51 | input:checked + .slider:before {
52 | -webkit-transform: translateX(26px);
53 | -ms-transform: translateX(26px);
54 | transform: translateX(26px);
55 | }
56 |
57 | /* Rounded sliders */
58 | .slider.round {
59 | border-radius: 34px;
60 | }
61 |
62 | .slider.round:before {
63 | border-radius: 50%;
64 | }
65 |
66 | .setting_table {
67 | display: grid;
68 | grid-template-columns: auto;
69 |
70 | }
71 |
72 | /*khen code*/
73 | .setting_block {
74 | display: grid;
75 | grid-template-columns: 80% 20%;
76 |
77 |
78 | }
79 |
80 | .name_setting_block {
81 | width: auto;
82 | margin: unset;
83 | margin-top: 5px;
84 | min-height: 37px;
85 | }
86 |
87 | .done_setting_block{
88 | font-size: 15px;
89 | /* padding-top: 5px; */
90 | /* margin-left: -50px; */
91 | white-space: nowrap;
92 | text-align: center;
93 | display: flex;
94 | justify-content: center;
95 | align-items: center;
96 | }
97 |
98 |
99 | .button_setting {
100 | width: auto;
101 | height: auto;
102 | }
103 |
104 | .alert-warning {
105 | border-radius: 20px;
106 | background-color: rgba(211, 207, 207, 0.82);
107 | border-color: #ffffff;
108 | color: black;
109 | }
110 |
111 | .option_button {
112 | width: 60px;
113 | height: 34px;
114 | border-radius: 25px;
115 | text-align: center;
116 | }
117 | #apply_button{
118 | margin-top: 10px;
119 | height: 34px;
120 | width: 300px;
121 | font-size: 13px;
122 | font-weight: bold;
123 | border-radius: 30px;
124 | text-align: center;
125 | cursor: pointer;
126 | outline: none;
127 | color: #000000;
128 | background-color: #00b46a;
129 | border: none;
130 | box-shadow: 0 5px #999;
131 | }
132 | #apply_button:hover {background-color: #3e8e41}
133 |
134 | #apply_button:active {
135 | background-color: #3e8e41;
136 | box-shadow: 0 5px #666;
137 | transform: translateY(4px);
138 | }
139 |
140 |
141 |
142 |
143 |
144 | /*#apply_button:hover {*/
145 | /* height: 36px;*/
146 | /* width: 66px;*/
147 | /* font-size: 13px;*/
148 | /* border-radius: 30px;*/
149 | /*}*/
150 | .button_setting_block
151 | {
152 | display: flex;
153 | justify-content: center;
154 | align-items: center;
155 | }
--------------------------------------------------------------------------------
/background_script/helpui.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function format_grade_present(params){
4 |
5 | return {
6 | classroomSessionId: params.classroomSessionId,
7 | roundId: params.roundId,
8 | privateCqId: params.privateCqId,
9 | bonusPoint : 0,
10 | presentingGroupDTO:{
11 | keepTime: 5,
12 | meetRequirement: 5,
13 | presentations: 5,
14 | goodInformation: 5,
15 | presentGroupId: params.presentGroupId
16 | },
17 | reviewingGroupDTO: null
18 |
19 | }
20 |
21 | }
22 |
23 |
24 | function check_course_list(params) {
25 | var boolean = false;
26 |
27 | USER_COURSE.forEach((element) => {
28 | if (element.id == params) {
29 | boolean = true;
30 | }
31 | });
32 | return boolean;
33 | }
34 |
35 | // convert questions to json
36 | function question_format(params) {
37 | for (let i = 0; i < params.length; i++) {
38 | const element = params[i];
39 | params[i].questions = JSON.parse(element.questions);
40 | }
41 |
42 | return params;
43 | }
44 |
45 | function check_group_user(params) {
46 | var boolean = false;
47 | params.listStudentByGroups.forEach((element) => {
48 | if (element.id == USER_INFOR.userId) {
49 | boolean = true;
50 | // console.log(params)
51 | }
52 | });
53 | return boolean;
54 | }
55 |
56 | function group_have_user(params) {
57 | var team = [];
58 | params.forEach((group) => {
59 | console.log("group: ", group);
60 |
61 | // return group.listStudentByGroups;
62 | group.listStudentByGroups.forEach((element) => {
63 | if (element.id == USER_INFOR.userId) {
64 | team = group;
65 | console.log(team);
66 | }
67 | });
68 | });
69 |
70 |
71 | return {
72 | listStudentByGroups: team.listStudentByGroups,
73 | classroomSessionId: team.classroomSessionId,
74 | groupId: team.id,
75 | };
76 | }
77 |
78 | function format_grade_teammates(
79 | groups,
80 | privateCqId,
81 | classroomSessionId,
82 | groupId
83 | ) {
84 | // console.log(params);
85 | // console.log(privateCqId, classroomSessionId, groupId);
86 | user_group = group_have_user(groups);
87 | var teamlist = user_group.listStudentByGroups;
88 | var team_classroomSessionId = user_group.classroomSessionId;
89 | var team_groupId = user_group.groupId;
90 | console.log("user_group: ", user_group);
91 | console.log("teamlist: ", teamlist);
92 | console.log("teamlist: ", teamlist.length);
93 |
94 | // var teamlist = params;
95 | var newParams = [];
96 |
97 | for (let index = 0; index < teamlist.length; index++) {
98 | if (teamlist[index].id != USER_INFOR.userId) {
99 | console.log("user_in_teamlist", teamlist[index]);
100 | console.log(privateCqId, classroomSessionId);
101 |
102 | newParams.push({
103 | id: 539319,
104 | hardWorking: 5,
105 | goodKnowledge: 5,
106 | teamWorking: 5,
107 | userIsGraded: teamlist[index].id ? teamlist[index].id : 0,
108 | groupId: team_groupId ? team_groupId : 0,
109 | privateCqId: privateCqId,
110 | classroomSessionId: team_classroomSessionId ? team_classroomSessionId : 0,
111 | userIsGradedId: teamlist[index].id ? teamlist[index].id : 0,
112 | });
113 | }
114 | }
115 |
116 | console.log("newparams: ", newParams);
117 | // console.log("newparams: \n\n\n\n\n\n\n\n\n" , newParams.length);
118 | return newParams;
119 | }
120 |
121 | //call update api from github
122 | function update_api() {
123 | const ans = get_api({
124 | url: "https://raw.githubusercontent.com/khengyun/autonext/main/background_script/apicallpack.json",
125 | });
126 | ans.then((data) => {
127 | API = data;
128 | console.log(API);
129 | });
130 | }
131 |
132 | // declare mess to post to popup script
133 | function messtopopup(params) {
134 | chrome.runtime.sendMessage({
135 | message: params.message,
136 | type: params.type,
137 | });
138 | }
139 | // declare mess to post to popup script
140 | function messtocontent(params, token) {
141 | chrome.tabs.sendMessage(params.tabId, {
142 | token: token,
143 | details: params,
144 | });
145 | }
146 |
147 | // background script listen message from popup script and content script
148 | chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
149 | // console.log(request);
150 | if (request.type == "content_to_background") {
151 | const ans = post_api({
152 | url: `https://fugw-edunext.fpt.edu.vn/api/auth/token`,
153 | });
154 | ans.then((data) => {
155 | // console.log(data)
156 | messtopopup({ type: "background", message: data.data });
157 | });
158 | }
159 | if (request.type == "popup_to_background") {
160 | const ans = post_api({
161 | url: `https://fugw-edunext.fpt.edu.vn/api/auth/token`,
162 | });
163 | ans.then((data) => {
164 | // console.log(data)
165 | messtopopup({ type: "background", message: data.data });
166 | });
167 | }
168 | });
169 |
--------------------------------------------------------------------------------
/background_script/background.js:
--------------------------------------------------------------------------------
1 | console.log("background.js");
2 | importScripts("api.js");
3 | importScripts("helpui.js");
4 | update_api();
5 |
6 | function get_grade_group(params) {
7 | privateCqId = params.privateCqId;
8 | classroomSessionId = params.classroomSessionId;
9 | roundId = params.roundId;
10 | presentGroupId = params.presentGroupId;
11 | presentGroupName = params.presentGroupName;
12 | reviewGroupId = params.reviewGroupId;
13 | reviewGroupName = params.reviewGroupName;
14 |
15 | const listgroup = post_api({
16 | url: `${API.list_group}${classroomSessionId}`,
17 | });
18 |
19 | // Handle the response from the API.
20 | listgroup
21 | .then((groups) => {
22 | user_group = group_have_user(groups);
23 | teamlist = user_group.listStudentByGroups;
24 | team_classroomSessionId = user_group.classroomSessionId;
25 | team_groupId = user_group.groupId;
26 |
27 | post_present = post_api({
28 | url: `${API.grading_group}`,
29 | body: format_grade_present({
30 | classroomSessionId: team_classroomSessionId,
31 | roundId: roundId,
32 | presentGroupId: presentGroupId,
33 | privateCqId: privateCqId,
34 | }),
35 | });
36 | post_present
37 | .then((data) => {
38 | console.log(data);
39 | })
40 | .catch((e) => {
41 | console.log(e);
42 | });
43 | })
44 | .catch((e) => {
45 | console.log({
46 | error: `${e}`,
47 | message: `${API.list_group}${course.classroomSessionId}`,
48 | });
49 | });
50 |
51 | // ans = post_api({
52 | // url: `https://fugw-edunext.fpt.edu.vn:8443/api/v1/grade/get-grade-group`,
53 | // body: {
54 | // classroomSessionId: classroomSessionId,
55 | // privateCqId: privateCqId,
56 | // roundId: roundId,
57 | // }
58 | // })
59 | // ans.then((data) => {
60 |
61 | // })
62 |
63 | // console.log(privateCqId, classroomSessionId, roundId, presentGroupId, presentGroupName, reviewGroupId, reviewGroupName)
64 | }
65 |
66 | function get_round_for_grading(params) {
67 | ans = get_api({
68 | url: `${API.round}${params}`,
69 | });
70 | ans
71 | .then((data) => {
72 | // console.log(data.datacqDetail)
73 | console.log(data.data);
74 | data.data.forEach((datum) => {
75 | get_grade_group(datum);
76 | });
77 |
78 | })
79 | .catch((e) => {
80 | console.log(e);
81 | });
82 | }
83 |
84 | function grade_teammates(groups, privateCqId, classroomSessionId, groupId) {
85 | console.log("groupsooo: ", groups);
86 | // console.log(params);
87 | const ans = post_api({
88 | url: `${API.grade_teammates}`,
89 | body: {
90 | gradeTeammatesList: format_grade_teammates(
91 | groups,
92 | privateCqId,
93 | classroomSessionId,
94 | groupId
95 | ),
96 | },
97 | });
98 | ans
99 | .then((data) => {})
100 | .catch((e) => {
101 | console.log("catch: ", {
102 | gradeTeammatesList: format_grade_teammates(
103 | groups,
104 | privateCqId,
105 | classroomSessionId,
106 | groupId
107 | ),
108 | });
109 | console.log({
110 | error: `${e}`,
111 | message: `${API.grade_teammates}`,
112 | });
113 | });
114 | }
115 |
116 | function get_grade(params, groups) {
117 | // param = {"privateCqId":privateCqId,"sessionId":sessionId,"groupId":groupID}
118 | privateCqId = params.privateCqId;
119 | sessionId = params.sessionId;
120 | groupId = params.groupId;
121 | console.log("get_grade: ", groups, params);
122 | grade_teammates(groups, privateCqId, sessionId, groupId);
123 | get_round_for_grading(privateCqId);
124 | }
125 |
126 | // This function lists all the groups in a classroom.
127 | // Iterate over all the courses in the USER_COURSE array.
128 | function list_group(params) {
129 | console.log("some thing here");
130 | // Get the current course.
131 | const element = params;
132 |
133 | // Iterate over all the courses in the current course.
134 | for (let j = 0; j < element.courseList.length; j++) {
135 | // Get the current course.
136 | var course = element.courseList[j];
137 |
138 | // Get the classroom session ID for the current course.
139 | classroomSessionId = course.classroomSessionId;
140 |
141 | // Iterate over all the questions in the current course.
142 | for (let k = 0; k < course.questions.length; k++) {
143 | // console.log(element2.questions[k]);
144 | const privateCqId = course.questions[k].privateCqId;
145 | const sessionId = course.questions[k].sessionId;
146 |
147 | // Post a request to the API to get the list of groups for the current course.
148 | const ans = post_api({
149 | url: `${API.list_group}${course.classroomSessionId}`,
150 | });
151 |
152 | // Handle the response from the API.
153 | ans
154 | .then((groups) => {
155 | get_grade(
156 | {
157 | privateCqId: privateCqId,
158 | sessionId: sessionId,
159 | groupId: 12345678,
160 | },
161 | groups
162 | );
163 |
164 | // Iterate over the groups in the response.
165 | })
166 | .then(() => {})
167 | .catch((e) => {
168 | console.log({
169 | error: `${e}`,
170 | message: `${API.list_group}${course.classroomSessionId}`,
171 | });
172 | });
173 | }
174 | }
175 | }
176 |
177 | function course_detail(params) {
178 | //load course detail
179 | for (let i = 0; i < USER_CLASS.length; i++) {
180 | const element = USER_CLASS[i];
181 | const ans = get_api({
182 | url: `${API.course_detail[0]}${element.id}${API.course_detail[1]}`,
183 | });
184 | ans
185 | .then((data) => {
186 | // console.log(data.data)
187 | console.log(
188 | USER_CLASS.length >= USER_COURSE.length,
189 | check_course_list(USER_CLASS[i].id)
190 | );
191 | if (
192 | USER_CLASS.length >= USER_COURSE.length &&
193 | check_course_list(USER_CLASS[i].id) == false
194 | ) {
195 | let format = {
196 | className: USER_CLASS[i].className,
197 | id: USER_CLASS[i].id,
198 | courseCode: USER_CLASS[i].courseCode,
199 | courseTitle: USER_CLASS[i].courseTitle,
200 | courseId: USER_CLASS[i].courseId,
201 | courseList: question_format(data.data),
202 | };
203 | USER_COURSE.push(format);
204 | }
205 | // console.log(USER_COURSE);
206 | })
207 | .then(() => {
208 | // question_detail()
209 | console.log("log here");
210 | console.log(USER_COURSE);
211 | list_group(USER_COURSE[i]);
212 | console.log("haha");
213 | })
214 | .catch((e) => {
215 | console.log({
216 | error: `${e}`,
217 | message: `${API.course_detail[0]}${element.id}${API.course_detail[1]}`,
218 | });
219 | });
220 | }
221 | }
222 |
223 | function class_infor() {
224 | for (let i = 0; i < USER_SUBJECTS.length; i++) {
225 | const element = USER_SUBJECTS[i];
226 | const ans = get_api({
227 | url: `${API.class_info}${element.classId}`,
228 | });
229 | ans
230 | .then((data) => {
231 | // console.log(data.data)
232 | if (USER_CLASS.length <= 2) {
233 | USER_CLASS.push(data.data);
234 | course_detail();
235 | }
236 | })
237 | .catch((e) => {
238 | console.log({
239 | error: `${e}`,
240 | message: `${API.class_info}${element.classId}`,
241 | });
242 | });
243 | }
244 | }
245 |
246 | function subjects_in_the_semester(params) {
247 | const ans = get_api({
248 | url: `${API.semester[0]}${USER_INFOR.userId}${API.semester[1]}${params}`,
249 | });
250 | ans
251 | .then((data) => {
252 | USER_SUBJECTS = data;
253 | // console.log(USER_SUBJECTS)
254 | class_infor();
255 | })
256 | .catch((e) => {
257 | console.log({
258 | error: `${e}`,
259 | message: `${API.semester[0]}${USER_INFOR.userId}${API.semester[1]}${params}`,
260 | });
261 | });
262 | }
263 |
264 | chrome.webRequest.onBeforeSendHeaders.addListener(
265 | function (details) {
266 | // initiator
267 | if (details.initiator == "https://fu-edunext.fpt.edu.vn") {
268 | const token = details.requestHeaders[2].value;
269 | if (token.includes("Bearer")) {
270 | TOKEN = token;
271 | // console.log(TOKEN);
272 | }
273 | //get token infor
274 | let ans = post_api(details);
275 | ans
276 | .then((data) => {
277 | USER_INFOR = data.data;
278 | console.log(USER_INFOR);
279 |
280 | subjects_in_the_semester("DEFAULT");
281 | //background
282 |
283 | // send mess from background script to popup script
284 | messtopopup({ type: "background", message: USER_INFOR });
285 | //send mess from background script to content script
286 | messtocontent(details, token);
287 | })
288 | .catch((e) => {
289 | console.log(e.message);
290 | });
291 | }
292 | },
293 | {
294 | urls: [
295 | `https://fugw-edunext.fpt.edu.vn/api/auth/token`,
296 | `https://fugw-edunext.fpt.edu.vn:8443/api/auth/token`,
297 | ],
298 | },
299 | ["requestHeaders"]
300 | );
301 |
--------------------------------------------------------------------------------
/popup/popup.css:
--------------------------------------------------------------------------------
1 | body {
2 | min-width: 400px;
3 | min-height: 60px;
4 | background-color: #ffffff;
5 | }
6 |
7 | .input-group {
8 | margin-top: 30px;
9 | margin-bottom: 30px;
10 | }
11 |
12 | .input-group-addon {
13 | border: none;
14 | }
15 |
16 |
17 | .copied {
18 | float: right;
19 | display: none;
20 | }
21 |
22 | image {
23 | display: inline-block;
24 | }
25 |
26 | .title {
27 |
28 | padding-left: 10px;
29 | display: inline-block;
30 | font-weight: bold;
31 | cursor: context-menu;
32 |
33 | }
34 |
35 | .text {
36 | color: white;
37 | font-size: 20px;
38 | position: absolute;
39 | top: 50%;
40 | left: 50%;
41 | transform: translate(-50%, -50%);
42 | -ms-transform: translate(-50%, -50%);
43 | white-space: nowrap;
44 | }
45 |
46 | .svg-inline--fa {
47 | vertical-align: -0.2em;
48 | }
49 |
50 | .rounded-social-buttons {
51 | text-align: center;
52 | }
53 |
54 | .rounded-social-buttons .social-button {
55 | display: inline-block;
56 | position: relative;
57 | cursor: pointer;
58 | width: 2.125rem;
59 | height: 2.125rem;
60 | border: 0.125rem solid transparent;
61 | padding: 0;
62 | text-decoration: none;
63 | text-align: center;
64 | color: #fefefe;
65 | font-weight: normal;
66 | border-radius: 0.3rem;
67 | transition: all 0.5s ease;
68 | margin-right: 0.25rem;
69 | margin-bottom: 0.25rem;
70 | }
71 |
72 | .rounded-social-buttons .social-button:hover,
73 | .rounded-social-buttons .social-button:focus {
74 | -webkit-transform: rotate(360deg);
75 | -ms-transform: rotate(360deg);
76 | transform: rotate(360deg);
77 | }
78 |
79 | .rounded-social-buttons .fa-facebook,
80 | .fa-github {
81 | padding-top: 3px;
82 | font-size: 25px;
83 | }
84 |
85 | .rounded-social-buttons .social-button.facebook {
86 | background: #3b5998;
87 | }
88 |
89 | .rounded-social-buttons .social-button.facebook:hover,
90 | .rounded-social-buttons .social-button.facebook:focus {
91 | color: #3b5998;
92 | background: #fefefe;
93 | border-color: #3b5998;
94 | }
95 |
96 | .rounded-social-buttons .social-button.youtube {
97 | background: #000000;
98 | }
99 |
100 | .rounded-social-buttons .social-button.youtube:hover,
101 | .rounded-social-buttons .social-button.youtube:focus {
102 | color: #000000;
103 | background: #fefefe;
104 | border-color: #000000;
105 | }
106 |
107 | .container {
108 | min-height: 75px;
109 | border-bottom: solid 1px rgba(163, 163, 163, 0.3);
110 | display: flex;
111 | justify-content: center;
112 | align-items: center;
113 | }
114 |
115 | footer {
116 | padding-top: 10px;
117 | padding-bottom: 10px;
118 | }
119 |
120 | #copyButton {
121 | border-radius: 3px 0 0 3px;
122 | }
123 |
124 | .alert {
125 | margin-top: 15px;
126 | }
127 |
128 | .titleContainer {
129 | min-height: 80px;
130 | border-bottom: solid 1px rgba(163, 163, 163, 0.3);
131 | display: flex;
132 | align-items: center;
133 | justify-content: space-between;
134 | padding-right: 28px;
135 | padding-top: 5px;
136 | }
137 |
138 | .title_header {
139 |
140 | margin-inline-start: 20px;
141 | height: auto;
142 | }
143 |
144 | .image_logo {
145 | padding-bottom: 10px;
146 | }
147 |
148 | .title {
149 | margin: auto;
150 | }
151 |
152 |
153 | /*!*css doc*!*/
154 |
155 | .loader {
156 |
157 |
158 | border: 16px solid #f3f3f3;
159 | border-radius: 50%;
160 | border-top: 16px solid #3498db;
161 | width: 120px;
162 | height: 120px;
163 | -webkit-animation: spin 2s linear infinite; /* Safari */
164 | animation: spin 2s linear infinite;
165 | }
166 |
167 | .button_setting{
168 | width: 100%;
169 | }
170 | .button_on_off_box{
171 | width: 35px;
172 | height: 35px;
173 | }
174 |
175 | #button_on_off{
176 | fill: rgb(194, 194, 194)
177 | }
178 |
179 | [data-c-tooltip] {
180 | position: relative;
181 | cursor: pointer;
182 | }
183 | /* Base styles for the entire c-tooltip */
184 |
185 |
186 | [data-c-tooltip]:before,
187 | [data-c-tooltip]:after {
188 | position: absolute;
189 | visibility: hidden;
190 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
191 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
192 | opacity: 0;
193 | -webkit-transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, -webkit-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
194 | -moz-transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, -moz-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
195 | transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
196 | -webkit-transform: translate3d(0, 0, 0);
197 | -moz-transform: translate3d(0, 0, 0);
198 | transform: translate3d(0, 0, 0);
199 | pointer-events: none;
200 | }
201 | /* Show the entire c-tooltip on hover and focus */
202 | [data-c-tooltip]:hover:before,
203 | [data-c-tooltip]:hover:after,
204 | [data-c-tooltip]:focus:before,
205 | [data-c-tooltip]:focus:after {
206 | visibility: visible;
207 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
208 | filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
209 | opacity: 1;
210 | }
211 | /* Base styles for the c-tooltip's directional arrow */
212 | [data-c-tooltip]:before {
213 | z-index: 1001;
214 | border: 6px solid transparent;
215 | background: transparent;
216 | content: "";
217 |
218 | }
219 | /* Base styles for the c-tooltip's content area */
220 | [data-c-tooltip]:after {
221 | z-index: 1000;
222 | padding: 8px;
223 | /*width: 160px;*/
224 | background-color: #000;
225 | background-color: rgba(51, 51, 51, 0.9);
226 | color: #fff;
227 | content: attr(data-c-tooltip);
228 | font-size: 14px;
229 | line-height: 1.2;
230 | text-align: center;
231 | width: 50px;
232 | height: auto;
233 | border-radius: 3px;
234 | }
235 | /* Directions */
236 | /* Top (default) */
237 | [data-c-tooltip]:before,
238 | [data-c-tooltip]:after {
239 | bottom: 100%;
240 | left: 50%;
241 | }
242 | [data-c-tooltip]:before{
243 | margin-left: -6px;
244 | margin-bottom: -12px;
245 | border-top-color: #000;
246 | border-top-color: rgba(51, 51, 51, 0.9);
247 | }
248 | /* Horizontally align top/bottom c-tooltips */
249 | [data-c-tooltip]:after {
250 | margin-left: -80px;
251 | }
252 | [data-c-tooltip]:hover:before,
253 | [data-c-tooltip]:hover:after,
254 | [data-c-tooltip]:focus:before,
255 | [data-c-tooltip]:focus:after{
256 | -webkit-transform: translateY(-12px);
257 | -moz-transform: translateY(-12px);
258 | transform: translateY(-12px);
259 | }
260 |
261 | /* Left */
262 | [tooltip-position='left']:before,
263 | [tooltip-position='left']:after {
264 | right: 100%;
265 | bottom: 50%;
266 | left: auto;
267 | }
268 | [tooltip-position='left']:before {
269 | margin-left: 0;
270 | margin-right: -12px;
271 | margin-bottom: 0;
272 | border-top-color: transparent;
273 | border-left-color: #000;
274 | border-left-color: rgba(51, 51, 51, 0.9);
275 | }
276 | [tooltip-position='left']:hover:before,
277 | [tooltip-position='left']:hover:after,
278 | [tooltip-position='left']:focus:before,
279 | [tooltip-position='left']:focus:after {
280 | -webkit-transform: translateX(-12px);
281 | -moz-transform: translateX(-12px);
282 | transform: translateX(-12px);
283 | }
284 | /* Bottom */
285 | [tooltip-position='bottom']:before,
286 | [tooltip-position='bottom']:after {
287 | top: 100%;
288 | bottom: auto;
289 | left: 50%;
290 | }
291 | [tooltip-position='bottom']:before {
292 | margin-top: -12px;
293 | margin-bottom: 0;
294 | border-top-color: transparent;
295 | border-bottom-color: #000;
296 | border-bottom-color: rgba(51, 51, 51, 0.9);
297 | }
298 | [tooltip-position='bottom']:hover:before,
299 | [tooltip-position='bottom']:hover:after,
300 | [tooltip-position='bottom']:focus:before,
301 | [tooltip-position='bottom']:focus:after {
302 | -webkit-transform: translateY(12px);
303 | -moz-transform: translateY(12px);
304 | transform: translateY(12px);
305 | }
306 | /* Right */
307 | [tooltip-position='right']:before,
308 | [tooltip-position='right']:after {
309 | bottom: 50%;
310 | left: 100%;
311 | }
312 | [tooltip-position='right']:before {
313 | margin-bottom: 0;
314 | margin-left: -12px;
315 | border-top-color: transparent;
316 | border-right-color: #000;
317 | border-right-color: rgba(51, 51, 51, 0.9);
318 | }
319 | [tooltip-position='right']:hover:before,
320 | [tooltip-position='right']:hover:after,
321 | [tooltip-position='right']:focus:before,
322 | [tooltip-position='right']:focus:after {
323 | -webkit-transform: translateX(12px);
324 | -moz-transform: translateX(12px);
325 | transform: translateX(12px);
326 | }
327 | /* Move directional arrows down a bit for left/right c-tooltips */
328 | [tooltip-position='left']:before,
329 | [tooltip-position='right']:before {
330 | top: 3px;
331 | }
332 | /* Vertically center c-tooltip content for left/right c-tooltips */
333 | [tooltip-position='left']:after,
334 | [tooltip-position='right']:after {
335 | margin-left: 0;
336 | margin-bottom: -16px;
337 | }
338 |
339 | #version{
340 | position: absolute;
341 | right: 20px;
342 | /* left: 5px; */
343 | font-size: small;
344 | cursor: context-menu;
345 | text-align: center;
346 | padding: 5px;
347 | color: #000000;
348 | font-weight: bold;
349 | }
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------