Skip to content

Commit

Permalink
instead of passing a link to the Mac app, just pass the query seriali…
Browse files Browse the repository at this point in the history
…zed as JSON and let the Mac app send the post request to the API to get the CSV.
  • Loading branch information
agilliland committed Feb 11, 2016
1 parent ad61be0 commit 847e253
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 20 deletions.
16 changes: 11 additions & 5 deletions OSX/Metabase/UI/MainViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ - (void)loadMainPage {
[self.webView.mainFrame loadRequest:request];
}

- (void)saveCSV:(NSString *)apiURL {
- (void)saveCSV:(NSString *)datasetQuery {
NSSavePanel *savePanel = [NSSavePanel savePanel];
savePanel.allowedFileTypes = @[@"csv"];
savePanel.allowsOtherFileTypes = NO;
Expand All @@ -133,8 +133,14 @@ - (void)saveCSV:(NSString *)apiURL {
if ([savePanel runModal] == NSFileHandlingPanelOKButton) {
NSLog(@"Will save CSV at: %@", savePanel.URL);

NSURL *url = [NSURL URLWithString:apiURL relativeToURL:[NSURL URLWithString:BaseURL()]];
NSURLRequest *csvRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
NSURL *url = [NSURL URLWithString:@"/api/dataset/csv" relativeToURL:[NSURL URLWithString:BaseURL()]];
NSString *postBody = [NSString stringWithFormat:@"query=%@",datasetQuery];
NSData *data = [postBody dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *csvRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
csvRequest.HTTPMethod = @"POST";
[csvRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[csvRequest setValue:[NSString stringWithFormat:@"%lu",(unsigned long)[data length]] forHTTPHeaderField:@"Content-Length"];
csvRequest.HTTPBody = data;
[NSURLConnection sendAsynchronousRequest:csvRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSError *writeError = nil;
[data writeToURL:savePanel.URL options:NSDataWritingAtomic error:&writeError];
Expand All @@ -159,8 +165,8 @@ - (void)injectJS {
};

// custom functions for OS X integration are available to the frontend as properties of window.OSX
context[@"OSX"] = @{@"saveCSV": ^(JSValue *apiURL){
[self saveCSV:apiURL.description];
context[@"OSX"] = @{@"saveCSV": ^(JSValue *datasetQuery){
[self saveCSV:datasetQuery.description];
}};
}

Expand Down
6 changes: 0 additions & 6 deletions frontend/src/card/card.controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,12 +358,6 @@ CardControllers.controller('CardDetail', [
visualizationModel.isRunning = isRunning;
visualizationModel.isObjectDetail = isObjectDetail;

if (queryResult && !queryResult.error) {
visualizationModel.downloadLink = '/api/dataset/csv?query=' + encodeURIComponent(JSON.stringify(card.dataset_query));
} else {
visualizationModel.downloadLink = null;
}

React.render(<QueryVisualization {...visualizationModel}/>, document.getElementById('react_qb_viz'));
}

Expand Down
13 changes: 4 additions & 9 deletions frontend/src/query_builder/QueryVisualization.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export default class QueryVisualization extends Component {
tableMetadata: PropTypes.object,
tableForeignKeys: PropTypes.array,
tableForeignKeyReferences: PropTypes.object,
downloadLink: PropTypes.string,
setDisplayFn: PropTypes.func.isRequired,
setChartColorFn: PropTypes.func.isRequired,
setSortFn: PropTypes.func.isRequired,
Expand Down Expand Up @@ -139,19 +138,15 @@ export default class QueryVisualization extends Component {
}

renderDownloadButton() {
const { downloadLink } = this.props;

// NOTE: we expect our component provider set this to something falsey if download not available
// TODO: it's likely the downloading won't work with large query expressions on the Mac App
if (downloadLink) {
const { result } = this.props;
const { card, result } = this.props;

if (result && !result.error) {
if (result && result.data && result.data.rows_truncated) {
// this is a "large" dataset, so show a modal to inform users about this and make them click again to d/l
let downloadButton;
if (window.OSX) {
downloadButton = (<button className="Button Button--primary" onClick={() => {
window.OSX.saveCSV(this.props.downloadLink);
window.OSX.saveCSV(JSON.stringify(card.dataset_query));
this.refs.downloadModal.toggle()
}}>Download CSV</button>);
} else {
Expand Down Expand Up @@ -190,7 +185,7 @@ export default class QueryVisualization extends Component {
if (window.OSX) {
return (
<a classname="mx1" title="Download this data" onClick={function() {
window.OSX.saveCSV(downloadLink);
window.OSX.saveCSV(JSON.stringify(card.dataset_query));
}}>
<Icon name='download' width="16px" height="16px" />
</a>
Expand Down

0 comments on commit 847e253

Please sign in to comment.