Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stories #13

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 49 additions & 11 deletions phpreport-report
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ class PeriodOfWork(object):
self.filter_tasks(date, day_offset, user, only_onsite)],
datetime.timedelta())

def stories(self):
stories = {}
self.get_tasks_if_necessary()
for task in self.tasks:
stories.setdefault(task.story, datetime.timedelta())
stories[task.story] += task.length()
return stories

@staticmethod
def fetch_tasks_for_all(periods):
filters = [period.filter for period in periods]
Expand Down Expand Up @@ -261,11 +269,23 @@ class AggregateReport(Report):
table_contents = []
total = datetime.timedelta()
total_onsite = datetime.timedelta()
total_stories = {}
for period in self.time_periods:
(time, time_onsite) = self.generate_report_for_period(period, table_contents)
total += time
total_onsite += time_onsite

stories = period.stories()
for story in stories:
total_stories.setdefault(story, datetime.timedelta())
total_stories[story] += stories[story]

self.formatter.generate_table(table_contents, has_headers=False)

self.formatter.generate_header("Total hours per story")
table_contents = []
for story in total_stories:
table_contents.append([story, "%s" % DateUtils.format_delta(total_stories[story])])
self.formatter.generate_table(table_contents, has_headers=False)

self.formatter.generate_header(
Expand All @@ -276,6 +296,9 @@ class AggregateReport(Report):


class DetailedReport(Report):

EOS = "PhpReportReportEOS"

def __init__(self, time_period, parent, formatter):
if parent:
header = "{0} for {1}".format(time_period, parent.header)
Expand Down Expand Up @@ -317,8 +340,15 @@ class DetailedReport(Report):
self.formatter.generate_large_text("Onsite hours worked: %s" % DateUtils.format_delta(onsite_time))

def get_stories_for_day_and_user(self, user, date):
def story_text(task):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe if the task doesn't have a story it doesn't make sense to add the time either? Also, if there is only one task for the day, isn't adding the story time a little redundant?

text = " (" + DateUtils.format_delta(task.length())
if task.story:
text += " " + task.story
text += ")"
return text

tasks_for_day = self.time_period.filter_tasks(date=date, user=user)
all_stories = " ".join([task.text + " " + task.story for task in tasks_for_day])
all_stories = " ".join([task.text + story_text(task) + self.EOS for task in tasks_for_day])

# Strip out duplicated whitespace
return re.compile(r'\s+').sub(' ', all_stories).strip()
Expand All @@ -328,7 +358,7 @@ class DetailedReport(Report):

all_dates = self.time_period.get_all_dates()
contents = [(date.strftime("%A"), self.get_stories_for_day_and_user(user, date)) for date in all_dates]
self.formatter.generate_aligned_list(contents)
self.formatter.generate_aligned_list(contents, self.EOS)

def generate_report(self):
self.pieces = []
Expand Down Expand Up @@ -365,19 +395,23 @@ class TextFormatter(object):
for row in table[1:]:
self.generate_table_row(row, lengths)

def generate_aligned_list(self, contents):
def generate_aligned_list(self, contents, separator = None):
first_column_size = max([len(content[0]) for content in contents])
format_string = "%%%i.%is: %%s\n" % (first_column_size, first_column_size)

indent = (first_column_size + 2) * ' ' # Enough to account for the day name offset.
width = 80 - len(indent)
for content in contents:
second_column = textwrap.fill(content[1],
break_long_words=False, # Don't break URLs.
width=width,
initial_indent=indent,
subsequent_indent=indent).strip()
self.pieces.append(format_string % (content[0], second_column))
second_column = []
for item in content[1].split(separator):
second_column.append(textwrap.fill(item.strip(),
break_long_words=False, # Don't break URLs.
width=width,
initial_indent=indent,
subsequent_indent=indent))
text = "\n".join(second_column).strip()
if text:
self.pieces.append(format_string % (content[0], text))

def generate_header(self, header):
self.pieces.append("\n%s\n" % header)
Expand Down Expand Up @@ -430,9 +464,13 @@ class TwikiFormatter(TextFormatter):
def generate_section_header(self, header):
self.pieces.append("\n---++++%s\n" % header)

def generate_aligned_list(self, contents):
def generate_aligned_list(self, contents, separator = None):
for content in contents:
self.pieces.append(" * *%s* - %s\n" % (content[0], content[1]))
if separator is not None:
text = content[1].replace(separator, "")
else:
text = content[1]
self.pieces.append(" * *%s* - %s\n" % (content[0], text))


def send_url_request(request):
Expand Down