projectal.linkers API documentation

# projectal.linkers

Linkers provide the interface to add/update/delete links between entities. Only certain entities can link to certain other entities. When using this library, your tooling should show you which link methods are available to the Entity subclass you are using.

Note that some links require additional data in the link. You must ensure the destination object has this data before adding or updating the link (example below). See the API documentation for exact link details. Missing data will raise a `projectal.errors.ProjectalException` with information about what is missing.

An instance of an entity class that inherits from a linker is able to link to an instance of the target entity class directly.

    # Get task and staff
    task = projectal.Task.get('1b21e445-f29a...')
    staff = projectal.Staff.get('1b21e445-f29a...')

    # Task-to-Staff links require a 'resourceLink'
    staff['resourceLink'] = {'utilization': 0.6}

    # Task inherits from StaffLinker, so staff linking available
    task.link_staff(staff)

View Source

      1"""
      2Linkers provide the interface to add/update/delete links between entities.
      3Only certain entities can link to certain other entities. When using this
      4library, your tooling should show you which link methods are available
      5to the Entity subclass you are using.
      6
      7Note that some links require additional data in the link. You must ensure
      8the destination object has this data before adding or updating the link
      9(example below). See the API documentation for exact link details.
     10Missing data will raise a `projectal.errors.ProjectalException` with
     11information about what is missing.
     12
     13
     14An instance of an entity class that inherits from a linker is able to link
     15to an instance of the target entity class directly.
     16
     17```
     18# Get task and staff
     19task = projectal.Task.get('1b21e445-f29a...')
     20staff = projectal.Staff.get('1b21e445-f29a...')
     21
     22# Task-to-Staff links require a 'resourceLink'
     23staff['resourceLink'] = {'utilization': 0.6}
     24
     25# Task inherits from StaffLinker, so staff linking available
     26task.link_staff(staff)
     27```
     28
     29"""
     30
     31from projectal import api
     32
     33class BaseLinker:
     34    # _link_name is the link name (usually the entity name)
     35    _link_name = None
     36
     37    # _link_key is the key within the source object that points to the
     38    # links. E.g., 'skillList'
     39    _link_key = None
     40
     41    # _link_data_name is the key within the linked (target) object that points
     42    # to a store of custom values within that link. E.g, Skill objects,
     43    # when linked, have a 'skillLink' property that holds data about
     44    # the link.
     45    _link_data_name = None
     46
     47    # _link_type is the data type of the value in entity[link_key]. This is
     48    # usually a list since most links appear as 'skillList', 'staffList',
     49    # etc. But some links are single-entity only and appear as dicts like
     50    # project[stage] = Stage.
     51    _link_type = list
     52
     53    # _link_entity is the string name (capitalized, like Stage) of the Entity
     54    # class within this library that fetched links will be converted to.
     55    # This is useful when the name of the list differs from the entity
     56    # name. E.g: stage_list needs to be converted to Stage.
     57    _link_entity = None
     58
     59class AccessPolicyLinker(BaseLinker):
     60    """Subclass can link to Access Policies"""
     61    _link_name = 'access_policy'
     62    _link_key = 'accessPolicyList'
     63    _link_entity = 'AccessPolicy'
     64
     65    def link_access_policy(self, access_policies):
     66        self._add_link('access_policy', access_policies)
     67
     68    def unlink_access_policy(self, access_policies):
     69        self._delete_link('access_policy', access_policies)
     70
     71
     72class CompanyLinker(BaseLinker):
     73    """Subclass can link to Companies"""
     74    _link_name = 'company'
     75
     76    def link_company(self, companies):
     77        self._add_link('company', companies)
     78
     79    def unlink_company(self, companies):
     80        self._delete_link('company', companies)
     81
     82
     83class ContactLinker(BaseLinker):
     84    """Subclass can link to Contacts"""
     85    _link_name = 'contact'
     86
     87    def link_contact(self, contacts):
     88        self._add_link('contact', contacts)
     89
     90    def unlink_contact(self, contacts):
     91        self._delete_link('contact', contacts)
     92
     93
     94class CustomerLinker(BaseLinker):
     95    """Subclass can link to Customers"""
     96    _link_name = 'customer'
     97
     98    def link_customer(self, customers):
     99        self._add_link('customer', customers)
    100
    101    def unlink_customer(self, customers):
    102        self._delete_link('customer', customers)
    103
    104
    105class DepartmentLinker(BaseLinker):
    106    """Subclass can link to Departments"""
    107    _link_name = 'department'
    108
    109    def link_department(self, departments):
    110        self._add_link('department', departments)
    111
    112    def unlink_department(self, departments):
    113        self._delete_link('department', departments)
    114
    115
    116class FileLinker(BaseLinker):
    117    """Subclass can link to Files"""
    118    _link_name = 'file'
    119    _link_key = 'storageFileList'
    120
    121    def link_file(self, files):
    122        self._add_link('file', files)
    123
    124    def unlink_file(self, files):
    125        self._delete_link('file', files)
    126
    127
    128class FolderLinker(BaseLinker):
    129    """Subclass can link to Folders"""
    130    _link_name = 'folder'
    131    _link_key = 'folders'
    132
    133    def link_folder(self, folders):
    134        self._add_link('folder', folders)
    135
    136    def unlink_folder(self, folders):
    137        self._delete_link('folder', folders)
    138
    139
    140class LocationLinker(BaseLinker):
    141    """Subclass can link to Locations"""
    142    _link_name = 'location'
    143
    144    def link_location(self, locations):
    145        self._add_link('location', locations)
    146
    147    def unlink_location(self, locations):
    148        self._delete_link('location', locations)
    149
    150
    151class PermissionLinker(BaseLinker):
    152    """Subclass can link to Permissions"""
    153    _link_name = 'permission'
    154
    155    def link_permission(self, permissions):
    156        return self._add_link('permission', permissions)
    157
    158    def unlink_permission(self, permissions):
    159        return self._delete_link('permission', permissions)
    160
    161
    162class ProjectLinker(BaseLinker):
    163    """Subclass can link to Projects"""
    164    _link_name = 'project'
    165
    166    def link_project(self, projects):
    167        self._add_link('project', projects)
    168
    169    def unlink_project(self, projects):
    170        self._delete_link('project', projects)
    171
    172
    173class RebateLinker(BaseLinker):
    174    """Subclass can link to Rebates"""
    175    _link_name = 'rebate'
    176
    177    def link_rebate(self, rebates):
    178        self._add_link('rebate', rebates)
    179
    180    def unlink_rebate(self, rebates):
    181        self._delete_link('rebate', rebates)
    182
    183
    184class ResourceLinker(BaseLinker):
    185    """Subclass can link to Resources"""
    186    _link_name = 'resource'
    187    _link_data_name = 'resourceLink'
    188
    189    def link_resource(self, resources):
    190        self._add_link('resource', resources)
    191
    192    def relink_resource(self, resources):
    193        self._update_link('resource', resources)
    194
    195    def unlink_resource(self, resources):
    196        self._delete_link('resource', resources)
    197
    198
    199class SkillLinker(BaseLinker):
    200    """Subclass can link to Skills"""
    201    _link_name = 'skill'
    202    _link_data_name = 'skillLink'
    203
    204    def link_skill(self, skills):
    205        self._add_link('skill', skills)
    206
    207    def relink_skill(self, skills):
    208        self._update_link('skill', skills)
    209
    210    def unlink_skill(self, skills):
    211        self._delete_link('skill', skills)
    212
    213
    214class StaffLinker(BaseLinker):
    215    """Subclass can link to Staff"""
    216    _link_name = 'staff'
    217    _link_data_name = 'resourceLink'
    218
    219    def link_staff(self, staffs):
    220        self._add_link('staff', staffs)
    221
    222    def relink_staff(self, staffs):
    223        self._update_link('staff', staffs)
    224
    225    def unlink_staff(self, staffs):
    226        self._delete_link('staff', staffs)
    227
    228
    229class StageLinker(BaseLinker):
    230    """Subclass can link to Stages"""
    231    _link_name = 'stage'
    232    _link_key = 'stage'
    233    _link_type = dict
    234
    235    def link_stage(self, stages):
    236        self._add_link('stage', stages)
    237
    238    def unlink_stage(self, stages):
    239        self._delete_link('stage', stages)
    240
    241
    242class StageListLinker(BaseLinker):
    243    """Subclass can link to Stage List"""
    244    _link_name = 'stage_list'
    245    _link_key = 'stageList'
    246    _link_entity = 'Stage'
    247
    248    def link_stage_list(self, stages):
    249        if not isinstance(stages, list):
    250            raise api.UsageException('Stage list link must be a list')
    251        self._add_link('stage_list', stages)
    252
    253    def unlink_stage_list(self, stages):
    254        if not isinstance(stages, list):
    255            raise api.UsageException('Stage list unlink must be a list')
    256        stages = [{'uuId': s['uuId']} for s in stages]
    257        self._delete_link('stage_list', stages)
    258
    259
    260class UserLinker(BaseLinker):
    261    _link_name = 'user'
    262
    263    def link_user(self, users):
    264        self._add_link('user', users)
    265
    266    def unlink_user(self, users):
    267        self._delete_link('user', users)
    268
    269
    270class TaskLinker(BaseLinker):
    271    _link_name = 'task'
    272
    273    def link_task(self, tasks):
    274        self._add_link('task', tasks)
    275
    276    def unlink_task(self, tasks):
    277        self._delete_link('task', tasks)
    278
    279
    280class TaskTemplateLinker(BaseLinker):
    281    _link_name = 'task_template'
    282    _link_entity = 'TaskTemplate'
    283
    284    def link_task_template(self, task_templates):
    285        self._add_link('task_template', task_templates)
    286
    287    def unlink_task_template(self, task_templates):
    288        self._delete_link('task_template', task_templates)
    289
    290class TagLinker(BaseLinker):
    291    _link_name = 'tag'
    292
    293    def link_tag(self, tags):
    294        self._add_link('tag', tags)
    295
    296    def unlink_tag(self, tags):
    297        self._delete_link('tag', tags)
    298
    299class NoteLinker(BaseLinker):
    300    _link_name = 'note'
    301
    302class CalendarLinker(BaseLinker):
    303    _link_name = 'calendar'
    304
    305# Projects have a list of tasks that we can fetch using the links=
    306# method, but they have no linker methods available.
    307class TaskInProjectLinker(BaseLinker):
    308    _link_name = "task"

class BaseLinker: View Source

    34class BaseLinker:
    35    # _link_name is the link name (usually the entity name)
    36    _link_name = None
    37
    38    # _link_key is the key within the source object that points to the
    39    # links. E.g., 'skillList'
    40    _link_key = None
    41
    42    # _link_data_name is the key within the linked (target) object that points
    43    # to a store of custom values within that link. E.g, Skill objects,
    44    # when linked, have a 'skillLink' property that holds data about
    45    # the link.
    46    _link_data_name = None
    47
    48    # _link_type is the data type of the value in entity[link_key]. This is
    49    # usually a list since most links appear as 'skillList', 'staffList',
    50    # etc. But some links are single-entity only and appear as dicts like
    51    # project[stage] = Stage.
    52    _link_type = list
    53
    54    # _link_entity is the string name (capitalized, like Stage) of the Entity
    55    # class within this library that fetched links will be converted to.
    56    # This is useful when the name of the list differs from the entity
    57    # name. E.g: stage_list needs to be converted to Stage.
    58    _link_entity = None

BaseLinker()
class AccessPolicyLinker(BaseLinker): View Source

    60class AccessPolicyLinker(BaseLinker):
    61    """Subclass can link to Access Policies"""
    62    _link_name = 'access_policy'
    63    _link_key = 'accessPolicyList'
    64    _link_entity = 'AccessPolicy'
    65
    66    def link_access_policy(self, access_policies):
    67        self._add_link('access_policy', access_policies)
    68
    69    def unlink_access_policy(self, access_policies):
    70        self._delete_link('access_policy', access_policies)

Subclass can link to Access Policies

AccessPolicyLinker()
def link_access_policy(self, access_policies): View Source

    66    def link_access_policy(self, access_policies):
    67        self._add_link('access_policy', access_policies)

def unlink_access_policy(self, access_policies): View Source

    69    def unlink_access_policy(self, access_policies):
    70        self._delete_link('access_policy', access_policies)

class CompanyLinker(BaseLinker): View Source

    73class CompanyLinker(BaseLinker):
    74    """Subclass can link to Companies"""
    75    _link_name = 'company'
    76
    77    def link_company(self, companies):
    78        self._add_link('company', companies)
    79
    80    def unlink_company(self, companies):
    81        self._delete_link('company', companies)

Subclass can link to Companies

CompanyLinker()
def link_company(self, companies): View Source

    77    def link_company(self, companies):
    78        self._add_link('company', companies)

def unlink_company(self, companies): View Source

    80    def unlink_company(self, companies):
    81        self._delete_link('company', companies)

class ContactLinker(BaseLinker): View Source

    84class ContactLinker(BaseLinker):
    85    """Subclass can link to Contacts"""
    86    _link_name = 'contact'
    87
    88    def link_contact(self, contacts):
    89        self._add_link('contact', contacts)
    90
    91    def unlink_contact(self, contacts):
    92        self._delete_link('contact', contacts)

Subclass can link to Contacts

ContactLinker()
def link_contact(self, contacts): View Source

    88    def link_contact(self, contacts):
    89        self._add_link('contact', contacts)

def unlink_contact(self, contacts): View Source

    91    def unlink_contact(self, contacts):
    92        self._delete_link('contact', contacts)

class CustomerLinker(BaseLinker): View Source

     95class CustomerLinker(BaseLinker):
     96    """Subclass can link to Customers"""
     97    _link_name = 'customer'
     98
     99    def link_customer(self, customers):
    100        self._add_link('customer', customers)
    101
    102    def unlink_customer(self, customers):
    103        self._delete_link('customer', customers)

Subclass can link to Customers

CustomerLinker()
def link_customer(self, customers): View Source

     99    def link_customer(self, customers):
    100        self._add_link('customer', customers)

def unlink_customer(self, customers): View Source

    102    def unlink_customer(self, customers):
    103        self._delete_link('customer', customers)

class DepartmentLinker(BaseLinker): View Source

    106class DepartmentLinker(BaseLinker):
    107    """Subclass can link to Departments"""
    108    _link_name = 'department'
    109
    110    def link_department(self, departments):
    111        self._add_link('department', departments)
    112
    113    def unlink_department(self, departments):
    114        self._delete_link('department', departments)

Subclass can link to Departments

DepartmentLinker()
def link_department(self, departments): View Source

    110    def link_department(self, departments):
    111        self._add_link('department', departments)

def unlink_department(self, departments): View Source

    113    def unlink_department(self, departments):
    114        self._delete_link('department', departments)

class FileLinker(BaseLinker): View Source

    117class FileLinker(BaseLinker):
    118    """Subclass can link to Files"""
    119    _link_name = 'file'
    120    _link_key = 'storageFileList'
    121
    122    def link_file(self, files):
    123        self._add_link('file', files)
    124
    125    def unlink_file(self, files):
    126        self._delete_link('file', files)

Subclass can link to Files

FileLinker()
def link_file(self, files): View Source

    122    def link_file(self, files):
    123        self._add_link('file', files)

def unlink_file(self, files): View Source

    125    def unlink_file(self, files):
    126        self._delete_link('file', files)

class FolderLinker(BaseLinker): View Source

    129class FolderLinker(BaseLinker):
    130    """Subclass can link to Folders"""
    131    _link_name = 'folder'
    132    _link_key = 'folders'
    133
    134    def link_folder(self, folders):
    135        self._add_link('folder', folders)
    136
    137    def unlink_folder(self, folders):
    138        self._delete_link('folder', folders)

Subclass can link to Folders

FolderLinker()
def link_folder(self, folders): View Source

    134    def link_folder(self, folders):
    135        self._add_link('folder', folders)

def unlink_folder(self, folders): View Source

    137    def unlink_folder(self, folders):
    138        self._delete_link('folder', folders)

class LocationLinker(BaseLinker): View Source

    141class LocationLinker(BaseLinker):
    142    """Subclass can link to Locations"""
    143    _link_name = 'location'
    144
    145    def link_location(self, locations):
    146        self._add_link('location', locations)
    147
    148    def unlink_location(self, locations):
    149        self._delete_link('location', locations)

Subclass can link to Locations

LocationLinker()
def link_location(self, locations): View Source

    145    def link_location(self, locations):
    146        self._add_link('location', locations)

def unlink_location(self, locations): View Source

    148    def unlink_location(self, locations):
    149        self._delete_link('location', locations)

class PermissionLinker(BaseLinker): View Source

    152class PermissionLinker(BaseLinker):
    153    """Subclass can link to Permissions"""
    154    _link_name = 'permission'
    155
    156    def link_permission(self, permissions):
    157        return self._add_link('permission', permissions)
    158
    159    def unlink_permission(self, permissions):
    160        return self._delete_link('permission', permissions)

Subclass can link to Permissions

PermissionLinker()
def link_permission(self, permissions): View Source

    156    def link_permission(self, permissions):
    157        return self._add_link('permission', permissions)

def unlink_permission(self, permissions): View Source

    159    def unlink_permission(self, permissions):
    160        return self._delete_link('permission', permissions)

class ProjectLinker(BaseLinker): View Source

    163class ProjectLinker(BaseLinker):
    164    """Subclass can link to Projects"""
    165    _link_name = 'project'
    166
    167    def link_project(self, projects):
    168        self._add_link('project', projects)
    169
    170    def unlink_project(self, projects):
    171        self._delete_link('project', projects)

Subclass can link to Projects

ProjectLinker()
def link_project(self, projects): View Source

    167    def link_project(self, projects):
    168        self._add_link('project', projects)

def unlink_project(self, projects): View Source

    170    def unlink_project(self, projects):
    171        self._delete_link('project', projects)

class RebateLinker(BaseLinker): View Source

    174class RebateLinker(BaseLinker):
    175    """Subclass can link to Rebates"""
    176    _link_name = 'rebate'
    177
    178    def link_rebate(self, rebates):
    179        self._add_link('rebate', rebates)
    180
    181    def unlink_rebate(self, rebates):
    182        self._delete_link('rebate', rebates)

Subclass can link to Rebates

RebateLinker()
def link_rebate(self, rebates): View Source

    178    def link_rebate(self, rebates):
    179        self._add_link('rebate', rebates)

def unlink_rebate(self, rebates): View Source

    181    def unlink_rebate(self, rebates):
    182        self._delete_link('rebate', rebates)

class ResourceLinker(BaseLinker): View Source

    185class ResourceLinker(BaseLinker):
    186    """Subclass can link to Resources"""
    187    _link_name = 'resource'
    188    _link_data_name = 'resourceLink'
    189
    190    def link_resource(self, resources):
    191        self._add_link('resource', resources)
    192
    193    def relink_resource(self, resources):
    194        self._update_link('resource', resources)
    195
    196    def unlink_resource(self, resources):
    197        self._delete_link('resource', resources)

Subclass can link to Resources

ResourceLinker()
def link_resource(self, resources): View Source

    190    def link_resource(self, resources):
    191        self._add_link('resource', resources)

def relink_resource(self, resources): View Source

    193    def relink_resource(self, resources):
    194        self._update_link('resource', resources)

def unlink_resource(self, resources): View Source

    196    def unlink_resource(self, resources):
    197        self._delete_link('resource', resources)

class SkillLinker(BaseLinker): View Source

    200class SkillLinker(BaseLinker):
    201    """Subclass can link to Skills"""
    202    _link_name = 'skill'
    203    _link_data_name = 'skillLink'
    204
    205    def link_skill(self, skills):
    206        self._add_link('skill', skills)
    207
    208    def relink_skill(self, skills):
    209        self._update_link('skill', skills)
    210
    211    def unlink_skill(self, skills):
    212        self._delete_link('skill', skills)

Subclass can link to Skills

SkillLinker()
def link_skill(self, skills): View Source

    205    def link_skill(self, skills):
    206        self._add_link('skill', skills)

def relink_skill(self, skills): View Source

    208    def relink_skill(self, skills):
    209        self._update_link('skill', skills)

def unlink_skill(self, skills): View Source

    211    def unlink_skill(self, skills):
    212        self._delete_link('skill', skills)

class StaffLinker(BaseLinker): View Source

    215class StaffLinker(BaseLinker):
    216    """Subclass can link to Staff"""
    217    _link_name = 'staff'
    218    _link_data_name = 'resourceLink'
    219
    220    def link_staff(self, staffs):
    221        self._add_link('staff', staffs)
    222
    223    def relink_staff(self, staffs):
    224        self._update_link('staff', staffs)
    225
    226    def unlink_staff(self, staffs):
    227        self._delete_link('staff', staffs)

Subclass can link to Staff

StaffLinker()
def link_staff(self, staffs): View Source

    220    def link_staff(self, staffs):
    221        self._add_link('staff', staffs)

def relink_staff(self, staffs): View Source

    223    def relink_staff(self, staffs):
    224        self._update_link('staff', staffs)

def unlink_staff(self, staffs): View Source

    226    def unlink_staff(self, staffs):
    227        self._delete_link('staff', staffs)

class StageLinker(BaseLinker): View Source

    230class StageLinker(BaseLinker):
    231    """Subclass can link to Stages"""
    232    _link_name = 'stage'
    233    _link_key = 'stage'
    234    _link_type = dict
    235
    236    def link_stage(self, stages):
    237        self._add_link('stage', stages)
    238
    239    def unlink_stage(self, stages):
    240        self._delete_link('stage', stages)

Subclass can link to Stages

StageLinker()
def link_stage(self, stages): View Source

    236    def link_stage(self, stages):
    237        self._add_link('stage', stages)

def unlink_stage(self, stages): View Source

    239    def unlink_stage(self, stages):
    240        self._delete_link('stage', stages)

class StageListLinker(BaseLinker): View Source

    243class StageListLinker(BaseLinker):
    244    """Subclass can link to Stage List"""
    245    _link_name = 'stage_list'
    246    _link_key = 'stageList'
    247    _link_entity = 'Stage'
    248
    249    def link_stage_list(self, stages):
    250        if not isinstance(stages, list):
    251            raise api.UsageException('Stage list link must be a list')
    252        self._add_link('stage_list', stages)
    253
    254    def unlink_stage_list(self, stages):
    255        if not isinstance(stages, list):
    256            raise api.UsageException('Stage list unlink must be a list')
    257        stages = [{'uuId': s['uuId']} for s in stages]
    258        self._delete_link('stage_list', stages)

Subclass can link to Stage List

StageListLinker()
def link_stage_list(self, stages): View Source

    249    def link_stage_list(self, stages):
    250        if not isinstance(stages, list):
    251            raise api.UsageException('Stage list link must be a list')
    252        self._add_link('stage_list', stages)

def unlink_stage_list(self, stages): View Source

    254    def unlink_stage_list(self, stages):
    255        if not isinstance(stages, list):
    256            raise api.UsageException('Stage list unlink must be a list')
    257        stages = [{'uuId': s['uuId']} for s in stages]
    258        self._delete_link('stage_list', stages)

class UserLinker(BaseLinker): View Source

    261class UserLinker(BaseLinker):
    262    _link_name = 'user'
    263
    264    def link_user(self, users):
    265        self._add_link('user', users)
    266
    267    def unlink_user(self, users):
    268        self._delete_link('user', users)

UserLinker()
def link_user(self, users): View Source

    264    def link_user(self, users):
    265        self._add_link('user', users)

def unlink_user(self, users): View Source

    267    def unlink_user(self, users):
    268        self._delete_link('user', users)

class TaskLinker(BaseLinker): View Source

    271class TaskLinker(BaseLinker):
    272    _link_name = 'task'
    273
    274    def link_task(self, tasks):
    275        self._add_link('task', tasks)
    276
    277    def unlink_task(self, tasks):
    278        self._delete_link('task', tasks)

TaskLinker()
def link_task(self, tasks): View Source

    274    def link_task(self, tasks):
    275        self._add_link('task', tasks)

def unlink_task(self, tasks): View Source

    277    def unlink_task(self, tasks):
    278        self._delete_link('task', tasks)

class TaskTemplateLinker(BaseLinker): View Source

    281class TaskTemplateLinker(BaseLinker):
    282    _link_name = 'task_template'
    283    _link_entity = 'TaskTemplate'
    284
    285    def link_task_template(self, task_templates):
    286        self._add_link('task_template', task_templates)
    287
    288    def unlink_task_template(self, task_templates):
    289        self._delete_link('task_template', task_templates)

TaskTemplateLinker()
def link_task_template(self, task_templates): View Source

    285    def link_task_template(self, task_templates):
    286        self._add_link('task_template', task_templates)

def unlink_task_template(self, task_templates): View Source

    288    def unlink_task_template(self, task_templates):
    289        self._delete_link('task_template', task_templates)

class TagLinker(BaseLinker): View Source

    291class TagLinker(BaseLinker):
    292    _link_name = 'tag'
    293
    294    def link_tag(self, tags):
    295        self._add_link('tag', tags)
    296
    297    def unlink_tag(self, tags):
    298        self._delete_link('tag', tags)

TagLinker()
def link_tag(self, tags): View Source

    294    def link_tag(self, tags):
    295        self._add_link('tag', tags)

def unlink_tag(self, tags): View Source

    297    def unlink_tag(self, tags):
    298        self._delete_link('tag', tags)

class NoteLinker(BaseLinker): View Source

    300class NoteLinker(BaseLinker):
    301    _link_name = 'note'

NoteLinker()
class CalendarLinker(BaseLinker): View Source

    303class CalendarLinker(BaseLinker):
    304    _link_name = 'calendar'

CalendarLinker()
class TaskInProjectLinker(BaseLinker): View Source

    308class TaskInProjectLinker(BaseLinker):
    309    _link_name = "task"

TaskInProjectLinker()