Code Monkey home page Code Monkey logo

andrewbrereton / obsidian-to-ical-plugin Goto Github PK

View Code? Open in Web Editor NEW
44.0 3.0 7.0 817 KB

This is a plugin for Obsidian that searches your vault for tasks that contain dates, and generates a calendar in iCal format that can be imported into your preferred calendar application.

License: MIT License

JavaScript 13.64% TypeScript 81.78% Shell 4.58%
apple-calendar calendar google-calendar ical icalendar obsidian obsidian-plugin outlook-calendar yahoo-calendar

obsidian-to-ical-plugin's Introduction

Obsidian to iCal

This is a plugin for Obsidian that searches your Obsidian vault for tasks that contain dates, and generates a calendar in iCal format that can be imported into your preferred calendar application.

How it works

Periodically, the plugin will:

  1. Find all tasks in your vault (A valid task is a Markdown checkbox (either checked or not) that contains a date in the format YYYY-MM-DD or YYYY-MM-D),
  2. Generate an iCal calendar file that contains all of these tasks,
  3. Tasks are appended with an emoji to quickly see their status (βœ… completed, πŸ”² to do, πŸƒ in progress, 🚫 canceled),
  4. Optionally, calendar can be saved to your filesystem, and/or
  5. Optionally, calendar can be stored on GitHub Gist.

If you choose to store your calendar on Gist, you can then use the URL to your Gist in your preferred calendar application.

Your vault will be scanned every now and then for changes to tasks to keep your calendar up-to-date.

Support for Obsidian Tasks

This plugin has rudimentary support for Obsidian Tasks emoji format and Obsidian Tasks dataview format. However it is not mandatory.

Support for Day Planner

This plugin supports Day Planner format tasks. If you enable this in the settings, then the date of the task will be taken from the tasks heading, and the start time and end time will be taken from the task. If there is no end time, the default end time will be 30 minutes from the start time.

Settings

iCal has various settings which I will try to explain.

Processing internal links

Obsidian supports two types of internal link: wikilinks and markdown.

Wikilinks can look like: [[Link to document]] or [[Link to document|Link title]]. Markdown links look like [Link title](Link to document).

Do not modify them (default)

This option will keep the links in your event just as they appear.

Keep the title

This option will keep just the Link title and remove the link. If the wikilink does not have a title then it will be removed.

Prefer the title

This option will take the Link title however if that does not exist, then it will use Link to document.

Remove them

This option will remove them entirely from your event summary.

Ignore completed tasks

This is to allow you to exclude completed tasks from being added to your calendar. It will also remove tasks from your calendar once they are marked as completed.

Add tasks as TODO items to your calendar

Enabling this will append all of your tasks as TODO items to the end of your calendar file. Some iCalendar clients are able to render these tasks separate to the calendar events. Some clients that support this include Google Tasks, Microsoft Outlook, Microsoft To Do, Mozilla Thunderbird with Lightning Calendar, Android CalDAV-Sync, Calendars by Readdle, Todoist and OmniFocus.

Only tasks without dates are TODO items

Enabling this will mean that only tasks that do not have dates will be created as TODO items. If you disable this, then every task (tasks with or without a date) will be added to your calendar as a TODO item.

Ignore old tasks?

Toggles on or off the functionality where you are able to exclude tasks whose dates are older than the value you specify.

How many days back to you want to keep old tasks?

If Ignore old tasks? is true then you will be asked to set the age in days. Minimum value is 1 day. Maximum value is 3650 days (10 years).

Which task date should be used?

Tasks can have one or more dates. From either a single raw date in YYYY-MM-DD format, to dates for when a task starts, is scheduled or is due. This setting is to customise which date is chosen when building your iCalendar.

Prefer due date (default)

Prefer due date means the following sequence will be followed:

  1. If the task has a due date and a start date, they will be the start and end date
  2. If the task only has a due date, that will be used
  3. If the task only has a start date, that will be used
  4. If neither are found, just find any date related to that task

Prefer start date

Prefer start date means the following sequence will be followed:

  1. If the task only has a start date, that will be used
  2. If the task only has a due date, that will be used
  3. If neither are found, just find any date related to that task

Create an event per start/scheduled/due date

Create an event for each start date, scheduled date and due date associated with a task. This means if your task has all three dates, then three separate events will be created in your calendar.

  1. If there is a start date, an event will be created using that date. The summary will be appended with a πŸ›«.
  2. If there is a scheduled date, an event will be created using that date. The summary will be appended with a ⏳.
  3. If there is a due date, an event will be created using that date. The summary will be appended with a πŸ“….
  4. If none of the above dates were found, then take any old date that we can find

Support Day Planner plugin?

Enabling this will tell the plugin to consider Day Planner plugin format if tasks are discovered with times in them.

Save calendar to GitHub Gist?

Enabling this will unlock the Save calendar to GitHub Gist settings.

Save calendar to disk?

Enabling this will unlock the Save calendar to disk settings.

Periodically save your calendar?

Enabling this will tell iCal that it should periodically scan your vault for tasks within Markdown files and generate a calendar. It also unlocks the How often should we parse and save your calendar? (minutes) setting.

How often should we parse and save your calendar? (minutes)

The number of minutes between each scan to generate and save your calendar. Must be a number between 1 and 1,440 (24 hours).

Only include tasks with certain tags?

Enabling this will unlock the Only include tasks that contain these tags setting.

Only include tasks that contain these tags

You can enter one or more tags. Only tasks that contains one or more of these tasks will be included in your calendar. Multiple tags should be separated by a space.

Exclude tasks with certain tags?

Enabling this will unlock the Exclude tasks that contain these tags setting.

Exclude tasks that contain these tags

You can enter one or more tags. If a task contains any of these tags, then it will be excluded from your calendar. Multiple tags should be separated by a space.

If you have include tags and exclude tags, then exclude tags take priority.

Save calendar to GitHub Gist

Saving to GitHub Gist means you will be given a URL that you can import into your calendar applications.

GitHub personal access token

To be able to write the calendar file to GitHub Gist, you need to generate a personal access token.

For further information please see How to generate a GitHub Personal Access Token.

GitHub Gist ID

The Gist ID is the Gist that you want to write your calendar to.

For further information please see How to generate a GitHub Gist ID.

GitHub username

This is used only to generate the URL to your GitHub Gist.

Filename

This should match the filename that you used when you created the GitHub Gist.

For further information please see How to generate a GitHub Gist ID.

Your calendar URL

This is the URL that you need to copy and paste into your preferred calendar application.

Save calendar to disk

Saving your calendar to disk means you can import it into a desktop application (like Thunderbird) or do further processing if you're that way inclined. For example, maybe you want to email the calendar to someone. I don't know.

Path

This is the path, relative to the root directory of your vault, in which the calendar file will be written. An empty string means the root directory of your vault.

Filename

Give the calendar file a name.

File extension

Choose the extension of the filename.

Your calendar path

This is just a way to copy the path and filename and extension so it's easy to find on your filesystem.

Debug mode

This turns on logging so that you can see what the extension is doing. It can be helpful to diagnose what is happening if there are any issues.

In the Obsidian menu, go to View and select Toggle Developer Tools. The log messages will appear in the Console tab.

How to generate a GitHub Personal Access Token

A GitHub Personal Access Token is a long random string that allows iCal to write to your GitHub Gist on your behalf.

To generate one, do the following:

  1. Go to https://github.com/settings/tokens/new
    1. Note: Enter something like "Obsidian iCal".
    2. Expiration: Best practice is to expire tokens periodically but that would be frustrating. Choose no expiration if you want to.
    3. Select scopes: Choose gist only.
    4. Click Generate token
  2. Copy the personal access token (It starts in ghp_)
  3. Paste it into the GitHub personal access token setting.

If your personal access token is leaked, go to the GitHub tokens page and click Delete. Then follow these steps again to generate a new one.

How to generate a GitHub Gist ID

  1. Go to here to create a new Gist: https://gist.github.com/
    1. Gist description: Enter anything you like. Eg: My calendar that is generated from my Obsidian vault
    2. Filename including extension: You could use obsidian.ics or your vault name. Whatever you enter here, you will need to enter it in the iCal settings so it knows which file to write to.
    3. For the contents of the Gist, just put anything in there. The iCal plugin will overwrite it.
    4. Click Create secret gist

After you create the Gist, you will see the URL is something like:

https://gist.github.com/andrewbrereton/11c399ce6c0d89c5f8101edb9a2b76d6

                        |------------| |------------------------------|
                           Username                 Gist ID
  1. Take the Username part and enter it in GitHub username setting.

  2. Take the Gist ID part and enter it in GitHub Gist ID setting.

Compatible calendars

  • Google Calendar
  • Apple Calendar
  • Microsoft Outlook
  • Lightning extension for Mozilla Thunderbird and SeaMonkey
  • Yahoo! Calendar
  • GNU Emacs
  • HCL Domino (formerly IBM Notes and Lotus Notes)
  • GNOME Evolution
  • eM Client
  • Novell GroupWise

obsidian-to-ical-plugin's People

Contributors

aidenlx avatar andrewbrereton avatar chrisgrieser avatar clemens-e avatar dependabot[bot] avatar edo78 avatar ericaxu avatar fyears avatar gitmurf avatar henrebotha avatar inouetakuya avatar joethei avatar kostapc avatar lishid avatar phibr0 avatar pozdneev avatar reorx avatar taurelas avatar tfthacker avatar timrogers avatar tokuhirom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

obsidian-to-ical-plugin's Issues

recurring export doesn't work

Hi @andrewbrereton

First of all, thank you for this plugin. I've been waiting for this for a long time and it's a turning point for me. I want to export to local (.ics) for reading via thunderbird.
If I make a parameter change, the export goes well the first time but after 5 min (default time) the update doesn't work. I get no error message in the obsidian console. πŸ€”

Implement rfc 5545 3.1 content lines length limit

https://datatracker.ietf.org/doc/html/rfc5545#section-3.1

Lines of text SHOULD NOT be longer than 75 octets, excluding the line break. Long content lines SHOULD be split into a multiple line representations using a line "folding" technique. That is, a long line can be split between any two characters by inserting a CRLF immediately followed by a single linear white-space character (i.e., SPACE or HTAB). Any sequence of CRLF followed immediately by a single linear white-space character is ignored (i.e., removed) when processing the content type.

For example, the line:

DESCRIPTION:This is a long description that exists on a long line.

Can be represented as:

DESCRIPTION:This is a lo
 ng description
  that exists on a long line.

(FR) Make the date adjust after completion

Hi @andrewbrereton

Unless I'm mistaken, when a task is completed, it's simply marked with an icon βœ…. This is very practical, but it would be even more so if the date were changed to match the completion date. Very useful when you visualize everything in a calendar.

For example. An event planned for tomorrow but finally carried out today could appear as βœ… today. For this to happen, the scheduled date would have to be adjusted. Without affecting the due date.

Eventually, "Initial planning: 2024-02-20" could appear in the description for those who need to keep track.

Your opinion about this ?

I ran the plugin once but now it doesnt recognise the existing ics file

I cant run the plugin.

Here are the steps I took:

  • Checked: Save calendar to disk
  • Checked: Periodically save calendar
  • Path: /SubFolder/Tasks/
  • File name: ICS-Tasks-From-Obsidian
  • Extention: ics

Yesterday I successfully created the .ics file in obsidian and synced it with my android calendar through nextcloud. But today the plugin gives the following error:

[info][ical] Skip saving calendar to Gist
plugin:ical:284 [info][ical] Saving calendar to file...
plugin:ical:284 [info][ical] File does not exist: creating -> But the file does exists
app.js:1 Uncaught (in promise) Error: File already exists. 

Am I defining the path in the correct way? Does anyone know whats causing the issue?

Thunderbird / Evolution -- the link is not recognized

Hi @andrewbrereton !

I would like to use the link contained in "location" more systematically to jump to the original note. It looks like this in my case:
ALTREP="obsidian://open?vault=Armoire&file=02%20-%20JOURNAL/2024-04-13.md":obsidian://open?vault=Armoire&file=02%20-%20JOURNAL/2024-04-13.md

However, this link is not recognized by Thunderbird. Is there a way to achieve this? It must be possible (closed issue) πŸ€”

[Feature Request] Chose how to add tasks to calendar: only as todo items, only as events or both

Thank you for this fantastic plugin! It makes life easier.

Use case:
I would really like to see my obsidian tasks only as todo items in my calendar (Im using CalDAV together with Nextcloud & aCalendar+)

Whats happening:
When I chose to add tasks as TODO items as well as events the calendar becomes crowded and full of duplicated information.

Feature request:
Im not sure if this is feasible but to be able to chose whether to add tasks as following options could be great.

  • only todo items
  • only calendar events
  • both

[Feature Proposal] 5 functionalities I've implemented for consideration

Hello, @andrewbrereton

I've been exploring the plugin and have implemented a few new features for my personal usage and I hope to contribute them to the repository.

However, before proceeding further, I wanted to discuss their potential inclusion in the plugin and gather your thoughts on them. If you think these features align with the plugin's direction, I would be more than happy to refine the documentation, provide setting instructions, and submit a separate PR for your review.

1. Add option to create multiple events without schedule icon.

Same as "Which task date should be used?" β†’ "Create an event per start/scheduled/due date" but without the schedule icon.

This is useful if you have a lot of tasks that are scheduled and you don't want to clutter your calendar with them. Start and due icons will still be appended to the summary to help you identify them.

2. Customizable status icons.

Enable users to customize icons for statuses such as "Incomplete", "Done", "Cancelled" and so on. Users can select their preferred icon or even input an empty string to hide the icon entirely.

3. Parse [startTime::], [length::] and [endTime::] properties (Tasks & DataView format of time).

If enabled, the plugin will parse tasks such as "- [ ] Something. [startTime:: 18:00] [length:: 3h30m] ⏳ 2024-03-01", extracting start time, end time, and duration.

4. Save calendar to private server.

Although calendars can currently be uploaded to Gist, in certain regions and under specific conditions, the gist raw refresh rate can be exceptionally slow. For instance, even though new versions are visible in the revision history, the raw content often remains outdated.

I have developed a feature that allows users to upload their calendars to their own private servers. Users can then set up public file access services, such as Nginx, on their private servers to ensure timely updates.

Users are required to deploy the GitHub - TwoStoryRobot/docker-simple-file-upload: Simple, secure file upload API in a docker container on their private server. Subsequently, within the plugin settings, users need to input the server address, port, and KEY.

Plus, utilizing a GitHub private repository (instead of Gist or a private server) might be a more suitable option.

5. Bug Fix: All day event.

The current format for all-day tasks in the generated iCal is DTSTART:20240301. I have corrected it to comply with the standard format for all-day events: DTSTART;VALUE=DATE:20240301.

Please let me know your thoughts on these proposed features and how you'd like to proceed. I'm open to feedback and willing to make any adjustments needed to align with the plugin's goals.

Thank you for your work on developing this plugin. I look forward to potentially contributing to its growth.

Add option to parse Dataview formatted tasks

Hi,

Thanks for the cool plugin. I might be the only person in the world who uses the Dataview format for tasks rather than the emoji format. That is, [scheduled:: <date>] instead of ⏳<date>, etc. (Changing to the emoji format now prevents the tasks plugin from reading any of the tasks, so that's not a viable option at the moment.)

The iCal plugin still seems to be finding all of the dates correctly. They are being displayed in the calendar with the dates removed, but the surrounding square brackets and marker are still present:

Screenshot 2024-01-30 at 10 24 26β€―pm

I've never done any Obsidian plugin development, but I may be able to tinker with this myself. I suppose it could be straightforward to replace the emojis with their respective Dataview properties in TaskDate.ts and TaskSummary.ts, and then provide the user with an option in the settings. Is this all that would need to be changed?

Thanks

Test test test

I develop this plugin inside a vault that has Markdown files containing all types of tasks. While testing a feature, I will run the plugin and manually check that the output matches my expectations.

Improvements I want to make:

  1. Add this test vault to the source code,
  2. Symlink the plugin into the vault so that the plugin is at the root and the test vault is in a child directory. This means I can still open the vault in Obsidian and it will load the plugin in my development environment,
  3. Create a way to unit test the logic so that a given line generates the expected VEVENT/VTODO iCalendar block,
  4. Write a suite of unit tests to test all functionality and configurations programmatically,
  5. Add a package script for bun run test, and
  6. Add bun run test to the release workflow.

DTSTART,DTEND empty

I created a task that doesn't include πŸ›« in the task

CleanShot 2023-11-07 at 13 02 58@2x

In this case, DTSTART and DTEND will not be generated

CleanShot 2023-11-07 at 13 03 04@2x

CleanShot 2023-11-07 at 13 03 21@2x

[Feature Request] Consider only tasks within a path

Hi, thanks a lot for the plugin!

I've been trying to integrate it into my workflow, where I have a folder for Daily Tasks, and then other folders with all kind of tasks for long-term planning, project management, etc. For my use case, I want to have my personal daily tasks on an external calendar, which are only those within the Daily Tasks folder, but as of now all tasks are considered (unless I tag all wanted/removed tasks).

Feature request: Add a "Root path" setting which selects the folder from which start looking for tasks. By default, it is the Vault root, so functionality remains the same.

Besides my specific use case, I think having this option could be quite helpful to other uses, and should be easy enough to add.

(idea) support task list filtering based on tags

I often have lots of tasks in a day but only need to calendar schedule a few of them that are really important. It'd be helpful if (say) a tag could be used to filter in (or out) tasks that go into the ics file.

[Nice work by the way. I found this only recently and will pull this into my workflow. At a quick test, it looks like the ics file can also be used with BusyCal on Mac]

(Feature) Unscheduled tasks

Context: .ics, .icalendar


First, thank you a lot. I was searching for something to synchronize my tasks with my calendar and this plugin is just perfect.

This would be even more perfect if the .ics file would also be populated with unscheduled tasks as "todo". I've try with both .ics and .icalendar format but does not seem to load the tasks.

This is compatible with .ics and .icalendar format:

BEGIN:VTODO
SUMMARY:Name
DESCRIPTION:Blablabla
STATUS:NEEDS-ACTION
PRIORITY:0
SEQUENCE:0
END:VTODO

This could be then enabled with a boolean switch in settings.

Thanks in advance

Wikilink square brackets [[ ]]

hello

- [ ] [[COCONUT]]
- [ ] [[APPLE|BANANA]]

CleanShot 2023-11-19 at 00 25 11@2x

In this case, these events are created

It would be cleaner to see only the event names COCONUT and BANANA

I think it would look better to hide the square brackets

Use addStatusBarItem()

Uses:

  • Show when scanning Vault
  • Show when saving to file
  • Show when uploading to Gist
  • Show last update date/time
  • Show if error writing to disk
  • Show if error uploading to Gist

Instructions are unclear

As a non coder I tried to connect gist with iCal plugin so that I can connect it with google calendar but it is not working. As I am also unfamiliar with github so is there any clear instruction which I could follow? It would be helpful.

So far I created a personal access token but I don't know whether I created it right or wrong. It was asking so many permission but I allowed the gist permission. I connected a random repository to it. Then I created the token and put its code in ical plugin.

Then I created a gist by watching a youtube video. I created a random readme .md file so that it allow me to create a gist but after that I don't know where to find its ID to put it in plugin.

And also I don't see any option to connect it with google calendar. That's why I got confused and opened this issue. Could you please help meπŸ™.

[question] Scheduled VS Deadline in GTD workflow

Hi @andrewbrereton

As I understand how the plugin works, this one follows the following logic:β€―

  1. if there's only one planning date, it's also used as a due date... and therefore appears in the export calendar on that date.
  2. if there is only a due date, it is exported as a due date.
  3. if there is both a planning date and a due date, the due date is given priority in the agenda (even if both exist in the file).

This behavior is quite logical in a pure planning strategy, but poses a bit of a problem in a GTD logic. In GTD, it's the planning dates that are important (when I decide to do it) and the due dates, when they exist, are indicative. Not every task has a hard deadline.

I'd like to find a solution to this problem. Would you be interested?

One solution might be to export tasks with only a deadline with an emoji πŸ“… and tasks with only a schedule with an emoji βŒ› (this follows the plugin in obsidian). For tasks with both, the task would be duplicated with a first task including πŸ“… and a second including βŒ›

Ignore SyncThing sync conflict files

I use SyncThing to synchronise my files between different devices. Occasionally SyncThing will encounter a sync conflict, and when this happens, it created a conflict file.

Example:
image

Because the conflict file is also a valid Markdown file, iCal sees this and adds it to the calendar. This is causing duplicate events.

iCal should ignore Markdown files that match this:

*.sync-conflict-*.md

Save to file

Allow users to choose whether they want to save the iCalendar file to disk and/or to Gist.

  • Add setting so user can save the iCalendar file to disk
  • Add setting to user can choose where the file should be saved to
  • Add setting to user can choose the file name
  • Change Gist settings so that they are optional
  • During saveCalender(), interrogate settings to see if we should save to disk (and where) and/or save to Gist

(idea) add description in event

Hi @andrewbrereton

Since you suggested it... πŸ˜ƒ

Another idea came to me recently, so I'm writing it down here.
I sometimes put context to a task (an address, a clarification, etc.) in an indented line below the task line.

- [ ] Task test ⏳ 2024-02-06 πŸ“… 2024-02-11 πŸ›« 2024-02-07 
      A short description

It might be interesting to retrieve the content of this line and integrate it into the event description in the ical or ics file πŸ€”

Add script to make versioning easier

Currently a manual process which is prone to error. Write a little script to get the current version and update to the next major.minor.patch. It could tag too I suppose.

Difficulties with deploying the plugin

Hey! I followed your instructions from the README.md and from this issue, but I still haven't had any luck with getting the plugin to work. I have filled out all the sections in both the gist and local saving sections, but can't get either to update. I have filled out every section in both the gist and local sections. Here are the tasks I am trying to get recognized (in a To Do.md file):

- [ ] #task 2023-12-04 work on stuff

- [ ] 2023-12-05 tasks

I am running Obsidian on Macos 14. What other information do I need to provide?

Screenshot 2023-12-04 at 11 42 06β€―AM

One interesting note is that every time I paste in my github personal access key, the field gets cleared. I'm not sure if this is intentional or part of the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.