# GSOC'20 Result announced!

**URL:** <https://discourse.joplinapp.org/t/gsoc20-result-announced/8412>\
**Category:** Lounge\
**Created:** [4 May 2020 18:19 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412 "2020-05-04T18:19:01Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![kowalskidev](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/kowalskidev/32/2877_2.png) [@kowalskidev](https://discourse.joplinapp.org/u/kowalskidev)\
**Post date:** [4 May 2020 18:19 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/1 "2020-05-04T18:19:01Z")

</div>

Congratulations to the selected candidates!! Would you please mind sharing your proposal? So that we can learn from them which can help us to finely curate our proposal for next year.

P.S. Unfortunately I didn't got selected. Better luck next time 🙂  
To those who are not selected here is the another chance of contributing to open-source by [Major League Hacking](https://fellowship.mlh.io/students) similar to GSOC powered by GitHub.

---

<div class="post-metadata">

**Author:** ![giteshsharma](https://avatars.discourse-cdn.com/v4/letter/g/8baadc/32.png) [@giteshsharma](https://discourse.joplinapp.org/u/giteshsharma)\
**Post date:** [4 May 2020 18:45 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/2 "2020-05-04T18:45:26Z")

</div>

Congrats @anjulalk and @naviji for getting selected.

---

<div class="post-metadata">

**Author:** ![giteshsharma](https://avatars.discourse-cdn.com/v4/letter/g/8baadc/32.png) [@giteshsharma](https://discourse.joplinapp.org/u/giteshsharma)\
**Post date:** [4 May 2020 18:47 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/3 "2020-05-04T18:47:46Z")

</div>

> [@kowalskidev](#):
>
> Congratulations to the selected candidates!! Would you please mind sharing your proposal? So that we can learn from them which can help us to finely curate our proposal for next year.

I want to see it too and it will great if guys can share few tips too 😄

> [@kowalskidev](#):
>
> another chance of contributing to open-source by [Major League Hacking](https://fellowship.mlh.io/students) similar to GSOC powered by GitHub.

Thanks for sharing this buddy.

---

<div class="post-metadata">

**Author:** ![giteshsharma](https://avatars.discourse-cdn.com/v4/letter/g/8baadc/32.png) [@giteshsharma](https://discourse.joplinapp.org/u/giteshsharma)\
**Post date:** [4 May 2020 18:53 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/4 "2020-05-04T18:53:10Z")

</div>

@PackElend  
Let us know if Joplin apply for something like this in future. It will be great to join it.

> [@kowalskidev](#):
>
> [Major League Hacking](https://fellowship.mlh.io/students)

And Is Joplin applying for this?

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [5 May 2020 09:09 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/5 "2020-05-05T09:09:54Z")

</div>

GSoC is our very first program we are joining.  
GSoD would be second if Joplin gets accepted.

The idea is, that we may join other programs to but have to get certain things sorted first.  
We keep you posted

---

<div class="post-metadata">

**Author:** ![naviji](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/naviji/32/2502_2.png) [@naviji](https://discourse.joplinapp.org/u/naviji)\
**Post date:** [5 May 2020 11:12 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/6 "2020-05-05T11:12:42Z")

</div>

Here’s my proposal.

[Make Joplin’s Search Better.pdf](https://discourse.joplinapp.org/uploads/short-url/wZIAqPOLPVjov5ba8Dswj7qAOzt.pdf) (84.8 KB)

---

<div class="post-metadata">

**Author:** ![bisraelsen](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/bisraelsen/32/2697_2.png) [@bisraelsen](https://discourse.joplinapp.org/u/bisraelsen)\
**Post date:** [5 May 2020 12:42 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/7 "2020-05-05T12:42:56Z")

</div>

@naviji This has been something I’ve been hoping for. Thanks, and good luck!

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [5 May 2020 15:01 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/8 "2020-05-05T15:01:06Z")

</div>

> [@bisraelsen](#):
>
> This has been something I’ve been hoping for. Thanks, and good luck!

work will be public feel free to watch and comment 🙂

---

<div class="post-metadata">

**Author:** ![roman\_r\_m](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/roman_r_m/32/3297_2.png) [@roman\_r\_m](https://discourse.joplinapp.org/u/roman_r_m)\
**Post date:** [5 May 2020 15:18 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/9 "2020-05-05T15:18:32Z")

</div>

@naviji @anjulalk you can even combine your projects to provide search for commands function similar to how Sublime Text (Ctrl+Shift+P) or IntelliJ IDEA (Ctrl+Shift+A) do it.

Though Joplin does not have nearly that many commands. Not yet at least.

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [5 May 2020 15:35 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/10 "2020-05-05T15:35:34Z")

</div>

we still have to create the space for communication etc. but there is an official bonding period what will be used to bond with the community.  
We mentors have been in touch with them for weeks, so we quite good bonded 😁.

The project can be adapted to a certain degree but we have to ensure that all can be done within the timeline.  
It also relies on the community how the result shell looks like. If the student sees the capacity to extend the scope, why not.

---

<div class="post-metadata">

**Author:** ![naviji](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/naviji/32/2502_2.png) [@naviji](https://discourse.joplinapp.org/u/naviji)\
**Post date:** [5 May 2020 16:13 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/11 "2020-05-05T16:13:39Z")

</div>

> [@roman\_r\_m](#):
>
> search for commands function similar to how Sublime Text (Ctrl+Shift+P) or IntelliJ IDEA (Ctrl+Shift+A) do it.

This is something I want Joplin to have too. Though I can't promise it'll get done in GSOC, I'll help in whatever way I can.

---

<div class="post-metadata">

**Author:** ![kowalskidev](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/kowalskidev/32/2877_2.png) [@kowalskidev](https://discourse.joplinapp.org/u/kowalskidev)\
**Post date:** [5 May 2020 17:14 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/12 "2020-05-05T17:14:28Z")

</div>

> [@PackElend](#):
>
> we still have to create the space for communication etc. but there is an official bonding period what will be used to bond with the community.

I would suggest creating SLACK or DISCORD channel which is highly adopted by open-source organizations for more effective & real-time communication.

---

<div class="post-metadata">

**Author:** ![PackElend](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/packelend/32/488_2.png) [@PackElend](https://discourse.joplinapp.org/u/PackElend)\
**Post date:** [5 May 2020 17:34 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/13 "2020-05-05T17:34:58Z")

</div>

> [@kowalskidev](#):
>
> DISCORD

there is already a discord channel see [Joplin](https://joplinapp.org/#community)  
We have to talk about how to optimize communication so that information is not scattered around in multiple topics and tools plus that topics won't get super long that you don't know what is going on

---

<div class="post-metadata">

**Author:** ![kowalskidev](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/kowalskidev/32/2877_2.png) [@kowalskidev](https://discourse.joplinapp.org/u/kowalskidev)\
**Post date:** [5 May 2020 18:32 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/14 "2020-05-05T18:32:01Z")

</div>

> [@PackElend](#):
>
> there is already a discord channel see [Joplin](https://joplinapp.org/#community)

Okay I'll check it out.

---

<div class="post-metadata">

**Author:** ![anjulalk](https://avatars.discourse-cdn.com/v4/letter/a/c6cbf5/32.png) [@anjulalk](https://discourse.joplinapp.org/u/anjulalk)\
**Post date:** [6 May 2020 09:54 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/15 "2020-05-06T09:54:00Z")

</div>

Thank you! Here’s my [project proposal.pdf](https://discourse.joplinapp.org/uploads/short-url/vpFMc0coDCKPodmBFatepsdLGqZ.pdf) (190.2 KB)

---

<div class="post-metadata">

**Author:** ![anjulalk](https://avatars.discourse-cdn.com/v4/letter/a/c6cbf5/32.png) [@anjulalk](https://discourse.joplinapp.org/u/anjulalk)\
**Post date:** [6 May 2020 09:55 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/16 "2020-05-06T09:55:09Z")

</div>

> [@roman\_r\_m](#):
>
> @naviji @anjulalk you can even combine your projects to provide search for commands function similar to how Sublime Text (Ctrl+Shift+P) or IntelliJ IDEA (Ctrl+Shift+A) do it.

That'd be a great addition. We'll discuss it. Thank you!

---

<div class="post-metadata">

**Author:** ![coderrsid](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/coderrsid/32/2558_2.png) [@coderrsid](https://discourse.joplinapp.org/u/coderrsid)\
**Post date:** [7 May 2020 09:46 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/17 "2020-05-07T09:46:33Z")

</div>

Hey everyone! That was a great participation by everyone. I don't really know why mine didn't get selected too. Here's it is though 😛  
[coderrsid GSOC Proposal.docx](https://drive.google.com/file/d/1qpNEjq99vwet1hz01DjxMbj9z1C4tkB7/view?usp=sharing) (1.2 MB)

I guess because i didn't write 20 lines of code for testing feature on my machine which wouldn't be at all helpful in making this whole component 😁

---

<div class="post-metadata">

**Author:** ![RedDocMD](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/reddocmd/32/2655_2.png) [@RedDocMD](https://discourse.joplinapp.org/u/RedDocMD)\
**Post date:** [7 May 2020 17:59 UTC](https://discourse.joplinapp.org/t/gsoc20-result-announced/8412/18 "2020-05-07T17:59:46Z")

</div>

Hi everyone! This is my GSoC proposal on supporting multiple profiles. I didn't get selected though, probably because I didn't have enough PR's 😄

# Introduction

- Name: **Deep Majumder**

- Github handle: `RedDocMD`

- Email: `deep.majumder2019@gmail.com`

# Project

## Synopsis

I am interested in working on the following ideas for my GSoC  
project, taken from the ideas page of Joplin  
([https://joplinapp.org/gsoc2020/ideas.html](https://joplinapp.org/gsoc2020/ideas.html)): **Support for multiple profiles**

## Benefits

The multiple profiles feature is important for people who use Joplin  
heavily and for multiple purposes. While the concept of notebooks allow  
grouping of notes, it does not insulate notebooks from each other. For  
an example, it is a very common scenario for a user to use Joplin for  
both taking notes at home and at work. Having separate _work_ and _home_  
profiles will be advantageous to them, so that the home notebooks don't  
show up while working at his/her office. In general, the concept of  
profiles allows for _blackbox_ separation between notes.

## Deliverables

Assuming that both these projects are assigned to me, users after the  
completion of this project will be able to do the following:

```
The user will be able to create multiple profiles with different
names, apart from the default profile which is automatically created
when the user opens Joplin for the first time. The profiles will be
completely insulated from each other. On switching profiles, the app
may be required to restart (depending on the final implementation).
It may be possible to add support for multiple instances of Joplin
running on different profiles.

```

My plans are to first implement these features for the desktop version.  
If time permits, I will implement it also for the mobile client.

## Details

The following details are based off the desktop client. I will work on  
the mobile client if time permits and my mentor allows it.

### Basic structure and Desktop UI

I will be taking ideas from the Github issue on this  
([https://github.com/laurent22/joplin/issues/591](https://github.com/laurent22/joplin/issues/591)). Currently, the files  
and directories where the metadata and database is stored are hard-coded  
in `BaseApplication.js` via a `profileDir` variable. I intend to make a  
new class called in `Profile` in a file `Profile.ts` (As instructed in  
CONTRIBUTING.md, I will be using Typescript). The class roughly would  
look like this:

```
class Profile {
    id: number;
    directoryName: string;
    parentDirectory: string;
    
    ...
}   

```

The `BaseApplication` object will contain a `Profile` object, which will  
store the current Profile which is being used. In addition, since the  
app will restart when profiles are switched, the next profile to open  
must be stored in the root folder of all profiles (the `.joplin-desktop`  
directory). As mentioned in the Github issue, it is a good idea to have  
an additional `Profiles.ini` file in the root directory. For handling  
that file, a separate class must be made, which I plan to call  
`ProfilesHandler`. An object of this class will be loaded in `app.js`.  
When the app restarts, it will look up the profile to load up and pass  
the requisite `Profile` object to `BaseApplication`.

As for the user interface, I intend to add a menu option in the Files  
menu, saying 'Switch Profile;, which will open up a screen or a  
pop-over. It is easier to make a screen, but a pop-over will look  
better. The pop-over will show the existing profiles as well as an  
option to create a new one. Overall, this can be implemented in a file  
called `ProfileScreen.tsx`, with some changes in `app.js`.

 ![popover_final](https://canada1.discourse-cdn.com/flex028/uploads/cozic/original/2X/3/3fc03ed22b2d28b071e18189f94b24f3253973c4.png)

### Where to change the code

Firstly, we need to change how the profile directory is determined, in `determineProfileDir(initArgs)` of `lib/BaseApplication.js`. Currently, it first checks whether a profile path is set in the command-line args, otherwise defaults to `$HOME/.config/<app-name>/`. Now, instead it will use the object of the `ProfilesHandler` class (created in the constructor), which will be defined in `Profileshandler.ts`. This class will read the `profiles.ini` file. This file will be stored in either the directory pointed by the `JOPLINAPP_ROOT` environment variable, if available, or else will default to `$HOME/.config/<app-name>/`. The `profiles.ini` file will point to the new profile to open. However, if the profile to open is passed via command-line args, then it will open that profile. As of now, the `--profile` option accepts the `profile-dir` but this will have to be changed to `profile-name` in `handleStartFlags_(arg, setDefault)`.

Apart from this, it is necessary to write to `profiles.ini` when the app exits to indicate the profile to open next time. This change will be reflected in `BaseApplication.exit()`, using the object of the `ProfilesHandler` class to do it.

For handling conflicts between the global custom css file, to be stored in the profiles root directory, and the custom css file in the profile directory, code must be added after line 1291 of `ElectronClient/app.js` to load the global css file as well. Then `CssUtils.injectCustomStyles()` must be modified to compare the two custom css files and load the one in the profile directory in case of a conflict. I will figure out the details in future. However, a simple hack that works will be to append the css file from the _profile_ directory after appending the css file from the _profiles root_ directory. By the CSS convention if there are conflicting rules, a later rule will override the previous one.

Apart from this, there will of course be code for the ProfileScreen and for creating profiles, but I have described that in my proposal. A lot of the heavy lifitng of the profiles will be done in the `ProfilesHandler.tsx`.

### A diagramatic view of how Profiles work

The following flowchart describes how the concept of Profiles is to be used in Joplin:

 ![flowchart1](https://canada1.discourse-cdn.com/flex028/uploads/cozic/original/2X/2/266c86ab1c6fead84070db824a5c84b68e87b5e7.jpeg)

### Simultaneously running multiple profiles

Now that there are seperate databases for seperate profiles, multiple instances of Joplin perhaps could be run on different profiles.  
Several problems may arise from this however:

1. _How does the new instance of Joplin know the current profile(s) running?_  
This can be fixed however by adding a section in the `profiles.ini` file listing the _currently active profiles_. An additional complication that may arise from this is that the instances may not be closed in the same order as they are opened. So the `profiles.ini` file has to be _clobbered and rewritten_ to completely every time some modifications have to be made to it.(For an instance while closing the app or while creating a new profile).

2. _When modifications are made to profiles in one instance how do(es) the other instance(s) know that?_  
A simple fix may be to outlaw making edits to profiles when multiple instances are running. A more complicated solution is to **watch** for file changes via the `fs.watchfile` or `fs.watch` module. Even this solution has potential problems. Because of the buffering mechanisms of the IO interface, while writing to the `profiles.ini` file, potentially at several intermediate writes, the file will be left in an illegal state yet triggering the watch listener, and this may lead to the app crashing. Perhaps during the write phase, locking the `profiles.ini` from both read and write may solve this problem (having a lockfile mechanism, that is). Even so, we have to disallow editing names of profiles which are currently being run in a seperate instance.

3. _What happens to the Electron metadata of the multiple instances?_  
This doesn't seem to be a problem, even in the current master build. The metadata of the last instance of Joplin to be closed will be the one that is used while opening new ones.

### Structure of the `$JOPLINAPP_ROOT` folder

As I have mentioned above, I intend to introduce a new environment variable called `JOPLINAP_ROOT`. The user can set this to modify where the database and other metadata is stored (not the Electron metadata, however). THe structure of this folder will be as follows:

 ![folder_str](https://canada1.discourse-cdn.com/flex028/uploads/cozic/original/2X/0/04cac82dd4f43a7ac05d6e14ceb55256b1dafb04.jpeg)

Note that

- Rectangles indicate directories, ellipses files
- `profile0` is the default profile, which is created the first time the app is opened
- `profile<id>*` denotes that there may be zero or more directorires of the name `profile<id>` where id is a number in the range 1, 2, 3 ... . The id is a number to denote the profile, the actual profile names will stored in `profiles.ini`.
- All the profile directories have a similar structure. I have shown it fully only for the default profile.

### Error handling

#### Malformed/Missing `profiles.ini` file

Malforming can occur if the user edits the file by hand, or due to some errors in the OS/harddisk (this is relatively rare on journalled file systems, such as in all relatively modern machines) or a computer virus. There will be an initial checking in the `ProfilesHandler.tsx`. Of course if a section is missing, it can be retrieved from the directory structure. However, under the current design, **profile names** will not be retrievable. Either the user has to re-input it or the profile name must also be stored in the profie directory (redundancy of data to recover from errors). This process extends to the case if the `profiles.ini` file is missing all together.

#### Altered directory structure

If the user modifies by hand contents of a profile directory, the error will be caught by existing code. If a profiles directory is missing, it will be detected when the user switches to that profile. The user will be informed and the profile directory will bw newly formed. Basically, this is the same as creating a new profile of a given name.

## Restarting the app on the desktop

The Electron app can be relaunched using `app.relaunch(); app.quit();` according to the official docs. A function encapsulating the same should be made in `bridge.js`.
