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