Commits

Dan Boitnott committed 06a36be

Improvements to output display

Comments (0)

Files changed (6)

             for fp in self.fps:
                 fp.close()
             self.closed = True
+
+class CommandOutput(object):
+    def __init__(self, path):
+        with open(path, 'r') as fp:
+            lines = [ line.rstrip() for line in fp ]
+
+        # Parse header
+        self.headers = {}
+        bodyStart = 0
+        for i in range(len(lines)):
+            line = lines[i]
+            if line[0] == '=':
+                bodyStart = i + 1
+                break
+            (key, value) = line.split(':', 1)
+            self.headers[key.strip()] = value.strip()
+
+        # Deal with re-echo'ed lines
+        for i in range(2):
+            if lines[bodyStart].strip() == self.headers['Command']:
+                bodyStart += 1
+
+        # Read footer
+        bodyEnd = len(lines) - 1
+        for i in range(bodyEnd, bodyStart, -1):
+            line = lines[i]
+            if line[0] == '=':
+                bodyEnd = i
+                break
+            (key, value) = line.split(':', 1)
+            self.headers[key.strip()] = value.strip()
+
+        # Remove trailing blank lines
+        while bodyEnd > bodyStart and lines[bodyEnd-1].strip() == '':
+            bodyEnd -= 1
+
+        self.bodyLines = lines[bodyStart:bodyEnd]
+
+    def getBody(self):
+        return '\n'.join(self.bodyLines)
+
+    def tail(self, lines = 10):
+        return '\n'.join(self.bodyLines[-lines:])
+
+    def head(self, lines = 10):
+        return '\n'.join(self.bodyLines[:lines])
Add a comment to this file

src/resources/static/edit-icon.png

Added
New image

src/resources/static/global.css

     border: 1px solid black;
     padding: 5px;
     margin: 5px;
+    position: relative;
 }
 
 .CommentTask {
     border-top: 1px dashed #454545;
     margin-top: 5px;
     padding-top: 5px;
+}
+
+.taskTools {
+    position: absolute;
+    top: 3px;
+    right: 3px;
 }

src/resources/templates/index.mustache

 
 {{#tasks}}
     <div class="TaskBox {{class}} {{colorClass}}">
+        <div class="taskTools">
+            <a href="editTask"><img src="static/edit-icon.png" alt="Edit Task" title="Edit Task"/></a>
+        </div>
         <pre>{{lines}}</pre>
         {{#isCommandTask}}
             {{#hasOutput}}
+                <pre class="taskOutput">{{lastOutputTail}}</pre>
                 <form class="viewOutputForm">
                     Output:
                     <select>
     """Returns the output of a command run at the given timestamp. ts should exactly match the one returned from
        getCommandOutputTimes()"""
 
-    fp = open(getCommandOutputPath(cmd, ts), 'r')
-    with fp:
-        return fp.read()
+    return output.CommandOutput(getCommandOutputPath(cmd, ts))
 
 def printToUser(msg, reprompt = True):
     # Print to STDERR so that it won't be sent to the shell
 RESOURCES = "resources"
 STATIC = "static"
 TEMPLATES = "templates"
+TAIL_LINES = 10
 
 def resourcePath(*args):
 	return os.path.abspath(os.path.join(os.path.dirname(__file__), RESOURCES, *args))
             else:
                 colorClass = '' # Comments are all colored the same
 
+            if len(times) > 0:
+                lastOutput = state.getCommandOutput(task.content.strip(), times[0])
+                lastOutputTail = lastOutput.tail(TAIL_LINES)
+                outputIsTail = len(lastOutput.bodyLines) > TAIL_LINES
+            else:
+                lastOutputTail = ''
+                outputIsTail = False
+
             tasks.append({
                 "class"         : task.__class__.__name__,
                 "isCommentTask" : type(task) is scripts.CommentTask,
                 "lines"         : "\n".join(task.getLines()),
                 "colorClass"    : colorClass,
                 "output"        : output,
-                "hasOutput"     : len(output) > 0
+                "hasOutput"     : len(output) > 0,
+                "lastOutputTail": lastOutputTail,
+                "outputIsTail"  : outputIsTail
             })
 
         self.sendTemplate("index", tasks=tasks, dirname=os.path.basename(os.getcwd()))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.