Ask / Submit
3

How to create a calendar event programmatically?

asked 2019-02-17 09:36:38 +0200

jsommer gravatar image

Following the Sailfish documentation I try to use the nemo QML calendar plugin:

import org.nemomobile.calendar 1.0

In the source code of the calendar plguin I can find a usefull QML component:

Component {
    name: "NemoCalendarApi"
    prototype: "QObject"
    exports: ["org.nemomobile.calendar/Calendar 1.0"]
    isCreatable: false
    isSingleton: true
    ...
    Method {
        name: "createModification"
        type: "NemoCalendarEventModification*"
        Parameter { name: "sourceEvent"; type: "NemoCalendarEvent"; isPointer: true }
    }

Because the component is a singleton I tried this in the code to set the properties from the QML form to save the event afterwards:

    var newEvent = Calendar.createModification

Unfortuantely I get the following error:

[W] unknown:0 - Unable to create calendar database directory: "/home/nemo/.local/share/system/privileged/Calendar/mkcal"
[C] unknown:0 - semaphore_p.cpp: 57 - Unable to get semaphore /home/nemo/.local/share/system/privileged/Calendar/mkcal/db: Invalid argument (22)
[C] unknown:0 - semaphore_p.cpp: 215 - Unable to create semaphore array!
[C] unknown:0 - semaphore_p.cpp: 57 - Unable to decrement semaphore /home/nemo/.local/share/system/privileged/Calendar/mkcal/db: Success (0)
[C] unknown:0 - sqlitestorage.cpp: 180 - cannot lock "/home/nemo/.local/share/system/privileged/Calendar/mkcal/db" error "Success"

Even if this would work, the next question would be, how to retrieve the calendar Ids to provide them as options for the event form.

I found a Nemo Mobile project for a calendar. It uses QtOrganiser. Unfortunately this module is currently part of Sailfish. I get an import error:

import QtOrganizer 5.0
...
property OrganizerModel organizer: OrganizerModel {
    manager: "qtorganizer:mkcal"
    ...
}

Any ideas? Maybe there is any open source project as a template?

Another approach is to trigger the standard app for the EditEvent.qml page. Unfortunately, I couldn't find a DBus service for this purpose.

edit retag flag offensive close delete

2 Answers

Sort by » oldest newest most voted
3

answered 2019-02-18 12:02:56 +0200

updated 2019-02-18 12:07:51 +0200

The QML bindings for calendar in SailfishOS are hosted on Mer infrastructure.

To use it, import as you did import org.nemomobile.calendar 1.0.

To list notebooks, use the NotebookModel which is a QAbstractListModel. It has the following roles:

To create a new event, as you have guessed already use the Calendar singleton. It has a createNewEvent() method. To set the notebook this event should go to, use the defaultNotebook property of the singleton, or use the calendarUid property of the newly created event. Then, when ready, use the save() method of the newly created event to add it to the database.

The calendar databse is not available to the default nemo user. The running process should have elevated priviledges. Run your executable with devel-su -p ./createANewEvent today "cook pancakes" for instance. Or if you run your executable through invoker, add a file in /usr/share/mapplauncherd/privileges.d/ directory containing the path of your executable, followed by a comma and the kind of priviledges you need. See examples of files already there.

edit flag offensive delete publish link more

Comments

1

Thanks for your help. Unfortunately Calendar.createNewEvent() causes the same eroor. This is surprising. Because I have configured several calendars with many entries on my Sailfish developer device.

I don't really understand the last paragraph of your recommendation. Do you mean, that accessing the calandar is not possible within a QML based app, because read access is denied by the system? Unfortunately, I don't know what an invoker is. Do you mean I have to add an entry in the mentioned privileges file? A user of an app, wouldn't be able to do that.

jsommer ( 2019-02-24 19:14:06 +0200 )edit
1

Yes, I mean that the calendar is not readable / writable from the user nemo, QML or not. It has specific priviledged access. You have to run your app with devel-su -p. If you run from a desktop entry creating an icon in the app drawer, you have to give the exec command through invoker. Look at /usr/share/applications/jolla-calendar.desktop for an example.

Damien Caliste ( 2019-02-24 20:09:22 +0200 )edit
1

I have modified the .desktop file with the following line:

Exec=invoker /usr/bin/myAppName

I relised, that I could deploy and start the app from Qt Creator, but not independently from Qt.Creator on my device.

Further more: It is correct, that I can't distribute and app that needs access to the calendar? Because the additional file has to be created in the /usr/share/mapplauncherd/privileges.d/ path.

I have seen that jolla-calendar has not entry in the file list of the said path. I saw several files with privileges r and one with a. I think r means root and a means accounts. Is a sufficient to access the calendar?

jsommer ( 2019-02-27 14:22:08 +0200 )edit
1

Sorry, I cannot comment on Qt Creator. I'm not using it.

Your furthermore is right though. Your app cannot be distributed on store. In my knowledge, no app can access the calendar entries in the store. jolla-calendar priviledges are stored in /usr/share/mapplauncherd/privilrdges.

Damien Caliste ( 2019-02-27 20:46:16 +0200 )edit
3

answered 2019-03-03 22:30:50 +0200

jsommer gravatar image

I found an alternative way without additional user rights:

  1. Capturing event details, that a user entered on a QML page.
  2. Write a temporary file with the event in the iCalendar format. I use python for this purpose.
  3. Use the DBus interface to import the event into the calender of the user's choice.

Here are some code snippets:

Import of the required libraries.

import Nemo.DBus 2.0
import io.thp.pyotherside 1.4

Add a python item to your QML page.

Python {
    id: python

    Component.onCompleted: {
        addImportPath(Qt.resolvedUrl('.'));
        importModule('tempfilesaver', function () {});
    }

    function saveEvent(text) {
        call('tempfilesaver.filesaver.saveEvent', [text], function() {})
    }
}

Create some python code. The following snipped is very simplified to explain the basic approach. You shoud add a background thread, error handling and termporary file handling to your solution.

import pyotherside import os

class Filesaver:
    def __init__(self):
        pass

    def saveEvent(self, text):
        file = open("/path/to/temp.ics","w")
        file.write(text)
        file.close()

filesaver = Filesaver()

Add a DBus component to your QML page.

DBusInterface {
    id: calendarInterface
    service: "com.jolla.calendar.ui"
    path: "/com/jolla/calendar/ui"
    iface: "com.jolla.calendar.ui"
}

For saving an event, create the iCalendar string, store the file and call the DBus interface.

var event = "BEGIN:VCALENDAR\n"
...
python.saveEvent(event)
calendarInterface.call("importFile", ["/path/to/temp.ics"])
edit flag offensive delete publish link more

Comments

That's a very good suggestion !

Damien Caliste ( 2019-03-04 12:27:22 +0200 )edit

Have you checked how FileBrowser does it? You can import an ical-file in the calendar using filebrowser.

hsjpekka ( 2019-03-07 15:43:43 +0200 )edit

@hsjpekka. I have to check it twice. I think FileBrowser just opens the file. So instead of the BDus, the simple Qt commant might be sufficient:

Qt.openUrlExternally("/path/to/temp.ics")
jsommer ( 2019-03-07 18:14:27 +0200 )edit

Great idea. As a next step I'd like to modify or remove events. Any idea how to do that?

Already tried to modify the ics file and re-import but new file.is ignored if uuid is already in calender

Also tried to add METHOD:CANCEL or STATUS:CANCELLED but that is also ignored

jollajo ( 2019-03-07 22:43:24 +0200 )edit
Login/Signup to Answer

Question tools

Follow
5 followers

Stats

Asked: 2019-02-17 09:36:38 +0200

Seen: 356 times

Last updated: Mar 03