continuing: I'm still struggling to understand how the... [fieldscheck] and 
 [ticketvalidator] entries in trac.ini are passing their values to the 
code, but I think all I need is some time to understand it.

On Friday, March 27, 2015 at 2:09:59 PM UTC-5, pineapplehandler wrote:
>
> I think I made some headway here. I removed ticketvalidator and deleted 
> the plugin folders:
> easy_install -m ticketvalidator
> rm -rf TicketValidator-0.2*
>
> Then I downloaded the source as a .zip file and unpacked it:
> unzip ticketvalidatorplugin.zip
> cp ticketvalidatorplugin/11/0.11/ticketvalidator/ /usr/local/lib/python2.7
> /dist-packages/
>
> Then I installed it using the *develop* switch:
> cd /usr/local/lib/python2.7/dist-packages/ticketvalidator/
> python setup.py develop
>
> Now I can make changes in core.py or admin.py and the changes take effect 
> almost (*) immediately, rather than having to recompile a new core.pyc.
>
> I'm still struggling to understand how the 
>
> From the docs 
> <http://pythonhosted.org//setuptools/setuptools.html#development-mode>: 
>
>>  It works very similarly to setup.py install or the EasyInstall tool, 
>> except that it doesn’t actually install anything. Instead, it creates a 
>> special .egg-link file in the deployment directory, that links to your 
>> project’s source code.
>>
>
> (*) Sometimes I am able to modify and save changes to admin.py and hit 
> refresh on my browser and see the changes. However when demonstrating this 
> to a colleague, of course it stopped behaving that way and I had to bounce 
> apache.
>
> On Friday, March 27, 2015 at 9:57:43 AM UTC-5, pineapplehandler wrote:
>>
>> Thanks for sharing this code John. I'm trying to recreate your mod and 
>> follow the steps:
>>>
>>> All I did was mod the core.py file, then re-run the setup.py, copy the 
>>> egg, and bounce the server
>>
>> but when I run 'python setup.py install' it seems to break the plugin. 
>> Can anyone share in more detail how exactly a Python plugin can be modified?
>>
>> On Tuesday, June 16, 2009 at 1:37:56 PM UTC-5, Dan Winslow wrote:
>>>
>>> Well, I can inline the code for ticketvalidator/core.py...be aware that 
>>> I know virtually nothing about python and was operating totally in the 
>>> dark. This operates off of an addition to the ini file as so : 
>>>
>>> [fieldscheck] 
>>> actual_hours = int,1,200 
>>> date_due = date 
>>> estimate_hours = int,1,200 
>>>
>>> the params for the field name are <data type>, optional val, optional 
>>> val. The 'int' means integer and the two optionals are min and max. Right 
>>> now int is the only one implemented, but you can see there's a case for 
>>> others. All I did was mod the core.py file, then re-run the setup.py, copy 
>>> the egg, and bounce the server. You should diff this with the stock core.py 
>>> to see the changes. Basically, I added _is_not_integer and also hacked the 
>>> validate_ticket function. 
>>>
>>>
>>>
>>> # -*- coding: utf-8 -*- 
>>> # 
>>> # Copyright (C) 2008 Max Stewart 
>>> # All rights reserved. 
>>> # 
>>> # This file is part of the TicketValidator plugin for Trac 
>>> # 
>>> # TicketValidator is free software: you can redistribute it and/or 
>>> # modify it under the terms of the GNU General Public License as 
>>> # published by the Free Software Foundation, either version 3 of 
>>> # the License, or (at your option) any later version. 
>>> # 
>>> # TicketValidator is distributed in the hope that it will be useful, 
>>> # but WITHOUT ANY WARRANTY; without even the implied warranty of 
>>> # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
>>> # GNU General Public License for more details. 
>>> # 
>>> # You should have received a copy of the GNU General Public License 
>>> # along with TicketValidator.  If not, see 
>>> # <http://www.gnu.org/licenses/>. 
>>>
>>> from trac.core import * 
>>> from trac.ticket import ITicketManipulator 
>>> from trac.ticket import TicketSystem 
>>>
>>> class RequiredFieldValidator(Component): 
>>>     """Basic ticket validator for required fields""" 
>>>
>>>     implements(ITicketManipulator) 
>>>
>>>     def _is_not_integer(self, value): 
>>>         if value is None: 
>>>             return True 
>>>         try: 
>>>             dummy = int(value.strip()) 
>>>             return False 
>>>         except ValueError: 
>>>             # 'source' does not represent a number 
>>>             return True 
>>>         return False 
>>>
>>>
>>>
>>>     def _is_empty(self, value): 
>>>         """Check if 'value' is empty. 
>>>
>>>         :param value: the value to check 
>>>         :type value: object""" 
>>>
>>>         if value is None: 
>>>             return True 
>>>
>>>         if len(value) == 0: 
>>>             return True 
>>>
>>>         return False 
>>>
>>>     def prepare_ticket(self, req, ticket, fields, actions): 
>>>         """Not currently called, but should be provided for future 
>>>         compatibility.""" 
>>>
>>>     def validate_ticket(self, req, ticket): 
>>>         """Make sure required fields for the next state have been 
>>>         the ticket will be in have been entered.""" 
>>>
>>>         state = self._get_state(req, ticket) 
>>>         res   = ticket["resolution"] 
>>>
>>>         #this section forces certain values based on resolution 
>>>         if res == "canceled - duplicate": 
>>>             ticket["actual_hours"]="0" 
>>>             ticket["estimate_hours"]="0" 
>>>             ticket["date_due"]="" 
>>>
>>>         #this section validates based on required and type lookup tables 
>>>         errors=[] 
>>>         required_fields = self.config.getlist('ticketvalidator',state + 
>>> '.required') 
>>>         for field_name in required_fields: 
>>>            field_name=field_name.lower() 
>>>            self.env.log.info("found required field name %s" % 
>>> field_name) 
>>>            flist = self.config.getlist('fieldscheck',field_name) 
>>>            if flist: 
>>>                self.env.log.info(" found custom validate for %s type : 
>>> %s value : %s" 
>>>                                  % 
>>> (field_name,flist[0],ticket[field_name])) 
>>>                if flist[0] == "int": 
>>>                    if self._is_not_integer(ticket[field_name]): 
>>>                        errors.append((field_name, '%s must be an integer 
>>> range %s to %s' % 
>>>                        (field_name,flist[1],flist[2]))) 
>>>                elif flist[0] == "date": 
>>>                    if ticket[field_name]=="<click to set date>" or 
>>> ticket[field_name]=="": 
>>>                        errors.append((field_name, '%s must be set to a 
>>> date.' % field_name)) 
>>>                else: 
>>>                    if self._is_empty(ticket[field_name]): 
>>>                        errors.append((field_name, ' cannot be empty.')) 
>>>            else: 
>>>                if self._is_empty(ticket[field_name]): 
>>>                    errors.append((field_name, ' cannot be empty.')) 
>>>
>>>         #this section does special validation based on resolution 
>>>         if state == "closed": 
>>>             self.env.log.info("resolution : %s" % ticket["resolution"]) 
>>>             if ticket["resolution"] == "canceled - duplicate": 
>>>                 if self._is_empty(ticket["duplicate"]): 
>>>                     errors.append(("duplicate", ' cannot be empty.')) 
>>>
>>>
>>>         #errors=[(field_name, '%s must be an integer' % field_name) 
>>>         #          for field_name in editcheck_fields 
>>>         #          if self._is_not_integer(ticket[field_name])] 
>>>
>>>         #required_fields = self.config.getlist('ticketvalidator', 
>>>         #                                      state + '.required') 
>>>
>>>         #errors = [(field_name, '%s is required' % field_name) 
>>>         #           for field_name in required_fields 
>>>         #           if self._is_empty(ticket[field_name])] 
>>>
>>>         return errors 
>>>
>>>     def _get_state(self, req, ticket): 
>>>         """Get the state this ticket is going to be in.""" 
>>>
>>>         if 'action' not in req.args: 
>>>             return 'new' 
>>>
>>>         action = req.args['action'] 
>>>         action_changes = {} 
>>>
>>>         for controller in self._get_action_controllers(req, ticket, 
>>> action): 
>>>             action_changes.update(controller.get_ticket_changes(req, 
>>> ticket, action)) 
>>>
>>>         return 'status' in action_changes and action_changes['status'] 
>>> or ticket['status'] 
>>>
>>>     def _get_action_controllers(self, req, ticket, action): 
>>>
>>>         for controller in TicketSystem(self.env).action_controllers: 
>>>             actions = [action for weight, action in 
>>>                        controller.get_ticket_actions(req, ticket)] 
>>>             if action in actions: 
>>>                 yield controller 
>>>
>>>
>>> -----Original Message----- 
>>> From: [email protected] [mailto:[email protected]] On 
>>> Behalf Of yoheeb 
>>> Sent: Tuesday, June 16, 2009 1:01 PM 
>>> To: Trac Users 
>>> Subject: [Trac] Re: Mandatory fields 
>>>
>>>
>>> On Jun 10, 3:33 pm, "Dan Winslow" <[email protected]> wrote: 
>>> > You can use a couple different plugins. I wound up using 
>>> TicketValidator 
>>> > plugin...although I had to modify it to do more than just check if the 
>>> > field was blank or not. 
>>> > 
>>> > -----Original Message----- 
>>> > From: [email protected] [mailto:[email protected]] 
>>> > 
>>> > On Behalf Of John Andrunas 
>>> > Sent: Wednesday, June 10, 2009 3:22 PM 
>>> > To: [email protected] 
>>> > Subject: [Trac] Mandatory fields 
>>> > 
>>> > Is there any way to make mandatory fields in trac?  I don't seen any 
>>> > way but it seems like the kind of thing that would be in there. 
>>> > 
>>> > -- 
>>> > John 
>>>
>>> Any chance you could post these modifications to the hack as an 
>>> attachment or something similiar? 
>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups "Trac 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Reply via email to