dullage / flatnotes Goto Github PK
View Code? Open in Web Editor NEWA self-hosted, database-less note taking web app that utilises a flat folder of markdown files for storage.
License: MIT License
A self-hosted, database-less note taking web app that utilises a flat folder of markdown files for storage.
License: MIT License
There's not much to translate so far, and would be the app much more accessible.
Consider:
Currently the API and the web front end load/save notes using a file extension. This extension is hidden from the user and so should also be hidden from the API. For simplicity, an extension of .md should be assumed.
Consider a server side warning message showing a count of files with a different extension.
Hi there, nice app. Kudos to everyone involved. Based on user feedback, we added Flatnotes on PikaPods.com for 1-click hosting. Will also feature it in our monthly newsletter this week.
While I love true self-hosting, it's not for everyone and every app. PikaPods is here to fill this gap and make great apps, like Flatnotes available to a wider audience. So I also wanted to check if it's an option to add a note about this managed hosting option in the README. Happy to add a PR with some initial wording.
We also offer a revenue share for app authors. Happy to discuss that too.
Create a demo site that automatically resets on a timed interval.
This is great and I think will solve my folder full of .md notes and make it easier to manage them.
Is it possible to display more than 5 of the most recent on the home page?
Or maybe another page (or a config option) to show all notes? Maybe sorted by recently changed?
Stupid noob question: Is there a way to change font-size? I could not find a css file, I checked in /var/lib/docker. Thanks!
For example, if you search for java it will not return results with javascript.
Like adding this HTML attribute dir="auto"
to the nodes to make them change direction automatically based on the typed character.
Right now, I'm using hackmd.io they don't support auto RTL support though, but at least they support YAML so I can use something like:
---
dir: rtl
---
to make the whole page RTL when needed.
I wish I can help but I only know some basic HTML and CSS ๐
Currently the user needs to create a data
folder to map to /app/data
inside the container and give user 1000 (the flatnotes user) permission to read/write in it. If they don't do this then Docker creates the folder with ownership assigned to root. If that happens, flatnotes doesn't have the ability to write to the directory and crashes.
Perhaps I need to initially run as root, update the folder ownership and then switch to the flatnotes user to run the app.
Suggestions from Reddit:
You might need to make an env for the user and group ID.
you can use something like su-exec or s6-overlay to do user masking. do all your startup/init as root and then the last action is to start the app as the env provided uid/gid.
Hi there! I just installed flatnotes using docker and everything is working perfectly, thanks a lot!
I wonder if you plan to add 2 factor authentication to the logon, as I'm a bit worried of a plain user/password logon for an internet-facing service.
Thanks for your great work!
Add the ability to "tag" a note by using a hashtag anywhere in the body (e.g. #work). Notes could be tagged multiple times.
This change would also require the ability to view a list of all tags used and the notes associated with each tag.
I should be able to use the search index for this but I would need it to index hashtags (currently it indexes "#work" as just "work").
Also consider including the tag itself in the search results i.e. if you search for "work" and there is a "#work" tag then display #work as the top result allowing the user to quickly navigate to notes associated with that tag.
Currently, the search terms "render" and "cafe" do not find documents that include the words "renders" and "cafรฉ". The underlying search library Whoosh has the functionality to deal with this which needs to be enabled.
Hi again, last question. Is it possible to disable auth? Thanks again!
Folder for each note that has attachments for proper image support and that would probably open the door for other attachments support, like what you disscussed here https://www.reddit.com/r/selfhosted/comments/ygc757/comment/iuc7b5y/?context=3.
Hi again. Are something like wikilinks in your plan for future updates?
Hi,
I have a note which I use as a template to create other notes from it, and it would be great if there was a "Clone note" option, so I don't have to copypaste the template contents to a new note. I know it's not a very important thing ๐
but would be nice to have.
Thanks!!
Hi,
I would like to make a suggestion. For me it would be great if notes could be password protected and then encrypted in the filesystem. Sounds a bit paranoid, but sometimes I write notes with more private content and I would love if these were encrypted and couldn't be easily read from the server.
Thanks for your great project!!
Edit: I mean an option to selectively protect individual notes, not all of them globally.
For example, when trying to use ? in a title I receive the following error in the logs:
"POST /api/notes HTTP/1.1" 400 Bad Request
Hi,
I have an issue when I use my markdown folder as the 'database' dir. The files with .MD
extension are not recognized as markdown files. As a result, these files do not show up in the frontend. To show them, I have to change all the files with .MD
extension to .md
.
I expect that both .MD
and .md
files should be treated as markdown files and show up in the frontend.
Thank you.
Hi. First, I really love the simplicity of flatnotes)
The only issue I have is an absence of id
s for h1
, h2
and other header tags. It makes tables of contents almost useless because clicking on anchor links does nothing:
# Example
- [A](#a)
- [AA](#aa)
- [B](#b)
## A
### AA
## B
I believe TOAST UI Editor
doesn't support it out of the box:
The simplest solution that comes into my mind is to use getElementsByTagName
on Viewer
component to get all header tags and generate all ids manually.
Generation of a valid id is an another issue, but I believe it's possible to use this code as a base. It is under MIT license, so, there should be no problems with copying it if the authors are mentioned.
Consider:
Currently, images are inserted as inline base64 which isn't ideal. Equally, other attachment types (e.g. PDFs) are not supported at all. It would be good to improve this.
Add the ability to order the A-Z page by Last Modified Date.
Consider grouping such as "Today", "Over 1 Week Ago", "Over 1 Year Ago"...
Is it possible to change the font face used by the toast editor?
I'm not a fan of the Inter font face and I would like to use either iA Writer font or something like JetBrains Mono.
Sure, I could fork this project, change index.html
to my taste and rebuild the docker image.
But maybe theming options have already been in consideration as a future change.
As an intermediate solution, could I replace/overwrite some of the files in the container by mapping them via volumes?
Suggested in this Reddit post.
Given the similarity, this should also include a re-design of:
I'm using the docker-compose.yml
from the readme as follows:
version: "3"
services:
flatnotes:
container_name: flatnotes
image: dullage/flatnotes:latest
environment:
FLATNOTES_AUTH_TYPE: "password"
FLATNOTES_USERNAME: "<snip>"
FLATNOTES_PASSWORD: "<snip>"
FLATNOTES_SECRET_KEY: "aLongRandomSeriesOfCharacters"
volumes:
- ./data:/app/data
- ./index:/app/data/.flatnotes
ports:
- 8080:80
restart: unless-stopped
When I try to bring it up with docker-compose up
, I get the following stacktrace:
flatnotes | Traceback (most recent call last):
flatnotes | File "<frozen runpy>", line 198, in _run_module_as_main
flatnotes | File "<frozen runpy>", line 88, in _run_code
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/__main__.py", line 4, in <module>
flatnotes | uvicorn.main()
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/click/core.py", line 1130, in __call__
flatnotes | return self.main(*args, **kwargs)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/click/core.py", line 1055, in main
flatnotes | rv = self.invoke(ctx)
flatnotes | ^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
flatnotes | return ctx.invoke(self.callback, **ctx.params)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/click/core.py", line 760, in invoke
flatnotes | return __callback(*args, **kwargs)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/main.py", line 404, in main
flatnotes | run(
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/main.py", line 569, in run
flatnotes | server.run()
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/server.py", line 60, in run
flatnotes | return asyncio.run(self.serve(sockets=sockets))
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
flatnotes | return runner.run(main)
flatnotes | ^^^^^^^^^^^^^^^^
flatnotes | File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
flatnotes | return self._loop.run_until_complete(task)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
flatnotes | return future.result()
flatnotes | ^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/server.py", line 67, in serve
flatnotes | config.load()
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/config.py", line 477, in load
flatnotes | self.loaded_app = import_from_string(self.app)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/uvicorn/importer.py", line 21, in import_from_string
flatnotes | module = importlib.import_module(module_str)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
flatnotes | return _bootstrap._gcd_import(name[level:], package, level)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
flatnotes | File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
flatnotes | File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
flatnotes | File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
flatnotes | File "<frozen importlib._bootstrap_external>", line 940, in exec_module
flatnotes | File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
flatnotes | File "/app/flatnotes/main.py", line 27, in <module>
flatnotes | flatnotes = Flatnotes(config.data_path)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/app/flatnotes/flatnotes.py", line 172, in __init__
flatnotes | self.index = self._load_index()
flatnotes | ^^^^^^^^^^^^^^^^^^
flatnotes | File "/app/flatnotes/flatnotes.py", line 196, in _load_index
flatnotes | return whoosh.index.create_in(
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/whoosh/index.py", line 102, in create_in
flatnotes | return FileIndex.create(storage, schema, indexname)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/whoosh/index.py", line 425, in create
flatnotes | TOC.create(storage, schema, indexname)
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/whoosh/index.py", line 611, in create
flatnotes | toc.write(storage, indexname)
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/whoosh/index.py", line 676, in write
flatnotes | stream = storage.create_file(tempfilename)
flatnotes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
flatnotes | File "/home/flatnotes/.local/share/virtualenvs/app-4PlAip0Q/lib/python3.11/site-packages/whoosh/filedb/filestore.py", line 490, in create_file
flatnotes | fileobj = open(path, mode)
flatnotes | ^^^^^^^^^^^^^^^^
flatnotes | PermissionError: [Errno 13] Permission denied: '/app/data/.flatnotes/_3_0.toc.1679147739.3350751'
# docker image inspect dullage/flatnotes | grep -i created
"Created": "2023-03-17T12:33:00.0331812Z",
I know the name is "flat" and you mention this in the design principle... but.. do you have any plans to add a lateral pane with a folder/tree/category structure so we could save the notes in a more ordered way?
Thanks for your work anyway, I love it so far!
Another suggestion :)
Since this an online editor I can host on my server it would be really awesome if other family members could use it as well. I mean, they can as it is now, but many notes are often private / not interesting to others. So a great improvement would be a possibility to create login for different users as well as being able to map multiple "repositories" (i.e. folders) into the container which an administrator can assign to different users.
Running the docker instance of flatnotes on a Synology box (DS415+) gives the following error even if I set the local port to somthing like 49161. It seems that flatnotes overrules this setting and tries to bind to local port 80 (which is not allowed):
ERROR: [Errno 13] error while attempting to bind on address ('0.0.0.0', 80): permission denied
2022-08-26 08:10:06 [ERROR]: [Errno 13] error while attempting to bind on address ('0.0.0.0', 80): permission denied
Docker is using the bridge network.
In the Dockerfile I noticed that host (0.0.0.0) and port (80) is mentioned:
ENTRYPOINT [ "pipenv", "run", "python", "-m", "uvicorn", "main:app", "--app-dir", "flatnotes", "--host", "0.0.0.0", "--port", "80" ]
I'm not sure but I think addition of host (0.0.0.0) and port (80) to the entrypoint forces flatnotes to use the local port 80 on Synology
I just started using this and it just what I need. Great job!!
It might be useful to somewhere (perhaps related to the search area) provide a list of tags found in the notes so that the user can click on a desired tag and get a list of the notes where that tag is used.
At the moment notes open in Markdown as default, would be nice to have a variable menu option to open in WYSIWYG
to produce, copy some texts in chinese character to notes, like this one: https://m.bjnews.com.cn/detail/154105774414080.html
search for ๆๅ
returns no result. but ่ฎข้
is okใ
version: docker:latest (0c7b3e7aaec0)
In the spirit of simple and database-less, the current plan is to generate temporary pre-signed URLs but this needs to be explored.
Overview:
Creating a new note with a title that contains a slash (/
) character, gives an error "Unable to communicate with the server".
I have not debugged the problem or checked the code, but I assume the title is used as part of a filename, and the slash messes up the path?
Suggestions:
This is the perfect note taking solution I was looking for, simple and clean, database-less, very fast, WYSIWYG, web-app (accessible from anywhere and any device without the need of a client), full text search, advanced searching, tagging, Docker/Podman support, Time-based one-time password, ... I really really appreciate your thoughts and efforts, thank you so much.
I want to start using it now, but the only things that are holding me (I will submit them as separate issues):
I will consider this page for the first issue on the list:
Inefficient mobile responsive design: This is noticeable when the virtual keyboard appears on a mobile screen, I wish that the only sticky bars are the main one and the editor toolbar and should be as small as possible to leave space for content which is the most important thing here.
These screenshots shows the difference:
Great work!
Suggestion: add a button to insert "Table of content" at the top of the note for the larger notes where you have created many different headers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.