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

Adding file size to views #3539

Merged
merged 28 commits into from
Apr 19, 2018
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3650cc7
adding file size to model
ashleytqy Apr 14, 2018
b864f5a
make file size optional pproperty
ckilcrease Apr 14, 2018
3315dbd
only get filesize for files and notebooks
ckilcrease Apr 15, 2018
388d636
starting out the sort function
ashleytqy Apr 15, 2018
38acc78
add file size text
ashleytqy Apr 15, 2018
59b7c66
revert chages
ashleytqy Apr 15, 2018
86c45a1
fix sort function
ashleytqy Apr 15, 2018
a299be7
fix sorting function foreal
ashleytqy Apr 15, 2018
6475eaa
empty function to format filesize
ashleytqy Apr 15, 2018
d6c7f2e
change column width, flip order
ashleytqy Apr 17, 2018
42c3c02
converting filesize to readable format
ckilcrease Apr 17, 2018
8c96ad5
cleanup
ashleytqy Apr 17, 2018
d19f970
fixed filesize
ckilcrease Apr 17, 2018
a47a188
Merge branch 'filesize' of https://github.com/nyu-ossd-s18/notebook i…
ckilcrease Apr 17, 2018
ff8e1cc
only get filesize for files and notebooks
ckilcrease Apr 15, 2018
abe05de
change column width, flip order
ashleytqy Apr 17, 2018
13933f3
converting filesize to readable format
ckilcrease Apr 17, 2018
acc2056
fixed filesize
ckilcrease Apr 17, 2018
2e9ba4a
use pretty-bytes
ashleytqy Apr 18, 2018
8cc9734
merged changes
ckilcrease Apr 18, 2018
06214ae
remove inline css
ckilcrease Apr 18, 2018
d35ac8b
right align file size column
ashleytqy Apr 18, 2018
dd608ad
add MIT licence
ashleytqy Apr 18, 2018
577cbe5
update api description
ashleytqy Apr 18, 2018
dee58e0
use text() not html()
ashleytqy Apr 18, 2018
174e724
get file size in base model
ckilcrease Apr 18, 2018
192e3fe
remove es6 syntax
ckilcrease Apr 18, 2018
160754d
None -> null for JSON API
takluyver Apr 19, 2018
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
3 changes: 3 additions & 0 deletions notebook/services/api/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,9 @@ definitions:
type: string
description: Last modified timestamp
format: dateTime
size:
type: integer
Copy link
Member

Choose a reason for hiding this comment

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

Integer or None ? If size can't be found, probably say that in the description at least.

description: "The size of the file or notebook in bytes. If no size is provided, defaults to None."
Copy link
Member

Choose a reason for hiding this comment

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

Since this is describing a JSON API, it's probably better to refer to null, which is the JSON/Javascript name, rather than None, which is from Python. This isn't worth holding the PR up for, so I'll change it myself and then merge.

mimetype:
type: string
description: "The mimetype of a file. If content is not null, and type is 'file', this will contain the mimetype of the file, otherwise this will be null."
Expand Down
16 changes: 15 additions & 1 deletion notebook/services/contents/filemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,14 @@ def _base_model(self, path):
"""Build the common base of a contents model"""
os_path = self._get_os_path(path)
info = os.lstat(os_path)

try:
# size of file
size = info.st_size
except (ValueError, OSError):
Copy link
Member

Choose a reason for hiding this comment

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

I don't think there can be an error here - if lstat() returns, then we should have a valid stat object from which we can get st_size. But it shouldn't be a problem to be defensive in case I'm wrong.

self.log.warning('Unable to get size.')
size = None

try:
last_modified = tz.utcfromtimestamp(info.st_mtime)
except (ValueError, OSError):
Expand All @@ -270,6 +278,8 @@ def _base_model(self, path):
model['content'] = None
model['format'] = None
model['mimetype'] = None
model['size'] = size

try:
model['writable'] = os.access(os_path, os.W_OK)
except OSError:
Expand All @@ -296,6 +306,7 @@ def _dir_model(self, path, content=True):

model = self._base_model(path)
model['type'] = 'directory'
model['size'] = None
if content:
model['content'] = contents = []
os_dir = self._get_os_path(path)
Expand Down Expand Up @@ -333,6 +344,7 @@ def _dir_model(self, path, content=True):

return model


def _file_model(self, path, content=True, format=None):
"""Build a model for a file

Expand Down Expand Up @@ -373,13 +385,15 @@ def _notebook_model(self, path, content=True):
"""
model = self._base_model(path)
model['type'] = 'notebook'
os_path = self._get_os_path(path)

if content:
os_path = self._get_os_path(path)
nb = self._read_notebook(os_path, as_version=4)
self.mark_trusted_cells(nb, path)
model['content'] = nb
model['format'] = 'json'
self.validate_notebook_model(model)

return model

def get(self, path, content=True, type=None, format=None):
Expand Down
51 changes: 51 additions & 0 deletions notebook/static/base/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,57 @@ define([
return (order == 1) ? 1 : -1;
}
};

/**
source: https://github.com/sindresorhus/pretty-bytes
The MIT License (MIT)

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
**/
var format_filesize = function(num) {
if (num === undefined || num === null)
return;

var UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

if (!Number.isFinite(num)) {
console.error("Expected finite number, got ", typeof(num) + ": " + num);
}

var neg = num < 0;

if (neg) {
num = -num;
}

if (num < 1) {
return (neg ? '-' : '') + num + ' B';
}

var exponent = Math.min(Math.floor(Math.log10(num) / 3), UNITS.length - 1);
var numStr = Number((num / Math.pow(1000, exponent)).toPrecision(3));
var unit = UNITS[exponent];

return (neg ? '-' : '') + numStr + ' ' + unit;
}

// javascript stores text as utf16 and string indices use "code units",
// which stores high-codepoint characters as "surrogate pairs",
Expand Down Expand Up @@ -1180,6 +1230,7 @@ define([
parse_b64_data_uri: parse_b64_data_uri,
time: time,
format_datetime: format_datetime,
format_filesize: format_filesize,
datetime_sort_helper: datetime_sort_helper,
dnd_contain_file: dnd_contain_file,
js_idx_to_char_idx: js_idx_to_char_idx,
Expand Down
35 changes: 34 additions & 1 deletion notebook/static/tree/js/notebooklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,34 @@ define([
});
}

function size_sorter(ascending) {
var order = ascending ? 1 : 0;
// directories have file size of undefined
return (function(a, b) {
if (a.size === undefined) {
return (ascending) ? -1 : 1;
}

if (b.size === undefined) {
return (ascending) ? 1 : -1;
}

if (a.size > b.size) {
return (ascending) ? -1 : 1;
}

if (b.size > a.size) {
return (ascending) ? 1 : -1;
}

return 0;
});
}

var sort_functions = {
'sort-name': name_sorter,
'last-modified': modified_sorter
'last-modified': modified_sorter,
'file-size': size_sorter
};

var NotebookList = function (selector, options) {
Expand Down Expand Up @@ -520,6 +545,11 @@ define([
.addClass("item_name")
.appendTo(link);

$("<span/>")
.addClass("file_size")
.addClass("pull-right")
.appendTo(item);

$("<span/>")
.addClass("item_modified")
.addClass("pull-right")
Expand Down Expand Up @@ -835,6 +865,9 @@ define([
// Add in the date that the file was last modified
item.find(".item_modified").text(utils.format_datetime(model.last_modified));
item.find(".item_modified").attr("title", moment(model.last_modified).format("YYYY-MM-DD HH:mm"));

var filesize = utils.format_filesize(model.size);
item.find(".file_size").text(filesize || '\xA0');
};


Expand Down
5 changes: 5 additions & 0 deletions notebook/static/tree/less/tree.less
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ ul.breadcrumb {
margin-left: @dashboard_lr_pad;
}

.file_size {
width: 65px;
text-align: right;
}

[dir="rtl"] .item_modified.pull-right{
.pull-left();
}
Expand Down
6 changes: 6 additions & 0 deletions notebook/templates/tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@
{% endfor %}
</ul>
</div>
<div id="file_size" class="pull-right sort_button">
<span class="btn btn-xs btn-default sort-action" id="file-size">
{% trans %}File size{% endtrans %}
<i class="fa"></i>
</span>
</div>
<div id="last_modified" class="pull-right sort_button">
<span class="btn btn-xs btn-default sort-action" id="last-modified">
{% trans %}Last Modified{% endtrans %}
Expand Down