예제 #1
0
async def test_create_get_update_delete_download_resource(get_token):

    joplin = JoplinApi(token=get_token)
    properties = {'title': 'test resource'}

    assert 'title' in properties

    file_name = 'tests/cactus.png'
    res = await joplin.create_resource(file_name, **properties)
    resource_id = json.loads(res.text)['id']

    assert res.status_code == 200

    res = await joplin.get_resource(resource_id)
    assert res.status_code == 200

    properties = {'title': 'test update resource'}
    file_name = 'tests/update_cactus.png'
    res = await joplin.update_resources(resource_id, **properties)
    assert res.status_code == 200

    res = await joplin.download_resources(resource_id)
    assert res.status_code == 200

    res = await joplin.delete_resources(resource_id)
    assert res.status_code == 200
예제 #2
0
async def test_get_folders(get_token):
    joplin = JoplinApi(token=get_token)

    res = await joplin.get_folders()
    print(res.json())
    assert type(res.json()) is list
    assert res.status_code == 200
예제 #3
0
async def test_create_folder(get_token):
    joplin = JoplinApi(token=get_token)

    folder = 'TEST FOLDER1'
    assert type(folder) is str

    res = await joplin.create_folder(folder=folder)
    assert type(res.text) is str
    assert res.status_code == 200
예제 #4
0
async def test_get_folder(get_token):
    joplin = JoplinApi(token=get_token)

    res = await joplin.create_folder(folder='MY FOLDER2')
    data = res.json()
    parent_id = data['id']
    res = await joplin.get_folder(parent_id)
    assert type(res.json()) is dict
    assert res.status_code == 200
예제 #5
0
async def test_get_folder(get_token):
    joplin = JoplinApi(token=get_token)

    res = await joplin.create_folder(folder='MY FOLDER2')
    res = await joplin.get_folder(res.json()['id'])
    assert type(res.json()) is dict
    assert res.status_code == 200
    res = await joplin.delete_folder(res.json()['id'])
    assert res.status_code == 200
예제 #6
0
async def test_delete_folder(get_token):
    joplin = JoplinApi(token=get_token)

    folder = 'TEST FOLDER1'
    assert type(folder) == str

    res = await joplin.create_folder(folder=folder)
    assert res.status_code == 200

    res = await joplin.delete_folder(res.json()['id'])
    assert res.status_code == 200
예제 #7
0
async def test_search(get_token):
    """
    grab receipt in all note
    :param get_token:
    :return:
    """
    joplin = JoplinApi(token=get_token)
    query = "recette"
    search = await joplin.search(query)
    assert type(search.text) is str
    assert search.status_code == 200
예제 #8
0
 def update(self, request, *args, **kwargs):
     serializer = FoldersSerializer(data=request.data)
     if serializer.is_valid():
         joplin = JoplinApi(api_type=settings.JOPLIN_API_TYPE, token=settings.JOPLIN_TOKEN)
         res = joplin.update_folder(request.data['id'], request.data['title'])
         if res.status_code == 200:
             return Response({'status folder updated'})
         return Response({'status': 'folder not updated {}'.format(res.status_code)})
     else:
         return Response(serializer.errors,
                         status=status.HTTP_400_BAD_REQUEST)
예제 #9
0
async def test_search_tag(get_token):
    """
    checkout a tag named 'git*'
    :param get_token:
    :return:
    """
    joplin = JoplinApi(token=get_token)
    query = "git*"
    item_type = 'tag'
    search = await joplin.search(query, item_type)
    assert type(search.text) is str
    assert search.status_code == 200
예제 #10
0
async def test_search_folder(get_token):
    """
    checkout a folder named 'database'
    :param get_token:
    :return:
    """
    joplin = JoplinApi(token=get_token)
    query = "database"
    item_type = 'folder'
    search = await joplin.search(query, item_type)
    assert type(search.text) is str
    assert search.status_code == 200
예제 #11
0
 def create(self, request, *args, **kwargs):
     request.data['nb_notes'] = 0
     serializer = TagsSerializer(data=request.data)
     if serializer.is_valid():
         # call the joplin wrapper to create a tag
         joplin = JoplinApi(api_type=settings.JOPLIN_API_TYPE, token=settings.JOPLIN_TOKEN)
         res = joplin.create_tag(title=request.data['title'])
         if res.status_code == 200:
             return Response({'status': 'tag created'})
         return Response({'status': 'tag not created {}'.format(res.status_code)})
     else:
         return Response(serializer.errors,
                         status=status.HTTP_400_BAD_REQUEST)
예제 #12
0
    def get_folders(self):
        """

        :return:
        """
        joplin = JoplinApi(token=settings.TH_JOPLIN_TOKEN)
        folders = joplin.get_folders().json()

        choices = []
        for folder in folders:
            line = (folder['id'], folder['title'])
            choices.append(line)
        return choices
예제 #13
0
async def test_search_limited_returned_field(get_token):
    """
    grab receipt in all note
    :param get_token:
    :return:
    """
    joplin = JoplinApi(token=get_token)
    query = "recette"
    search = await joplin.search(query,
                                 item_type='note',
                                 field_restrictions='title')
    assert type(search.text) is str
    assert search.status_code == 200
예제 #14
0
async def test_create_note(get_token):
    joplin = JoplinApi(token=get_token)
    # 1 - create a folder
    res = await joplin.create_folder(folder='MY FOLDER3')
    data = res.json()
    parent_id = data['id']
    assert type(parent_id) is str
    # 2 - create a note with tag
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    kwargs = {'tags': 'tag1, tag2', 'id': '00a87474082744c1a8515da6aa5792d2'}
    assert 'id' in kwargs
    assert re.match('[a-z0-9]{32}', kwargs['id'])
    # let's set a user created time
    timestamp = 1545730073
    kwargs['user_created_time'] = timestamp
    res = await joplin.create_note(title="NOTE TEST",
                                   body=body,
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    note_id = res.json()['id']

    note_user_created_time = res.json()['user_created_time']
    assert note_user_created_time == timestamp
    """
    # 3 - update a note with tag
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    # BUG : joplin does not update TAG yet
    # @TOFIX once fixed by Joplin
    kwargs = {'tags': 'tag1, tag2, tag11'}
    res = await joplin.update_note(note_id=note_id,
                                   body=body,
                                   title="NOTE TEST",
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    """
    # drop the testing data
    # 4 - get the tag of that note
    tags_to_delete = await joplin.get_notes_tags(note_id)
    # 5 - delete the tags
    for line in tags_to_delete.json():
        await joplin.delete_tags_notes(line['id'], note_id)

    # delete note
    await joplin.delete_note(note_id)
    # delete folder
    await joplin.delete_folder(parent_id)
예제 #15
0
    def __init__(self):
        try:
            self.orphanes = []

            conf_file_abspath = os.path.join(os.path.dirname(__file__),
                                             'joplintool.conf')
            config = configparser.ConfigParser()

            if config.read(conf_file_abspath) == []:
                with open(conf_file_abspath, 'w') as f:
                    f.writelines([
                        '[paths]\n', 'path_joplin  = c:\_office_\Joplin\n',
                        'path_Dropbox = f:\_Archive_\Dropbox\Apps\Joplin\n',
                        '\n[misc]\n',
                        'token = xxxxxxxxxxxxxxxxxxxxxxxxxxxx #insert token here\n'
                    ])
                raise BaseException(
                    'could not find joplintool.conf\ncreating new config file\nplease edit paths etc. in config file'
                )

            self.path_joplin = config['paths']['path_joplin'].strip(
                '\'\"')  # strip '' and "" from strings
            self.path_Dropbox = config['paths']['path_dropbox'].strip('\'\"')
            self.path_db = os.path.join(self.path_joplin, 'JoplinProfile',
                                        'database.sqlite')
            self.path_resources = os.path.join(self.path_joplin,
                                               'JoplinProfile', 'resources')
            if not os.path.exists(self.path_db):
                raise BaseException('wrongs paths ... check joplintool.conf')

            self.joplin = JoplinApi(token=config['misc']['token'])

            asyncio.run(self.joplin.ping(
            ))  # raises exception if it cannot connect to web clipper

            self.cursor = sqlite3.connect(self.path_db).cursor()

        except ConnectionRefusedError:
            print(
                'cannot connect to web clipper....\nis joplin running ?\nalso check token in conf file'
            )
            exit()

        except BaseException as err:
            print(err)
            print('exiting...')
            exit()
예제 #16
0
    def create(self, request, *args, **kwargs):
        serializer = NotesSerializer(data=request.data)
        if serializer.is_valid():
            data = {'is_todo': request.data.get('is_todo', 0),
                    'tags': request.data.get('tag', '')}
            joplin = JoplinApi(api_type=settings.JOPLIN_API_TYPE, token=settings.JOPLIN_TOKEN)

            res = joplin.create_note(title=request.data['title'],
                                     body=request.data['body'],
                                     parent_id=request.data['parent_id'],
                                     **data)
            if res.status_code == 200:
                return Response({'status': 'note created'})
            return Response({'status': 'note not created {}'.format(res.status_code)})
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)
예제 #17
0
async def test_create_tag(get_token):
    """
    Create and delete a new tag
    :param get_token:
    :return:
    """

    joplin = JoplinApi(token=get_token)

    title = 'TEST TAG1'

    res = await joplin.create_tag(title=title)
    assert type(res.text) is str
    assert res.status_code == 200

    res = await joplin.delete_tag(res.json()['id'])
    assert res.status_code == 200
예제 #18
0
async def mailer():
    todo_due = []
    joplin = JoplinApi(
        token=config['JOPLIN_CONFIG']['JOPLIN_WEBCLIPPER_TOKEN'])
    # get all the notes
    res = await joplin.get_notes()
    if res.status_code != 200:
        raise ConnectionError(res.raise_for_status())
    # read all the note
    for note in res.json():
        # just get the todo_due ones
        if note['todo_due'] > 0:
            todo_due.append({
                'title': note['title'],
                'body': note['body'],
                'todo_due': note['todo_due']
            })

    if len(todo_due) > 0:
        # sort all of them by todo_due date
        sorted_x = sorted(todo_due, key=lambda i: i['todo_due'])
        # for each of them, calculate if the date will be due soon
        for data in sorted_x:
            """
            as Timer() only handles 'secondes', have to convert twice,
            to calculate current date and diff between now and todo_due
            """
            # 1 - todo_due is in millisecond, so have to calendar timegm in milliseconds
            now = calendar.timegm(time.gmtime()) * 1000
            # 2 - diff in milliseconds, converted in second
            in_sec = math.ceil((data['todo_due'] - now) / 1000)
            # tododate already due
            if in_sec < 0:
                continue
            else:
                # due date found
                logger.debug("note to send to %s : title %s" %
                             (config['MAIL']['EMAIL_TO'], data['title']))
                # let's mail
                t = Timer(in_sec,
                          _send_msg,
                          args=[data['title'], data['body']])
                t.start()
                t.join()
예제 #19
0
async def test_create_note(get_token):
    joplin = JoplinApi(token=get_token)
    # 1 - create a folder
    res = await joplin.create_folder(folder='MY FOLDER3')
    data = res.json()
    parent_id = data['id']
    assert type(parent_id) is str
    # 2 - create a note with tag
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    kwargs = {'tags': 'tag1, tag2'}
    res = await joplin.create_note(title="NOTE TEST",
                                   body=body,
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    note_id = res.json()['id']
    """
    # 3 - update a note with tag
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    # BUG : joplin does not update TAG yet
    # @TOFIX once fixed by Joplin
    kwargs = {'tags': 'tag1, tag2, tag11'}
    res = await joplin.update_note(note_id=note_id,
                                   body=body,
                                   title="NOTE TEST",
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    """
    # drop the testing data
    # 4 - get the tag of that note
    tags_to_delete = await joplin.get_notes_tags(note_id)
    # 5 - delete the tags
    for line in tags_to_delete.json():
        await joplin.delete_tags_notes(line['id'], note_id)

    # delete note
    await joplin.delete_note(note_id)
    # delete folder
    await joplin.delete_folder(parent_id)
예제 #20
0
async def test_add_tag(get_token):
    """
    Add tag to a note and remove it
    :param get_token:
    :return:
    """

    joplin = JoplinApi(token=get_token)

    # 1 - create a folder
    res = await joplin.create_folder(folder='MY FOLDER')
    assert res.status_code == 200
    data = res.json()
    parent_id = data['id']

    # 2 - create a note
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    res = await joplin.create_note(title="NOTE TEST",
                                   body=body,
                                   parent_id=parent_id)
    assert res.status_code == 200
    note_id = res.json()['id']

    # 3 - create a tag
    title = 'TEST TAG2'
    res = await joplin.create_tag(title=title)
    assert res.status_code == 200
    tag_id = res.json()['id']

    # 4 - add tag to Note
    res = await joplin.create_tags_notes(note_id=note_id, tag=tag_id)
    assert res.status_code == 200

    # drop the testing data
    # delete tag
    await joplin.delete_tag(tag_id)
    # delete note
    await joplin.delete_note(note_id)
    # delete folder
    await joplin.delete_folder(parent_id)
예제 #21
0
async def test_get_note(get_token):
    joplin = JoplinApi(token=get_token)
    res = await joplin.create_folder(folder='MY FOLDER4')
    data = res.json()
    parent_id = data['id']

    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    res = await joplin.create_note(title="NOTE TEST2",
                                   body=body,
                                   parent_id=parent_id)
    data = res.json()
    note_id = data['id']

    assert type(note_id) is str
    res = await joplin.get_note(note_id)

    assert type(res.json()) is dict
    assert res.status_code == 200

    # drop the testing data
    await joplin.delete_note(note_id)
    await joplin.delete_folder(parent_id)
예제 #22
0
async def test_create_note(get_token):
    joplin = JoplinApi(token=get_token)

    res = await joplin.create_folder(folder='MY FOLDER3')
    data = res.json()
    parent_id = data['id']

    assert type(parent_id) is str
    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    kwargs = {'tags': 'tag1, tag2'}
    res = await joplin.create_note(title="NOTE TEST",
                                   body=body,
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    note_id = res.json()['id']

    body = '# title 1\n ## subtitle \n ```python\npython --version\n```'
    assert type(body) is str
    kwargs = {'tags': 'tag1, tag2, tag11'}
    res = await joplin.update_note(note_id=note_id,
                                   body=body,
                                   title="NOTE TEST",
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200

    # drop the testing data
    tags_to_delete = await joplin.get_notes_tags(note_id)

    for line in tags_to_delete.json():
        await joplin.delete_tags_notes(line['id'], note_id)

    await joplin.delete_note(note_id)

    await joplin.delete_folder(parent_id)
예제 #23
0
async def test_create_note_no_body(get_token):
    joplin = JoplinApi(token=get_token)
    # 1 - create a folder
    res = await joplin.create_folder(folder='MY FOLDER3')
    data = res.json()
    parent_id = data['id']
    assert type(parent_id) is str
    # 2 - create a note with tag
    body = ''
    assert type(body) is str
    kwargs = {'tags': 'tag1, tag2', 'id': '00a87474082744c1a8515da6aa5792d2'}
    assert 'id' in kwargs
    assert re.match('[a-z0-9]{32}', kwargs['id'])
    # let's set a user created time
    timestamp = 1545730073
    kwargs['user_created_time'] = timestamp
    res = await joplin.create_note(title="NOTE TEST",
                                   body='',
                                   parent_id=parent_id,
                                   **kwargs)
    assert res.status_code == 200
    note_id = res.json()['id']

    note_user_created_time = res.json()['user_created_time']
    assert note_user_created_time == timestamp

    # drop the testing data
    # 4 - get the tag of that note
    tags_to_delete = await joplin.get_notes_tags(note_id)
    # 5 - delete the tags
    for line in tags_to_delete.json():
        await joplin.delete_tags_notes(line['id'], note_id)

    # delete note
    await joplin.delete_note(note_id)
    # delete folder
    await joplin.delete_folder(parent_id)
예제 #24
0
파일: test.py 프로젝트: sciurius/joplin-api
 def setUp(self):
     token = '5fa5a79fdd9feb428297b32b8ebfb92160b95678d6a05b7823df19212046106e89c71e3674df7b8c60ee47c53469cfe3cb4c8b9a174cde5960fabc9186503ae4'
     self.joplin = JoplinApi(token=token)
    def export_to_joplin(self, token: str, nsx_content: Dict) -> None:
        """Exports notes to Joplin

        Parameters
        ----------
        token : str
            Authorization token. Within the Joplin app, go to
            Tools/Options/Web Clipper to find token.
        nsx_content : Dict
            Python dictionary with keys 'notebooks' and 'notes'.
            It will contain all relevant extracted information
            that will be necessary to use for an import into
            another note taking app.

        Returns
        -------
        None
        """
        joplin = JoplinApi(token=token)

        async def create_folder(notebook_title):
            res = await joplin.create_folder(folder=notebook_title)
            data = res.json()
            parent_id = data["id"]
            assert type(parent_id) is str

            return parent_id

        async def create_resource(attachments, content, attachment_path):
            for index, attachment in enumerate(attachments, start=0):

                attachment_type = attachment["type"]
                name = attachment["name"]

                res = await joplin.create_resource(
                    attachment_path.joinpath(name), **{"title": name}
                )
                resource_id = res.json()["id"]
                attachments[index]["joplin_resource_id"] = resource_id
                assert res.status_code == 200

                if attachment_type == "image":
                    content = re.sub(
                        r"!\[\]\(.*\)", f"![{name}](:/{resource_id})", content, 1,
                    )
                elif attachment_type == "binary":
                    content = f"[{name}](:/{resource_id})\n\n" + content

            return content

        async def create_note(
            joplin_id,
            note_title,
            note_content,
            note_tags,
            user_created_time,
            user_updated_time,
        ):
            body = note_content
            assert type(body) is str
            kwargs = {
                "tags": note_tags,
                "user_created_time": user_created_time,
                "user_updated_time": user_updated_time,
            }
            res = await joplin.create_note(
                title=note_title, body=body, parent_id=joplin_id, **kwargs
            )
            assert res.status_code == 200

        for notebook in nsx_content["notebooks"]:
            joplin_id = asyncio.run(create_folder(notebook["title"]))

            # filter notes that belong to current notebook
            filtered_notes = [
                note
                for note in nsx_content["notes"]
                if note["parent_nb_id"] == notebook["id"]
            ]
            num_filtered_notes = len(filtered_notes)

            for idx, note in enumerate(filtered_notes, start=1):

                print(
                    f"Writing note {idx}/{num_filtered_notes} in {notebook['title']}: "
                    f"{note['title']}"
                )

                # transform list of tags to string
                tag = None
                if note["tag"]:
                    tag = ",".join(note["tag"])

                # Create resource, if necessary
                if note["attachment"]:
                    note["content"] = asyncio.run(
                        create_resource(
                            attachments=note["attachment"],
                            content=note["content"],
                            attachment_path=notebook["media_path"],
                        )
                    )

                asyncio.run(
                    create_note(
                        joplin_id=joplin_id,
                        note_title=note["title"],
                        note_content=note["content"],
                        note_tags=tag,
                        user_created_time=note["ctime"] * 1000,
                        user_updated_time=note["mtime"] * 1000,
                    )
                )

                if idx % 1000 == 0:
                    seconds = 300
                    print(
                        f"Sleep for {seconds} seconds in order to not crash Joplin web "
                        "clipper"
                    )
                    time.sleep(seconds)
                elif idx % 500 == 0:
                    seconds = 120
                    print(
                        f"Sleep for {seconds} seconds in order to not crash Joplin web "
                        "clipper"
                    )
                    time.sleep(seconds)
예제 #26
0
async def test_get_resources(get_token):

    joplin = JoplinApi(token=get_token)

    res = await joplin.get_resources()
    assert res.status_code == 200
예제 #27
0
파일: app.py 프로젝트: mevans845/joplin-web
from starlette.templating import Jinja2Templates

# uvicorn
import uvicorn

from joplin_api import JoplinApi

templates = Jinja2Templates(directory="templates")

# load configuration
settings = Config('.env')

main_app = Starlette()
main_app.debug = settings('JW_DEBUG')

joplin = JoplinApi(token=settings('JOPLIN_WEBCLIPPER_TOKEN'))


async def tag_for_notes(data):
    """
    alter the original data to add the tag related to the note
    :param data:
    :return:
    """
    payload = []
    for note in data.json():
        tag = await joplin.get_notes_tags(note['id'])
        new_note = note
        new_note['tag'] = tag.json() if tag else ''
        payload.append(new_note)
    return payload
예제 #28
0
파일: anki.py 프로젝트: aradove/baeuda
import asyncio
from bs4 import BeautifulSoup
from joplin_api import JoplinApi
import json
import pypandoc
import settings
import requests

joplin = JoplinApi(settings.TOKEN)


def subfolder(folder):
    """

    :param folder: subfolder
    :return: line of the founded children
    """
    for line in folder['children']:
        if settings.FOLDER == line['title']:
            return line['id']


async def myfolder():
    """

    :return: the folder id
    """
    res = await joplin.get_folders()
    for line in res.json():
        if settings.FOLDER == line['title']:
            return line['id']
예제 #29
0
import subprocess
from urllib.request import urlopen

# external lib
from joplin_api import JoplinApi
from bs4 import BeautifulSoup
import pypandoc


current_folder = os.path.dirname(__file__)
config = configparser.ConfigParser()
config.read(os.path.join(current_folder, 'settings.ini'))
if not config['JOPLIN_CONFIG']['JOPLIN_WEBCLIPPER_TOKEN']:
    raise ValueError('Token not provided, edit the settings.ini and set JOPLIN_WEBCLIPPER_TOKEN accordingly')

joplin = JoplinApi(token=config['JOPLIN_CONFIG']['JOPLIN_WEBCLIPPER_TOKEN'])

logging.basicConfig(filename='jong_toolkit.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logger = getLogger("joplin_api.api")


def grab_note( note):
    """
    grab the webpage of that note
    :note :dict: dict of the shared note
    :return title of the grabed page and its body
    """
    # the body contains the URL all alone
    body = urlopen(note['title'])
    page = BeautifulSoup(body, 'html.parser')
    title = page.title.string if page.title else 'no title found'
예제 #30
0
async def main(options):
    joplin = JoplinApi(token=options.joplin_token)

    # Get all notes, folders and resources info.
    all_folders = (await joplin.get_folders()).json()
    all_notes = (await joplin.get_notes()).json()
    folder_id_paths = {}
    note_to_folder_ids_dict = {}

    # Set default locations for generated files
    notes_folder = "notes"
    resource_folder = "resources"

    # Give the user an option to parse all the notebooks or a selection.
    # Rasul TODO: allow to choose multiple notebooks.
    response = input("Do you want to parse all notebooks? [y/n]")
    if response == "n":
        all_folders = choose_folders_to_parse(all_folders)
    elif response == "y":
        pass
    else:
        print("Incorrect response")

    # Generate folders for chosen notebooks
    for folder in all_folders:
        create_folders(folder, notes_folder, folder_id_paths)

    # Generate a dictionary with notes ids as keys and folder ids as values
    for k in folder_id_paths:
        notes = (await joplin.get_folders_notes(k)).json()
        for note in notes:
            note_to_folder_ids_dict[note["id"]] = k

    # Create a new list of notes that appear in selected folders only
    filtered_all_notes = []
    for note in all_notes:
        if note["id"] in note_to_folder_ids_dict:
            filtered_all_notes.append(note)

    # Get a dictionary with note titles and ids
    notes_dict = generate_dict_with_all_notes_and_ids(filtered_all_notes)

    for note in filtered_all_notes:
        all_resources = []
        resources = (await joplin.get_notes_resources(note["id"])).json()

        for resource in resources:
            all_resources.append(resource)
            response = await download_resource(
                joplin, resource, os.path.join(notes_folder, resource_folder))

    resources_types_dict = generate_dict_with_all_resources(all_resources)
    resources_names_dict = generate_dict_with_all_resources_filenames(
        all_resources)

    for note in filtered_all_notes:
        folder_path = folder_id_paths[note_to_folder_ids_dict[note["id"]]]
        file_path = os.path.join(folder_path, remove_spaces(note["title"]))
        try:
            note["body"] = search_and_replace_joplin_note_links(
                note["body"], notes_dict)
        except KeyError:
            note["body"] = search_and_replace_joplin_resource_links(
                note["body"],
                resources_types_dict,
                resources_names_dict,
                resource_folder,
            )

        note["category"] = os.path.basename(os.path.normpath(folder_path))
        generate_note(file_path, note)