Merge with upstream
diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py
index 0c9af1a..a8958ab 100644
--- a/erpnext/hub_node/api.py
+++ b/erpnext/hub_node/api.py
@@ -56,7 +56,7 @@
 			'item_code': item_code,
 			'hub_category': item.get('hub_category'),
 			'image_list': item.get('image_list')
-		}).insert()
+		}).insert(ignore_if_duplicate=True)
 
 	try:
 		hub_settings = frappe.get_doc('Hub Settings')
diff --git a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
index e981b2d..eb57f3a 100644
--- a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
+++ b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py
@@ -1,4 +1,5 @@
-import frappe, io, base64, urllib, os
+import frappe, io, base64, urllib, os, json
+from frappe.utils.file_manager import get_file_path
 
 def pre_process(doc):
 
@@ -9,11 +10,17 @@
 		url = file_path
 		file_path = os.path.join('/tmp', file_name)
 		urllib.urlretrieve(url, file_path)
+	else:
+		file_path = os.path.abspath(get_file_path(file_path))
 
-	with io.open(file_path, 'rb') as f:
-		doc.image = base64.b64encode(f.read())
-
-	doc.image_file_name = file_name
+	try:
+		with io.open(file_path, 'rb') as f:
+			doc.image = json.dumps({
+				'file_name': file_name,
+				'base64': base64.b64encode(f.read())
+			})
+	except Exception as e:
+		frappe.log_error(title='Hub Sync Error')
 
 	cached_details = frappe.get_doc('Hub Tracked Item', doc.item_code)
 
diff --git a/erpnext/hub_node/doctype/hub_settings/hub_settings.py b/erpnext/hub_node/doctype/hub_settings/hub_settings.py
index 8ec3d56..0044cef 100644
--- a/erpnext/hub_node/doctype/hub_settings/hub_settings.py
+++ b/erpnext/hub_node/doctype/hub_settings/hub_settings.py
@@ -81,6 +81,7 @@
 	def create_hub_connector(self, message):
 		if frappe.db.exists('Data Migration Connector', 'Hub Connector'):
 			hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
+			hub_connector.hostname = self.get_hub_url()
 			hub_connector.username = message['email']
 			hub_connector.password = message['password']
 			hub_connector.save()
diff --git a/erpnext/hub_node/doctype/hub_tracked_item/test_hub_tracked_item.js b/erpnext/hub_node/doctype/hub_tracked_item/test_hub_tracked_item.js
deleted file mode 100644
index 9f7314d..0000000
--- a/erpnext/hub_node/doctype/hub_tracked_item/test_hub_tracked_item.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Hub Tracked Item", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Hub Tracked Item
-		() => frappe.tests.make('Hub Tracked Item', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index 953efe4..a7b7761 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -149,8 +149,10 @@
 
 	update_sidebar() {
 		const route = frappe.get_route();
-		const route_str = route.slice(0, 2).join('/');
-		const $sidebar_item = this.$sidebar.find(`[data-route="${route_str}"]`);
+		const route_str = route.join('/');
+		const part_route_str = route.slice(0, 2).join('/');
+		const $sidebar_item = this.$sidebar.find(`[data-route="${route_str}"], [data-route="${part_route_str}"]`);
+
 
 		const $siblings = this.$sidebar.find('[data-route]');
 		$siblings.removeClass('active').addClass('text-muted');
diff --git a/erpnext/public/js/hub/pages/publish.js b/erpnext/public/js/hub/pages/publish.js
index 9c5fc24..5eb3178 100644
--- a/erpnext/public/js/hub/pages/publish.js
+++ b/erpnext/public/js/hub/pages/publish.js
@@ -185,7 +185,7 @@
 	show_publish_progress() {
 		const items_to_publish = this.items_data_to_publish.length
 			? this.items_data_to_publish
-			: JSON.parse(hub.settings.custom_data);
+			: JSON.parse(hub.settings.custom_data || '[]');
 
 		const $publish_progress = $(`<div class="sync-progress">
 			<p><b>${__(`Syncing ${items_to_publish.length} Products`)}</b></p>