# How To Contribute

Here is a description of how to contribute. I am not a software engineer, JavaScript developer, or programmer (and I do not plan to become one), so please be understanding of any bugs or unorganized parts.


---

## Table of Contents

* [Codebase Structure](#codebase-structure)
* [Add Useful Link](#add-useful-link)
* [Create New Plugin](#create-new-plugin)
* [Edit Plugin](#edit-plugin)
* [Change Extension Logic](#change-extension-logic)
* [Build](#build)
* [Testing](#testing)
* [Roadmap](#roadmap)
* [Become Maintainer](#maintainer)


## Terms and Definitions

* `plugin` - Single-file Immediately Invoked Function Expression (IIFE) script that performs some functionality on certain URLs. For example, gened-plugin or courses-plugin. Such plugins MUST be compatible to work both with Tampermonkey and inside extensions (for both Firefox and Chrome).
* `extension` - The actual extension in Chrome and add-on in Firefox, which can then be installed.
* `[NAME]` - Choose a name for a new plugin, for example `myplugin`. In the text, it will be referred to using the `[NAME]` syntax.


---





# Codebase Structure

Here is a description of how the code is structured and what each item is in the root folder of the project and its subfolders.


- `LICENSE.md` - License file that defines the license. Currently, it is GNU GPL Version 3. If you have a better option, please let me know.
- `README.md` - Here is a description of the project for GitHub.
- `index.html` - Static HTML file for GitHub Pages, which serves as the homepage for this project.
- `CONTRIBUTING.md` - This file describes the structure of the codebase and the rules for contributing.

- `Makefile` - This forms the actual project. What it does is simply call two separate Makefiles in different folders. The paths for these Makefiles are `src/extension/Makefile` and `tampermonkey/Makefile`.

- `src/` - Here is the source of the project and all scripts and extension building files are here.
    - `scripts/` - This is the actual one-function-script plugin's location where these scripts are stored, and in other locations, scripts from here are just copied.
    - `static/` - Here must be placed files for index.html and that provide functionality for GitHub Pages (like styles, other HTML files, or scripts).
    
    - `extension/` - Here are stored all files required for building the extension for both Firefox and Chrome.
        - `Makefile` - Generates Chrome-compatible and separately Firefox-compatible sources and also generates archives (.zip) for them. Read more in README.md.
        - `src/` - Here is the source of the extension, but it can't be directly used in any browser and must be built using make, which will select browser-compatible parts.

- `tampermonkey/` - This is a special folder for Tampermonkey scripts, which are automatically generated by combining the `tampermonkey/metadata/some-plugin` metadata with `src/scripts/some-plugin.js`. That combination is done with the Makefile. Also, scripts can auto-update from raw GitHub files stored in the `tampermonkey/output/scripts` subfolder.
    - `README.md` - Provides more detailed information on how this folder is used.
    - `Makefile` - Generates Tampermonkey-compatible scripts by combining metadata with the original scripts and recreates the `tampermonkey/output` folder with the newest scripts.
    - `metadata/` - Path where metadata for each single-function-script plugin is stored.
    - `output/scripts/` - Stores the plugin's raw scripts to allow loading them using Tampermonkey.





# Add Useful Link 

First of all, you must really consider whether the link is useful or not, because it often solves a problem for you but creates a problem for others. If you are sure the link is actually useful for AUA students and you have asked your friends, then we can continue further.

If you are not programmer or you do not have enough time just send that useful link to my telegram and I will add it :)

But to add in the code you need to do the following steps.

1. Open the file `src/extension/popup/popup.js` in any IDE or text editor.

2. Locate an object named as `usefulLinks` and add there your useful link. You can change the order but plese consider others' opinions too. 

- name - The visible name that will be displayed in extension's popup.
- url - The url that it will open (the useful link)
- image - If you think that in place of AUA icon it would be better to put some special image then you are welcome, but again consider that it will take time and resources to load.

```js
// List of useful links to show in popup
const usefulLinks = [
        {
                name: "AUA General Education",
                url: "https://gened.aua.am/courses-and-their-clusters/",
                image: "",
        },
        {
                name: "AUA Courses",
                url: "https://auasonis.jenzabarcloud.com/GENSRsC.cfm",
                image: "",
        },
        {
```




# Create New Plugin

Here are described steps what you need to do to create new plugin which is single-function-script file.

1. Go to `src/scripts` path and create a plugin named like this: `SomeUniqueName-plugin.js`. For example there exists now `courses-plugin.js` and `gened-plugin.js`. The simpler you name it the simpler will be for everyone.

2. Inside it create a Immediately Invoked Function Expressions (IIFE) which is a special function in javascript which calls itself. Here is an example:

```js
(function () {
    // Your code here
})();
```

Please do not write anything outside it and do all javascript, HTML and CSS modifications directly inside that function. Maybe that will work if we put something outside but for compatibility and for portability it is better to seperate it from everything with one js function block.

3. Go to `tampermonkey/` folder and create there file named EXACTLY same as you named in `src/scripts` but WITHOUT `.js` after it. Then you need to put tampermonkey metadata inside it. You can just copy paste it from other plugins and just change uncompatible parameters. Here is an example.

```js

// ==UserScript==
// @name         AUA Gened Plugin
// @namespace    https://github.com/rezocrypt/aua-utils/
// @version      1.0.0
// @description  AUA GenEd Plugin helps you find general education courses by keyword, theme, or level.
// @match        https://gened.aua.am/courses-and-their-clusters/
// @run-at       document-end
// @grant        none
// @icon         https://aua.am/favicon.ico
// @author       rezocrypt
// @supportURL   https://t.me/rezocrypt
// @updateURL    https://github.com/rezocrypt/aua-utils/blob/main/tampermonkey/output/scripts/gened-plugin.js
// @downloadURL  https://github.com/rezocrypt/aua-utils/blob/main/tampermonkey/output/scripts/gened-plugin.js
// @license      GPL-3.0
// ==/UserScript==

```

Also in `all-plugins.js` you need to add the line similar to other plugins, which will let Tampermonkey to install your plugin when someone installs all plugins.

```js
// @require      https://raw.githubusercontent.com/rezocrypt/aua-utils/refs/heads/main/tampermonkey/output/scripts/courses-plugin.js
// @require      https://raw.githubusercontent.com/rezocrypt/aua-utils/refs/heads/main/tampermonkey/output/scripts/gened-plugin.js
// @require      https://raw.githubusercontent.com/rezocrypt/aua-utils/refs/heads/main/tampermonkey/output/scripts/[NAME]-plugin.js
```


Remember, this will be added to JavaScript, so it must use this comment-like structure and NOTHING ELSE. Also, it is good practice to add one new line at the end, because later it will be combined directly with the script that follows.

4. Go to `src/extension/src/` folder. 

In `manifestChrome.json` add the url (with * after if it needs to work with subpaths or you aren't sure that there are no subpaths) in hostPermissions.

```json
  "host_permissions": [
    "https://gened.aua.am/*",
    "https://auasonis.jenzabarcloud.com/*",
    "[YOUR URL]"
  ],
```

In `manifestFirefox.json` add the url with the same principle in permissions field (please add in the end).

```json
  "permissions": [
    "tabs",
    "storage",
    "https://gened.aua.am/*",
    "https://auasonis.jenzabarcloud.com/*",
    "[YOUR URL]"
  ],
```

5. Go to `src/extension/src/popup/` folder.

Open `popup.html` and add there a `<div>` element with corresponding id structure like in the example below. Do not forget to put id as in the example.

```html
<!-- ----- Plugins Controllers ----- -->
<div class="pluginsTitle">Enable / Disable Plugins</div>
<div id="pluginControllersContainer">
        <div id="coursesController" class="pluginController">
                Courses Plugin
        </div>

        <div id="[NAME]Controller" class="pluginController">
                [NAME] Plugin
        </div>
</div>
```

Open `popup.js` and edit this object and add there your plugin name like follows: `[NAME]Controller: "[NAME]-plugin"`. That `[NAME-PLUGIN` is used as a referrance for finding in browsers local storage (which is created by extension) weather the plugin is disabled or enabled and later to disable and enable it. 

```js
const pluginControllerMap = {
        genedController: "gened-plugin",
        coursesController: "courses-plugin",
        [NAME]Controller: "[NAME]-plugin",
};
```

6. Go to `src/extension/src/background/` folder.

Open `background.js` file and find the `PLUGINS` object. Add there your plugin as object like in the example below.

```js
// Maps plugin names to their matching URL patterns and script files
const PLUGINS = {
        "gened-plugin": {
                matches: [
                        "https://gened.aua.am/courses-and-their-clusters",
                        "https://gened.aua.am/courses-and-their-clusters/",
                ],
                file: "scripts/gened-plugin.js",
        },
        "[NAME]-plugin": {
                matches: [
                        "[YOUR MATCHING URL 1]",
                        "[OTHER MATCHING URL IF EXISTS]",
                ],
                file: "scripts/[NAME]-plugin.js",
        }
}
```

7. Now it is ready (at least I think so). To be honest, I just collected steps that I did and I haven't done something like this step by step but please if you find any problem just contact me and we will solve any problem as fast as possible. I am actually bad from software engineering). 

Now what you need to do is to enter the cicle `BUILD -> TEST -> BUILD -> TEST -> ... -> TEST -> BUILD -> PUBLISH`.

- Go to [Build Section](#build) to see how to build.
- Go to [Testing Section](#testing) to see how to test what you have build.


8. When logic will be ready please add also some description to the README.md and in Github Pages index.html file which will explain for what is you plugin and how to use it.


Please test multiple times with multiple browsers and computers to save time for all of us. And finally if it is ready do `git push` (yes you need to build before pushing and it is okay that outputs will be included). And if I won't see your commit during few days just write me in telegram. 





# Edit Plugin

To edit plugin you need to do the following steps.

1. Go to the directory `src/scripts/` and find there the plugin which you want to edit. Each plugin is single file named as `[NAME]-plugin.js`.

2. Inside that file you will see Immediately Invoked Function Expressions (IIFE) and all code is inside it for that plugin, and NOWHERE ELSE. Do the changes that you want.

3. Then you need to build and test and build and test until you will get the final result. 

- Here is how to [Build](build)
- Here is how to [Test](test)





# Change Extension Logic

To change extension logic you need to go `src/extension/src` folder.

- There is `popup` folder for window which is opened when the extension icon in browser tab is clicked (not the plugins). 
- In `background` folder there is stored background.js which is reponsible for installation setup and loading plugins.





# Build

To finally generate tampermonkey scripts and extensions run the following command in the root of codebase. It copies your plugin scripts to tampermonkey and extension source destination and creates sources both for Firefox and Chrome (not enough money and energy for Apple Developer Account for Safari).

```bash
make all
```





# Testing

Here is how you can test in different browsers and also using tampermonkey. You NEED to build before testing. See [Build Section](#build)

## Chrome

1. Open your chrome browser.

2. Enter the string `chrome://extensions/` in URL section.

3. On the left top side find `Load Unpacked` button and click to it. Navigate to the folder of aua-utils and select the following path: 

`[aua-utils-path]/src/extension/output/chrome-source/`

Then if everything is okay it will appear as a new extension and you can manipulate and work with it. When you do some changes in files chrome automatically reloads the plugin and you see the final state (but you can do it manually, sometimes it glitches).THIS had nothing to do with Build, you need to build after every even minor change. Sorry, thats what I could. Also if you do changes in background.js and such changes that it will change the structure stored in browser's local storage it is recommended to remove and add that plugin again.


## Firefox

1. Open your firefox browser.

2. Enter the string `about:debugging#/runtime/this-firefox` in URL section.

3. In the top-middle part find a button `Load Temporary Add-on...` and click to it. Navigate to the folder of aua-utils and select the following path:

`[aua-utils-path]/src/extension/output/firefox-source/`

Then if everything is okay it will appear as a new extension and you can manipulate and work with it. Firefox doesn't AUTOMATICALLY apply changes when you change something in your codebase. So you need to MANUALLY reload it from the same url that you entered for adding plugin.


## Tampermonkey

This works also for **Safari**. Do not forget to run [Build](#build) before doing this.

1. I assume you have preinstalled Tampermonkey which is very easy, just go your browsers extension store and install it.

2. Click to tampermonkey plugin in toolbar and then click to `Dashboard` option. It will open new window where you can add and test your script.

3. Press `[+]` button in the top right corner near `Installed Userscripts` button. 

4. Go to the directory `tampermonkey/output/scripts/` and you must see there `[NAME]-plugin.js`. Open the following file, copy its content and paste it into the new opened window in Tampermonkey dashboard. 

5. Then press [CONTROL] + [S] to save the script or just File -> Save.

6. Make sure that plugin is enabled by clicking the plugin icon in browser's toolbar. If it is disabled then enable it.

7. Then go to you matching url and test weather it is working correctly.





# Roadmap

## Planned Features

Here are listed some planned features which I (or others) will add as soon as possible.

### Courses Plugin

- [ ] A better schedule icon if possible.

### Other

- [ ] Create some class review platform (telegram bot or maybe even hosted website) to give recommendation to class (or vise versa).

## Known Issues
- [ ] The project itself lacks icon, so if someone can create a beautiful icon for the project aua-utils I would be very happy.
- [ ] Please be careful when selecting general education courses because it doesn't perform 100% course-gened match.
- [ ] There may be some grammatical mistakes in the documentation. If someone is proficient in English—or simply notices an error—please let me know. I am not very good at English either, but I am happy that I scored 94 on the TOEFL :)
- [ ] I think there is need for normal youtube tutorial videos so if someone can record and send it to me I would be very grateful.
- [ ] I have never tested for Safari and Opera so if someone will test (and even record video for YouTube) it would be very helpful for the project.





# Maintainer

I tried my best to create a well-organized and as simple as possible codebase, but you can clearly see that I am not even a mid-level software engineer (and I am not planning to become one). So, if you see more potential, understand better what other plugins could make AUA students' lives easier, and are a skilled software engineer, please let me know. I would be happy to transfer the entire project to you, because it has the potential to scale to very large sizes, which I would be unable to maintain. Thank you very much!



