def pitz_add_person(): p = setup_options() p.add_option('-t', '--title', help='Person title') options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() person = Person( proj, title=options.title or raw_input("Person title: ").strip(), description=clepy.edit_with_editor('# Person description goes here'), ) proj.append(person) print("Added %s to the project." % person.summarized_view) proj.save_entities_to_yaml_files() if raw_input("Should I identify you as %(title)s? (y/N)" % person)\ .strip().lower().startswith('y'): person.save_as_me_yaml() print("OK, I'll recognize you as %(title)s from now on.")
def pitz_destroy(): p = setup_options() p.add_option('-t', '--title', help='Status title') options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() e = proj[args[0]] if isinstance(e, Entity): e.self_destruct(proj) print("""%(frag)s: "%(title)s" is no longer part of the project.""" % e) proj.save_entities_to_yaml_files()
def pitz_estimate_task(): # Start of code to set up project. p = setup_options() p.set_usage("%prog task [estimate]") options, args = p.parse_args() if not args: p.print_usage() return if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() # end of code to set up project. t = proj[args[0]] if len(args) == 2: est = proj[args[1]] else: est = Estimate.choose_from_already_instantiated() t['estimate'] = est # Save the project. proj.save_entities_to_yaml_files()
def pitz_add_milestone(): p = setup_options() p.add_option('-t', '--title', help='Milestone title') options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) pidfile = write_pidfile_or_die(pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() m = Milestone( proj, title=options.title or raw_input("Milestone title: ").strip(), description=clepy.edit_with_editor( '# Milestone description goes here'), reached=Milestone.choose_from_allowed_values('reached', False), ) proj.append(m) print("Added %s to the project." % m.summarized_view) proj.save_entities_to_yaml_files() os.remove(pidfile)
def pitz_attach_file(): # Generic. p = setup_options() # Every script may have a slightly different usage. p.set_usage("%prog entity file-to-attach") # This is generic. options, args = p.parse_args() if options.version: print_version() return # End of generic stuff. # Every script may have different required args. if len(args) != 2: p.print_usage() return # Generic code to build the project. pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() # Start of interesting stuff that is specific just for this script. e, filepath = proj[args[0]], args[1] e.save_attachment(filepath) # Save the project. (This could also be generic). proj.save_entities_to_yaml_files()
def pitz_claim_task(): p = setup_options() p.set_usage("%prog task") options, args = p.parse_args() if not args: p.print_usage() return if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() if not proj.me: print("Sorry, I don't know who you are.") print("Use pitz-me to add yourself to the project.") return t = proj[args[0]] t.assign(proj.me) proj.save_entities_to_yaml_files()
def pitz_add_status(): p = setup_options() p.add_option('-t', '--title', help='Status title') options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() s = Status( proj, title=options.title or raw_input("Status title: ").strip(), description=clepy.edit_with_editor('# Status description goes here'), ) proj.append(s) print("Added %s to the project." % s.summarized_view) proj.save_entities_to_yaml_files()
def setup_proj(self, p, options, args): pitzdir = Project.find_pitzdir(options.pitzdir) pidfile = write_pidfile_or_die(pitzdir) proj = Project.from_pitzdir(pitzdir) log.debug("Loaded project from %s" % proj.loaded_from) proj.pidfile = pidfile proj.find_me() return proj
class TestFromPitzdir(unittest.TestCase): def setUp(self): self.p = Project(pathname='/tmp') self.p.to_yaml_file() self.p.to_pickle() def tearDown(self): for f in glob.glob('/tmp/*.yaml'): os.unlink(f) if os.path.isfile('/tmp/project.pickle'): os.unlink('/tmp/project.pickle') def test_fresh_pickle(self): """ Verify we use the pickle when we can. """ p = Project.from_pitzdir('/tmp') assert p.loaded_from == 'pickle', p.loaded_from def test_stale_pickle(self): """ Verify we use the yaml files when the pickle is too old. """ stat = os.stat('/tmp/project.pickle') os.utime('/tmp/project.pickle', (stat.st_atime-1, stat.st_mtime-1)) print("pickle file: %s" % os.stat('/tmp/project.pickle').st_mtime) print("newest yaml file: %s" % max([os.stat(f).st_mtime for f in glob.glob('/tmp/*.yaml')])) p = Project.from_pitzdir('/tmp') assert p.loaded_from == 'yaml', p.loaded_from def test_from_yaml_files(self): """ Verify we can use the yaml files when no pickle exists. """ os.unlink('/tmp/project.pickle') p = Project.from_pitzdir('/tmp') assert p.loaded_from == 'yaml', p.loaded_from
def test_self_destruct_1(): """ Delete an entity. """ p = Project() p.pathname = '/tmp' e1 = Entity(p, title="e1", a=1, b=2) file_written = e1.to_yaml_file(p.pathname) files_deleted = e1.self_destruct(p) assert files_deleted == [file_written] assert not os.path.exists(file_written)
def test_from_yaml_file_1(m1, m2, m3): # yaml.load(...) will return m2. m2.return_value = { 'order_method_name': 'bogus_method', 'module': 'pitz.project', 'classname': 'Project'} # globals() will return m3. m3.return_value = {'bogus_method': lambda e1, e2: 1} p = Project("Bogus") b2 = p.from_yaml_file('xyz') assert b2.order_method == m3.return_value['bogus_method']
class TestSorting1(unittest.TestCase): """ Verify that we can sort on the pscore attribute. """ def setUp(self): self.p = Project(title="test pscore") self.e1 = Entity(self.p, title="e1") self.e2 = Entity(self.p, title="e2") self.e3 = Entity(self.p, title="e3") self.e4 = Entity(self.p, title="e4") print("Original order of entities:") for e in self.p: print("%(title)s %(pscore)s" % e) def test_sort(self): assert self.p.length == 4 assert self.p.order_method == \ pitz.by_milestone_status_pscore_created_time, \ self.p.order_method for e in self.p: assert e['pscore'] == 0, e['pscore'] assert list(self.p) == [self.e1, self.e2, self.e3, self.e4] self.e1['pscore'] = -10 self.p.order() print("After first pscore change") for e in self.p: print("%(title)s %(pscore)s" % e) assert list(self.p) == [self.e2, self.e3, self.e4, self.e1] self.e3['pscore'] = 10 self.p.order() print("After second pscore change") for e in self.p: print "%(title)s %(pscore)s" % e assert list(self.p) == [self.e3, self.e2, self.e4, self.e1], \ "self.p is \n---\n%s\n---\n" % self.p
def pitz_webapp(): """ This function gets run by the command-line script pitz-webapp. """ p = setup_options() p.add_option('-p', '--port', help='HTTP port (default is 9876)', type='int', action='store', default=9876) options, args = p.parse_args() pitz.setup_logging(getattr(logging, options.log_level)) if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() app = webapp.SimpleWSGIApp(proj) # Remember that the order that you add handlers matters. When a # request arrives, the app starts with the first handler added and # asks it if wants to handle that request. So, the default handler # (if you make one) belongs at the end. # Consider this section below the same as the urls.py file in # django. static_files = os.path.join(os.path.split( os.path.dirname(__file__))[0], 'static') app.handlers.append(handlers.FaviconHandler(static_files)) app.handlers.append(handlers.StaticHandler(static_files)) app.handlers.append(handlers.HelpHandler(proj)) app.handlers.append(handlers.Update(proj)) app.handlers.append(handlers.ByFragHandler(proj)) app.handlers.append(handlers.EditAttributes(proj)) app.handlers.append(handlers.Project(proj)) app.handlers.append(handlers.Team(proj)) httpd = make_server('', options.port, app) print "Serving on port %d..." % options.port httpd.serve_forever()
def test_4(self): """ Verify we can walk up and find pitzdir. """ os.chdir('/tmp/walkup/pitzdir/foo') assert Project.find_pitzdir() == '/tmp/walkup/pitzdir'
def test_1(self): """ Verify we can use the parameter """ assert Project.find_pitzdir('/tmp/walkup/pitzdir') \ == '/tmp/walkup/pitzdir'
def test_fresh_pickle(self): """ Verify we use the pickle when we can. """ p = Project.from_pitzdir('/tmp') assert p.loaded_from == 'pickle', p.loaded_from
def setUp(self): self.p = Project(title='Bogus project for testing webapp') c = Entity(self.p, title="c") Entity(self.p, title="t") matt = Person(self.p, title='matt') self.webapp = webapp.SimpleWSGIApp(self.p) self.webapp.handlers.append(handlers.HelpHandler(self.p)) Status(self.p, title='bogus status') Estimate(self.p, title='bogus estimate') Milestone(self.p, title='bogus milestone') Tag(self.p, title='bogus tag') Task(self.p, title='bogus task') Component(self.p, title='bogus component') Comment( self.p, title='bogus comment', who_said_it=matt, entity=c) Activity( self.p, title='bogus activity', who_did_it=matt, entity=c)
def test_2(self): """ Verify we check os.environ. """ os.environ['PITZDIR'] = '/tmp/walkup/pitzdir' assert Project.find_pitzdir() == '/tmp/walkup/pitzdir'
def pitz_html(): """ Write out a bunch of HTML files. """ with clepy.spinning_distraction(): p = setup_options() p.set_usage('%prog [options] directory') p.add_option('--force', help='Ignore timestamps and regenerate all files', action='store_true', default=False) options, args = p.parse_args() if options.version: print_version() return if not args: p.print_usage() sys.exit() pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() htmldir = args[0] proj.to_html(htmldir) proj.todo.to_html(htmldir) proj.milestones.to_html(htmldir) proj.tasks.to_html(htmldir) proj.components.to_html(htmldir) print("Wrote %d html files out of %d entities in project." % ( len([e for e in proj if e.to_html_file(htmldir, options.force)]), len(proj))) # Record that we rebuilt all the HTML files. proj.save_entities_to_yaml_files()
def pitz_setup(): """ Start a new project """ p = optparse.OptionParser() p.epilog = "Set up pitz" p.add_option('--version', action='store_true', help='show pitz version') options, args = p.parse_args() if options.version: print_version() return dir = os.path.basename(os.getcwd()) project_name = raw_input( "Project name (hit ENTER for %s): " % dir).strip() if not project_name: project_name = dir pitzdir = mk_pitzdir() proj = Project(pathname=pitzdir, title=project_name) proj.to_yaml_file() Status.setup_defaults(proj) pw_name = pwd.getpwuid(os.getuid()).pw_name name = raw_input("Your name (hit ENTER for %s): " % pw_name).strip() if not name: name = pw_name person = Person(proj, title=name) proj.save_entities_to_yaml_files() print("All done!") print("Run pitz-add-task to add a task, or run pitz-help for help.")
def test_from_yaml_files(self): """ Verify we can use the yaml files when no pickle exists. """ os.unlink('/tmp/project.pickle') p = Project.from_pitzdir('/tmp') assert p.loaded_from == 'yaml', p.loaded_from
def test_unpickle(self): assert not os.path.exists('/tmp/project.pickle') self.p.to_pickle('/tmp') assert os.path.exists('/tmp/project.pickle') new_p = Project.from_pickle('/tmp/project.pickle') assert self.p.length == new_p.length assert new_p.length for e in new_p: assert e.project
def pitz_add_estimate(): p = setup_options() p.add_option('-t', '--title', help='Estimate title') p.add_option('--from-builtin-estimates', action='store_true', help='Choose from estimates I already made') options, args = p.parse_args() if options.version: print_version() raise SystemExit pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() if options.from_builtin_estimates: print("Right now, you got %d estimates in your project." % (proj.estimates.length)) range = Estimate.choose_estimate_range() if range: print("Adding...") Estimate.add_range_of_estimates_to_project(proj, range) proj.save_entities_to_yaml_files() raise SystemExit est = Estimate( proj, title=options.title or raw_input("Estimate title: ").strip(), description=clepy.edit_with_editor('# Estimate description goes here'), points=int(raw_input("Points: ").strip()), ) proj.append(est) print("Added %s to the project." % est.summarized_view) proj.save_entities_to_yaml_files()
def test_setup_defaults(self): """ Verify the project calls setup_defaults. """ p = Project( entities=[ Entity(title='abc'), Entity(title='def'), Entity(title='ghi')]) m = Mock() p.classes = dict(bogus_entity=m) p.setup_defaults() assert ('setup_defaults', (p, ), {}) in m.method_calls, \ m.method_calls
class TestByPscoreAndMilestone(unittest.TestCase): def setUp(self): self.p = Project(title="test sorting...") Entity(self.p, title="a", pscore=2) Entity(self.p, title="b", pscore=1) Entity(self.p, title="c", pscore=3) def test_by_pscore_and_milestone(self): self.p.order(by_pscore_and_milestone) prevscore = 99 for e in self.p: print(e) assert e["pscore"] < prevscore, "%s, %s" % (e["pscore"], prevscore) prevscore = e["pscore"]
def test_5(self): """ Verify we can walk down and find the pitzdir. """ os.chdir('/tmp/walkdown') pitzdir_location = Project.find_pitzdir(walkdown=True) assert pitzdir_location == '/tmp/walkdown/foo/bar/baz/pitzdir', \ pitzdir_location
def pitz_shell(): """ Start an ipython session after loading in a project. """ p = setup_options() options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) pidfile = write_pidfile_or_die(pitzdir) proj = Project.from_pitzdir(pitzdir) proj._shell_mode = True proj.find_me() # Everything in this dictionary will be added to the top-level # namespace in the shell. ns = dict([(C.__name__, C) for C in proj.classes.values()]) ns['p'] = proj ns['send_through_pager'] = clepy.send_through_pager ns['edit_with_editor'] = clepy.edit_with_editor from IPython.Shell import IPShellEmbed s = IPShellEmbed(['-colors', 'Linux']) s(local_ns=ns) # This stuff happens when you close the IPython session. answer = raw_input("Write out updated yaml files? ([y]/n) ").strip() if answer.lower() not in ['n', 'no']: proj.to_yaml_file() proj.to_pickle() proj.save_entities_to_yaml_files() # Remove the pidfile. os.remove(pidfile)
def setUp(self): self.p = Project(title="test pscore") self.e1 = Entity(self.p, title="e1") self.e2 = Entity(self.p, title="e2") self.e3 = Entity(self.p, title="e3") self.e4 = Entity(self.p, title="e4") print("Original order of entities:") for e in self.p: print("%(title)s %(pscore)s" % e)
def pitz_assign_task(): """ Add this task to somebody's to-do list """ script_name = 'pitz-assign-task' p = setup_options() p.set_usage("%prog task [person]") options, args = p.parse_args() if not args: p.print_usage() return if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() t = proj[args[0]] if len(args) == 2: person = proj[args[1]] else: person = Person.choose_from_already_instantiated() if not person: print("Pick somebody!") return t.assign(person) proj.save_entities_to_yaml_files()
def pitz_me(): """ Pick a Person or make a new one, then save a me.yaml file. """ p = setup_options() options, args = p.parse_args() if options.version: print_version() return pitzdir = Project.find_pitzdir(options.pitzdir) proj = Project.from_pitzdir(pitzdir) proj.find_me() if proj.me: print("You are %(title)s." % proj.me) print("Delete this file if you want to be somebody else:") print(os.path.join(proj.pathname, 'me.yaml')) return if Person.already_instantiated: print("You may already be in pitz:") choice = Person.choose_from_already_instantiated() if choice: person = choice person.save_as_me_yaml() print("OK, I'll recognize you as %(title)s from now on." % person) return print("I'll add you to pitz.") pitz_add_person()