class ComponentSearchForm(): data_source = None related_mashups = None widget = None table = None add_btn = None graph_form = None highlighted_api = None highlighted_mashup = None categoryWindow = None dataSetListWdiget = None climateData = None def show_main_window(self): # Get datasets from server data = json.load(urllib2.urlopen(RECO_API_SERVER_ADDR + "/getAllDataSets/")) # self.climateData = self.loadClimateDataSet(data) self.climateData = self.parseServerData(data) self.graph_form = matplotlibWidget() if self.widget: self.widget.destroy() self.widget = None; self.widget = QWidget() self.widget.setMinimumSize(1000, 900) self.widget.setWindowTitle("Recommendation PlugIn") margin = 30 # Search Feature self.textboxLabel = QLabel(self.widget) self.textboxLabel.setText("Describe your goals:") self.textboxLabel.move(30, 20) self.textboxLabel.show self.textbox = QTextEdit(self.widget) self.textbox.move(30, 45) self.textbox.setFixedWidth(300) self.textbox.setFixedHeight(28) btn_api = QtGui.QPushButton("Recommend Services", self.widget) btn_api.move(30, 80) btn_mashup = QtGui.QPushButton("Recommend Workflows", self.widget) btn_mashup.move(230, 80) btn_api.clicked.connect(self.api_button_clicked) btn_mashup.clicked.connect(self.mashups_button_clicked) self.table = QTableView(self.widget) self.table.clicked.connect(self.table_clicked) self.table.setMinimumSize(600, 300) self.table.resizeColumnsToContents() self.table.move(30, 120) # Top Service self.textboxLabel = QLabel("Top Datasets (Usage)", self.widget) self.textboxLabel.move(650, 20) self.textboxLabel.show self.listWidget = QListWidget(self.widget) topDatasets = json.load(urllib2.urlopen(RECO_API_SERVER_ADDR + "/getTop10UsedDataset/")) for topDataset in topDatasets: id = int(topDataset["datasetID"]) item = QListWidgetItem("{} ({})".format(self.climateData[id]["name"], topDataset["usage"])) item.setData(Qt.UserRole,self.climateData[id]) self.listWidget.addItem(item) self.listWidget.move(650, 45) self.listWidget.resize(280, 380) self.listWidget.show() self.listWidget.clicked.connect(lambda: self.dataset_clicked(\ self.listWidget.currentItem().data(Qt.UserRole))) # Username input box and button for generating recommendations userTopOffset = 430 self.textboxLabel = QLabel("Enter username for dataset recommendations:", self.widget) self.textboxLabel.move(30, userTopOffset) self.textboxLabel.show() self.userTextbox = QTextEdit(self.widget) self.userTextbox.move(30, userTopOffset + 30) self.userTextbox.setFixedWidth(200) self.userTextbox.setFixedHeight(28) userBtn = QPushButton("Recommend Datasets", self.widget) userBtn.move(30 + self.userTextbox.width() + 10, userTopOffset + 30) #print RECO_API_SERVER_ADDR + "/getTop5RecommendationByUserName/" ## Jan.20 2016 ## Change the API names here by shenggu ## According to github.com/cmusv-sc/RecommendationAPIs ## userBtn.clicked.connect(lambda: self.getRecommendations(RECO_API_SERVER_ADDR + "/getTopKContentBasedCFRecommendedDatasetByUsername", self.recListFeature)) userBtn.clicked.connect(lambda: self.getRecommendations(RECO_API_SERVER_ADDR + "/getTopKItemBasedCFRecommendedDatasetByUsername", self.recListItem)) userBtn.clicked.connect(lambda: self.getRecommendations(RECO_API_SERVER_ADDR + "/getTopKUserBasedCFRecommendedDatasetByUsername", self.recListUser)) userBtn.show() # Test QlineEdit # self.userTextbox2 = QLineEdit(self.widget) # self.userTextbox.move(200, userTopOffset + 30) # self.userTextbox.setFixedWidth(200) # self.userTextbox.setFixedHeight(28) # Feature Recommendations recTopOffset = 500 self.textboxLabel = QLabel("Feature Recommendations", self.widget) self.textboxLabel.move(30, recTopOffset) self.textboxLabel.show() self.recListFeature = QListWidget(self.widget) self.recListFeature.move(30, recTopOffset + 30) self.recListFeature.resize(280, 250) self.recListFeature.show() # Item-based Recommendations self.textboxLabel = QLabel("Item-based Recommendations", self.widget) self.textboxLabel.move(340, recTopOffset) self.textboxLabel.show self.recListItem = QListWidget(self.widget) self.recListItem.move(340, recTopOffset + 30) self.recListItem.resize(280, 250) self.recListItem.show() # User-based Recommendations self.textboxLabel = QLabel("User-based Recommendations", self.widget) self.textboxLabel.move(650, recTopOffset) self.textboxLabel.show self.recListUser = QListWidget(self.widget) self.recListUser.move(650, recTopOffset + 30) self.recListUser.resize(280, 250) self.recListUser.show() # Categories categoryTopOffset = 300 self.textboxLabel = QLabel("Categories", self.widget) self.textboxLabel.move(30, recTopOffset + categoryTopOffset) self.textboxLabel.show button1 = QPushButton("By Agency", self.widget) button1.clicked.connect(lambda: self.listCategory_clicked("agency")) button1.move(30, recTopOffset + categoryTopOffset + 30) button1.show() button2 = QPushButton("By Instrument", self.widget) button2.clicked.connect(lambda: self.listCategory_clicked("instrument")) button2.move(margin + button1.width() + 20, recTopOffset + categoryTopOffset + 30) button2.show() button3 = QPushButton("By Data Source Input", self.widget) button3.clicked.connect(lambda: self.listCategory_clicked("input")) button3.move(margin + button1.width() + button2.width() + 40, recTopOffset + categoryTopOffset + 30) button3.show() # Show and move widget self.widget.move(QtGui.QApplication.desktop().screen().rect().center() - \ self.widget.rect().center()) self.widget.show() # Service and workflow recommendation self.add_btn = QPushButton("Add to Palette", self.widget) self.add_btn.clicked.connect(self.add_new_api) self.add_btn.hide() self.add_btn.setFixedWidth(160) self.add_btn.move(470, 20) self.recommendLabel = QLabel("Also Used", self.widget) self.recommendLabel.hide() self.recommendLabel.setFixedWidth(160) self.recommendLabel.move(470, 50) self.switch_btn_apis = QPushButton("Related Workflows", self.widget) self.switch_btn_apis.clicked.connect(self._show_related_apis) self.switch_btn_apis.hide() self.switch_btn_apis.setFixedWidth(160) self.switch_btn_apis.move(470, 80) self.switch_btn_mashups = QPushButton("Related Modules", self.widget) self.switch_btn_mashups.clicked.connect(self._show_related_mashups) self.switch_btn_mashups.hide() self.switch_btn_mashups.setFixedWidth(160) self.switch_btn_mashups.move(470, 80) def printMessage(self): print "testing" def __init__(self, parent=None): self.data_source = DataSource() def getRecommendations(self, url, listWidget): # http GET request username = str(self.userTextbox.toPlainText()) url = url + "?username=kzhang&top_num=5" # + username print url results = json.load(urllib2.urlopen(url)) # Update recommendation list listWidget.clear() for result in results: dataset = self.climateData[int(result["datasetID"])] item = QListWidgetItem(dataset["name"]) item.setData(Qt.UserRole, dataset) listWidget.addItem(item) listWidget.clicked.connect(lambda: self.dataset_clicked(\ listWidget.currentItem().data(Qt.UserRole))) def listCategory_clicked(self, category): self.categoryWindow = QWidget() c = self.categoryWindow c.setWindowTitle("Search dataset by category") c.setMinimumSize(600, 500) # Category list showing all posible options label1 = QLabel("Options by {0}:".format(category), c) label1.move(50, 20) label1.show() categoryListWidget = QListWidget(c) optionSet = set() for key in self.climateData: optionSet.add(self.climateData[key][category]) for option in sorted(list(optionSet)): item = QListWidgetItem(option) item.setData(Qt.UserRole, option) categoryListWidget.addItem(item) categoryListWidget.move(50, 50) categoryListWidget.resize(200, 400) categoryListWidget.show() categoryListWidget.clicked.connect(lambda: self.categoryItem_clicked(\ category, categoryListWidget.currentItem().data(Qt.UserRole))) # List showing all datasets associated with the selected option label2 = QLabel("Available Datasets:", c) label2.move(250, 20) label2.show() self.datasetListWidget = QListWidget(c) self.datasetListWidget.move(250, 50) self.datasetListWidget.resize(400, 400) self.datasetListWidget.show() c.move(QtGui.QApplication.desktop().screen().rect().center() - \ c.rect().center()) c.show() def categoryItem_clicked(self, category, option): self.datasetListWidget.clear() results = [] for key in self.climateData: if self.climateData[key][category] == option: results.append(self.climateData[key]) for result in sorted(results): item = QListWidgetItem(result["name"]) item.setData(Qt.UserRole,result) self.datasetListWidget.addItem(item) self.datasetListWidget.clicked.connect(lambda: self.dataset_clicked(\ self.datasetListWidget.currentItem().data(Qt.UserRole))); def dataset_clicked(self, data): # Initiate Table keyOrder = ["name", "agency", "instrument", "pvar", "var", "units", "grid", \ "webvar", "input", "start", "end"] sortedData = sorted(data.items(), key=lambda dataPair:keyOrder.index(dataPair[0])) self.topServiceTable = QTableWidget() t = self.topServiceTable t.setWindowTitle(data["name"]) t.resize(550, 400) t.setRowCount(len(data.keys())) t.setColumnCount(2) t.setColumnWidth(0, 100); t.setColumnWidth(1, 400); # Set label t.setHorizontalHeaderLabels(("Variable;Value").split(";")) # Set data for row, pair in enumerate(sortedData): t.setItem(row, 0, QTableWidgetItem(pair[0])) t.setItem(row, 1, QTableWidgetItem(pair[1])) t.move(QtGui.QApplication.desktop().screen().rect().topRight() - t.rect().topRight()) t.show() def table_clicked(self): """ Click the table, the graph form may change according to the selection. """ model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: row = index.row() # data = index.model().headerData(0,Qt.Horizontal).toString() data = index.model().headerData(0,Qt.Horizontal) newIndex = index.model().index(row, 0) if data == "API": api_id = get_api_full_name(newIndex.model().data(newIndex)) api = self.data_source.api_by_id(api_id) print api mashups = self.data_source.mashups_by_api(api) apis = [] for mashup in mashups: apis.extend(self.data_source.apis_by_mashup(mashup)) self.graph_form.draw_apis(apis, api, self.highlighted_api) else: mashup_id = get_mashup_full_name(newIndex.model().data(newIndex)) mashup = self.data_source.mashup_by_id(mashup_id) if not mashup: return apis = self.data_source.apis_by_mashup(mashup) mashups = [] if len(apis) > 0: mashups.extend(self.data_source.mashups_by_api(apis[0])) self.graph_form.draw_mashups(mashups, mashup, self.highlighted_mashup) return def _show_apis(self, apis, recommend=False): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 model = QStandardItemModel(len(apis), 4) model.setColumnCount(4) #QVariant(...) -> ... for api in apis: model.setData(model.index(row, 0), get_api_name(api)) model.setData(model.index(row, 1), api['protocols']) model.setData(model.index(row, 2), api['provider']) model.setData(model.index(row, 3), api['version']) row += 1 model.setHeaderData(0, Qt.Horizontal, "Service") # Replaced "Module" with "Service" model.setHeaderData(1, Qt.Horizontal, "Protocol") model.setHeaderData(2, Qt.Horizontal, "Provider") model.setHeaderData(3, Qt.Horizontal, "Version") self.table.setModel(model) self.table.resizeColumnsToContents() if recommend: self.recommendLabel.show() self.add_btn.show() def _show_mashups(self, mashups): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 model = QStandardItemModel(len(mashups), 4) model.setColumnCount(4) for mashup in mashups: model.setData(model.index(row, 0), get_mashup_name(mashup)) model.setData(model.index(row, 1), mashup['title']) model.setData(model.index(row, 2), mashup['self']) model.setData(model.index(row, 3), mashup['description']) row += 1 model.setHeaderData(0, Qt.Horizontal, "Workflow") model.setHeaderData(1, Qt.Horizontal, "Short Description") model.setHeaderData(2, Qt.Horizontal, "Provider") model.setHeaderData(3, Qt.Horizontal, "Detailed Info") self.table.setModel(model) self.table.resizeColumnsToContents() self.add_btn.show() def api_button_clicked(self): """ Trigger to search APIs """ self.graph_form.draw_api() self.graph_form.show() # Get user input from textbox apis = self.data_source.apis() key = str(self.textbox.toPlainText()) if key: self.api_search_button_clicked() else: self._show_apis(apis) def mashups_button_clicked(self): """ Trigger to search mashups """ self.graph_form.draw_mashup() self.graph_form.show() key = str(self.textbox.toPlainText()) print key print "button clicked" if key: self.mashup_search_button_clicked() else: self._show_mashups(self.data_source.mashups()) #Should probably refactor this into one method. def api_search_button_clicked(self): """ Search when keyword is present """ self.highlighted_api = None self.highlighted_mashup = None key = str(self.textbox.toPlainText()) if key != "": apis = self.data_source.search_api(key) self._show_apis(apis) def mashup_search_button_clicked(self): """ Search when keyword is present """ self.highlighted_api = None self.highlighted_mashup = None key = str(self.textbox.toPlainText()) if key != "": mashups = self.data_source.search_mashup(key) self._show_mashups(mashups) def add_new_api(self): """ Add new api to the modules package. """ apis = self.data_source.apis() model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: api = apis[index.row()] self._add_new_api(api) return def add_related_api(self): objs = [] for mashup in self.related_mashups: objs.append(mashup) for api in mashup["related_mashups"]: objs.append(api) model = self.table.selectionModel() indexes = model.selectedIndexes() for index in indexes: api = objs[index.row()] if api.get("protocols"): self._add_new_api(api) return def _show_related_mashups(self): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() apis = [] objs = [] for mashup in self.related_mashups: apis.extend(mashup["related_mashups"]) for api in apis: objs.append(api) mashups = self.data_source.mashups_by_api(api) objs.extend(mashups) row = 0 model = QStandardItemModel(len(objs), 4) model.setColumnCount(4) for obj in objs: if obj.get('protocols'): model.setData(model.index(row, 0), get_api_name(obj)) model.setData(model.index(row, 1), obj['protocols']) model.setData(model.index(row, 2), obj['provider']) else: model.setData(model.index(row, 3), get_mashup_name(obj)) row += 1 model.setHeaderData(0, Qt.Horizontal, "API") model.setHeaderData(1, Qt.Horizontal, "Protocols") model.setHeaderData(2, Qt.Horizontal, "Provider") model.setHeaderData(3, Qt.Horizontal, "Mashup") self.table.setModel(model) self.table.resizeColumnsToContents() self.switch_btn_apis.show() def _show_related_apis(self): self.switch_btn_apis.hide() self.switch_btn_mashups.hide() self.recommendLabel.hide() row = 0 objs = [] for mashup in self.related_mashups: objs.append(mashup) for api in mashup["related_mashups"]: objs.append(api) #Combining similarity and related. similar_apis = self.data_source.search_api_similarity(self.highlighted_api) #return str(mashup['id'])[(len("http://www.programmableweb.com/mashup/")):] objs.append({'id': "http://www.programmableweb.com/mashup/Using-Similarity-Metric"}) objs.extend(similar_apis) #Combining similarity and related. #http://localhost:9000/getReputation/John%20Lions model = QStandardItemModel(len(objs), 6) for obj in objs: if obj.get('protocols'): model.setData(model.index(row, 1), get_api_name(obj)) model.setData(model.index(row, 2), obj['protocols']) model.setData(model.index(row, 3), obj['provider']) model.setData(model.index(row, 4), obj['version']) #trust = requests.get('http://localhost:9000/getReputation/Luis Ramos').content model.setData(model.index(row, 5), str(random.random())) #model.setData(model.index(row, 5), QVariant(trust)) else: model.setData(model.index(row, 0), get_mashup_name(obj)) row += 1 model.setHeaderData(0, Qt.Horizontal, "Mashup") model.setHeaderData(1, Qt.Horizontal, "API") model.setHeaderData(2, Qt.Horizontal, "Protocols") model.setHeaderData(3, Qt.Horizontal, "Provider") model.setHeaderData(4, Qt.Horizontal, "Version") model.setHeaderData(5, Qt.Horizontal, "Trust") self.table.setModel(model) self.table.resizeColumnsToContents() self.switch_btn_mashups.show() def _add_new_api(self, api): self.highlighted_api = api mashups = self.data_source.mashups_by_api(api) for mashup in mashups: mashup['related_mashups'] = (self.data_source.apis_by_mashup(mashup)) if len(mashups) > 0: self.related_mashups = mashups self._show_related_apis() manager = core.packagemanager.get_package_manager() reg = core.modules.module_registry.get_module_registry() package = manager.get_package("edu.cmu.sv.components", "1.0.0") core.modules.module_registry.set_current_package(package) if (api["protocols"] == "SOAP" and api["wsdl"] != ""): s = Service(api["wsdl"]) # add_new_service(s, api["wsdl"]) else: new_module = vistrails_module.new_module(Module, get_api_name(api)) reg.add_module(new_module) reg.add_input_port(new_module, "value1", (core.modules.basic_modules.String, 'the first argument')) reg.add_input_port(new_module, "value2", (core.modules.basic_modules.String, 'the second argument')) reg.add_output_port(new_module, "value", (core.modules.basic_modules.String, 'the result')) # def loadClimateDataSet(self): # filename = '/home/hywel/Documents/VisTrailsRecommendation/vistrails_current/vistrails/packages/componentSearch/Climate_Datasets.csv' # with open(filename, mode='r') as infile: # reader = csv.reader(infile) # next(reader, None) # with open('coors_new.csv', mode='w') as outfile: # writer = csv.writer(outfile) # climateData = {} # for row in reader: # id = int(row[0]) # climateData[id] = {} # climateData[id]["dataset"] = row[1] # climateData[id]["agency"] = row[2] # climateData[id]["instrument"] = row[3] # climateData[id]["pvar"] = row[4] # climateData[id]["var"] = row[5] # climateData[id]["units"] = row[6] # climateData[id]["grid"] = row[7] # climateData[id]["webvar"] = row[8] # climateData[id]["input"] = row[9] # climateData[id]["start"] = row[10] # climateData[id]["end"] = row[11] # return climateData def parseServerData(self, data): climateData = {} for dataset in data: id = int(dataset["datasetID"]) climateData[id] = {} climateData[id]["name"] = dataset["dataset"] climateData[id]["agency"] = dataset["agency"] climateData[id]["instrument"] = dataset["instrument"] climateData[id]["pvar"] = dataset["pvar"] climateData[id]["var"] = dataset["var"] climateData[id]["units"] = dataset["units"] climateData[id]["grid"] = dataset["grid"] climateData[id]["webvar"] = dataset["webvar"] climateData[id]["input"] = dataset["input"] climateData[id]["start"] = dataset["start"] climateData[id]["end"] = dataset["end"] return climateData
class Ui_RightWidget(object): def setupUi(self, RightWidget, server): RightWidget.setMinimumHeight(500) main_layout = QVBoxLayout(RightWidget) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(10) # We hide all the main elements, to allow the proper viewer to enable # (only) the elements that uses. if hasattr(server, 'wild_chars'): self.text_map = QTextEdit() self.text_map.setObjectName('text_map') self.text_map.setVisible(False) self.text_map.setFocusPolicy(Qt.NoFocus) self.text_map.setAutoFillBackground(True) self.text_map.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_map.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_map.setUndoRedoEnabled(False) self.text_map.setReadOnly(True) # for some unknown reason, the fontmetrics of the text map is wrong # if the font is set with a global stylesheet, so we set it on the # specific widget. self.text_map.setStyleSheet("QTextEdit { font: 13px \"Courier\";}") main_layout.addWidget(self.text_map) # We calculate the map area size using the size of the font used. We # assume that the font is a monospace ones. font_metrics = self.text_map.fontMetrics() self.text_map.setFixedWidth(font_metrics.width('#' * server.map_width)) self.text_map.setFixedHeight(font_metrics.height() * server.map_height) # The rightwidget width is determined by the map area size RightWidget.setMinimumWidth(self.text_map.width()) else: RightWidget.setMinimumWidth(220) self.box_status = QWidget() self.box_status.setVisible(False) main_layout.addWidget(self.box_status) status_layout = QGridLayout(self.box_status) status_layout.setContentsMargins(5, 5, 5, 0) status_layout.setHorizontalSpacing(0) status_layout.setVerticalSpacing(15) label_health = QLabel() label_health.setMinimumWidth(80) label_health.setText(QApplication.translate("RightWidget", "Health")) status_layout.addWidget(label_health, 0, 0) self.bar_health = QProgressBar() self.bar_health.setObjectName("bar_health") self.bar_health.setFixedHeight(22) self.bar_health.setProperty("value", QVariant(100)) self.bar_health.setTextVisible(False) status_layout.addWidget(self.bar_health, 0, 1) label_mana = QLabel() label_mana.setMinimumWidth(80) label_mana.setText(QApplication.translate("RightWidget", "Mana")) status_layout.addWidget(label_mana, 1, 0) self.bar_mana = QProgressBar() self.bar_mana.setObjectName("bar_mana") self.bar_mana.setFixedHeight(22) self.bar_mana.setProperty("value", QVariant(100)) self.bar_mana.setTextVisible(False) status_layout.addWidget(self.bar_mana, 1, 1) label_movement = QLabel() label_movement.setMinimumWidth(80) label_movement.setText(QApplication.translate("RightWidget", "Movement")) status_layout.addWidget(label_movement, 2, 0) self.bar_movement = QProgressBar() self.bar_movement.setObjectName("bar_movement") self.bar_movement.setFixedHeight(22) self.bar_movement.setProperty("value", QVariant(100)) self.bar_movement.setTextVisible(False) status_layout.addWidget(self.bar_movement, 2, 1) main_layout.addStretch()