Setting up import for plugin extras

13 views
Skip to first unread message

Chris Nelson

unread,
Mar 27, 2012, 2:05:04 PM3/27/12
to trac...@googlegroups.com
In http://groups.google.com/group/trac-dev/msg/828db3da4963ed9a?hl=en, I
got a good pointer to FullBlogPlugin as a model of how to have
conditional dependencies between plugins. I'm now trying to use that
and running into problems understanding what it all means.

I'm trying to add an IResourceCalendar implementation to TeamCalendar so
its database can drive scheduling in Trac-JSGantt. My extra is pretty
simple:

from trac.core import Component, implements
from datetime import date

from tracjsgantt.pmapi import IResourceCalendar

from teamcalendar.calendar import TeamCalendar

class TracPMConnector(Component):
implements(IResourceCalendar)
# IResourceCalendar methods

def __init__(self):
self.teamCalendar = TeamCalendar(self.env)

def hoursAvailable(self, when, resource = None):
# Scheduling works with time of day, Team Calendar is indexed
by days
date = when.date()

# Get the availability for that date.
timetable = self.teamCalendar.get_timetable(date, date, [
resource ])

# Available is 0.0 or 1.0 but could be any fraction of a day
# in the future.
available = timetable[date][resource]

# Assume 8 hours per work day.
hours = available * 8.0

return hours

and my setup.py is modeled on FullBlogPlugin:

from setuptools import setup

setup(
name = 'teamcalendar',
author = 'Martin Aspeli',
author_email = 'opti...@gmail.com',
maintainer = 'Chris Nelson',
maintainer_email = 'Chris....@SIXNET.com',
description = 'Trac plugin for managing team availability',
version = '0.1',
license='BSD',
packages=['teamcalendar'],
extras_require={
'rescal': 'Trac-jsGantt>=0.10'},
package_data={'teamcalendar': ['templates/*.html',
'htdocs/css/*.css',]},
entry_points = {
'trac.plugins': [
'teamcalendar.calendar = teamcalendar.calendar',
'teamcalendar.resourcecalendar =
teamcalendar.resourcecalender[rescal]'
]
},
install_requires = [
],
)

teamcalendar/__init__.py was:

import calendar

but for my resource calendar to show up in webadmin, I seem to have to add:

import resourcecalendar

but that would fail if TracPM wasn't available, right? How do import my
code conditionally?

Also, I have Trac-jsGantt 0.10 installed but even if I make 'rescal'
require 0.12, the resource calendar shows up in webadmin. How do I use
extras_require to only show the extra when the requirement is met?

If there's a Python setup tutorial that covers this, I haven't found it
but would welcome a pointer. Thanks.

Chris
--
Christopher Nelson, Software Engineering Manager
Sixnet, a Red Lion business | www.sixnet.com
+1 (518) 877-5173, x135

Carsten Klein

unread,
Mar 28, 2012, 5:02:35 PM3/28/12
to trac...@googlegroups.com

Hi Chris,

perhaps a look at the official documentation on how to provide
implementations for extension points, especially the topic on how to setup
your python package descriptor so that trac will automatically discover
your plugin.

See for example
http://trac.edgewall.org/wiki/TracDev/PluginDevelopment#Packagingplugins

When you package your plugin, and include a proper entry point named
trac.plugins to your setup.py, and also deploy your plugin on the python
module path, then trac's component loader will automatically load and
register your plugin with the required extension points. There is no need
to import your module explicitly.


Regards
Carsten

> --
> You received this message because you are subscribed to the Google Groups
> "Trac Development" group.
> To post to this group, send email to trac...@googlegroups.com.
> To unsubscribe from this group, send email to
> trac-dev+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/trac-dev?hl=en.
>
>


--
Carsten Klein
www.axn-software.de


Carsten Klein

unread,
Mar 28, 2012, 5:20:09 PM3/28/12
to trac...@googlegroups.com

> Also, I have Trac-jsGantt 0.10 installed but even if I make 'rescal'
> require 0.12, the resource calendar shows up in webadmin. How do I use
> extras_require to only show the extra when the requirement is met?

Now, the extras requirement is resolved during installation of your
package, for example when using pip or setup.py.

AFAIK the extras requirement is not being further examined by the
component loader responsible for automatic load of the plugins provided by
your package. Unless your component fails to instantiate during component
load due to the missing dependency which might be caused for example an
import going wrong, in that case the issue will be reported in trac.log
and the component will not be made available. Other than that, your
missing dependency might cause a runtime failure during for example
rendering of the gantt chart.... This, however will not be detected during
component load, unless you prepare the import statements so that they will
test for the available version of the required package and raise if the
requirement is not being met.

You mention that your resource calendar does show up in webadmin. After
the explicit import or without it? If so, then the component loader
already recognized your package and loaded the components it provided.

> If there's a Python setup tutorial that covers this, I haven't found it
> but would welcome a pointer. Thanks.

Just look for python distutils or use the below link :D

http://docs.python.org/distutils/index.html

Regards

Carsten

osimons

unread,
Mar 29, 2012, 6:08:50 AM3/29/12
to trac...@googlegroups.com
On Tuesday, March 27, 2012 8:05:04 PM UTC+2, Chris Nelson wrote:
In http://groups.google.com/group/trac-dev/msg/828db3da4963ed9a?hl=en, I
got a good pointer to FullBlogPlugin as a model of how to have
conditional dependencies between plugins.  I'm now trying to use that
and running into problems understanding what it all means.

Basically I have extracted the optional Blog features for TagsPlugin and SpamFilterPlugin into separate files, and added entry_point conditionals to only present them to Trac if they have no requirements, or have requirements that are met ('extras_require'). Your code looks to have caught the general idea of it, but your intra-code dependency explanation I cannot quite understand. So in essence; All code is installed, but pkg_resources will just present the 'entry_points' that are valid, so nothing in Trac will try to load your optional components so the code just sits there for a sunny day when requirements are met.
 
Also, I have Trac-jsGantt 0.10 installed but even if I make 'rescal'

require 0.12, the resource calendar shows up in webadmin.  How do I use
extras_require to only show the extra when the requirement is met?

If there's a Python setup tutorial that covers this, I haven't found it
but would welcome a pointer.

Check out the setuptools documentation, it is likely the most relevant. Note that extras_require can be a list of requirements, so it can be 'rescal': ['Trac-jsGantt>=0.10', 'Trac>=0.12'] (or whatever suits your code structure).

http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional-features-with-their-own-dependencies


:::simon

https://www.coderesort.com
http://trac-hacks.org/wiki/osimons

 

Chris Nelson

unread,
Mar 29, 2012, 8:44:44 AM3/29/12
to trac...@googlegroups.com
On 03/29/2012 06:08 AM, osimons wrote:
> On Tuesday, March 27, 2012 8:05:04 PM UTC+2, Chris Nelson wrote:
>
> In
> http://groups.google.com/group/trac-dev/msg/828db3da4963ed9a?hl=en
> <http://groups.google.com/group/trac-dev/msg/828db3da4963ed9a?hl=en>, I

> got a good pointer to FullBlogPlugin as a model of how to have
> conditional dependencies between plugins. I'm now trying to use that
> and running into problems understanding what it all means.
>
>
> Basically I have extracted the optional Blog features for TagsPlugin and
> SpamFilterPlugin into separate files, and added entry_point conditionals
> to only present them to Trac if they have no requirements, or have
> requirements that are met ('extras_require'). Your code looks to have
> caught the general idea of it, but your intra-code dependency
> explanation I cannot quite understand.

In TracJSGantt, I have three files:

* tracjsgantt.py - The Python wrapper around jsGantt.js
* pmapi.py - The interfaces for the Project Management adapters
* tracpm.py - The implementation of the adapters

In Team Calendar, I have:

* calendar.py - The existing calendar editor page
* resourcecalendar.py - Implements pmapi.IResourceCalendar and
accesses the database edited by calendar.py

If TracPM 0.10 or later is installed, I expect to see two components
under Team Calendar in web admin: TeamCalendar and TracPMConnector. If
TracPMConnector is enabled, TracPM uses Team Calendar's
IResourceCalendar. If not, another might be (e.g,. the one built in to
TracPM).

If TracPM 0.10 isn't installed (e.g., 0.9 is installed or there's no
TracPM at all), I want Team Calendar to work as it always has: when
enabled, there is a "Team Calendar" item on the Trac ribbon. I expect
that if that condition isn't met, there would not be a TracPMConnector
item in web admin but perhaps I've got that wrong.

(Of course, there is the further issue that TracPMConnector depends on
TeamCalendar so if the calendar isn't enabled, the connector should not.

> ...


> Check out the setuptools documentation, it is likely the most relevant.
> Note that extras_require can be a list of requirements, so it can be
> 'rescal': ['Trac-jsGantt>=0.10', 'Trac>=0.12'] (or whatever suits your
> code structure).
>
> http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional-features-with-their-own-dependencies

Thanks, I'll look there. (And at the pointers Carsten provided.)

Reply all
Reply to author
Forward
0 new messages