[hub] Track Hub Sync on the Server

- Create a Hub Seller activity on start of Hub Sync
- Store its name as remote_id in the Run
- Update that activity remotely once the Run here is complete, status
diff --git a/erpnext/demo/data/drug_list.json b/erpnext/demo/data/drug_list.json
index f34ca57..9b101cb 100644
--- a/erpnext/demo/data/drug_list.json
+++ b/erpnext/demo/data/drug_list.json
@@ -48,7 +48,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -133,7 +132,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -218,7 +216,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -303,7 +300,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -388,7 +384,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -473,7 +468,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -558,7 +552,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -643,7 +636,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -728,7 +720,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -813,7 +804,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -898,7 +888,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -983,7 +972,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1068,7 +1056,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1153,7 +1140,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1238,7 +1224,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1323,7 +1308,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1408,7 +1392,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1493,7 +1476,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1578,7 +1560,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1663,7 +1644,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1748,7 +1728,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1833,7 +1812,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -1918,7 +1896,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2003,7 +1980,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2088,7 +2064,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2173,7 +2148,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2258,7 +2232,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2343,7 +2316,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2428,7 +2400,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2513,7 +2484,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2598,7 +2568,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2683,7 +2652,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2768,7 +2736,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2853,7 +2820,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -2938,7 +2904,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3023,7 +2988,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3108,7 +3072,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3193,7 +3156,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3278,7 +3240,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3363,7 +3324,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3448,7 +3408,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3533,7 +3492,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3618,7 +3576,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3703,7 +3660,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3788,7 +3744,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3873,7 +3828,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -3958,7 +3912,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4043,7 +3996,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4128,7 +4080,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4213,7 +4164,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4298,7 +4248,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4383,7 +4332,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4468,7 +4416,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4553,7 +4500,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4638,7 +4584,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4723,7 +4668,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4808,7 +4752,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4893,7 +4836,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -4978,7 +4920,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -5063,7 +5004,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -5148,7 +5088,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -5233,7 +5172,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
@@ -5318,7 +5256,6 @@
   "naming_series": null,
   "net_weight": 0.0,
   "opening_stock": 0.0,
-  "publish_in_hub": 1,
   "quality_parameters": [],
   "reorder_levels": [],
   "route": null,
diff --git a/erpnext/hub_node/__init__.py b/erpnext/hub_node/__init__.py
index 3a23daa..471f039 100644
--- a/erpnext/hub_node/__init__.py
+++ b/erpnext/hub_node/__init__.py
@@ -2,7 +2,7 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe, requests, json, time
+import frappe, requests, json
 from frappe.utils import now, nowdate, cint
 from frappe.utils.nestedset import get_root_of
 from frappe.contacts.doctype.contact.contact import get_default_contact
@@ -18,7 +18,9 @@
 def call_hub_method(method, params=None):
 	connection = get_client_connection()
 
-	params = json.loads(params)
+	if type(params) == unicode:
+		params = json.loads(params)
+
 	params.update({
 		'cmd': 'hub.hub.api.' + method
 	})
@@ -67,17 +69,46 @@
 
 @frappe.whitelist()
 def publish_selected_items(items_to_publish):
-	for item_code in json.loads(items_to_publish):
+	items_to_publish = json.loads(items_to_publish)
+	if not len(items_to_publish):
+		return
+
+	for item_code in items_to_publish:
 		frappe.db.set_value('Item', item_code, 'publish_in_hub', 1)
 
-	# frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 1)
-	# time.sleep(10)
-	# frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 0)
-
 	hub_settings = frappe.get_doc('Hub Settings')
-	hub_settings.sync()
+	remote_id = item_sync_preprocess()
+	hub_settings.sync(remote_id)
 
-	return
+	return remote_id
+
+def item_sync_preprocess():
+	# Call Hub to make a new activity
+	# and return an activity ID
+	# that will be used as the remote ID for the Migration Run
+
+	response = call_hub_method('init_new_activity_for_seller', {
+		'hub_seller': frappe.db.get_value("Hub Settings", "Hub Settings", "company_email"),
+		'activity_type': 'Items Publish'
+	})
+
+	if response:
+		# frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 1)
+		return response
+	else:
+		return ''
+
+def item_sync_postprocess(obj):
+	response = call_hub_method('update_activity_for_seller', {
+		'hub_seller': frappe.db.get_value("Hub Settings", "Hub Settings", "company_email"),
+		'name': obj["remote_id"],
+		'status': obj["status"]
+	})
+
+	if response:
+		frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 0)
+	else:
+		frappe.throw("Unable to update remote activity")
 
 @frappe.whitelist()
 def get_item_favourites(start=0, limit=20, fields=["*"], order_by=None):
diff --git a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json
index befc87f..edcf91a 100644
--- a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json
+++ b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json
@@ -35,7 +35,7 @@
  "mapping_name": "Item to Hub Item",
  "mapping_type": "Push",
  "migration_id_field": "hub_sync_id",
- "modified": "2018-07-27 21:52:52.383842",
+ "modified": "2018-07-28 22:25:35.289335",
  "modified_by": "cave@aperture.com",
  "name": "Item to Hub Item",
  "owner": "Administrator",
diff --git a/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json b/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json
index c07623a..7490e43 100644
--- a/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json
+++ b/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json
@@ -1,18 +1,19 @@
 {
- "creation": "2017-09-07 11:39:38.445902", 
- "docstatus": 0, 
- "doctype": "Data Migration Plan", 
- "idx": 1, 
+ "creation": "2017-09-07 11:39:38.445902",
+ "docstatus": 0,
+ "doctype": "Data Migration Plan",
+ "idx": 1,
  "mappings": [
   {
-   "enabled": 1, 
+   "enabled": 1,
    "mapping": "Item to Hub Item"
   }
- ], 
- "modified": "2018-07-27 21:52:52.324025", 
- "modified_by": "cave@aperture.com", 
- "module": "Hub Node", 
- "name": "Hub Sync", 
- "owner": "Administrator", 
- "plan_name": "Hub Sync"
-}
\ No newline at end of file
+ ],
+ "modified": "2018-07-28 22:25:35.216172",
+ "modified_by": "cave@aperture.com",
+ "module": "Hub Node",
+ "name": "Hub Sync",
+ "owner": "Administrator",
+ "plan_name": "Hub Sync",
+ "postprocess_method": "erpnext.hub_node.item_sync_postprocess"
+}
diff --git a/erpnext/hub_node/doctype/hub_settings/hub_settings.py b/erpnext/hub_node/doctype/hub_settings/hub_settings.py
index 0b7dc48..66dd560 100644
--- a/erpnext/hub_node/doctype/hub_settings/hub_settings.py
+++ b/erpnext/hub_node/doctype/hub_settings/hub_settings.py
@@ -2,7 +2,7 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe, requests, json
+import frappe, requests, json, time
 
 from frappe.model.document import Document
 from frappe.utils import add_years, now, get_datetime, get_datetime_str
@@ -28,19 +28,23 @@
 	def get_hub_url(self):
 		return hub_url
 
-	def sync(self):
+	def sync(self, remote_id):
 		"""Create and execute Data Migration Run for Hub Sync plan"""
 		frappe.has_permission('Hub Settings', throw=True)
 
-		doc = frappe.get_doc({
-			'doctype': 'Data Migration Run',
-			'data_migration_plan': 'Hub Sync',
-			'data_migration_connector': 'Hub Connector',
-		}).insert()
+		if remote_id:
+			doc = frappe.get_doc({
+				'doctype': 'Data Migration Run',
+				'data_migration_plan': 'Hub Sync',
+				'data_migration_connector': 'Hub Connector',
+				'remote_id': remote_id
+			}).insert()
 
-		# self.sync_in_progress = 1
-		doc.run()
-		# self.sync_in_progress = 0
+			self.sync_in_progress = 1
+			# time.sleep(10)
+			doc.run()
+		else:
+			frappe.throw("No remote ID specified")
 
 	def register(self):
 		""" Create a User on hub.erpnext.org and return username/password """
diff --git a/erpnext/public/js/hub/marketplace.js b/erpnext/public/js/hub/marketplace.js
index f024e77..5261c3f 100644
--- a/erpnext/public/js/hub/marketplace.js
+++ b/erpnext/public/js/hub/marketplace.js
@@ -767,7 +767,16 @@
 }
 
 erpnext.hub.Publish = class Publish extends SubPage {
-	load_publish_page() {
+	make_wrapper() {
+		super.make_wrapper();
+		if(!hub.settings.sync_in_progress) {
+			this.make_publish_header();
+		} else {
+			this.show_publishing_state();
+		}
+	}
+
+	make_publish_header() {
 		const title_html = `<b>${__('Select Products to Publish')}</b>`;
 
 		const info = `<p class="text-muted">${__("Status decided by the 'Publish in Hub' field in Item.")}</p>`;
@@ -808,7 +817,6 @@
 
 	setup_events() {
 		this.$wrapper.find('.publish-items').on('click', () => {
-			this.load_publishing_state();
 			this.publish_selected_items()
 				.then(r => {
 					frappe.msgprint('check');
@@ -828,7 +836,7 @@
 
 	get_items_and_render() {
 		if(hub.settings.sync_in_progress) {
-			this.load_publishing_state();
+			this.show_publishing_state();
 			return;
 		}
 
@@ -868,7 +876,7 @@
 		);
 	}
 
-	load_publishing_state() {
+	show_publishing_state() {
 		this.$wrapper.html(get_empty_state(
 			'Publishing items ... You will be notified once published.'
 		));
@@ -880,6 +888,8 @@
 			items_to_publish.push($(this).attr("data-id"));
 		});
 
+		this.show_publishing_state();
+
 		return frappe.call(
 			'erpnext.hub_node.publish_selected_items',
 			{