Skip to content

Commit

Permalink
starting on #82
Browse files Browse the repository at this point in the history
  • Loading branch information
timkpaine committed Dec 14, 2019
1 parent 62c7cfc commit 7e9bc16
Show file tree
Hide file tree
Showing 22 changed files with 2,804 additions and 15 deletions.
Binary file modified paperboy.db
Binary file not shown.
4 changes: 2 additions & 2 deletions paperboy/assets/static/css/font-awesome.min.css

Large diffs are not rendered by default.

Binary file added paperboy/assets/static/fonts/FontAwesome.otf
Binary file not shown.
Binary file not shown.
2,671 changes: 2,671 additions & 0 deletions paperboy/assets/static/fonts/fontawesome-webfont.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file modified paperboy/assets/static/fonts/fontawesome-webfont.woff
Binary file not shown.
Binary file not shown.
6 changes: 3 additions & 3 deletions paperboy/assets/static/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion paperboy/config/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def _validate_auth(self, proposed):
##################
# Output #
##################
output = Instance(klass=LocalOutputConfig, args=(), kwargs={})
output = Instance(klass=LocalOutputConfig, args=(), kwargs={}) # TODO make configurable
##################

def start(self):
Expand Down
3 changes: 2 additions & 1 deletion paperboy/config/storage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from traitlets import HasTraits, Unicode, Bool
from ..storage.sqla import UserSQLStorage, NotebookSQLStorage, JobSQLStorage, ReportSQLStorage
from ..storage.sqla import UserSQLStorage, NotebookSQLStorage, JobSQLStorage, ReportSQLStorage, OutputSQLStorage


class StorageConfig(HasTraits):
Expand All @@ -23,3 +23,4 @@ class SQLAStorageConfig(StorageConfig):
notebook_storage = NotebookSQLStorage
job_storage = JobSQLStorage
report_storage = ReportSQLStorage
output_storage = OutputSQLStorage
6 changes: 5 additions & 1 deletion paperboy/server/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ def from_api(url):
###########
# Storage #
###########
db = StorageEngine(config.storage.user_storage(config), config.storage.notebook_storage(config), config.storage.job_storage(config), config.storage.report_storage(config))
db = StorageEngine(config.storage.user_storage(config),
config.storage.notebook_storage(config),
config.storage.job_storage(config),
config.storage.report_storage(config),
config.storage.output_storage(config))
api = falcon.API(middleware=[config.auth_required_middleware(config, db),
config.load_user_middleware(config, db)] +
config.essential_middleware +
Expand Down
5 changes: 5 additions & 0 deletions paperboy/storage/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ class ReportStorage(BaseStorage):
def generate(self, *args, **kwargs):
'''Generate reports from Job instance and JSONL papermill parameters'''
pass


class OutputStorage(BaseStorage):
'''Base class for Output storage. Output backends should inherit from this class'''
pass
5 changes: 4 additions & 1 deletion paperboy/storage/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ class StorageEngine(object):
notebooks = property(lambda self: self._notebook_storage)
jobs = property(lambda self: self._job_storage)
reports = property(lambda self: self._report_storage)
outputs = property(lambda self: self._output_storage)
################################

def __init__(self, user_storage, notebook_storage, job_storage, report_storage):
def __init__(self, user_storage, notebook_storage, job_storage, report_storage, output_storage):
# resources get with self.db
self._user_storage = user_storage
self._notebook_storage = notebook_storage
self._job_storage = job_storage
self._report_storage = report_storage
self._output_storage = output_storage

# storage classes get with self.db
self._user_storage.db = self
self._notebook_storage.db = self
self._job_storage.db = self
self._report_storage.db = self
self._output_storage.db = self

def get_things(self, marker, limit):
return [{'id': str(uuid.uuid4()), 'color': 'green'}]
Expand Down
1 change: 1 addition & 0 deletions paperboy/storage/sqla/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .models.base import Base # noqa: F401
from .job import JobSQLStorage # noqa: F401
from .notebook import NotebookSQLStorage # noqa: F401
from .output import OutputSQLStorage # noqa: F401
from .report import ReportSQLStorage # noqa: F401
from .user import UserSQLStorage # noqa: F401
2 changes: 2 additions & 0 deletions paperboy/storage/sqla/models/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ReportSQL(Base):
jobId = Column(Integer, ForeignKey('jobs.id', ondelete='cascade'))
job = relationship('JobSQL', back_populates='reports')

outputs = relationship('OutputSQL', cascade='all,delete,delete-orphan', back_populates='report')

parameters = Column(String)
type = Column(String)
output = Column(String)
Expand Down
62 changes: 62 additions & 0 deletions paperboy/storage/sqla/output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import logging
from datetime import datetime
from paperboy.config import OutputConfig
from paperboy.storage import OutputStorage
from .base import BaseSQLStorageMixin, justid
from .models.report import ReportSQL
from .models.output import OutputSQL


class OutputSQLStorage(BaseSQLStorageMixin, OutputStorage):
def status(self, user, params, session, *args, **kwargs):
base = session.query(OutputSQL) \
.filter(OutputSQL.userId == int(user.id))
return {'total': base.count()}

def form(self):
'''Pass through to shared method in BaseSQLStorageMixin'''
return self._form(OutputConfig)

def search(self, user, params, session, *args, **kwargs):
'''Pass through to shared method in BaseSQLStorageMixin'''
return self._search(OutputSQL, 'Output', user, params, session, *args, **kwargs)

def list(self, user, params, session, *args, **kwargs):
'''Pass through to shared method in BaseSQLStorageMixin'''
return self._list(OutputSQL, 'outputs', user, params, session, *args, **kwargs)

def detail(self, user, params, session, *args, **kwargs):
'''Pass through to shared method in BaseSQLStorageMixin'''
return self._detail(OutputSQL, user, params, session, *args, **kwargs)

def store(self, user, params, session, *args, **kwargs):
name = params.get('name')
reportid = params.get('report')
data = params.get('data')
report = session.query(ReportSQL).get(int(justid(reportid)))

created = datetime.now()

op = OutputSQL(name=name,
reportId=reportid,
report=report,
created=created,
data=data)

session.add(op)

# generate id
session.flush()
session.refresh(op)

store = op.to_config(self.config).store()
logging.critical("Storing output {}".format(op))
return store

def delete(self, user, params, session, *args, **kwargs):
# TODO only if allowed
id = justid(params.get('id'))
op = session.query(OutputSQL).filter(OutputSQL.id == id).first()
session.delete(op)
return [{"name": "", "type": "p", "value": "Success!", "required": False, "readonly": False, "hidden": False},
{"name": "", "type": "p", "value": "Successfully deleted output: " + id, "required": False, "readonly": False, "hidden": False}]
12 changes: 12 additions & 0 deletions src/ts/define.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const COMMANDS = {
browseReports: "browse-reports",
newReport: "new-report",

// outputs
openOutputs: "open-output",
browseOutputs: "browse-outputs",

// status
openStatus: "open-status",

Expand Down Expand Up @@ -52,6 +56,10 @@ const COMMAND_ICONS = {
browseReports: "fa fa-envelope",
newReport: "fa fa-plus",

// outputs
openOutput: "fa fa-address-card",
browseOutputs: "fa fa-address-card",

// status
openStatus: "fa fa-clock-o",

Expand Down Expand Up @@ -80,6 +88,10 @@ const COMMAND_LABELS = {
browseReports: "Browse Reports",
newReport: "Add Report",

// outputs
openOutput: "Open Output",
browseOutputs: "Browse Outputs",

// status
openStatus: "Open Status",
};
8 changes: 6 additions & 2 deletions src/ts/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {DockPanel, MenuBar, Widget} from "@phosphor/widgets";

import "../src/style/index.css";
import {hideLoader, showLoader} from "./utils/index";
import {Browser, buildMenus, Header, Jobs, Notebooks, Reports, Status} from "./views/index";
import {Browser, buildMenus, Header, Jobs, Notebooks, Reports, Outputs, Status} from "./views/index";

export
function main(): void {
Expand All @@ -25,8 +25,11 @@ function main(): void {
const jobs = new Jobs(main, status);
/* Create Reports page */
const reports = new Reports(main, status);
/* Create Outputs page */
const outputs = new Outputs(main, status);

/* Create Search browser page */
const browser = new Browser(notebooks, jobs, reports, status);
const browser = new Browser(notebooks, jobs, reports, outputs, status);

browser.title.label = "Home";
browser.title.closable = true;
Expand All @@ -44,6 +47,7 @@ function main(): void {
main,
notebooks,
reports,
outputs,
status,
});

Expand Down
8 changes: 7 additions & 1 deletion src/ts/views/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {Status} from "./status";

export
class Browser extends SplitPanel {
constructor(notebooks: PrimaryTab, jobs: PrimaryTab, reports: PrimaryTab, status: Status) {
constructor(notebooks: PrimaryTab,
jobs: PrimaryTab,
reports: PrimaryTab,
outputs: PrimaryTab,
status: Status) {
super({ orientation: "vertical", spacing: 0 });
this.node.classList.add("browser");
const searchpanel = new BoxPanel();
Expand Down Expand Up @@ -70,6 +74,8 @@ class Browser extends SplitPanel {
resultspanel.addWidget(new PrimaryDetail(type, search.value, jobs, status));
} else if (type === "reports") {
resultspanel.addWidget(new PrimaryDetail(type, search.value, reports, status));
} else if (type === "outputs") {
resultspanel.addWidget(new PrimaryDetail(type, search.value, outputs, status));
}
hideLoader();
});
Expand Down
12 changes: 12 additions & 0 deletions src/ts/views/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface IMenuPages {
notebooks: PrimaryTab;
jobs: PrimaryTab;
reports: PrimaryTab;
outputs: PrimaryTab;
status: Widget;
}

Expand Down Expand Up @@ -61,6 +62,16 @@ function buildFile(pages: IMenuPages): Menu {
mnemonic: 2,
});

commands.addCommand(COMMANDS.browseOutputs, {
execute: () => {
pages.main.addWidget(pages.outputs);
pages.main.selectWidget(pages.outputs);
},
iconClass: COMMAND_ICONS.browseOutputs,
label: COMMAND_LABELS.browseOutputs,
mnemonic: 2,
});

commands.addCommand(COMMANDS.openStatus, {
execute: () => {
pages.main.addWidget(pages.status);
Expand All @@ -75,6 +86,7 @@ function buildFile(pages: IMenuPages): Menu {
menu.addItem({ command: COMMANDS.browseNotebooks});
menu.addItem({ command: COMMANDS.browseJobs});
menu.addItem({ command: COMMANDS.browseReports});
menu.addItem({ command: COMMANDS.browseOutputs});
return menu;
}

Expand Down
12 changes: 9 additions & 3 deletions src/ts/views/primary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
BoxPanel, DockPanel, Panel, Widget,
} from "@phosphor/widgets";

// tslint:disable: max-classes-per-file

import {IRequestResult, request} from "requests-helper";
import {apiurl,
createConfigForm,
Expand Down Expand Up @@ -158,26 +160,30 @@ class PrimaryTab extends Panel {
}
}

// tslint:disable-next-line: max-classes-per-file
export
class Notebooks extends PrimaryTab {
constructor(home: DockPanel, status: Status) {
super("uploader", "notebooks", status, home);
}
}

// tslint:disable-next-line: max-classes-per-file
export
class Jobs extends PrimaryTab {
constructor(home: DockPanel, status: Status) {
super("scheduler", "jobs", status, home);
}
}

// tslint:disable-next-line: max-classes-per-file
export
class Reports extends PrimaryTab {
constructor(home: DockPanel, status: Status) {
super("configurator", "reports", status, home);
}
}

export
class Outputs extends PrimaryTab {
constructor(home: DockPanel, status: Status) {
super("configurator", "outputs", status, home);
}
}

0 comments on commit 7e9bc16

Please sign in to comment.