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.
