From e824a8d1e9e09b70933bd10948b7efdaade7736b Mon Sep 17 00:00:00 2001 From: Chimezirim Ekemam Date: Fri, 28 Jan 2022 14:11:45 +0100 Subject: [PATCH 01/50] flask server and apis --- api_import_one.py | 32 ++++++++ main.py | 77 ++++++++++++++++++ requirements.txt | 4 + user-password.py | 2 +- util/PropertyWikidataIdentifier.py | 2 + wikibase-scripts/working-copy.js | 121 +++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 api_import_one.py create mode 100644 main.py create mode 100644 wikibase-scripts/working-copy.js diff --git a/api_import_one.py b/api_import_one.py new file mode 100644 index 0000000..343edb1 --- /dev/null +++ b/api_import_one.py @@ -0,0 +1,32 @@ +# configuration for pywikibot +import sys + +import pywikibot + + +def mth_import_one(arg): + # connect to the wikibase + wikibase = pywikibot.Site("my", "my") + wikibase_repo = wikibase.data_repository() + wikibase_repo.login() + + # connect to wikidata + wikidata = pywikibot.Site("wikidata", "wikidata") + wikidata_repo = wikidata.data_repository() + + from util.util import WikibaseImporter + wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) + + # import a single item or property + print(f"Importing {arg}") + if arg.startswith("Q"): + print("before get") + wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) + wikidata_item.get() + print("after get") + wikibase_importer.change_item(wikidata_item, wikibase_repo, True) + elif arg.startswith("P"): + wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) + wikidata_property.get() + wikibase_importer.change_property(wikidata_property, wikibase_repo, True) + return True diff --git a/main.py b/main.py new file mode 100644 index 0000000..c5cdf3d --- /dev/null +++ b/main.py @@ -0,0 +1,77 @@ +from flask import Flask # +from flask_restful import Api, Resource +from flask_cors import CORS, cross_origin +import requests + +app = Flask(__name__) +CORS(app) + + +api = Api(app) + + +# RESOURCES: CONTROLLERS AND ACTIONS +class Index(Resource): + def get(self): + return {"data": "Welcome to the index"} + + +# dummy +class Sync(Resource): + def get(self, item_name, id): + return {"data": "Sync" + item_name} + + def post(self): + return {"data": "Nothing posted for now "} + + +# import one +class ImportOne(Resource): + def get(self, q_id): + from api_import_one import mth_import_one + response = mth_import_one(q_id) + if response: + payload = {"status_code": 200, "message": "Import successful"} + else: + payload = {"status_code": 500, "message": "Import could not be completed"} + return payload + + +class WikiDataQuery(Resource): + def get(self, query_string): + url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" + response = requests.get(url) + response = response.json() + if response: + payload = {"status_code": 200, "response": response} + else: + payload = {"status_code": 500, "message": "Import could not be completed"} + return payload + + +# ROUTES +api.add_resource(Index, "/") +api.add_resource(Sync, "/sync//") +api.add_resource(ImportOne, "/import-wikidata-item/") +api.add_resource(WikiDataQuery, "/remote-wikidata-query/") + +# @app.route("/") +# def hello_world(): +# return "

Hello, World!

" +# +# +# @app.route("/syncc") +# def syncc(): +# return "Sync page" +# +# @app.route("/import-one/") +# def get(id): +# from import_one import mth_import_one +# mth_import_one(id) +# return {"message": "import complete"} + + +if __name__ == '__main__': + app.run(debug=True) + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/requirements.txt b/requirements.txt index 2ad8527..770f6df 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,7 @@ requests==2.22.0 six==1.13.0 SPARQLWrapper==1.8.4 urllib3==1.25.7 + +Flask~=2.0.2 +Flask-Restful==0.3.9 +Flask-Cors==3.0.10 \ No newline at end of file diff --git a/user-password.py b/user-password.py index e7b7567..f09b018 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) +(u'admin', BotPassword(u'WikibaseUpdater', u'7h5j0q95ktbm3638hf916oq5jenpoitg')) \ No newline at end of file diff --git a/util/PropertyWikidataIdentifier.py b/util/PropertyWikidataIdentifier.py index ea7e864..5dc7de6 100644 --- a/util/PropertyWikidataIdentifier.py +++ b/util/PropertyWikidataIdentifier.py @@ -11,8 +11,10 @@ def wikiitemexists(wikibase_repo, label): params = {'action': 'wbsearchentities', 'format': 'json', 'language': 'en', 'type': 'property', 'limit':1, 'search': label} + print(params) request = api.Request(site=wikibase_repo, parameters=params) result = request.submit() + print(result) return result['search'] class PropertyWikidataIdentifier: diff --git a/wikibase-scripts/working-copy.js b/wikibase-scripts/working-copy.js new file mode 100644 index 0000000..2e0195a --- /dev/null +++ b/wikibase-scripts/working-copy.js @@ -0,0 +1,121 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = "" + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + + +(function (mw, $) { + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { + console.log('No found'); + var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + console.log(notFoundEl); + + //if (entries.length == 3) { + //console.log(added_node); + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + console.log(focusInput); + //} + if (focusInput) { + console.log('here'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + } + }); + + //insert clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + console.log('new value: ' + _propertyId); + $("#mez-appended-button").remove(); + inputWithSuggestionParent.append(""); + } + } + + } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction() { + //clone action called + console.log(_propertyId); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + // data: {term: request.term}, + // dataType: "json", + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); +} \ No newline at end of file From 072f605ed39a55d659ccf187423a8863c4f26089 Mon Sep 17 00:00:00 2001 From: Chimezirim Ekemam Date: Mon, 31 Jan 2022 06:17:15 +0100 Subject: [PATCH 02/50] query update --- main.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index c5cdf3d..eeae253 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from flask import Flask # +from flask import Flask from flask_restful import Api, Resource from flask_cors import CORS, cross_origin import requests @@ -6,7 +6,6 @@ app = Flask(__name__) CORS(app) - api = Api(app) @@ -27,25 +26,34 @@ def post(self): # import one class ImportOne(Resource): - def get(self, q_id): + def get(self, q_id): from api_import_one import mth_import_one response = mth_import_one(q_id) if response: payload = {"status_code": 200, "message": "Import successful"} else: - payload = {"status_code": 500, "message": "Import could not be completed"} + payload = {"status_code": 500, + "message": "Import could not be completed"} return payload class WikiDataQuery(Resource): def get(self, query_string): - url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" + + # general english + url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ + query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" + + # british english + # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" + response = requests.get(url) response = response.json() if response: payload = {"status_code": 200, "response": response} else: - payload = {"status_code": 500, "message": "Import could not be completed"} + payload = {"status_code": 500, + "message": "Import could not be completed"} return payload From 601d13a108fc6a7f36de5b0bc19733878faebebe Mon Sep 17 00:00:00 2001 From: Chimezirim Ekemam Date: Tue, 1 Feb 2022 14:13:04 +0100 Subject: [PATCH 03/50] clone button updates --- .DS_Store | Bin 0 -> 6148 bytes wikibase-scripts/last-working-copy.js | 121 +++++++++++++++ wikibase-scripts/working-copy copy.js | 209 ++++++++++++++++++++++++++ wikibase-scripts/working-copy.js | 45 +++++- 4 files changed, 372 insertions(+), 3 deletions(-) create mode 100644 .DS_Store create mode 100644 wikibase-scripts/last-working-copy.js create mode 100644 wikibase-scripts/working-copy copy.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..de459015607cb2145c0d584fd50f090d920757bf GIT binary patch literal 6148 zcmeHKIZgvX5Ud6VmPj@voDUH2gOO!k;16&LA&@~fN4gR3;%QVLLRbru6B1M{b=OR9 z*NnD;?QHZEJKWR1^RKXB z<_XW(zOFXwhsX78-m~Aqs*(ayKnh3!DIf)YRKR;LZGM!fC*bB$R z_;fJD2tb@M9maLc62#^SVlNyMnW0%yiAl8@F)ZoKx2o%fV`9=_HGEjzY&D@++|Kh` zl*4+Wq7;wClone"); + } + } + + } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction() { + //clone action called + console.log(_propertyId); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + // data: {term: request.term}, + // dataType: "json", + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); +} \ No newline at end of file diff --git a/wikibase-scripts/working-copy copy.js b/wikibase-scripts/working-copy copy.js new file mode 100644 index 0000000..57261bb --- /dev/null +++ b/wikibase-scripts/working-copy copy.js @@ -0,0 +1,209 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +// (function (mw, $) { + +// try{ +// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); + +// if (!__inputWithSuggestion) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } + +// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; +// if (!__focusInput) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } +// }catch(err){} +// }(mediaWiki, jQuery)); + + +(function (mw, $) { + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { + console.log('No found'); + var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + //if (entries.length == 3) { + //console.log(added_node); + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + $("#new .ui-entityselector-input").on("keydown", "", function (e) { + console.log("key down"); + //$(".mez-appended-button").remove(); + + //find the closest parent that has a button + var closestParentWithButton = $(this).closest(':has(button)'); + var closestCloneButton = closestParentWithButton.children('button')[0]; + // var closestCloneButtinId = closestCloneButton.attr('id'); + + //.parentsUntil(closest) will call all parents until the closest parent that has a button + // .nextAll('button') will call the buttons that comes only next each parents + // .first() will filter the first one that comes next + + //var foundButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); + console.log(closestCloneButton); + }); + //} + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + } + }); + + //insert clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + console.log('new value: ' + _propertyId); + + //replace classname with the id of the specific applicable element + + $(".mez-appended-button").remove(); + // $(document).ready(function() { + // $(".mez-appended-button").click(function(event) { + // currentlyClickedCloneButtonId = event.target.id; + // alert(currentlyClickedCloneButtonId); + // if (currentlyClickedCloneButtonId) { + // $("#"+ currentlyClickedCloneButtonId +"").remove(); + // } + // }); + // }); + + + + var currentCount = cloneButtonCounter; + var myCloneButtonId = cloneButtonIdPrefix + ''+currentCount +''; + + //increase button counter + cloneButtonCounter = cloneButtonCounter+1; + + inputWithSuggestionParent.append(""); + //pushNewButtonInfo(myCloneButtonId, currentCount); + } + } + if (!focusInput) { + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + //replace classname with the id of the specific applicable element + $(".mez-appended-button").remove(); + } + } + + } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction() { + //clone action called + console.log(_propertyId); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + // data: {term: request.term}, + // dataType: "json", + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey){ + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} \ No newline at end of file diff --git a/wikibase-scripts/working-copy.js b/wikibase-scripts/working-copy.js index 2e0195a..4960339 100644 --- a/wikibase-scripts/working-copy.js +++ b/wikibase-scripts/working-copy.js @@ -7,6 +7,24 @@ var _propertyLabel = "" var _wikibasesync_base_url = "http://127.0.0.1:5000/"; +(function (mw, $) { + + try{ + var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); + + if (!__inputWithSuggestion) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } + + var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + if (!__focusInput) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } + }catch(err){} +}(mediaWiki, jQuery)); + (function (mw, $) { var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') @@ -26,10 +44,17 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; console.log(notFoundEl); + //if (entries.length == 3) { //console.log(added_node); focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; console.log(focusInput); + + //always remove clone button while typing + $("#new .ui-entityselector-input").on("keydown", "", function (e) { + console.log("key down"); + $(".mez-appended-button").remove(); + }); //} if (focusInput) { console.log('here'); @@ -66,11 +91,19 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; //insert clone button var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - + if (inputWithSuggestionParent) { console.log('new value: ' + _propertyId); - $("#mez-appended-button").remove(); - inputWithSuggestionParent.append(""); + $(".mez-appended-button").remove(); + inputWithSuggestionParent.append(""); + } + } + if (!focusInput) { + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + $(".mez-appended-button").remove(); } } @@ -106,7 +139,13 @@ function cloneAction() { }, success: function (data) { console.log(data); + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + if (inputWithSuggestionParent) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } // response($.map(data.response.search, function (item) { // _propertyId = item.id; // _propertyLabel = item.label; From 190e9d3304f1377150d2b94838683161b7775d84 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 8 Feb 2022 10:22:02 +0100 Subject: [PATCH 04/50] working copy update draft --- wikibase-scripts/working-copy copy.js | 41 +++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/wikibase-scripts/working-copy copy.js b/wikibase-scripts/working-copy copy.js index 57261bb..1cccc53 100644 --- a/wikibase-scripts/working-copy copy.js +++ b/wikibase-scripts/working-copy copy.js @@ -6,6 +6,8 @@ var _propertyId = ""; var _propertyLabel = ""; var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; var propertyDetailArray = []; var cloneButtonIdPrefix = 'clone_btn_'; var currentlyClickedCloneButtonId = ''; @@ -53,26 +55,55 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; //if (entries.length == 3) { //console.log(added_node); focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - console.log(focusInput); + //console.log(focusInput); //always remove clone button while typing //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + $("#new .ui-entityselector-input").on("focus", "", function (e) { + var _focused = $(':focus'); + console.log(_focused); + $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); + autoInputIDCounter = autoInputIDCounter + 1; + + //find the closest parent that has a button + $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); + parentIDCounter = parentIDCounter + 1; + }); $("#new .ui-entityselector-input").on("keydown", "", function (e) { + var _focused = $(':focus') + if (_focused.get(0).id === undefined || _focused.get(0).id.length < 5) { + $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); + autoInputIDCounter = autoInputIDCounter + 1; + + //find the closest parent that has a button + $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); + parentIDCounter = parentIDCounter + 1;s + } + + + var _focused = $(':focus') + + console.log(_focused.get(0).id); console.log("key down"); //$(".mez-appended-button").remove(); //find the closest parent that has a button var closestParentWithButton = $(this).closest(':has(button)'); - var closestCloneButton = closestParentWithButton.children('button')[0]; - // var closestCloneButtinId = closestCloneButton.attr('id'); + var closestParentWithButtonID = closestParentWithButton.get(0).id; + // closestCloneButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); + console.log(closestParentWithButton); + //var closestCloneButton = closestParentWithButton.children('button').eq(0) + var closestCloneButton = $("#"+closestParentWithButtonID).children('button').eq(0) + var closestCloneButtonId = closestCloneButton.get(0).id; //.parentsUntil(closest) will call all parents until the closest parent that has a button // .nextAll('button') will call the buttons that comes only next each parents // .first() will filter the first one that comes next + //see https://stackoverflow.com/questions/23784755/jquery-closest-button-after-input/23785154 - //var foundButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); - console.log(closestCloneButton); + console.log(closestCloneButtonId); + $("#"+closestCloneButtonId).remove(); }); //} if (focusInput) { From 73cf1abd948467923c3d60a95108185fd7c5ece0 Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 23 Feb 2022 16:25:42 +0100 Subject: [PATCH 05/50] new working copy --- main.py | 2 +- wikibase-scripts/draft.js | 258 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 wikibase-scripts/draft.js diff --git a/main.py b/main.py index eeae253..8ced203 100644 --- a/main.py +++ b/main.py @@ -80,6 +80,6 @@ def get(self, query_string): if __name__ == '__main__': - app.run(debug=True) + app.run(host='0.0.0.0', debug=True) # See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/wikibase-scripts/draft.js b/wikibase-scripts/draft.js new file mode 100644 index 0000000..bb403cb --- /dev/null +++ b/wikibase-scripts/draft.js @@ -0,0 +1,258 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +// (function (mw, $) { + +// try{ +// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); + +// if (!__inputWithSuggestion) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } + +// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; +// if (!__focusInput) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } +// }catch(err){} +// }(mediaWiki, jQuery)); + + +(function (mw, $) { + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { + console.log('No found'); + var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + //if (entries.length == 3) { + //console.log(added_node); + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + $('.wikibase-snakview-property input').on('keydown', function() { + //console.log($(this).closest('div').find(':button').index(this)); + console.log('input parent div'); + //console.log($(this).closest('div').find(':button').get(0).id); + //console.log($(this).closest('div').find('button')); + //console.log($(this).siblings(".mez-appended-button"))x; + //$('.ui-entityselector-input-unrecognized').siblings('.mez-appended-button').remove() + //$('.ui-entityselector-input-recognized').siblings('.mez-appended-button').remove() + currentBtn = $(this).siblings('.mez-appended-button')[0] + if($(this).siblings('.mez-appended-button').length === 0){ + $("").insertAfter($(this)); + } + + }); + + /*$("#new .ui-entityselector-input").on("keydown", "", function (e) { + var _focused = $(':focus') + if (_focused.get(0).id === undefined || _focused.get(0).id.length < 5) { + $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); + autoInputIDCounter = autoInputIDCounter + 1; + + //find the closest parent that has a button + $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); + parentIDCounter = parentIDCounter + 1; + } + + + var _focused = $(':focus') + + console.log(_focused.get(0).id); + console.log("key down"); + //$(".mez-appended-button").remove(); + + //find the closest parent that has a button + var closestParentWithButton = $(this).closest(':has(button)'); + var closestParentWithButtonID = closestParentWithButton.get(0).id; + // closestCloneButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); + console.log(closestParentWithButton); + //var closestCloneButton = closestParentWithButton.children('button').eq(0) + var closestCloneButton = $("#"+closestParentWithButtonID).children('button').eq(0) + var closestCloneButtonId = closestCloneButton.get(0).id; + + //.parentsUntil(closest) will call all parents until the closest parent that has a button + // .nextAll('button') will call the buttons that comes only next each parents + // .first() will filter the first one that comes next + //see https://stackoverflow.com/questions/23784755/jquery-closest-button-after-input/23785154 + + console.log(closestCloneButtonId); + $("#"+closestCloneButtonId).remove(); + });*/ + //} + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }, + select: function(event, ui){ +console.log("HERE") +console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + } + }); + + //insert clone button + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + //if (inputWithSuggestionParent) { + // console.log('new value: ' + _propertyId); + + //replace classname with the id of the specific applicable element + + //$(".mez-appended-button").remove(); + //inputWithSuggestionParent.append(""); + + // $(document).ready(function() { + // $(".mez-appended-button").click(function(event) { + // currentlyClickedCloneButtonId = event.target.id; + // alert(currentlyClickedCloneButtonId); + // if (currentlyClickedCloneButtonId) { + // $("#"+ currentlyClickedCloneButtonId +"").remove(); + // } + // }); + // }); + + + + //var currentCount = cloneButtonCounter; + //var myCloneButtonId = cloneButtonIdPrefix + ''+currentCount +''; + + //increase button counter + //cloneButtonCounter = cloneButtonCounter+1; + + //inputWithSuggestionParent.append(""); + + //pushNewButtonInfo(myCloneButtonId, currentCount); + //} + } + if (!focusInput) { + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + //replace classname with the id of the specific applicable element + $(".mez-appended-button").remove(); + } + } + + } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called +console.log("Clone information: ") +console.log(ele.getAttribute('item-id')); +console.log(ele.getAttribute('item-description')); +console.log(ele.getAttribute('item-value')); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + // data: {term: request.term}, + // dataType: "json", + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey){ + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} From e3c998b341316c3f61353b6d10cd51e989fd360b Mon Sep 17 00:00:00 2001 From: mez Date: Thu, 24 Feb 2022 12:24:33 +0100 Subject: [PATCH 06/50] draft-wip --- .DS_Store | Bin 6148 -> 8196 bytes main.py | 21 +++ wikibase-scripts/draft-wip.js | 176 ++++++++++++++++++++ wikibase-scripts/draft-wip_1.js | 281 ++++++++++++++++++++++++++++++++ wikibase-scripts/draft.js | 13 +- 5 files changed, 485 insertions(+), 6 deletions(-) create mode 100644 wikibase-scripts/draft-wip.js create mode 100644 wikibase-scripts/draft-wip_1.js diff --git a/.DS_Store b/.DS_Store index de459015607cb2145c0d584fd50f090d920757bf..dbabfc318dcc37255a47893997e405b424fcb280 100644 GIT binary patch literal 8196 zcmeHM!EVz)5S?uUaTHPoiHcm1EFp1fOG_yd;*zHAp%QRt5F7v*I}WW?*ABMRfU2UL z;UD+~u6zmq!U^82x53_|R9p~Jcca}|+w*2;o@ecjOGKhG^w)@5L}a0}Y}PT%XndXf zRGU+0ZbAy+iF)LsA5fp1DQ$DYFkl!k3>XFs1BQYBfdRa;xmoAD_w%b}Gz=I9E+qr} ze6Z13wv`;`Qa(B`$Pxgug442LjygbMY$e-Dj&muYu$fm6LP3QpF+>i>b(_^8+e(ge znZrrsa1v@|p(+$1R|n3P>Ll8^G^1g_Ffh#k*Y0&x>kbX*L#cjucEh;mg|P<>-c+0D zD?eq!jOaRQ{Q(6)26Tj3ObKN;iYY?`>>Lsb58jx%0S-dzSO%gUdeoMt%l5~Gy5La<2x2& z#X&hH&Tp|$V7^9sU}=-K=?UZteD*a2xGf=?@Uc(tXbA6lcBCTU{L1J(Wo10)bqU{q z)&Y?0V+J327xgepDAbVPzl2=Cnkn=XS}yJl;HP#W-;ENsS-=j!eTv^m-WPuso*6FT zE5K)nSo2Zx`LV!fg^nd3$K_Z!Lq$=qImrf3decWtDWXcS#sDj&WxQnZukhX|9jNEp zH*XLIX|}rhUChl_u3W8JRjY2j?jFRWZsumgwBsf(`RG|3hu+!T^_~a)k<+}f6-SvH zMEyhp0>2NHS1*Fdk4K$&82PEhcJm8X&8j)g*2&5J^#@D##@fc|l6~^<-s+N#6Q`#& zYw`BoM|;j;cofB-u)olR`eTP0`SE1r{dXZx$K50fD(g;+`4J2HFxNT$Mcjn3bGP;}~Qw{(z!(/") api.add_resource(ImportOne, "/import-wikidata-item/") api.add_resource(WikiDataQuery, "/remote-wikidata-query/") +api.add_resource(WikibaseQuery, "/local-wikibase-query/") # @app.route("/") # def hello_world(): diff --git a/wikibase-scripts/draft-wip.js b/wikibase-scripts/draft-wip.js new file mode 100644 index 0000000..a0a844a --- /dev/null +++ b/wikibase-scripts/draft-wip.js @@ -0,0 +1,176 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; +// var localDataLength = 1; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + + +(function (mw, $) { + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + //console.log("RECEIVED LOCAL DATA"); + //console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + // localDataLength = 0; + + console.log('No found'); + // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + $('.wikibase-snakview-property input').on('keydown', function () { + //console.log($(this).closest('div').find(':button').index(this)); + console.log('input parent div'); + currentBtn = $(this).siblings('.mez-appended-button')[0] + if ($(this).siblings('.mez-appended-button').length === 0) { + $("").insertAfter($(this)); + } + + }); + + + + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }, + select: function (event, ui) { + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + } + }); + + + + + } + } else { + // localDataLength = 1; + } + } + }); + }); + // if (localDataLength == 0) { + + + + // } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + ele.remove(); + console.log('clone button removed'); + + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey) { + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} diff --git a/wikibase-scripts/draft-wip_1.js b/wikibase-scripts/draft-wip_1.js new file mode 100644 index 0000000..0a6f432 --- /dev/null +++ b/wikibase-scripts/draft-wip_1.js @@ -0,0 +1,281 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; +var localDataLength = 1; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +// (function (mw, $) { + +// try{ +// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); + +// if (!__inputWithSuggestion) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } + +// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; +// if (!__focusInput) { +// $(".mez-appended-button").remove(); +// console.log('clone button removed'); +// } +// }catch(err){} +// }(mediaWiki, jQuery)); + + +(function (mw, $) { + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + $('.wikibase-snakview-property input').on('keyup', function () { + console.log("TYPED VALUE"); + var typedValue = $(this).val(); + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log("RECEIVED LOCAL DATA"); + console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + localDataLength = 0; + // $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + // source: function (request, response) { + // console.log('Request term: ' + request.term); + // $.ajax({ + // // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + // url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // // data: {term: request.term}, + // // dataType: "json", + // crossDomain: true, + // headers: { + // // "accept": "application/json", + // "Access-Control-Allow-Origin": "*", + // "Access-Control-Request-Headers3": "x-requested-with" + // }, + // success: function (data) { + // console.log(data); + // data_length = data.response.search.length + + // if (data_length > 0) { + // currentBtn = $(this).siblings('.mez-appended-button')[0] + // if ($(this).siblings('.mez-appended-button').length === 0) { + // $("").insertAfter($(this)); + // } + // } + + + // } + // }); + // }, + // select: function (event, ui) { + // console.log("REMOTE OPTION SELECTED") + // console.log($(event.target).siblings('button')); + // $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + // $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + // $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + // } + // }); + } else { + localDataLength = 1; + } + + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); + }); + // if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { + if (localDataLength == 0) { + console.log('No found'); + var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + $('.wikibase-snakview-property input').on('keydown', function () { + //console.log($(this).closest('div').find(':button').index(this)); + console.log('input parent div'); + currentBtn = $(this).siblings('.mez-appended-button')[0] + if ($(this).siblings('.mez-appended-button').length === 0) { + $("").insertAfter($(this)); + } + + }); + + + + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }, + select: function (event, ui) { + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + } + }); + + //insert clone button + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + //if (inputWithSuggestionParent) { + // console.log('new value: ' + _propertyId); + + //replace classname with the id of the specific applicable element + + //$(".mez-appended-button").remove(); + //inputWithSuggestionParent.append(""); + + // $(document).ready(function() { + // $(".mez-appended-button").click(function(event) { + // currentlyClickedCloneButtonId = event.target.id; + // alert(currentlyClickedCloneButtonId); + // if (currentlyClickedCloneButtonId) { + // $("#"+ currentlyClickedCloneButtonId +"").remove(); + // } + // }); + // }); + + + } + // if (!focusInput) { + // //remove clone button + // var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + // if (inputWithSuggestionParent) { + // //replace classname with the id of the specific applicable element + // $(".mez-appended-button").remove(); + // } + // } + + } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + $.ajax({ + // data: {term: request.term}, + // dataType: "json", + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if (inputWithSuggestionParent) { + $(".mez-appended-button").remove(); + console.log('clone button removed'); + } + // response($.map(data.response.search, function (item) { + // _propertyId = item.id; + // _propertyLabel = item.label; + // return { + // label: item.description, + // value: item.label, + // id: item.id + // } + // })); + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey) { + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} diff --git a/wikibase-scripts/draft.js b/wikibase-scripts/draft.js index bb403cb..a4776a3 100644 --- a/wikibase-scripts/draft.js +++ b/wikibase-scripts/draft.js @@ -111,6 +111,7 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; $("#"+closestCloneButtonId).remove(); });*/ //} + if (focusInput) { console.log('in focus input'); $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: @@ -143,8 +144,8 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; }); }, select: function(event, ui){ -console.log("HERE") -console.log($(event.target).siblings('button')); + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) @@ -211,10 +212,10 @@ console.log($(event.target).siblings('button')); //clone button clicked function cloneAction(ele) { //clone action called -console.log("Clone information: ") -console.log(ele.getAttribute('item-id')); -console.log(ele.getAttribute('item-description')); -console.log(ele.getAttribute('item-value')); + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); //api call var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; From b34ad73d1dcdf60932b8ea64606a0e1b70872bd6 Mon Sep 17 00:00:00 2001 From: mez Date: Thu, 3 Mar 2022 21:19:54 +0100 Subject: [PATCH 07/50] remote wikidata clone and scripts update --- main.py | 18 ++- user-password.py | 2 +- wikibase-scripts/draft-wip.js | 4 +- wikibase-scripts/draft.js | 277 ++++++++++++---------------------- 4 files changed, 116 insertions(+), 185 deletions(-) diff --git a/main.py b/main.py index c930151..7d9dc76 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,9 @@ +import socket +import requests from flask import Flask from flask_restful import Api, Resource from flask_cors import CORS, cross_origin -import requests +from threading import Thread app = Flask(__name__) CORS(app) @@ -26,10 +28,18 @@ def post(self): # import one class ImportOne(Resource): + + def import_thread_spinner(self, query_id): + def handle(): + from api_import_one import mth_import_one + response = mth_import_one(query_id) + t = Thread(target=handle) + return t def get(self, q_id): - from api_import_one import mth_import_one - # TODO RUN THIS IS A THREAD AND RETURN TRUE IMMEDIATELY - response = mth_import_one(q_id) + #from api_import_one import mth_import_one + self.import_thread_spinner(q_id).start() + #response = mth_import_one(q_id) + response = 2 if response: payload = {"status_code": 200, "message": "Import successful"} else: diff --git a/user-password.py b/user-password.py index f09b018..96568c3 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikibaseUpdater', u'7h5j0q95ktbm3638hf916oq5jenpoitg')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'8pqo3igu0p00mqkbik6uomeamnve8aae')) \ No newline at end of file diff --git a/wikibase-scripts/draft-wip.js b/wikibase-scripts/draft-wip.js index a0a844a..6eae589 100644 --- a/wikibase-scripts/draft-wip.js +++ b/wikibase-scripts/draft-wip.js @@ -148,8 +148,10 @@ function cloneAction(ele) { console.log(ele.getAttribute('item-description')); console.log(ele.getAttribute('item-value')); + var _myPropertyId = ele.getAttribute('item-id') + //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; $.ajax({ url: wikibaseSyncUrl, crossDomain: true, diff --git a/wikibase-scripts/draft.js b/wikibase-scripts/draft.js index a4776a3..e9154b4 100644 --- a/wikibase-scripts/draft.js +++ b/wikibase-scripts/draft.js @@ -12,27 +12,10 @@ var propertyDetailArray = []; var cloneButtonIdPrefix = 'clone_btn_'; var currentlyClickedCloneButtonId = ''; var currentBtn = null; +// var localDataLength = 1; var _wikibasesync_base_url = "http://127.0.0.1:5000/"; -// (function (mw, $) { - -// try{ -// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); - -// if (!__inputWithSuggestion) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } - -// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; -// if (!__focusInput) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } -// }catch(err){} -// }(mediaWiki, jQuery)); - (function (mw, $) { var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') @@ -47,156 +30,104 @@ var _wikibasesync_base_url = "http://127.0.0.1:5000/"; if (entries.length == 2) { if (entries[0][1]) { - if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { - console.log('No found'); - var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - //if (entries.length == 3) { - //console.log(added_node); - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - $('.wikibase-snakview-property input').on('keydown', function() { - //console.log($(this).closest('div').find(':button').index(this)); - console.log('input parent div'); - //console.log($(this).closest('div').find(':button').get(0).id); - //console.log($(this).closest('div').find('button')); - //console.log($(this).siblings(".mez-appended-button"))x; - //$('.ui-entityselector-input-unrecognized').siblings('.mez-appended-button').remove() - //$('.ui-entityselector-input-recognized').siblings('.mez-appended-button').remove() - currentBtn = $(this).siblings('.mez-appended-button')[0] - if($(this).siblings('.mez-appended-button').length === 0){ - $("").insertAfter($(this)); - } - - }); - - /*$("#new .ui-entityselector-input").on("keydown", "", function (e) { - var _focused = $(':focus') - if (_focused.get(0).id === undefined || _focused.get(0).id.length < 5) { - $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); - autoInputIDCounter = autoInputIDCounter + 1; - - //find the closest parent that has a button - $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); - parentIDCounter = parentIDCounter + 1; - } - - - var _focused = $(':focus') - - console.log(_focused.get(0).id); - console.log("key down"); - //$(".mez-appended-button").remove(); - - //find the closest parent that has a button - var closestParentWithButton = $(this).closest(':has(button)'); - var closestParentWithButtonID = closestParentWithButton.get(0).id; - // closestCloneButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); - console.log(closestParentWithButton); - //var closestCloneButton = closestParentWithButton.children('button').eq(0) - var closestCloneButton = $("#"+closestParentWithButtonID).children('button').eq(0) - var closestCloneButtonId = closestCloneButton.get(0).id; - - //.parentsUntil(closest) will call all parents until the closest parent that has a button - // .nextAll('button') will call the buttons that comes only next each parents - // .first() will filter the first one that comes next - //see https://stackoverflow.com/questions/23784755/jquery-closest-button-after-input/23785154 - - console.log(closestCloneButtonId); - $("#"+closestCloneButtonId).remove(); - });*/ - //} - - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + //console.log("RECEIVED LOCAL DATA"); + //console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + // localDataLength = 0; + + console.log('No found'); + // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + $('.wikibase-snakview-property input').on('keydown', function () { + //console.log($(this).closest('div').find(':button').index(this)); + console.log('input parent div'); + currentBtn = $(this).siblings('.mez-appended-button')[0] + if ($(this).siblings('.mez-appended-button').length === 0) { + $("").insertAfter($(this)); } - }); - }, - select: function(event, ui){ - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - } - }); - - //insert clone button - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - //if (inputWithSuggestionParent) { - // console.log('new value: ' + _propertyId); - - //replace classname with the id of the specific applicable element - - //$(".mez-appended-button").remove(); - //inputWithSuggestionParent.append(""); - - // $(document).ready(function() { - // $(".mez-appended-button").click(function(event) { - // currentlyClickedCloneButtonId = event.target.id; - // alert(currentlyClickedCloneButtonId); - // if (currentlyClickedCloneButtonId) { - // $("#"+ currentlyClickedCloneButtonId +"").remove(); - // } - // }); - // }); - + }); - //var currentCount = cloneButtonCounter; - //var myCloneButtonId = cloneButtonIdPrefix + ''+currentCount +''; - //increase button counter - //cloneButtonCounter = cloneButtonCounter+1; - //inputWithSuggestionParent.append(""); + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }, + select: function (event, ui) { + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + } + }); + + + + + } + } else { + // localDataLength = 1; + } + } + }); + }); + // if (localDataLength == 0) { - //pushNewButtonInfo(myCloneButtonId, currentCount); - //} - } - if (!focusInput) { - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - if (inputWithSuggestionParent) { - //replace classname with the id of the specific applicable element - $(".mez-appended-button").remove(); - } - } - } + // } } } @@ -217,11 +148,11 @@ function cloneAction(ele) { console.log(ele.getAttribute('item-description')); console.log(ele.getAttribute('item-value')); + var _myPropertyId = ele.getAttribute('item-id') + //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; $.ajax({ - // data: {term: request.term}, - // dataType: "json", url: wikibaseSyncUrl, crossDomain: true, headers: { @@ -232,26 +163,14 @@ function cloneAction(ele) { success: function (data) { console.log(data); //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); + ele.remove(); + console.log('clone button removed'); + } }); } -function pushNewButtonInfo(buttonId, arrayKey){ +function pushNewButtonInfo(buttonId, arrayKey) { //add button info to array propertyDetailArray[arrayKey] = buttonId; From 86f5579dae33724b9a4512960b335f9a942f9a0b Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 15 Mar 2022 11:17:26 +0100 Subject: [PATCH 08/50] clone button spacing --- user-password.py | 2 +- wikibase-scripts/draft-wip.js | 22 ++++++++++++++++++++++ wikibase-scripts/draft.js | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/user-password.py b/user-password.py index 96568c3..4999de4 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'8pqo3igu0p00mqkbik6uomeamnve8aae')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'password')) \ No newline at end of file diff --git a/wikibase-scripts/draft-wip.js b/wikibase-scripts/draft-wip.js index 6eae589..3cf7893 100644 --- a/wikibase-scripts/draft-wip.js +++ b/wikibase-scripts/draft-wip.js @@ -16,8 +16,25 @@ var currentBtn = null; var _wikibasesync_base_url = "http://127.0.0.1:5000/"; +function insertStyle(){ + var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; + //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet){ + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} (function (mw, $) { + insertStyle() var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') console.log(_parentEl) @@ -176,3 +193,8 @@ function pushNewButtonInfo(buttonId, arrayKey) { console.log(propertyDetailArray); } + +//TODO PENDING ISSUES +//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS +//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED +//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS \ No newline at end of file diff --git a/wikibase-scripts/draft.js b/wikibase-scripts/draft.js index e9154b4..23636e3 100644 --- a/wikibase-scripts/draft.js +++ b/wikibase-scripts/draft.js @@ -16,8 +16,25 @@ var currentBtn = null; var _wikibasesync_base_url = "http://127.0.0.1:5000/"; +function insertStyle(){ + var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; + //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet){ + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} (function (mw, $) { + insertStyle() var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') console.log(_parentEl) From 7157a4844a70b2379881dba45ffa2f91680a35fc Mon Sep 17 00:00:00 2001 From: mez Date: Mon, 4 Apr 2022 10:17:21 +0200 Subject: [PATCH 09/50] additional comments --- wikibase-scripts/draft-wip.js | 1 + 1 file changed, 1 insertion(+) diff --git a/wikibase-scripts/draft-wip.js b/wikibase-scripts/draft-wip.js index 3cf7893..3747def 100644 --- a/wikibase-scripts/draft-wip.js +++ b/wikibase-scripts/draft-wip.js @@ -197,4 +197,5 @@ function pushNewButtonInfo(buttonId, arrayKey) { //TODO PENDING ISSUES //ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS //WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED +//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW //WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS \ No newline at end of file From e96102b4411500b79652d4eed865b7e4daea1e21 Mon Sep 17 00:00:00 2001 From: mez Date: Thu, 14 Apr 2022 13:32:25 +0200 Subject: [PATCH 10/50] algorithm updates --- wikibase-scripts/draft-clem.js | 210 +++++++++++++++++++++++++++++ wikibase-scripts/draft-old-clem.js | 196 +++++++++++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 wikibase-scripts/draft-clem.js create mode 100644 wikibase-scripts/draft-old-clem.js diff --git a/wikibase-scripts/draft-clem.js b/wikibase-scripts/draft-clem.js new file mode 100644 index 0000000..8d1e010 --- /dev/null +++ b/wikibase-scripts/draft-clem.js @@ -0,0 +1,210 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; +// var localDataLength = 1; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +function insertStyle(){ + var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; + //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet){ + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} + +(function (mw, $) { + insertStyle() + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + var isLocallyAvailable = true + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + // secondary wikidata autocomplete + + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + if(isLocallyAvailable == false){ + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }else{ + $(".ui-autocomplete").hide() + response = null + return null + } + + }, + select: function (event, ui) { + if(!isLocallyAvailable){ + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + }else{ + } + + } + }); + + + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + var currentContext = $(this) + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + //console.log("RECEIVED LOCAL DATA"); + //console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + isLocallyAvailable = false + $("ui-entityselector-notfound").hide() + + //console.log('No found'); + + + //focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + var appendedButton = currentContext.siblings('.mez-appended-button') + if (appendedButton.length === 0 && isLocallyAvailable == false) { + $("").insertAfter($(currentContext)); + } + + //if (focusInput) { + // console.log('in focus input'); + + //} + } else { + console.log("IN ELSE") + //console.log(isLocallyAvailable) + isLocallyAvailable = true + + var appendedButton = currentContext.siblings('.mez-appended-button') + if((appendedButton.length > 0 && isLocallyAvailable) || + ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ + currentContext.siblings('.mez-appended-button').remove() + } + } + } + }); + }); + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); + + var _myPropertyId = ele.getAttribute('item-id') + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; + $.ajax({ + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + ele.remove(); + console.log('clone button removed'); + + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey) { + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} + +//TODO PENDING ISSUES +//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS +//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED +//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW +//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS diff --git a/wikibase-scripts/draft-old-clem.js b/wikibase-scripts/draft-old-clem.js new file mode 100644 index 0000000..078914a --- /dev/null +++ b/wikibase-scripts/draft-old-clem.js @@ -0,0 +1,196 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; +// var localDataLength = 1; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +function insertStyle(){ + var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; + //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet){ + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} + +(function (mw, $) { + insertStyle() + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var focusInput; + + if (entries.length == 2) { + if (entries[0][1]) { + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + //console.log("RECEIVED LOCAL DATA"); + //console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + // localDataLength = 0; + + console.log('No found'); + // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; + //console.log(notFoundEl); + + + focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + + if ($('.wikibase-snakview-property input').siblings('.mez-appended-button').length === 0) { + $("").insertAfter($('.wikibase-snakview-property input')); + } + + + + if (focusInput) { + console.log('in focus input'); + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }, + select: function (event, ui) { + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + } + }); + + + + + } + } else { + // localDataLength = 1; + } + } + }); + }); + // if (localDataLength == 0) { + + + + // } + } + } + + + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); + + var _myPropertyId = ele.getAttribute('item-id') + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; + $.ajax({ + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + ele.remove(); + console.log('clone button removed'); + + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey) { + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} + +//TODO PENDING ISSUES +//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS +//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED +//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW +//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS From 3f54a75cc44f10574ed0c0b447624b74cc1dd8f3 Mon Sep 17 00:00:00 2001 From: mez Date: Thu, 14 Apr 2022 14:03:39 +0200 Subject: [PATCH 11/50] algorithm updates optimised --- wikibase-scripts/draft-clem.js | 119 ++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/wikibase-scripts/draft-clem.js b/wikibase-scripts/draft-clem.js index 8d1e010..b7751d6 100644 --- a/wikibase-scripts/draft-clem.js +++ b/wikibase-scripts/draft-clem.js @@ -44,9 +44,124 @@ function insertStyle(){ mutation.addedNodes.forEach(function (added_node) { //console.log(Object.keys(added_node)); var entries = Object.entries(added_node); + var isStatement = added_node.classList && ['listview-item', 'wikibase-statementgroupview', 'wb-new'].every(function(c){return added_node.classList.contains(c)}) + var isReference = added_node.classList && ['listview-item', 'wikibase-snakview', 'wb-edit'].every(function(c){return added_node.classList.contains(c)}) + + + var focusInput; - if (entries.length == 2) { + if (isStatement || isReference) { + // secondary wikidata autocomplete + + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + if(isLocallyAvailable == false){ + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + }else{ + $(".ui-autocomplete").hide() + response = null + return null + } + + }, + select: function (event, ui) { + if(!isLocallyAvailable){ + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + }else{ + } + + } + }); + + + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + var currentContext = $(this) + //check if there's data found locally + $.ajax({ + url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + //console.log("RECEIVED LOCAL DATA"); + //console.log(data.response.search.length); + data_length = data.response.search.length + + if (data_length < 1) { + console.log("No local data found"); + isLocallyAvailable = false + $("ui-entityselector-notfound").hide() + + //console.log('No found'); + + + //focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; + //console.log(focusInput); + + //always remove clone button while typing + //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); + var appendedButton = currentContext.siblings('.mez-appended-button') + if (appendedButton.length === 0 && isLocallyAvailable == false) { + $("").insertAfter($(currentContext)); + } + + //if (focusInput) { + // console.log('in focus input'); + + //} + } else { + console.log("IN ELSE") + //console.log(isLocallyAvailable) + isLocallyAvailable = true + + var appendedButton = currentContext.siblings('.mez-appended-button') + if((appendedButton.length > 0 && isLocallyAvailable) || + ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ + currentContext.siblings('.mez-appended-button').remove() + } + } + } + }); + }); + + } + + /*if (entries.length == 2) { if (entries[0][1]) { // secondary wikidata autocomplete @@ -155,7 +270,7 @@ function insertStyle(){ }); }); } - } + }*/ }); From b0ccba6cee995ff4258bc2cd6f1db3472ddefff4 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 19 Apr 2022 11:32:43 +0200 Subject: [PATCH 12/50] code base cleanup --- wikibase-scripts/draft-old-clem.js | 196 ------------------ wikibase-scripts/draft-wip.js | 201 ------------------ wikibase-scripts/draft-wip_1.js | 281 -------------------------- wikibase-scripts/last-working-copy.js | 121 ----------- wikibase-scripts/working-copy copy.js | 240 ---------------------- wikibase-scripts/working-copy.js | 160 --------------- 6 files changed, 1199 deletions(-) delete mode 100644 wikibase-scripts/draft-old-clem.js delete mode 100644 wikibase-scripts/draft-wip.js delete mode 100644 wikibase-scripts/draft-wip_1.js delete mode 100644 wikibase-scripts/last-working-copy.js delete mode 100644 wikibase-scripts/working-copy copy.js delete mode 100644 wikibase-scripts/working-copy.js diff --git a/wikibase-scripts/draft-old-clem.js b/wikibase-scripts/draft-old-clem.js deleted file mode 100644 index 078914a..0000000 --- a/wikibase-scripts/draft-old-clem.js +++ /dev/null @@ -1,196 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -// var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -function insertStyle(){ - var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; - //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - - head.appendChild(style); - - style.type = 'text/css'; - if (style.styleSheet){ - // This is required for IE8 and below. - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } -} - -(function (mw, $) { - insertStyle() - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - //console.log("RECEIVED LOCAL DATA"); - //console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - // localDataLength = 0; - - console.log('No found'); - // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if ($('.wikibase-snakview-property input').siblings('.mez-appended-button').length === 0) { - $("").insertAfter($('.wikibase-snakview-property input')); - } - - - - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }, - select: function (event, ui) { - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - } - }); - - - - - } - } else { - // localDataLength = 1; - } - } - }); - }); - // if (localDataLength == 0) { - - - - // } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - var _myPropertyId = ele.getAttribute('item-id') - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; - $.ajax({ - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - ele.remove(); - console.log('clone button removed'); - - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} - -//TODO PENDING ISSUES -//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS -//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED -//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW -//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS diff --git a/wikibase-scripts/draft-wip.js b/wikibase-scripts/draft-wip.js deleted file mode 100644 index 3747def..0000000 --- a/wikibase-scripts/draft-wip.js +++ /dev/null @@ -1,201 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -// var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -function insertStyle(){ - var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; - //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - - head.appendChild(style); - - style.type = 'text/css'; - if (style.styleSheet){ - // This is required for IE8 and below. - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } -} - -(function (mw, $) { - insertStyle() - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - //console.log("RECEIVED LOCAL DATA"); - //console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - // localDataLength = 0; - - console.log('No found'); - // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - $('.wikibase-snakview-property input').on('keydown', function () { - //console.log($(this).closest('div').find(':button').index(this)); - console.log('input parent div'); - currentBtn = $(this).siblings('.mez-appended-button')[0] - if ($(this).siblings('.mez-appended-button').length === 0) { - $("").insertAfter($(this)); - } - - }); - - - - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }, - select: function (event, ui) { - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - } - }); - - - - - } - } else { - // localDataLength = 1; - } - } - }); - }); - // if (localDataLength == 0) { - - - - // } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - var _myPropertyId = ele.getAttribute('item-id') - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; - $.ajax({ - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - ele.remove(); - console.log('clone button removed'); - - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} - -//TODO PENDING ISSUES -//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS -//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED -//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW -//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS \ No newline at end of file diff --git a/wikibase-scripts/draft-wip_1.js b/wikibase-scripts/draft-wip_1.js deleted file mode 100644 index 0a6f432..0000000 --- a/wikibase-scripts/draft-wip_1.js +++ /dev/null @@ -1,281 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -// (function (mw, $) { - -// try{ -// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); - -// if (!__inputWithSuggestion) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } - -// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; -// if (!__focusInput) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } -// }catch(err){} -// }(mediaWiki, jQuery)); - - -(function (mw, $) { - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - $('.wikibase-snakview-property input').on('keyup', function () { - console.log("TYPED VALUE"); - var typedValue = $(this).val(); - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log("RECEIVED LOCAL DATA"); - console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - localDataLength = 0; - // $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - // source: function (request, response) { - // console.log('Request term: ' + request.term); - // $.ajax({ - // // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - // url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // // data: {term: request.term}, - // // dataType: "json", - // crossDomain: true, - // headers: { - // // "accept": "application/json", - // "Access-Control-Allow-Origin": "*", - // "Access-Control-Request-Headers3": "x-requested-with" - // }, - // success: function (data) { - // console.log(data); - // data_length = data.response.search.length - - // if (data_length > 0) { - // currentBtn = $(this).siblings('.mez-appended-button')[0] - // if ($(this).siblings('.mez-appended-button').length === 0) { - // $("").insertAfter($(this)); - // } - // } - - - // } - // }); - // }, - // select: function (event, ui) { - // console.log("REMOTE OPTION SELECTED") - // console.log($(event.target).siblings('button')); - // $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - // $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - // $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - // } - // }); - } else { - localDataLength = 1; - } - - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); - } - }); - }); - // if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { - if (localDataLength == 0) { - console.log('No found'); - var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - $('.wikibase-snakview-property input').on('keydown', function () { - //console.log($(this).closest('div').find(':button').index(this)); - console.log('input parent div'); - currentBtn = $(this).siblings('.mez-appended-button')[0] - if ($(this).siblings('.mez-appended-button').length === 0) { - $("").insertAfter($(this)); - } - - }); - - - - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }, - select: function (event, ui) { - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - } - }); - - //insert clone button - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - //if (inputWithSuggestionParent) { - // console.log('new value: ' + _propertyId); - - //replace classname with the id of the specific applicable element - - //$(".mez-appended-button").remove(); - //inputWithSuggestionParent.append(""); - - // $(document).ready(function() { - // $(".mez-appended-button").click(function(event) { - // currentlyClickedCloneButtonId = event.target.id; - // alert(currentlyClickedCloneButtonId); - // if (currentlyClickedCloneButtonId) { - // $("#"+ currentlyClickedCloneButtonId +"").remove(); - // } - // }); - // }); - - - } - // if (!focusInput) { - // //remove clone button - // var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - // if (inputWithSuggestionParent) { - // //replace classname with the id of the specific applicable element - // $(".mez-appended-button").remove(); - // } - // } - - } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; - $.ajax({ - // data: {term: request.term}, - // dataType: "json", - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} diff --git a/wikibase-scripts/last-working-copy.js b/wikibase-scripts/last-working-copy.js deleted file mode 100644 index 45e8ae8..0000000 --- a/wikibase-scripts/last-working-copy.js +++ /dev/null @@ -1,121 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = "" - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - - -(function (mw, $) { - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { - console.log('No found'); - var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - console.log(notFoundEl); - - //if (entries.length == 3) { - //console.log(added_node); - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - console.log(focusInput); - //} - if (focusInput) { - console.log('here'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - } - }); - - //insert clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - console.log('new value: ' + _propertyId); - $("#mez-appended-button").remove(); - inputWithSuggestionParent.append(""); - } - } - - } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction() { - //clone action called - console.log(_propertyId); - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; - $.ajax({ - // data: {term: request.term}, - // dataType: "json", - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); - } - }); -} \ No newline at end of file diff --git a/wikibase-scripts/working-copy copy.js b/wikibase-scripts/working-copy copy.js deleted file mode 100644 index 1cccc53..0000000 --- a/wikibase-scripts/working-copy copy.js +++ /dev/null @@ -1,240 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -// (function (mw, $) { - -// try{ -// var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); - -// if (!__inputWithSuggestion) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } - -// var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; -// if (!__focusInput) { -// $(".mez-appended-button").remove(); -// console.log('clone button removed'); -// } -// }catch(err){} -// }(mediaWiki, jQuery)); - - -(function (mw, $) { - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { - console.log('No found'); - var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - //if (entries.length == 3) { - //console.log(added_node); - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - $("#new .ui-entityselector-input").on("focus", "", function (e) { - var _focused = $(':focus'); - console.log(_focused); - $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); - autoInputIDCounter = autoInputIDCounter + 1; - - //find the closest parent that has a button - $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); - parentIDCounter = parentIDCounter + 1; - }); - - $("#new .ui-entityselector-input").on("keydown", "", function (e) { - var _focused = $(':focus') - if (_focused.get(0).id === undefined || _focused.get(0).id.length < 5) { - $(':focus').attr('id', 'autoCompleteInput'+autoInputIDCounter); - autoInputIDCounter = autoInputIDCounter + 1; - - //find the closest parent that has a button - $(this).closest(':has(button)').attr('id', 'autoCompleteInputParent'+parentIDCounter); - parentIDCounter = parentIDCounter + 1;s - } - - - var _focused = $(':focus') - - console.log(_focused.get(0).id); - console.log("key down"); - //$(".mez-appended-button").remove(); - - //find the closest parent that has a button - var closestParentWithButton = $(this).closest(':has(button)'); - var closestParentWithButtonID = closestParentWithButton.get(0).id; - // closestCloneButton = $(this).parentsUntil(closestParentWithButton).nextAll('button').first(); - console.log(closestParentWithButton); - //var closestCloneButton = closestParentWithButton.children('button').eq(0) - var closestCloneButton = $("#"+closestParentWithButtonID).children('button').eq(0) - var closestCloneButtonId = closestCloneButton.get(0).id; - - //.parentsUntil(closest) will call all parents until the closest parent that has a button - // .nextAll('button') will call the buttons that comes only next each parents - // .first() will filter the first one that comes next - //see https://stackoverflow.com/questions/23784755/jquery-closest-button-after-input/23785154 - - console.log(closestCloneButtonId); - $("#"+closestCloneButtonId).remove(); - }); - //} - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - } - }); - - //insert clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - console.log('new value: ' + _propertyId); - - //replace classname with the id of the specific applicable element - - $(".mez-appended-button").remove(); - // $(document).ready(function() { - // $(".mez-appended-button").click(function(event) { - // currentlyClickedCloneButtonId = event.target.id; - // alert(currentlyClickedCloneButtonId); - // if (currentlyClickedCloneButtonId) { - // $("#"+ currentlyClickedCloneButtonId +"").remove(); - // } - // }); - // }); - - - - var currentCount = cloneButtonCounter; - var myCloneButtonId = cloneButtonIdPrefix + ''+currentCount +''; - - //increase button counter - cloneButtonCounter = cloneButtonCounter+1; - - inputWithSuggestionParent.append(""); - //pushNewButtonInfo(myCloneButtonId, currentCount); - } - } - if (!focusInput) { - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - //replace classname with the id of the specific applicable element - $(".mez-appended-button").remove(); - } - } - - } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction() { - //clone action called - console.log(_propertyId); - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; - $.ajax({ - // data: {term: request.term}, - // dataType: "json", - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey){ - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} \ No newline at end of file diff --git a/wikibase-scripts/working-copy.js b/wikibase-scripts/working-copy.js deleted file mode 100644 index 4960339..0000000 --- a/wikibase-scripts/working-copy.js +++ /dev/null @@ -1,160 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = "" - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -(function (mw, $) { - - try{ - var __inputWithSuggestion = $('#new .ui-entityselector-input').val(); - - if (!__inputWithSuggestion) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - - var __focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - if (!__focusInput) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - }catch(err){} -}(mediaWiki, jQuery)); - - -(function (mw, $) { - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - if (entries[0][1].uiOoMenuItem && entries[0][1].uiOoMenuItem._label == "No match was found") { - console.log('No found'); - var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - console.log(notFoundEl); - - - //if (entries.length == 3) { - //console.log(added_node); - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - console.log(focusInput); - - //always remove clone button while typing - $("#new .ui-entityselector-input").on("keydown", "", function (e) { - console.log("key down"); - $(".mez-appended-button").remove(); - }); - //} - if (focusInput) { - console.log('here'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - } - }); - - //insert clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - console.log('new value: ' + _propertyId); - $(".mez-appended-button").remove(); - inputWithSuggestionParent.append(""); - } - } - if (!focusInput) { - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - $(".mez-appended-button").remove(); - } - } - - } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction() { - //clone action called - console.log(_propertyId); - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _propertyId; - $.ajax({ - // data: {term: request.term}, - // dataType: "json", - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - - if (inputWithSuggestionParent) { - $(".mez-appended-button").remove(); - console.log('clone button removed'); - } - // response($.map(data.response.search, function (item) { - // _propertyId = item.id; - // _propertyLabel = item.label; - // return { - // label: item.description, - // value: item.label, - // id: item.id - // } - // })); - } - }); -} \ No newline at end of file From 74919a3ba7febd9a4d9ca2d42520b3d5c4282c31 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 26 Apr 2022 12:01:42 +0200 Subject: [PATCH 13/50] autocomplete redesign --- .DS_Store | Bin 8196 -> 8196 bytes api_import_one.py | 27 + main.py | 4 +- wikibase-scripts/draft-clem-bk2.js | 201 ++++ wikibase-scripts/draft-clem.js | 397 ++------ .../jquery.ui.TemplatedWidget.js | 226 ++++ .../jquery.wikibase.entityselector.js | 775 ++++++++++++++ .../wikibase_source_files/snakview.js | 963 ++++++++++++++++++ .../wikibase_source_files/templates.php | 341 +++++++ 9 files changed, 2619 insertions(+), 315 deletions(-) create mode 100644 wikibase-scripts/draft-clem-bk2.js create mode 100644 wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js create mode 100644 wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js create mode 100644 wikibase-scripts/wikibase_source_files/snakview.js create mode 100644 wikibase-scripts/wikibase_source_files/templates.php diff --git a/.DS_Store b/.DS_Store index dbabfc318dcc37255a47893997e405b424fcb280..027cf8295f8f70c3f98344748514d4a2b0bbd591 100644 GIT binary patch delta 33 fcmZp1XmQw3FUoFas-s|HVYazV^d~zKr;Z5#tN{tB delta 33 fcmZp1XmQw3FUoFgrlVkLXu7#g^d~zKr;Z5#s{9F; diff --git a/api_import_one.py b/api_import_one.py index 343edb1..75828b3 100644 --- a/api_import_one.py +++ b/api_import_one.py @@ -30,3 +30,30 @@ def mth_import_one(arg): wikidata_property.get() wikibase_importer.change_property(wikidata_property, wikibase_repo, True) return True + +def mth_import_one_without_statements(arg): + # connect to the wikibase + wikibase = pywikibot.Site("my", "my") + wikibase_repo = wikibase.data_repository() + wikibase_repo.login() + + # connect to wikidata + wikidata = pywikibot.Site("wikidata", "wikidata") + wikidata_repo = wikidata.data_repository() + + from util.util import WikibaseImporter + wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) + + # import a single item or property + print(f"Importing {arg}") + if arg.startswith("Q"): + print("before get") + wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) + wikidata_item.get() + print("after get") + wikibase_importer.change_item(wikidata_item, wikibase_repo, False) + elif arg.startswith("P"): + wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) + wikidata_property.get() + wikibase_importer.change_property(wikidata_property, wikibase_repo, False) + return True \ No newline at end of file diff --git a/main.py b/main.py index 7d9dc76..5cc59e8 100644 --- a/main.py +++ b/main.py @@ -31,8 +31,8 @@ class ImportOne(Resource): def import_thread_spinner(self, query_id): def handle(): - from api_import_one import mth_import_one - response = mth_import_one(query_id) + from api_import_one import mth_import_one, mth_import_one_without_statements + response = mth_import_one_without_statements(query_id) t = Thread(target=handle) return t def get(self, q_id): diff --git a/wikibase-scripts/draft-clem-bk2.js b/wikibase-scripts/draft-clem-bk2.js new file mode 100644 index 0000000..b517574 --- /dev/null +++ b/wikibase-scripts/draft-clem-bk2.js @@ -0,0 +1,201 @@ +/* Any JavaScript here will be loaded for all users on every page load. */ +//final draftttt + + +var _propertyId = ""; +var _propertyLabel = ""; + +var cloneButtonCounter = 0; +var parentIDCounter = 0; +var autoInputIDCounter = 0; +var propertyDetailArray = []; +var cloneButtonIdPrefix = 'clone_btn_'; +var currentlyClickedCloneButtonId = ''; +var currentBtn = null; +// var localDataLength = 1; + +var _wikibasesync_base_url = "http://127.0.0.1:5000/"; + +function insertStyle(){ + var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; + //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet){ + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} + +(function (mw, $) { + insertStyle() + var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') + var isLocallyAvailable = true + var isRemotelyAvailable = false + console.log(_parentEl) + + const observer = new MutationObserver(function (mutations_list) { + mutations_list.forEach(function (mutation) { + mutation.addedNodes.forEach(function (added_node) { + //console.log(Object.keys(added_node)); + var entries = Object.entries(added_node); + var isStatement = added_node.classList && ['listview-item', 'wikibase-statementgroupview', 'wb-new'].every(function(c){return added_node.classList.contains(c)}) + var isReference = added_node.classList && ['listview-item', 'wikibase-snakview', 'wb-edit'].every(function(c){return added_node.classList.contains(c)}) + + var localList = added_node.classList && ['ui-ooMenu', 'ui-widget', 'ui-widget-content', 'ui-suggester-list', 'ui-entityselector-list'].every(function(c){return added_node.classList.contains(c)}) + var remoteList = added_node.classList && ['ui-autocomplete' 'ui-menu' 'ui-widget' 'ui-widget-content' 'ui-corner-all'].every(function(c){return added_node.classList.contains(c)}) + + + + var focusInput; + + if (isStatement || isReference) { + + // secondary wikidata autocomplete + + $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: + source: function (request, response) { + console.log('Request term: ' + request.term); + + $.ajax({ + // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', + url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, + // data: {term: request.term}, + // dataType: "json", + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + data_length = data.response.search.length + + if (data_length < 1) { + isRemotelyAvailable = false; + //$("ui-entityselector-notfound").hide(); +// var appendedButton = currentContext.siblings('.mez-appended-button') +// if((appendedButton.length > 0 && isLocallyAvailable) || +// if((appendedButton.length > 0 && isLocallyAvailable) || +// ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ +// currentContext.siblings('.mez-appended-button').remove() +// } + } + + if (data_length >= 1) { + isRemotelyAvailable = true; + //var appendedButton = currentContext.siblings('.mez-appended-button') + + //if (appendedButton.length === 0 && isLocallyAvailable == false) { +// if (appendedButton.length === 0) { +// $("").insertAfter($(currentContext)); +// } + } + + response($.map(data.response.search, function (item) { + _propertyId = item.id; + _propertyLabel = item.label; + return { + label: item.description, + value: item.label, + id: item.id + } + })); + } + }); + + + }, + select: function (event, ui) { + + console.log("REMOTE OPTION SELECTED") + console.log($(event.target).siblings('button')); + $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) + $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) + $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) + + } + }); + + + $('.wikibase-snakview-property input').on('keyup', function () { + //console.log("TYPED VALUE"); + var typedValue = $(this).val(); + var currentContext = $(this) + var appendedButton = currentContext.siblings('.mez-appended-button') + if (isRemotelyAvailable) { + if (appendedButton.length === 0) { + $("").insertAfter($(currentContext)); + } + } + if (!isRemotelyAvailable) { + if (appendedButton.length === 0) { + $("").insertAfter($(currentContext)); + } + } + + if(appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === ""){ + currentContext.siblings('.mez-appended-button').remove() + } + + //check if there's data found locally + + }); + } + }); + }); + }); + + observer.observe(document.querySelector("body"), { subtree: true, childList: true }); +}(mediaWiki, jQuery)); + +//ui-menu-item. +//clone button clicked +function cloneAction(ele) { + //clone action called + console.log("Clone information: ") + console.log(ele.getAttribute('item-id')); + console.log(ele.getAttribute('item-description')); + console.log(ele.getAttribute('item-value')); + + var _myPropertyId = ele.getAttribute('item-id') + + //api call + var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; + $.ajax({ + url: wikibaseSyncUrl, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + ele.remove(); + console.log('clone button removed'); + + } + }); +} + +function pushNewButtonInfo(buttonId, arrayKey) { + //add button info to array + propertyDetailArray[arrayKey] = buttonId; + + console.log(propertyDetailArray); +} + +//TODO PENDING ISSUES +//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS +//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED +//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW +//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS diff --git a/wikibase-scripts/draft-clem.js b/wikibase-scripts/draft-clem.js index b7751d6..4b23938 100644 --- a/wikibase-scripts/draft-clem.js +++ b/wikibase-scripts/draft-clem.js @@ -1,325 +1,96 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -// var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -function insertStyle(){ - var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; - //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - - head.appendChild(style); - - style.type = 'text/css'; - if (style.styleSheet){ - // This is required for IE8 and below. - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); +var STATEMENT_CLASSES = ['listview-item', 'wikibase-statementgroupview', 'wb-new']; +var REFERENCE_CLASSES = ['listview-item', 'wikibase-snakview', 'wb-edit']; +var REFERENCE_INPUT_CLASSES = ['ui-suggester-input', 'ui-entityselector-input']; +var AUTOCOMPLETE_CLASSES = ['ui-ooMenu', 'ui-widget', 'ui-widget-content', 'ui-suggester-list', 'ui-entityselector-list']; + +var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + +var nextId = 0; + +var lastAutocompleteElement = null; +var requestsResults = {}; // key=statementId, value=result +var lastResultStatementId = null; + +(function (mw, _$) { + + function makeWikidataCall (userInput, statementId) { + $.ajax({ + url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + userInput, + crossDomain: true, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + requestsResults[statementId] = data; + lastResultStatementId = statementId; + updateAutocompleteElement(statementId); + } + }); } -} - -(function (mw, $) { - insertStyle() - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - var isLocallyAvailable = true - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var isStatement = added_node.classList && ['listview-item', 'wikibase-statementgroupview', 'wb-new'].every(function(c){return added_node.classList.contains(c)}) - var isReference = added_node.classList && ['listview-item', 'wikibase-snakview', 'wb-edit'].every(function(c){return added_node.classList.contains(c)}) - - - - var focusInput; - - if (isStatement || isReference) { - // secondary wikidata autocomplete - - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - if(isLocallyAvailable == false){ - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }else{ - $(".ui-autocomplete").hide() - response = null - return null - } - }, - select: function (event, ui) { - if(!isLocallyAvailable){ - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - }else{ - } - - } - }); - - - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - var currentContext = $(this) - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - //console.log("RECEIVED LOCAL DATA"); - //console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - isLocallyAvailable = false - $("ui-entityselector-notfound").hide() - - //console.log('No found'); - - - //focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - var appendedButton = currentContext.siblings('.mez-appended-button') - if (appendedButton.length === 0 && isLocallyAvailable == false) { - $("").insertAfter($(currentContext)); - } - - //if (focusInput) { - // console.log('in focus input'); - - //} - } else { - console.log("IN ELSE") - //console.log(isLocallyAvailable) - isLocallyAvailable = true - - var appendedButton = currentContext.siblings('.mez-appended-button') - if((appendedButton.length > 0 && isLocallyAvailable) || - ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ - currentContext.siblings('.mez-appended-button').remove() - } - } - } - }); - }); + function updateAutocompleteElement (statementId) { + if (lastAutocompleteElement === null) return; + + var data = requestsResults[statementId]; + var children = Array.from(lastAutocompleteElement.children); + + if (children.length === 1 && children[0].matches('li.ui-entityselector-notfound')) { + // No match found + console.log('no match'); + } else { + // At least one match found + console.log('At least one match'); + // data.response.search.forEach(proposition => { + // // TODO + // }); + } + } + function setLastAutocompleteElement (el) { + // Update the global var + lastAutocompleteElement = el; + + // Attach an observer to
    to monitor its children (detect a change) + var acObserver = new MutationObserver(function (mutationsList) { + mutationsList.forEach(function (mutation) { + if (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0) { + // Children have been removed/added + if (lastResultStatementId !== null) updateAutocompleteElement(lastResultStatementId); } + }); + }); + acObserver.observe(el, { childList: true }); + } - /*if (entries.length == 2) { - if (entries[0][1]) { - // secondary wikidata autocomplete - - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - if(isLocallyAvailable == false){ - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }else{ - $(".ui-autocomplete").hide() - response = null - return null - } - - }, - select: function (event, ui) { - if(!isLocallyAvailable){ - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - }else{ - } - - } - }); - - - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - var currentContext = $(this) - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - //console.log("RECEIVED LOCAL DATA"); - //console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - isLocallyAvailable = false - $("ui-entityselector-notfound").hide() - - //console.log('No found'); - - - //focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - var appendedButton = currentContext.siblings('.mez-appended-button') - if (appendedButton.length === 0 && isLocallyAvailable == false) { - $("").insertAfter($(currentContext)); - } - - //if (focusInput) { - // console.log('in focus input'); - - //} - } else { - console.log("IN ELSE") - //console.log(isLocallyAvailable) - isLocallyAvailable = true - - var appendedButton = currentContext.siblings('.mez-appended-button') - if((appendedButton.length > 0 && isLocallyAvailable) || - ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ - currentContext.siblings('.mez-appended-button').remove() - } - } - } - }); + const observer = new MutationObserver(function (mutationsList) { + mutationsList.forEach(function (mutation) { + mutation.addedNodes.forEach(function (addedNode) { + // Check for new statement block + var isStatement = addedNode.classList && STATEMENT_CLASSES.every(function (c) { return addedNode.classList.contains(c) }); + if (isStatement) { + // A new statement block has been added + var statementId = nextId; + nextId += 1; + var input = addedNode.querySelector('input.' + REFERENCE_INPUT_CLASSES.join('.')); + lastInputElement = input; + input.addEventListener('input', function () { + makeWikidataCall(input.value, statementId); }); - } - }*/ - + return; + } + // Check for new autocomplete element + var isAutocomplete = addedNode.classList && AUTOCOMPLETE_CLASSES.every(function (c) { return addedNode.classList.contains(c) }); + if (isAutocomplete) { + // Keep track of the last one (which is the only one valid) + setLastAutocompleteElement(addedNode); + //uodate last autocomplete el with the last known result + if (lastResultStatementId !== null) updateAutocompleteElement(lastResultStatementId); + } }); }); }); + observer.observe(document.body, { subtree: true, childList: true }); - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); }(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - var _myPropertyId = ele.getAttribute('item-id') - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; - $.ajax({ - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - ele.remove(); - console.log('clone button removed'); - - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} - -//TODO PENDING ISSUES -//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS -//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED -//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW -//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS diff --git a/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js b/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js new file mode 100644 index 0000000..40660b4 --- /dev/null +++ b/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js @@ -0,0 +1,226 @@ +( function () { + 'use strict'; + + var PARENT = $.Widget; + + /** + * Base prototype for all widgets using the `mw.wbTemplate` templating system. + * Uses `jQuery.fn.applyTemplate`. + * @see mediaWiki.WbTemplate + * @class jQuery.ui.TemplatedWidget + * @abstract + * @extends jQuery.Widget + * @uses jQuery.fn + * @license GPL-2.0-or-later + * @author Daniel Werner < daniel.a.r.werner@gmail.com > + * + * @constructor + * + * @param {Object} options + * @param {string} options.template + * Name of a template to use. The template should feature a single root node which will + * be replaced by the widget's subject node. + * @param {*[]} [options.templateParams] + * Parameters injected into the template on its initial construction. A parameter can be + * what is compatible with `mw.wbTemplate` but can also be a function which will be + * executed in the widget's context and provide the parameter's value by its return + * value. + * @param {Object} [options.templateShortCuts] + * A map pointing from a short-cut name to a node within the widget's template. The map + * is used during the widget creation process to automatically add members to the widget + * object that may be accessed during the widget's life time. + * The location of the target node has to be given as a valid jQuery query expression, + * i.e. `{ $foo: li.example-class > .foo }` results in being able to access the selected + * node using `this.$foo` within the widget instance. + * @param {boolean} [options.encapsulate=false] + * Whether non-native `jQuery.Widget` events shall be triggered on the widget's node only + * and not bubble up the DOM tree (using `jQuery.triggerHandler()` instead of + * `jQuery.trigger()`). + */ + /** + * @event disable + * Triggered whenever the widget is disabled (after disabled state has been set). + * @param {jQuery.Event} + * @param {boolean} Whether widget has been dis- oder enabled. + */ + $.widget( 'ui.TemplatedWidget', PARENT, { + /** + * @see jQuery.Widget.options + */ + options: $.extend( true, {}, PARENT.prototype.options, { + template: null, + templateParams: [], + templateShortCuts: {}, + encapsulate: false + } ), + + /** + * Creates the DOM structure according to the template and assigns the template short-cuts. + * Consequently, when overriding `_create` in inheriting widgets, calling the parent's + * `_create` should be the first action in the overridden `_create`, as that ensures the + * basic template DOM is created and template short-cuts can be used. The function should + * be overridden only to perform DOM manipulation/creation while initializing should be + * performed in `_init`. + * + * @see jQuery.Widget._create + * @protected + * + * @throws {Error} if `template` option is not specified. + */ + _create: function () { + if ( !this.options.template ) { + throw new Error( 'template needs to be specified' ); + } + + // FIXME: Find sane way to detect that template is applied already. + if ( this.element.contents().length === 0 ) { + this._applyTemplate(); + } + + this._createTemplateShortCuts(); + + PARENT.prototype._create.apply( this ); + }, + + /** + * @see jQuery.fn.applyTemplate + * @private + */ + _applyTemplate: function () { + var templateParams = [], + self = this; + + // template params which are functions are callbacks to be called in the widget's context + this.options.templateParams.forEach( function ( value ) { + if ( typeof value === 'function' ) { + value = value.call( self ); + } + templateParams.push( value ); + } ); + + // the element node will be preserved, no matter whether it is of the same kind as the + // template's root node (it is assumed that the template has a root node) + this.element.addClass( this.widgetBaseClass ); + this.element.applyTemplate( this.option( 'template' ), templateParams ); + }, + + /** + * Creates the short-cuts to DOM nodes within the template's DOM structure as specified in + * the `templateShortCuts` option. + * + * @private + * + * @throws {Error} if no DOM node is found using a specified selector. + */ + _createTemplateShortCuts: function () { + var shortCuts = this.options.templateShortCuts, + shortCut, shortCutSelector, $shortCutTarget; + + for ( shortCut in shortCuts ) { + shortCutSelector = shortCuts[ shortCut ]; + $shortCutTarget = this.element.find( shortCutSelector ); + if ( $shortCutTarget.length < 1 ) { + throw new Error( 'Template "' + this.option( 'template' ) + '" has no DOM node ' + + ' selectable via the jQuery expression "' + shortCutSelector + '"' ); + } + this[ shortCut ] = $shortCutTarget; + + } + }, + + /** + * @see jQuery.Widget.destroy + */ + destroy: function () { + PARENT.prototype.destroy.call( this ); + + this.element.removeClass( this.widgetBaseClass ); + + // nullify references to short-cut DOM nodes + for ( var shortCut in this.options.templateShortCuts ) { + this[ shortCut ] = null; + } + }, + + /** + * @see jQuery.Widget._setOption + * @protected + * + * @param {string} key + * @param {*} value + * @return {jQuery.Widget} + * + * @throws {Error} when trying to set `template`, `templateParams` or `templateShortCuts` + * option. + */ + _setOption: function ( key, value ) { + switch ( key ) { + case 'template': + case 'templateParams': + case 'templateShortCuts': + throw new Error( 'Can not set template related options after initialization' ); + } + + var response = PARENT.prototype._setOption.apply( this, arguments ); + + if ( key === 'disabled' ) { + this._trigger( 'disable', null, [ value ] ); + } + + return response; + }, + + /** + * Applies focus to the widget. + */ + focus: function () { + this.element.trigger( 'focus' ); + }, + + /** + * Clone of jQuery.Widget._trigger with the difference that `$.triggerHandler()` instead of + * `$.trigger()` is used to trigger the event on `this.element` if `encapsulate` option is + * `true`. + * + * @see jQuery.Widget._trigger + * @protected + * + * @param {string} type + * @param {jQuery.Event|string} event + * @param {*} data + * @return {boolean} + */ + _trigger: function ( type, event, data ) { + var prop, + orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( + type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type + ).toLowerCase(); + // The original event may come from any element, so we need to reset the target on the + // new event: + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event: + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element[ this.options.encapsulate ? 'triggerHandler' : 'trigger' ]( event, data ); + return !( + typeof callback === 'function' + && callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false + || event.isDefaultPrevented() + ); + } + } ); + +}() ); diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js new file mode 100644 index 0000000..eca8546 --- /dev/null +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -0,0 +1,775 @@ +var wikidataResults = []; +var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + +function removeExistingRecordsFromWikidataResults(wikidataResults, localResults){ + if (!wikidataResults || !localResults){ + return wikidataResults; + } + var updatedResults = []; + wikidataResults.concat(localResults).forEach(function (element) { + var index = updatedResults.findIndex(function(x){ + return x.label.toLowerCase().trim() == element.label && x.description == element.description.toLowerCase().trim() + }) + if (index == -1) { + updatedResults.push(element); + } + }) + return updatedResults + + +} + +( function () { + 'use strict'; + + // TODO: Get rid of MediaWiki context detection by submitting a message provider as option. + + /** + * Whether loaded in MediaWiki context. + * + * @property {boolean} + * @ignore + */ + var IS_MW_CONTEXT = mw !== undefined && mw.msg; + + /** + * Whether actual `entityselector` resource loader module is loaded. + * + * @property {boolean} + * @ignore + */ + var IS_MODULE_LOADED = ( + IS_MW_CONTEXT + && mw.loader.getModuleNames().indexOf( 'jquery.wikibase.entityselector' ) !== -1 + ); + + /** + * Returns a message from the MediaWiki context if the `entityselector` module has been loaded. + * If it has not been loaded, the corresponding string defined in the options will be returned. + * + * @ignore + * + * @param {string} msgKey + * @param {string} string + * @return {string} + */ + function mwMsgOrString( msgKey, string ) { + // eslint-disable-next-line mediawiki/msg-doc + return IS_MODULE_LOADED ? mw.msg( msgKey ) : string; + } + + /** + * Enhances an input box with auto-complete and auto-suggestion functionality for Wikibase entities. + * + * @example + * $( 'input' ).entityselector( { + * url: <{string} URL to the API of a MediaWiki instance running Wikibase repository>, + * language: <{string} language code of the language to fetch results in> + * } ); + * + * @class jQuery.wikibase.entityselector + * @extends jQuery.ui.suggester + * @uses jQuery.event.special.eachchange + * @uses jQuery.ui.ooMenu + * @license GPL-2.0-or-later + * @author H. Snater < mediawiki@snater.com > + * + * @constructor + * + * @param {Object} options + * @param {string} options.url + * URL to retrieve results from. + * @param {string} options.language + * (optional when in MediaWiki context) + * Language code of the language results shall be fetched in. + * Defaults to the user language (`mw.config.get( 'wgUserLanguage' )` when in MediaWiki + * context. + * @param {string} [options.type='item'] + * `Entity` type that will be queried for results. + * @param {number|null} [options.limit=null] + * Number of results to query the API for. Will pick limit specified server-side if ´null´. + * @param {boolean} [options.caseSensitive=false] + * Whether the widget shall consider letter case when determining if the first suggestion + * matches with the current input triggering the "select" mechanism. + * @param {number} [options.timeout=8000] + * Default AJAX timeout in milliseconds. + * @param {Object} [options.messages=Object] + * Strings used within the widget. + * Messages should be specified using `mwMsgOrString(, + * )` in order to use the messages specified in the resource loader module + * (if loaded). + * @param {string} [options.searchHookName='wikibase.entityselector.search'] + * Name of the hook that fires when searching for entities. + * @param {string} [options.messages.more='more'] + * Label of the link to display more suggestions. + * @param {string[]} [options.showErrorCodes=['failed-property-search']] + * Show errors with these error-codes in the ui. + * @param {Function} [options.responseErrorFactory=null] + * Optional Callback to parse error message from response object + * @see wikibase.api.RepoApiError.newFromApiResponse + */ + /** + * @event selected + * Triggered after having selected an entity. + * @param {jQuery.Event} event + * @param {string} entityId + */ + $.widget( 'wikibase.entityselector', $.ui.suggester, { + + /** + * @property {Object} + */ + options: { + url: null, + language: ( IS_MW_CONTEXT ) ? mw.config.get( 'wgUserLanguage' ) : null, + type: 'item', + limit: null, + caseSensitive: false, + timeout: 8000, + messages: { + more: mwMsgOrString( 'wikibase-entityselector-more', 'more' ), + notfound: mwMsgOrString( 'wikibase-entityselector-notfound', 'Nothing found' ), + error: null + }, + searchHookName: 'wikibase.entityselector.search', + searchApiParametersHookName: 'wikibase.entityselector.search.api-parameters', + showErrorCodes: [ 'failed-property-search' ], + responseErrorFactory: null + }, + + /** + * Caching the most current entity returned from the API. + * + * @property {Object} + * @private + */ + _selectedEntity: null, + + /** + * Caches retrieved results. + * + * Warning, PropertySuggester's EntitySelector accesses this! + * + * @property {Object} [_cache={}] + * @protected + */ + _cache: null, + + /** + * Error object from last search. + * + * @property {Object} [_error={}] + * @protected + */ + _error: null, + + /** + * Warning, PropertySuggester's EntitySelector overrides this! + * + * @inheritdoc + * @protected + */ + _create: function () { + var self = this; + + this._cache = {}; + + if ( !this.options.source ) { + if ( this.options.url === null ) { + throw new Error( 'When not specifying a dedicated source, URL option needs to be ' + + 'specified' ); + } else if ( this.options.language === null ) { + throw new Error( 'When not specifying a dedicated source, language option needs to ' + + 'be specified.' ); + } + this.options.source = this._initDefaultSource(); + } else if ( typeof this.options.source !== 'function' && !Array.isArray( this.options.source ) ) { + throw new Error( 'Source needs to be a function or an array' ); + } + + if ( !this.options.messages.error ) { + this.options.messages.error = function () { + return self._error && self._error.detailedMessage ? self._error.detailedMessage : null; + }; + } + + //console.log('MY OUTPUT from outside',this.options); + + $.ui.suggester.prototype._create.call( this ); + + this.element + .addClass( 'ui-entityselector-input' ) + .prop( 'dir', $( document ).prop( 'dir' ) ); + + this.options.menu.element.addClass( 'ui-entityselector-list' ); + + this.element + .off( 'blur' ) + .on( 'eachchange.' + this.widgetName, function ( event ) { + self._search( event ); + } ) + .on( 'focusout', function () { + self._indicateRecognizedInput(); + } ) + .on( 'focusin', function () { + self._inEditMode(); + self._showDefaultSuggestions(); + } ); + }, + + _indicateRecognizedInput: function () { + this._resetInputHighlighting(); + + if ( this._selectedEntity !== null ) { + this.element.addClass( 'ui-entityselector-input-recognized' ); + } else if ( this.element.val() !== '' ) { + this.element.addClass( 'ui-entityselector-input-unrecognized' ); + } + }, + + _inEditMode: function () { + this._resetInputHighlighting(); + }, + + _resetInputHighlighting: function () { + this.element.removeClass( + 'ui-entityselector-input-recognized ui-entityselector-input-unrecognized' + ); + }, + + /** + * @inheritdoc + */ + destroy: function () { + this.element.removeClass( 'ui-entityselector-input' ); + + this._cache = {}; + + $.ui.suggester.prototype.destroy.call( this ); + }, + + /** + * @protected + * + * @param {jQuery.Event} event + */ + _search: function ( event ) { + var self = this; + + this._select( null ); + + clearTimeout( this._searching ); + this._searching = setTimeout( function () { + self.search( event ); + }, this.options.delay ); + }, + + /** + * Create and return the data object for the api call. + * + * Warning, PropertySuggester's EntitySelector overrides this! + * + * @protected + * @param {string} term + * @return {Object} + */ + _getSearchApiParameters: function ( term ) { + var data = { + action: 'wbsearchentities', + search: term, + format: 'json', + errorformat: 'plaintext', + language: this.options.language, + uselang: this.options.language, + type: this.options.type + }; + + if ( this._cache.term === term && this._cache.nextSuggestionOffset ) { + data.continue = this._cache.nextSuggestionOffset; + } + + if ( this.options.limit ) { + data.limit = this.options.limit; + } + + mw.hook( this.options.searchApiParametersHookName ).fire( data ); + + return data; + }, + + /** + * Initializes the default source pointing to the `wbsearchentities` API module via the URL + * provided in the options. + * + * @protected + * + * @return {Function} + */ + _initDefaultSource: function () { + var self = this; + + return function ( term ) { + var deferred = $.Deferred(), + hookResults = self._fireSearchHook( term ); + + // clear previous error + if ( self._error ) { + self._error = null; + self._cache.suggestions = null; + self._updateMenu( [] ); + } + + $.ajax( { + url: self.options.url, + timeout: self.options.timeout, + dataType: 'json', + data: self._getSearchApiParameters( term ), + success: function(data){ + $.ajax({ + url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + term, + crossDomain: true, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + wikidataResults = data.response.search; + } + }); + } + } ) + .done( function ( response, statusText, jqXHR ) { + // T141955 + if ( response.error ) { + deferred.reject( response.error.info ); + return; + } + + // The default endpoint wbsearchentities responds with an array of errors. + if ( response.errors && self.options.responseErrorFactory ) { + var error = self.options.responseErrorFactory( response, 'search' ); + + if ( error && self.options.showErrorCodes.indexOf( error.code ) !== -1 ) { + self._error = error; + self._cache = {}; + self._updateMenu( [] ); + deferred.reject( error.message ); + return; + } + } + + //TODO MERGE THE WIKIDATA RESULTS WITH RESPONSE SEARCH + // console.log("hooksResults"); + // console.log(hookResults); + // console.log("wikidataResults"); + // console.log(wikidataResults); + // console.log("wikibase results"); + // console.log(response.search); + // UPDATE THE TITLE AND SOURCE TO REFELECT WIKIDATA + // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH + var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, response.search) + //console.log("updatedWikidataResults", updatedWikidataResults); + //self._combineResults( hookResults, response.search ).then( function ( results ) { + self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { + //console.log(results) + deferred.resolve( + results, + term, + response[ 'search-continue' ], + jqXHR.getResponseHeader( 'X-Search-ID' ) + ); + } ); + } ) + .fail( function ( jqXHR, textStatus ) { + deferred.reject( textStatus ); + } ); + + return deferred.promise(); + }; + }, + /** + * @private + */ + _fireSearchHook: function ( term ) { + var hookResults = [], + addPromise = function ( p ) { + hookResults.push( p ); + }; + + if ( this._cache.term === term ) { + return hookResults; // Don't fire hook when paginating + } + + mw.hook( this.options.searchHookName ).fire( { + element: this.element, + term: term, + options: this.options + }, addPromise ); + + return hookResults; + }, + /** + * @private + */ + _combineResults: function ( hookResults, searchResults ) { + var self = this, + deferred = $.Deferred(), + ids = {}, + result = [], + uniqueFilter = function ( item ) { + if ( ids[ item.id ] ) { + return false; + } + ids[ item.id ] = true; + return true; + }, + ratingSorter = function ( item1, item2 ) { + if ( !item1.rating && !item2.rating ) { + return 0; + } + if ( !item1.rating ) { + return 1; + } + if ( !item2.rating ) { + return -1; + } + if ( item1.rating < item2.rating ) { + return 1; + } + if ( item1.rating === item2.rating ) { + return 0; + } + return -1; + }; + + searchResults = searchResults || []; + + $.when.apply( $, hookResults ).then( function () { + + var args = Array.prototype.slice.call( arguments ); + args.forEach( function ( data ) { + result = data.concat( result ); + } ); + + result = self._stableSort( result, ratingSorter ); + result = result.concat( searchResults ); + result = result.filter( uniqueFilter ); + deferred.resolve( result ); + } ); + + return deferred.promise(); + }, + + /** + * @private + */ + _stableSort: function stableSort( items, compareFn ) { + var indices = Object.keys( items ).map( Number ); + indices.sort( function ( index1, index2 ) { + var compare = compareFn( items[ index1 ], items[ index2 ] ); + if ( compare !== 0 ) { + return compare; + } + // fall back to comparing indices to ensure stability + if ( index1 < index2 ) { + return -1; + } + if ( index1 > index2 ) { + return 1; + } + return 0; + } ); + var sorted = indices.map( function ( index ) { + return items[ index ]; + } ); + return sorted; + }, + + /** + * @private + */ + _showDefaultSuggestions: function () { + if ( this.element.val() !== '' ) { + return; + } + + var self = this, + term = this.element.val(), + promises = this._fireSearchHook( term ); + + this._combineResults( promises, [] ).then( function ( suggestions ) { + if ( suggestions.length > 0 ) { + self._updateMenu( suggestions ); + } + } ); + + }, + + /** + * @inheritdoc + * @protected + */ + _updateMenu: function ( suggestions ) { + var scrollTop = this.options.menu.element.scrollTop(); + + $.ui.suggester.prototype._updateMenu.apply( this, arguments ); + + this.options.menu.element.scrollTop( scrollTop ); + }, + + /** + * Generates the label for a suggester entity. + * + * @protected + * + * @param {Object} entityStub + * @return {jQuery} + */ + _createLabelFromSuggestion: function ( entityStub ) { + var $suggestion = $( '' ).addClass( 'ui-entityselector-itemcontent' ), + $label = $( '' ).addClass( 'ui-entityselector-label' ).text( entityStub.label || entityStub.id ); + + if ( entityStub.aliases ) { + $label.append( + $( '' ).addClass( 'ui-entityselector-aliases' ).text( ' (' + entityStub.aliases.join( ', ' ) + ')' ) + ); + } + + $suggestion.append( $label ); + + if ( entityStub.description ) { + $suggestion.append( + $( '' ).addClass( 'ui-entityselector-description' ) + .text( entityStub.description ) + ); + } + + return $suggestion; + }, + + /** + * @see jQuery.ui.suggester._createMenuItemFromSuggestion + * @protected + * + * @param {Object} entityStub + * @return {jQuery.wikibase.entityselector.Item} + */ + _createMenuItemFromSuggestion: function ( entityStub ) { + var $label = this._createLabelFromSuggestion( entityStub ), + value = entityStub.label || entityStub.id; + + return new $.wikibase.entityselector.Item( $label, value, entityStub ); + }, + + /** + * @inheritdoc + * @protected + */ + _initMenu: function ( ooMenu ) { + var self = this; + $.ui.suggester.prototype._initMenu.apply( this, arguments ); + + $( this.options.menu ) + .off( 'selected.suggester' ) + .on( 'selected.entityselector', function ( event, item ) { + if ( item.getEntityStub ) { + if ( !self.options.caseSensitive + && item.getValue().toLowerCase() === self._term.toLowerCase() + ) { + self._term = item.getValue(); + } else { + self.element.val( item.getValue() ); + } + + self._close(); + self._trigger( 'change' ); + + var entityStub = item.getEntityStub(); + + if ( !self._selectedEntity || entityStub.id !== self._selectedEntity.id ) { + self._select( entityStub ); + } + } + } ); + + var customItems = ooMenu.option( 'customItems' ); + + customItems.unshift( new $.ui.ooMenu.CustomItem( + this.options.messages.more, + function () { + return self._cache.term === self._term && self._cache.nextSuggestionOffset; + }, + function () { + self.search( $.Event( 'programmatic' ) ); + }, + 'ui-entityselector-more' + ) ); + + customItems.unshift( new $.ui.ooMenu.CustomItem( + this.options.messages.notfound, + function () { + return !self._error && self._cache.suggestions && !self._cache.suggestions.length + && self.element.val().trim() !== ''; + }, + null, + 'ui-entityselector-notfound' + ) ); + + customItems.unshift( new $.ui.ooMenu.CustomItem( + this.options.messages.error, + function () { + return self._error !== null; + }, + null, + 'ui-entityselector-error' + ) ); + + ooMenu._evaluateVisibility = function ( customItem ) { + if ( customItem instanceof $.ui.ooMenu.CustomItem ) { + return customItem.getVisibility( ooMenu ); + } else { + return ooMenu._evaluateVisibility.apply( this, arguments ); + } + }; + + ooMenu.option( 'customItems', customItems ); + + return ooMenu; + }, + + /** + * @inheritdoc + * @protected + */ + _getSuggestions: function ( term ) { + var self = this; + + return $.ui.suggester.prototype._getSuggestions.apply( this, arguments ) + .then( function ( suggestions, searchTerm, nextSuggestionOffset, searchId ) { + var deferred = $.Deferred(); + + if ( self._cache.term === searchTerm && self._cache.nextSuggestionOffset ) { + self._cache.suggestions = self._cache.suggestions.concat( suggestions ); + self._cache.nextSuggestionOffset = nextSuggestionOffset; + } else { + self._cache = { + term: searchTerm, + suggestions: suggestions, + nextSuggestionOffset: nextSuggestionOffset + }; + } + if ( searchId ) { + self._cache.searchId = searchId; + } else { + delete self._cache.searchId; + } + + deferred.resolve( self._cache.suggestions, searchTerm ); + return deferred.promise(); + } ); + }, + + /** + * @inheritdoc + * @protected + */ + _getSuggestionsFromArray: function ( term, source ) { + var deferred = $.Deferred(), + matcher = new RegExp( this._escapeRegex( term ), 'i' ); + + deferred.resolve( source.filter( function ( item ) { + if ( item.aliases ) { + for ( var i = 0; i < item.aliases.length; i++ ) { + if ( matcher.test( item.aliases[ i ] ) ) { + return true; + } + } + } + + return matcher.test( item.label ) || matcher.test( item.id ); + } ), term ); + + return deferred.promise(); + }, + + /** + * Selects an entity. + * + * @protected + * + * @param {Object} entityStub + */ + _select: function ( entityStub ) { + var id = entityStub && entityStub.id; + this._selectedEntity = entityStub; + if ( id ) { + this._trigger( 'selected', null, [ id ] ); + } + }, + + /** + * Gets and sets the current state. The optional parameter can be used to let the initial + * state of the selector reflect what can be seen in the input field the selector is + * attached to. + * + * @param {string} [entityId] + * @return {Object} Plain object featuring `Entity` stub data. + */ + selectedEntity: function ( entityId ) { + if ( typeof entityId === 'string' ) { + this._selectedEntity = { id: entityId }; + } + + return this._selectedEntity; + } + } ); + + /** + * Default `entityselector` suggestion menu item. + * + * @class jQuery.wikibase.entityselector.Item + * @extends jQuery.ui.ooMenu.Item + * + * @constructor + * + * @param {jQuery|string} label + * @param {string} value + * @param {Object} entityStub + * + * @throws {Error} if a required parameter is not specified properly. + */ + var Item = function ( label, value, entityStub ) { + if ( !label || !value || !entityStub ) { + throw new Error( 'Required parameter(s) not specified properly' ); + } + + this._label = label; + this._value = value; + this._entityStub = entityStub; + this._link = entityStub.url; + }; + + Item = util.inherit( + $.ui.ooMenu.Item, + Item, + { + /** + * @property {Object} + * @protected + */ + _entityStub: null, + + /** + * @return {Object} + */ + getEntityStub: function () { + return this._entityStub; + } + } + ); + + $.extend( $.wikibase.entityselector, { + Item: Item + } ); + +}() ); diff --git a/wikibase-scripts/wikibase_source_files/snakview.js b/wikibase-scripts/wikibase_source_files/snakview.js new file mode 100644 index 0000000..1008868 --- /dev/null +++ b/wikibase-scripts/wikibase_source_files/snakview.js @@ -0,0 +1,963 @@ +( function ( wb, dv ) { + 'use strict'; + + // Back-up components already initialized in the namespace to re-apply them after initializing + // the snakview widget. + $.wikibase = $.wikibase || {}; + var existingSnakview = $.wikibase.snakview || {}; + + // Erase existing object to prevent jQuery.Widget detecting an existing constructor: + delete $.wikibase.snakview; + + var PARENT = $.ui.EditableTemplatedWidget, + datamodel = require( 'wikibase.datamodel' ), + ViewState = require( './snakview.ViewState.js' ), + variations = require( './snakview.variations.js' ), + wbserialization = require( 'wikibase.serialization' ); + + /** + * View for displaying and editing `datamodel.Snak` objects. + * + * @see datamodel.Snak + * @class jQuery.wikibase.snakview + * @extends jQuery.ui.EditableTemplatedWidget + * @author Daniel Werner < daniel.a.r.werner@gmail.com > + * @author H. Snater < mediawiki@snater.com > + * + * @constructor + * + * @param {Object} options + * @param {Object|datamodel.Snak|null} [options.value] + * The `Snak` this `snakview` should represent initially. If omitted, an empty view will be + * served, ready to take some input by the user. The value may be overwritten later, by using + * the `value()` or the `snak()` function. + * Default: `{ snaktype: datamodel.PropertyValueSnak.TYPE }` + * @param {Object|boolean} [options.locked=false] + * Key-value pairs determining which `snakview` elements to lock from being edited by the + * user. May also be a boolean value enabling/disabling all elements. If `false`, no elements + * will be locked. + * @param {boolean} [options.autoStartEditing=true] + * Whether the `snakview` should switch to edit mode automatically upon initialization if its + * initial value is empty. + * @param {wikibase.entityIdFormatter.EntityIdHtmlFormatter} options.entityIdHtmlFormatter + * Required for dynamically rendering links to `Entity`s. + * @param {wikibase.entityIdFormatter.EntityIdPlainFormatter} options.entityIdPlainFormatter + * Required for dynamically rendering plain text references to `Entity`s. + * @param {PropertyDataTypeStore} options.propertyDataTypeStore + * Required for looking up the Snak's property's data type. + * @param {wikibase.ValueViewBuilder} options.valueViewBuilder + * Required to interfacing a `snakview` "value" `Variation` to `jQuery.valueview`. + * @param {wikibase.dataTypes.DataTypeStore} options.dataTypeStore + * Required to retrieve and evaluate a proper `wikibase.dataTypes.DataType` object when interacting on + * a "value" `Variation`. + * @param {boolean} [options.drawProperty=true] + * The `Property` part of the `snakview` is not rendered when `drawProperty` is false. + */ + /** + * @event afterstartediting + * Triggered after having started the widget's edit mode. + * @param {jQuery.Event} event + */ + /** + * @event afterstopediting + * Triggered after having stopped the widget's edit mode. + * @param {jQuery.Event} event + * @param {boolean} dropValue + */ + /** + * @event change + * Triggered whenever the widget's content or status is changed. + * @param {jQuery.Event} event + */ + $.widget( 'wikibase.snakview', PARENT, { + /** + * @inheritdoc + * @protected + */ + options: { + template: 'wikibase-snakview', + templateParams: [ '', '', '', '', '' ], + templateShortCuts: { + $property: '.wikibase-snakview-property', + $snakValue: '.wikibase-snakview-value', + $snakTypeSelector: '.wikibase-snakview-typeselector', + $cloneBtn: '.wikibase-snakview-clonebtn' + }, + value: { + snaktype: datamodel.PropertyValueSnak.TYPE + }, + locked: { + property: false, + snaktype: false + }, + autoStartEditing: true, + entityIdPlainFormatter: null, + entityIdHtmlFormatter: null, + valueViewBuilder: null, + dataTypeStore: null, + drawProperty: true, + getSnakRemover: null, + propertyDataTypeStore: null + }, + + /** + * `Variation` object responsible for presenting the essential parts of a certain kind of + * `Snak`. May be `null` if an unsupported `Snak` type is represented by the `snakview`. In this + * case, the `snakview` won't be able to display the `Snak` but displays an appropriate message + * instead. + * + * @property {Variation|null} + * @private + */ + _variation: null, + + /** + * Cache for the values of specific `variation`s used to have those + * values restored when toggling the `Snak` type. + * + * @property {Object} + * @private + */ + _cachedValues: null, + + /** + * Whether then `snakview`'s value is regarded "valid" at the moment. + * + * @property {boolean} + * @private + */ + _isValid: false, + + _isCloneBtnEnabled: false, + _item_id: "", + _item_description: "", + + /** + * @inheritdoc + * @protected + */ + _create: function () { + if ( this.options.locked === true || this.options.locked.property === true ) { + if ( !( + this.options.value instanceof datamodel.Snak || ( this.options.value && this.options.value.property ) + ) ) { + mw.log.warn( 'You cannot lock the property without specifying a property' ); + } + } + + PARENT.prototype._create.call( this ); + + this._cachedValues = {}; + + this.updateVariation(); + this.updateHash(); + + // Re-render on previously generated DOM should be avoided. However, when regenerating the + // whole snakview, every component needs to be drawn. + var propertyIsEmpty = !this.$property.contents().length, + snakValueIsEmpty = !this.$snakValue.contents().length; + + if ( propertyIsEmpty && this.options.drawProperty ) { + this.drawProperty(); + } + + if ( snakValueIsEmpty ) { + this.drawVariation(); + } + + if ( this.option( 'autoStartEditing' ) && !this.snak() ) { + // If no Snak is represented, offer UI to build one. + // This clearly implies draw() since it requires visual changes! + this.startEditing(); + } + }, + + /** + * @inheritdoc + * @protected + * + * @throws {Error} when trying to set an invalid value. + */ + _setOption: function ( key, value ) { + if ( key === 'value' ) { + if ( value !== null + && !$.isPlainObject( value ) + && !( value instanceof datamodel.Snak ) + ) { + throw new Error( 'The given value has to be a plain object, an instance of ' + + 'datamodel.Snak, or null' ); + } + } else if ( key === 'locked' && typeof value === 'boolean' ) { + var locked = value; + value = $.extend( {}, $.wikibase.snakview.prototype.options.locked ); + Object.keys( $.wikibase.snakview.prototype.options.locked ).forEach( function ( k ) { + value[ k ] = locked; + } ); + } + + var response = PARENT.prototype._setOption.apply( this, arguments ); + + if ( key === 'value' ) { + this.updateVariation(); + this.draw(); + } else if ( key === 'disabled' ) { + var propertySelector = this._getPropertySelector(), + snakTypeSelector = this._getSnakTypeSelector(); + + if ( propertySelector ) { + propertySelector.option( 'disabled', key ); + } + + if ( snakTypeSelector ) { + snakTypeSelector.option( 'disabled', key ); + } + + if ( this._snakRemover ) { + this._snakRemover[ value ? 'disable' : 'enable' ](); + } + + if ( this._variation ) { + this._variation[ value ? 'disable' : 'enable' ](); + } + } + + return response; + }, + + /** + * Returns an input element with initialized `entityselector` for selecting entities. + * + * @private + * + * @return {jQuery} + */ + _buildPropertySelector: function () { + var self = this, + repoConfig = mw.config.get( 'wbRepo' ), + repoApiUrl = repoConfig.url + repoConfig.scriptPath + '/api.php'; + var input = $( '' ); + input.on( 'input' , function ( event ) { + if (!input.value) { + self._isCloneBtnEnabled = false; + self.drawEntityCloneBtn(); + } + }); + return input.entityselector( { + url: repoApiUrl, + type: 'property', + responseErrorFactory: wb.api.RepoApiError.newFromApiResponse + } ) + .prop( 'placeholder', mw.msg( 'wikibase-snakview-property-input-placeholder' ) ) + .on( 'eachchange', function ( event, oldValue ) { + // remove out-dated variations + if ( self._variation ) { + self.drawSnakTypeSelector(); + self.updateVariation(); + self.drawVariation(); + self._trigger( 'change' ); + } + } ) + .on( 'entityselectorselected', function ( event, entityId ) { + self._selectProperty(); + var selectedItemData = self._getPropertySelector()._selectedEntity; + // console.log("source:",selectedItemData.repository.toLowerCase()); + if (selectedItemData.repository.toLowerCase() !== "local") { + //externally sourced data to be clone + self._isCloneBtnEnabled = true; + + self._item_id = selectedItemData.id; + self._item_description = selectedItemData.description; + }else{ + self._isCloneBtnEnabled = false; + // reset button information + self._item_id = ""; + self._item_description = ""; + } + // self._getPropertySelector()._selectedEntity + self.drawEntityCloneBtn(); + + } ); + }, + + /** + * @private + */ + _selectProperty: function () { + var self = this; + + // Display spinner as long as the ValueView is loading: + this.$snakValue.empty().append( + $( '
    ' ).append( $( '' ).addClass( 'mw-small-spinner' ) ) + ); + + // The "value" variation contains experts that depend on the property and value type. Must + // be recreated when the property changes. Would be better to do this in updateVariation, + // and only when the value type changes, but at this point we can't find out any more. + if ( this._variation ) { + this._variation.destroy(); + this._variation = null; + } + + this.updateVariation(); + this.drawSnakTypeSelector(); + + // Since it might take a while for the value view to gather its data from the API, + // the property might not be valid anymore aborting the rendering of the value + // view. + if ( this._variation ) { + $( this._variation ).one( 'afterstartediting', function () { + self._variation.focus(); + } ); + } + + this.drawVariation(); + + this._trigger( 'change' ); + }, + + /** + * @inheritdoc + */ + destroy: function () { + if ( this._snakRemover ) { + this._snakRemover.destroy(); + this._snakRemover = null; + } + var snakTypeSelector = this._getSnakTypeSelector(); + if ( snakTypeSelector ) { + snakTypeSelector.destroy(); + snakTypeSelector.element.remove(); + } + $.Widget.prototype.destroy.call( this ); + }, + + _startEditing: function () { + var deferred = $.Deferred(); + if ( this.options.getSnakRemover ) { + this._snakRemover = this.options.getSnakRemover( this.element ); + } + + if ( this._variation ) { + $( this._variation ).one( 'afterstartediting', function () { + deferred.resolve(); + } ); + this.draw(); + this._variation.startEditing(); + } else { + this.draw(); + deferred.resolve(); + } + return deferred.promise(); + }, + + /** + * @inheritdoc + */ + focus: function () { + if ( this._variation && this._variation.isFocusable() ) { + this._variation.focus(); + } else { + var propertySelector = this._getPropertySelector(); + if ( propertySelector ) { + propertySelector.element.trigger( 'focus' ); + } else { + this.element.trigger( 'focus' ); + } + } + }, + + /** + * Stops the widget's edit mode. + * + * @param {boolean} [dropValue=false] If `true`, the widget's value will be reset to the one + * from before edit mode was started. + */ + _stopEditing: function ( dropValue ) { + if ( this._snakRemover ) { + this._snakRemover.destroy(); + this._snakRemover = null; + } + + if ( this._variation ) { + this._variation.stopEditing( dropValue ); + } + this.drawSnakTypeSelector(); + + this.element.off( 'keydown.' + this.widgetName ); + + return $.Deferred().resolve().promise(); + }, + + /** + * Updates this `snakview`'s status. + * + * @param {string} status May either be 'valid' or 'invalid' + */ + updateStatus: function ( status ) { + if ( status === 'valid' ) { + this._isValid = true; + } else if ( status === 'invalid' ) { + this._isValid = false; + } + if ( this._variation ) { + this._trigger( 'change' ); + } + }, + + /** + * Returns the `entityselector` for choosing the `Snak`'s `Property`. Returns `null` if the + * `Snak` is created and has a `Property` already. (Once created, the `Property` is immutable.) + * + * @private + * + * @return {jQuery.wikibase.entityselector|null} + */ + _getPropertySelector: function () { + if ( this.$property ) { + return this.$property.children().first().data( 'entityselector' ) || null; + } + return null; + }, + + /** + * Returns the `snaktypeselector` for choosing the `Snak`'s type. Returns `null` if the `Snak` + * is created and has a `Property` already. (Once created, the `Property` is immutable.) + * + * @private + * + * @return {jQuery.wikibase.snakview.SnakTypeSelector|null} + */ + _getSnakTypeSelector: function () { + if ( this.$snakTypeSelector ) { + return this.$snakTypeSelector.children().first().data( 'snaktypeselector' ) || null; + } + return null; + }, + + /** + * Returns an object representing the currently displayed `Snak`. This is equivalent to the JSON + * structure of a `Snak`, except that it does not have to be complete. For example, for a + * `PropertyValueSnak` where only the `Property` and `Snak` type are specified, but the value + * has not yet been supplied, the returned object would not have a field for the value either. + * + * @param {Object|datamodel.Snak|null} [value] + * @return {datamodel.Snak|Object|undefined} `undefined` in case `value()` is called to + * set the value. + */ + value: function ( value ) { + if ( value !== undefined ) { + this.option( 'value', value ); + return; + } + + var snakSerializer = new wbserialization.SnakSerializer(), + serialization = this.options.value instanceof datamodel.Snak + ? snakSerializer.serialize( this.options.value ) + : this.options.value; + + if ( !this.isInEditMode() ) { + return serialization; + } + + value = {}; + + if ( this.options.locked.property && serialization.property !== undefined ) { + value.property = serialization.property; + } else if ( !this.options.locked.property ) { + var propertyStub = this._getSelectedProperty(); + + if ( propertyStub && propertyStub.id !== undefined ) { + value.property = propertyStub.id; + } + } + + if ( this.options.locked.snaktype && serialization.snaktype !== undefined ) { + value.snaktype = serialization.snaktype; + } else if ( !this.options.locked.snaktype ) { + var snakTypeSelector = this._getSnakTypeSelector(), + snakType = snakTypeSelector && snakTypeSelector.snakType(); + if ( snakType ) { + value.snaktype = snakType; + } + } + + if ( serialization.hash ) { + value.hash = serialization.hash; + } + + return this._variation ? $.extend( this._variation.value(), value ) : value; + }, + + /** + * If a `datamodel.Snak` instance is passed, the `snakview` is updated to represent the + * `Snak`. If no parameter is supplied, the current `Snak` represented by the `snakview` is + * returned. + * + * @param {datamodel.Snak|null} [snak] + * @return {datamodel.Snak|null|undefined} + */ + snak: function ( snak ) { + if ( snak !== undefined ) { + this.value( snak || {} ); + return; + } + + if ( !this._isValid ) { + return null; + } + + var value = this.value(); + if ( value.datavalue instanceof dv.DataValue ) { + value.datavalue = { + type: value.datavalue.getType(), + value: value.datavalue.toJSON() + }; + } + + var snakDeserializer = new wbserialization.SnakDeserializer(); + try { + return snakDeserializer.deserialize( value ); + } catch ( e ) { + return null; + } + }, + + /** + * Sets/Gets the ID of the `Property` for the `Snak` represented by the `snakview`. If no + * `Property` is set, `null` is returned. + * + * @since 0.3 (setter since 0.4) + * + * @param {string|null} [propertyId] + * @return {string|null|undefined} + */ + propertyId: function ( propertyId ) { + if ( propertyId === undefined ) { + return this.value().property || null; + } else { + var value = this.value(); + + if ( propertyId !== value.property ) { + if ( propertyId === null ) { + delete value.property; + } else { + value.property = propertyId; + } + this.option( 'value', value ); + } + } + }, + + /** + * Sets/Gets the ID of the `Snak` type for the `Snak` represented by the `snakview`. If no + * `Snak` type is set, `null` is returned. + * + * @see datamodel.Snak.TYPE + * + * @param {string|null} [snakType] + * @return {string|null|undefined} + */ + snakType: function ( snakType ) { + var value = this.value(); + + if ( snakType === undefined ) { + return value.snaktype || null; + } else if ( snakType === value.snaktype ) { + return; + } + + if ( snakType === null ) { + delete value.snaktype; + } else { + // TODO: check whether given snak type is actually valid! + value.snaktype = snakType; + } + + this.option( 'value', value ); + }, + + /** + * Returns the `snakview`'s `Variation` object required for presenting the current `Snak` type. + * If a `Snak` type has not been defined yet, `null` is returned. + * + * @return {Variation|null} + */ + variation: function () { + return this._variation; + }, + + /** + * Updates the `Variation` according to the widget's current value. + */ + updateVariation: function () { + var value = this.value(), + propertyId = value ? value.property : null, + snakType = value ? value.snaktype : null, + VariationConstructor = snakType ? variations.getVariation( snakType ) : null; + + this._setDataTypeForSelectedProperty(); + + if ( this._variation + && ( !propertyId || this._variation.constructor !== VariationConstructor ) + ) { + var variationValue = this._variation.value(); + + if ( variationValue.datavalue ) { + variationValue.datavalue = { + type: variationValue.datavalue.getType(), + value: variationValue.datavalue.toJSON() + }; + } + + this._cachedValues[ this._variation.variationSnakConstructor.TYPE ] = variationValue; + + this.$snakValue.empty(); + + // clean destruction of old variation in case variation will change or property not set + this._variation.destroy(); + this._variation = null; + } + + if ( !this._variation && propertyId && VariationConstructor ) { + // Snak type has changed so we need another variation Object! + this._variation = new VariationConstructor( + new ViewState( this ), + this.$snakValue, + this.options.propertyDataTypeStore, + this.options.valueViewBuilder, + this.options.dataTypeStore + ); + + if ( !value.datavalue + && this._cachedValues[ snakType ] && this._cachedValues[ snakType ].datavalue + ) { + value.datavalue = $.extend( {}, this._cachedValues[ snakType ].datavalue ); + } + + // Update Variation with fields not directly managed by the snakview. If necessary + // within the Variation, those fields should be accessed via the Variation's + // ViewState object. + var serializationCopy = $.extend( {}, value ); + delete serializationCopy.property; + delete serializationCopy.snaktype; + this._variation.value( serializationCopy ); + } + }, + + /** + * (Re-)renders the widget. + */ + draw: function () { + this.updateHash(); + this.drawProperty(); + this.drawSnakTypeSelector(); + this.drawEntityCloneBtn(); + this.drawVariation(); + }, + + /** + * Updates the class list of the DOM element + * to contain the right wikibase-snakview-{hash} class if a hash is configured, + * and no other wikibase-snakview-{otherHash} classes. + */ + updateHash: function () { + var hash; + this.element.removeClass( function ( index, className ) { + var matches = className.match( /\bwikibase-snakview-([0-9a-fA-F]{40})?(\s|$)/g ); + return matches ? matches.join( ' ' ) : ''; + } ); + hash = this.snak() && this.snak().getHash(); + if ( hash ) { + this.element.addClass( 'wikibase-snakview-' + hash ); + } + }, + + /** + * (Re-)renders the Property DOM structure according to the current value. The `Property` DOM + * is not (re-)rendered if changing the `Property` is locked via the `locked` option and + * previously generated HTML is detected. + * + * @return {Object} jQuery.Promise + * @return {Function} return.done + * @return {Function} return.fail + */ + drawProperty: function () { + var self = this, + deferred = $.Deferred(), + propertyId = this.value().property; + + if ( this.options.locked.property + && ( this.$property.contents().length || !this.options.drawProperty ) + ) { + return deferred.resolve().promise(); + } + + this._getPropertyDOM( propertyId ) + .done( function ( $property ) { + self.$property.empty().append( $property ); + deferred.resolve(); + } ) + .fail( function () { + self.$property.empty().text( propertyId ); + deferred.reject(); + } ); + + return deferred.promise(); + }, + + /** + * Retrieves the DOM structure representing the `Property` of the `Snak` represented by the + * `snakview`. + * + * @private + * + * @param {string} [propertyId] + * @return {Object} jQuery.Promise + * @return {Function} return.done + * @return {jQuery} return.$property + * @return {Function} return.fail + */ + _getPropertyDOM: function ( propertyId ) { + var self = this, + deferred = $.Deferred(), + editable = !this.options.locked.property && this.isInEditMode(); + + if ( !propertyId ) { + if ( editable ) { + deferred.resolve( this._createPropertyDOM( '' ) ); + } else { + deferred.resolve( '' ); + } + } else { + if ( editable ) { + this.options.entityIdPlainFormatter.format( propertyId ).done( function ( propertyLabel ) { + deferred.resolve( self._createPropertyDOM( propertyLabel ) ); + } ); + } else { + // Property is set already and cannot be changed, display label only: + return this.options.entityIdHtmlFormatter.format( propertyId ); + } + } + return deferred.promise(); + }, + + /** + * Creates the DOM structure specific for a `Property`, a generic DOM + * structure or an input element. + * + * @private + * + * @param {string} propertyLabel Rendered label for the `Property` + * @return {jQuery|null} + */ + _createPropertyDOM: function ( propertyLabel ) { + var $propertyDom; + + // No Property set for this Snak, serve edit view to specify it: + var propertySelector = this._getPropertySelector(); + + // TODO: use selectedEntity() or other command to set selected entity in both cases! + if ( propertySelector ) { + // property selector in DOM already, just replace current value + var currentValue = propertySelector.widget().val(); + // Impose case-insensitivity: + if ( propertyLabel.toLowerCase() !== currentValue.toLocaleLowerCase() ) { + propertySelector.widget().val( propertyLabel ); + } + } else { + $propertyDom = this._buildPropertySelector().val( propertyLabel ); + + // propagate snakview state: + $propertyDom.data( 'entityselector' ).option( 'disabled', this.options.disabled ); + } + return $propertyDom; + }, + + drawEntityCloneBtn: function () { + var self = this; + var firstChild = this.$cloneBtn.children().first(); + var isBtnMounted = firstChild.length > 0; + + var btn; + + if ( isBtnMounted ) { + btn = firstChild; + } else { + //btn = $('') + btn = $("") + this.$cloneBtn.append(btn); + } + btn.attr('item-id',self._item_id); + btn.css("margin-left","0.5rem"); + btn.css("margin-top","1rem"); + btn.on('click', function () { + //api call + var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + var full_endpoint = WIKIBASE_SYNC_URL + 'import-wikidata-item/' + self._item_id; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + //remove clone button + self._isCloneBtnEnabled = false; + self._item_id = ""; + self._item_description = ""; + btn.remove(); + console.log('clone button removed'); + + } + }); + }); + + if ( this._isCloneBtnEnabled ) { + btn.show(); + } else { + btn.hide(); + } + }, + + /** + * Updates the `SnakTypeSelector` for choosing the `Snak` type. The `SnakTypeSelector` DOM + * is not (re-)rendered if changing the `Snak` type is locked via the `locked` option and + * previously generated HTML is detected. + */ + drawSnakTypeSelector: function () { + if ( this.options.locked.snaktype && this.$snakTypeSelector.contents().length ) { + return; + } + + var snakTypes = variations.getCoveredSnakTypes(), + selector = this._getSnakTypeSelector(); + + if ( !this.isInEditMode() + || snakTypes.length <= 1 + || this.options.locked.snaktype + ) { + if ( selector ) { + selector.destroy(); + } + this.$snakTypeSelector.empty(); + return; // No type selector required! + } + + var snakType = this.options.value instanceof datamodel.Snak + ? this.options.value.getType() + : this.options.value.snaktype; + + if ( selector ) { + // mark current Snak type as chosen one in the menu: + selector.snakType( snakType ); + } else { + var $selector = this._buildSnakTypeSelector( snakType ); + this.$snakTypeSelector.empty().append( $selector ); + selector = $selector.data( 'snaktypeselector' ); + } + + // only show selector if a property is chosen: + this.$snakTypeSelector[ ( this.value().property ? 'show' : 'hide' ) ](); + + // propagate snakview state: + selector.option( 'disabled', this.options.disabled ); + }, + + /** + * Renders the `Variation` or placeholder text if no proper `Variation` is available. + */ + drawVariation: function () { + // property ID will be null if not in edit mode and no Snak set or if in edit mode and user + // didn't choose property yet. + var self = this, + value = this.value(), + propertyId = value ? value.property : null; + + if ( propertyId && this._variation ) { + $( this._variation ).one( 'afterdraw', function () { + if ( self.isInEditMode() ) { + self.variation().startEditing(); + } + } ); + this.variation().draw(); + } else { + // remove any remains from previous rendering or initial template (e.g. '$4') + this.$snakValue.empty(); + + if ( propertyId ) { + // property ID selected but apparently no variation available to handle it + $( '' ).text( mw.msg( 'wikibase-snakview-choosesnaktype' ) ) + .addClass( this.widgetBaseClass + '-unsupportedsnaktype' ) + .appendTo( this.$snakValue ); + // NOTE: instead of doing this here and checking everywhere whether this._variation + // is set, we could as well use variations for displaying system messages like + // this, e.g. having a UnsupportedSnakType variation which is not registered for a + // specific snak type but is known to updateVariation(). + } + } + }, + + /** + * @private + * + * @param {string|null} snakType + * @return {jQuery} + */ + _buildSnakTypeSelector: function ( snakType ) { + var self = this, + $anchor = $( '' ), + // initiate snak type selector widget which is a normal widget just without a + // jQuery.widget.bridge... + selector = new $.wikibase.snakview.SnakTypeSelector( {}, $anchor ); + + // ...add the data information nevertheless: + $anchor.data( 'snaktypeselector', selector ); + + // Set value before binding the change event handler to avoid handling first + // useless change event + selector.snakType( snakType ); + + var changeEvent = ( selector.widgetEventPrefix + 'change' ).toLowerCase(); + + // bind user interaction on selector to snakview's state: + $anchor.on( changeEvent + '.' + this.widgetName, function ( event ) { + self.updateVariation(); + self.drawVariation(); + if ( self._variation ) { + self._variation.focus(); + } + self._trigger( 'change' ); + } ); + + return $anchor; + }, + + hidePropertyLabel: function () { + this.$property.hide(); + }, + + showPropertyLabel: function () { + this.$property.show(); + }, + + _getSelectedProperty: function () { + var propertySelector = this._getPropertySelector(); + + return propertySelector && propertySelector.selectedEntity(); + }, + + _setDataTypeForSelectedProperty: function () { + var property = this._getSelectedProperty(); + + if ( property && property.datatype ) { + this.options.propertyDataTypeStore.setDataTypeForProperty( property.id, property.datatype ); + } + } + } ); + + $.extend( $.wikibase.snakview, existingSnakview ); + +}( wikibase, dataValues ) ); diff --git a/wikibase-scripts/wikibase_source_files/templates.php b/wikibase-scripts/wikibase_source_files/templates.php new file mode 100644 index 0000000..c5d8e31 --- /dev/null +++ b/wikibase-scripts/wikibase_source_files/templates.php @@ -0,0 +1,341 @@ + + * + * @return array templates + */ + +return call_user_func( function() { + $templates = []; + + $templates['wikibase-entityview'] = +<< +
    $5
    +
    $6
    +
    +HTML; + + $templates['wb-entity-header-separator'] = +<< +HTML; + + $templates['wikibase-title'] = +<< + $2 + $3 +
    +HTML; + + $templates['wb-section-heading'] = +<<$1 +HTML; + + // empty toc to help MobileFrontend + $templates['wikibase-toc'] = +<< +HTML; + + $templates['wikibase-statementgrouplistview'] = +<<$1 +HTML; + + $templates['wikibase-statementgroupview'] = +<< +
    +
    $1
    +
    + $2 + +HTML; + + $templates['wikibase-statementlistview'] = +<< +
    + $1 +
    + $2 + +HTML; + + $templates['wikibase-snakview'] = +<< +
    +
    $1
    +
    $5
    +
    +
    +
    +
    +
    $3
    +
    +
    +
    + +HTML; + + $templates['wikibase-statementview'] = +<< +
    $3
    +
    +
    $4
    +
    $5
    +
    + $6 +
    +
    $7
    +
    $8
    +
    + +HTML; + + $templates['wikibase-rankselector'] = +<< + + +HTML; + + $templates['wikibase-referenceview'] = +<< +
    +
    $2
    + +HTML; + + $templates['wikibase-listview'] = +<<$1 +HTML; + + $templates['wikibase-snaklistview'] = +<< +
    $1
    + +HTML; + + $templates['wikibase-labelview'] = +<< +
    + $2 + $3 +
    + +HTML; + + $templates['wikibase-descriptionview'] = +<< +
    + $2 + $3 +
    + +HTML; + + $templates['wikibase-aliasesview'] = +<< +
      $2
    + $3 + +HTML; + + $templates['wikibase-aliasesview-list-item'] = +<<$1 +HTML; + + $templates['wikibase-entitytermsview'] = +<< + $1 + $4 +
    $2
    + +HTML; + + $templates['wikibase-entitytermsview-heading'] = +<< + $1 + +HTML; + + $templates['wikibase-entitytermsview-heading-part'] = +<<$3 +HTML; + + $templates['wikibase-entitytermsview-aliases'] = +<<$1
+HTML; + + $templates['wikibase-entitytermsview-aliases-alias'] = +<<$1 +HTML; + + $templates['wikibase-entitytermsforlanguagelistview'] = +<< + + + $1 + $2 + $3 + $4 + + + $5 + +HTML; + + $templates['wikibase-entitytermsforlanguageview'] = +<< + <$9 class="wikibase-entitytermsforlanguageview-language">$4 + <$2 class="wikibase-entitytermsforlanguageview-label">$5 + <$2 class="wikibase-entitytermsforlanguageview-description">$6 + <$2 class="wikibase-entitytermsforlanguageview-aliases">$7 + $8 + +HTML; + + $templates['wikibase-sitelinkgrouplistview'] = +<<$1 +HTML; + + $templates['wikibase-sitelinkgroupview'] = +<< +
+
+ + $6 +
+
+
+ $4 +
+ +HTML; + + $templates['wikibase-sitelinklistview'] = +<< +
    $1
+ +HTML; + + $templates['wikibase-sitelinkview'] = +<< + + $2 + $4 + +HTML; + + $templates['wikibase-sitelinkview-pagename'] = +<<$2$3 +HTML; + + $templates['wikibase-sitelinkview-unknown'] = +<< + $1 + $2 + +HTML; + + $templates['wb-badge'] = +<< +HTML; + + $templates['wikibase-badgeselector'] = +<<$1 +HTML; + + $templates['wikibase-propertyview-datatype'] = +<< +
$1
+ +HTML; + + $templates['wikibase-toolbar-item'] = +<<$1 +HTML; + + $templates['wikibase-toolbar-button'] = +<<$3 +HTML; + + $templates['wikibase-toolbar'] = +<<$2 +HTML; + + $templates['wikibase-toolbar-container'] = +<<$1 +HTML; + +// Helper template for styling +// TODO: Remove template + $templates['wikibase-toolbar-wrapper'] = +<<$1 +HTML; + + $templates['wikibase-toolbar-bracketed'] = +<< +
✕
+
$1
+ +HTML; + + $templates['wikibase-pageimage'] = +<< +
+   +
+ +HTML; + + return $templates; +} ); From e6c63a5cfb95d36f01bd9ce3310953a1fa8e23a3 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 26 Apr 2022 16:40:36 +0200 Subject: [PATCH 14/50] autocomplete redesign fixes --- user-password.py | 2 +- .../wikibase_source_files/jquery.wikibase.entityselector.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/user-password.py b/user-password.py index 4999de4..9e6b792 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'password')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'r0017mdhj09chphc682hhhupgi5l4jcp')) \ No newline at end of file diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index eca8546..c8c7d46 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -6,7 +6,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) return wikidataResults; } var updatedResults = []; - wikidataResults.concat(localResults).forEach(function (element) { + localResults.concat(wikidataResults).forEach(function (element) { var index = updatedResults.findIndex(function(x){ return x.label.toLowerCase().trim() == element.label && x.description == element.description.toLowerCase().trim() }) From de4c3d99e62f249f95f0546c11fe01af0b2b4941 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 3 May 2022 11:42:47 +0200 Subject: [PATCH 15/50] remote-autocomplete-and-clone --- user-password.py | 2 +- wikibase-scripts/wikibase_source_files/snakview.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/user-password.py b/user-password.py index 9e6b792..c9dab66 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'r0017mdhj09chphc682hhhupgi5l4jcp')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) \ No newline at end of file diff --git a/wikibase-scripts/wikibase_source_files/snakview.js b/wikibase-scripts/wikibase_source_files/snakview.js index 1008868..4a7daaa 100644 --- a/wikibase-scripts/wikibase_source_files/snakview.js +++ b/wikibase-scripts/wikibase_source_files/snakview.js @@ -789,7 +789,11 @@ } btn.attr('item-id',self._item_id); btn.css("margin-left","0.5rem"); - btn.css("margin-top","1rem"); + btn.css("margin-top","1.5rem"); + btn.css("color","#0645ad"); + btn.css("background-color","white"); + btn.css("border-color","#0645ad"); + btn.css("border-radius","5px"); btn.on('click', function () { //api call var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; From 5b370a48923cbf21d8631b6f30d2c2ce50a27f9a Mon Sep 17 00:00:00 2001 From: mez Date: Mon, 9 May 2022 15:28:10 +0200 Subject: [PATCH 16/50] ui enhancement and bug fix --- .../wikibase_source_files/jquery.wikibase.entityselector.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index c8c7d46..0778d27 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -8,9 +8,12 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) var updatedResults = []; localResults.concat(wikidataResults).forEach(function (element) { var index = updatedResults.findIndex(function(x){ - return x.label.toLowerCase().trim() == element.label && x.description == element.description.toLowerCase().trim() + return x.label.toLowerCase().trim() == element.label.toLowerCase().trim() && x.description.toLowerCase().trim() == element.description.toLowerCase().trim() }) if (index == -1) { + if (element.repository.toLowerCase() !== "local") { + element.label = element.label + " [source: wikidata]" + } updatedResults.push(element); } }) From 9734e2f6427b88bf9a61f0342fcd4483d1725069 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 17 May 2022 09:40:22 +0200 Subject: [PATCH 17/50] api updates and frontend scripts update --- api_import_one.py | 6 ++- main.py | 21 +++++--- util/util.py | 14 ++++- .../jquery.wikibase.entityselector.js | 51 +++++++++++++++++-- 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/api_import_one.py b/api_import_one.py index 75828b3..635be1b 100644 --- a/api_import_one.py +++ b/api_import_one.py @@ -51,9 +51,11 @@ def mth_import_one_without_statements(arg): wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) wikidata_item.get() print("after get") - wikibase_importer.change_item(wikidata_item, wikibase_repo, False) + item = wikibase_importer.change_item(wikidata_item, wikibase_repo, False) elif arg.startswith("P"): wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) wikidata_property.get() - wikibase_importer.change_property(wikidata_property, wikibase_repo, False) + item = wikibase_importer.change_property(wikidata_property, wikibase_repo, False) + if item: + return item return True \ No newline at end of file diff --git a/main.py b/main.py index 5cc59e8..316d8a8 100644 --- a/main.py +++ b/main.py @@ -36,12 +36,15 @@ def handle(): t = Thread(target=handle) return t def get(self, q_id): - #from api_import_one import mth_import_one - self.import_thread_spinner(q_id).start() - #response = mth_import_one(q_id) - response = 2 + # #from api_import_one import mth_import_one + # self.import_thread_spinner(q_id).start() + # #response = mth_import_one(q_id) + + from api_import_one import mth_import_one, mth_import_one_without_statements + response = mth_import_one_without_statements(q_id) + print(response) if response: - payload = {"status_code": 200, "message": "Import successful"} + payload = {"status_code": 200, "message": "Import successful", "pid": response} else: payload = {"status_code": 500, "message": "Import could not be completed"} @@ -49,11 +52,13 @@ def get(self, q_id): class WikiDataQuery(Resource): - def get(self, query_string): + def get(self, query_string, query_type): # general english + # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ + # query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ - query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" + query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=" + query_type # british english # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" @@ -91,7 +96,7 @@ def get(self, query_string): api.add_resource(Index, "/") api.add_resource(Sync, "/sync//") api.add_resource(ImportOne, "/import-wikidata-item/") -api.add_resource(WikiDataQuery, "/remote-wikidata-query/") +api.add_resource(WikiDataQuery, "/remote-wikidata-query//") api.add_resource(WikibaseQuery, "/local-wikibase-query/") # @app.route("/") diff --git a/util/util.py b/util/util.py index ca31082..9f02bb6 100644 --- a/util/util.py +++ b/util/util.py @@ -1167,6 +1167,8 @@ def change_item(self, wikidata_item, wikibase_repo, statements): new_id = self.import_item(wikidata_item) wikibase_item = pywikibot.ItemPage(wikibase_repo, new_id) wikibase_item.get() + if not statements: + return new_id else: print("This entity corresponds to ", self.id.get_id(wikidata_item.getID())) wikibase_item = pywikibot.ItemPage(wikibase_repo, self.id.get_id(wikidata_item.getID())) @@ -1175,6 +1177,8 @@ def change_item(self, wikidata_item, wikibase_repo, statements): self.change_aliases(wikidata_item, wikibase_item) self.change_descriptions(wikidata_item, wikibase_item) self.wikidata_link(wikibase_item, wikidata_item) + if not statements: + return self.id.get_id(wikidata_item.getID()) if statements: self.change_site_links(wikidata_item, wikibase_item) self.change_claims(wikidata_item, wikibase_item) @@ -1192,16 +1196,22 @@ def change_item_given_id(self, wikidata_item, id, wikibase_repo, statements): self.change_site_links(wikidata_item, wikibase_item) self.change_claims(wikidata_item, wikibase_item) - def change_property(self, wikidata_item, wikibase_repo, statements): + def change_property(self, wikidata_item, wikibase_repo, statements, ): print("Change Property", wikidata_item.getID()) wikidata_item.get() wikibase_item = None if not self.id.contains_id(wikidata_item.getID()): new_id = self.importProperty(wikidata_item) + # if not statements: + # return new_id # import done from front end clone wikibase_item = pywikibot.PropertyPage(wikibase_repo, new_id, datatype=wikidata_item.type) wikibase_item.get() + if not statements: + return new_id else: print("Entering here") + # if not statements: + # return self.id.get_id(wikidata_item.getID()) # import done from front end clone wikibase_item = pywikibot.PropertyPage(wikibase_repo, self.id.get_id(wikidata_item.getID()), datatype=wikidata_item.type) wikibase_item.get() @@ -1209,6 +1219,8 @@ def change_property(self, wikidata_item, wikibase_repo, statements): self.change_labels(wikidata_item, wikibase_item) self.change_aliases(wikidata_item, wikibase_item) self.change_descriptions(wikidata_item, wikibase_item) + if not statements: + return self.id.get_id(wikidata_item.getID()) if statements: self.change_claims(wikidata_item, wikibase_item) return wikibase_item diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index 0778d27..2a2366f 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -12,7 +12,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) }) if (index == -1) { if (element.repository.toLowerCase() !== "local") { - element.label = element.label + " [source: wikidata]" + element.label = "[source: wikidata] " + element.label } updatedResults.push(element); } @@ -329,7 +329,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) data: self._getSearchApiParameters( term ), success: function(data){ $.ajax({ - url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + term, + url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + term + "/" + self.options.type, crossDomain: true, headers: { "Access-Control-Allow-Origin": "*", @@ -705,8 +705,53 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) _select: function ( entityStub ) { var id = entityStub && entityStub.id; this._selectedEntity = entityStub; + const ff = {...entityStub} + console.log(ff); if ( id ) { - this._trigger( 'selected', null, [ id ] ); + var self = this; + if (entityStub.repository !== "local") { + //remote source, clone + + //api call + var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + var full_endpoint = WIKIBASE_SYNC_URL + 'import-wikidata-item/' + id; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + if (data.pid) { + id = data.pid; + console.log(self._selectedEntity); + + if (self.options.type.toLowerCase() == "property") { + self._selectedEntity.id = id; + self._selectedEntity.title = "Property:" + id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = "http://localhost/wiki/Property:" + id; + self._selectedEntity.pageid = null; + } else if (self.options.type.toLowerCase() == "item"){ + self._selectedEntity.id = id; + self._selectedEntity.title = id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = "http://localhost/wiki/" + id; + self._selectedEntity.pageid = null; + } + + //this._selectedEntity = { id: id }; + //TODO + self._trigger( 'selected', null, [ id ] ); + } + } + }); + } else { + this._trigger( 'selected', null, [ id ] ); + } } }, From 289fa523d9ab235489bdae00fdc670e6790821cf Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 17 May 2022 11:01:16 +0200 Subject: [PATCH 18/50] frontend scripts update --- user-password.py | 2 +- .../jquery.wikibase.entityselector.js | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/user-password.py b/user-password.py index c9dab66..0b7d9f6 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'0eqdnmid4gj8ev3r89nih2lokg2n1her')) \ No newline at end of file diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index 2a2366f..1da249a 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -34,6 +34,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) * @ignore */ var IS_MW_CONTEXT = mw !== undefined && mw.msg; + var focused; /** * Whether actual `entityselector` resource loader module is loaded. @@ -575,6 +576,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) $( this.options.menu ) .off( 'selected.suggester' ) .on( 'selected.entityselector', function ( event, item ) { + self.focused = $(':focus')[0]; if ( item.getEntityStub ) { if ( !self.options.caseSensitive && item.getValue().toLowerCase() === self._term.toLowerCase() @@ -707,9 +709,15 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) this._selectedEntity = entityStub; const ff = {...entityStub} console.log(ff); + + //var bootstrapcdn = "" + //var loader = "
" + if ( id ) { var self = this; if (entityStub.repository !== "local") { + var cloningEl = '

cloning...

'; + $(cloningEl).insertAfter(self.focused); //remote source, clone //api call @@ -726,6 +734,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) success: function (data) { console.log(data); if (data.pid) { + console.log($(self.focused).siblings('p').remove()); id = data.pid; console.log(self._selectedEntity); From 423a4bb8e9cf29c7dd7b456f3960a70cd925b6f8 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 17 May 2022 11:03:20 +0200 Subject: [PATCH 19/50] frontend scripts update --- .../wikibase_source_files/jquery.wikibase.entityselector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index 1da249a..b648ed4 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -716,7 +716,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) if ( id ) { var self = this; if (entityStub.repository !== "local") { - var cloningEl = '

cloning...

'; + var cloningEl = '

importing...

'; $(cloningEl).insertAfter(self.focused); //remote source, clone From 43b10ea0c8cc5214fcf17f11c99f03ae772d3296 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 17 May 2022 11:06:51 +0200 Subject: [PATCH 20/50] frontend scripts update --- user-password.py | 2 +- .../jquery.wikibase.entityselector.js | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/user-password.py b/user-password.py index 0b7d9f6..c9dab66 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'0eqdnmid4gj8ev3r89nih2lokg2n1her')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) \ No newline at end of file diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index b648ed4..b49e12b 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -707,11 +707,6 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) _select: function ( entityStub ) { var id = entityStub && entityStub.id; this._selectedEntity = entityStub; - const ff = {...entityStub} - console.log(ff); - - //var bootstrapcdn = "" - //var loader = "

" if ( id ) { var self = this; @@ -734,9 +729,9 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) success: function (data) { console.log(data); if (data.pid) { - console.log($(self.focused).siblings('p').remove()); + $(self.focused).siblings('p').remove(); id = data.pid; - console.log(self._selectedEntity); + //console.log(self._selectedEntity); if (self.options.type.toLowerCase() == "property") { self._selectedEntity.id = id; From 5958e00ea536a126f6119915b58cbd25907dce6a Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 20 May 2022 13:59:01 +0200 Subject: [PATCH 21/50] bug fix --- .../wikibase_source_files/jquery.wikibase.entityselector.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index b49e12b..15cf97c 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -197,7 +197,6 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) }; } - //console.log('MY OUTPUT from outside',this.options); $.ui.suggester.prototype._create.call( this ); @@ -311,7 +310,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) */ _initDefaultSource: function () { var self = this; - + wikidataResults = []; return function ( term ) { var deferred = $.Deferred(), hookResults = self._fireSearchHook( term ); From d48f970e86895a9977198a039ba0dc4cbd7d5f1b Mon Sep 17 00:00:00 2001 From: mez Date: Mon, 30 May 2022 10:49:47 +0200 Subject: [PATCH 22/50] add loader --- .../wikibase_source_files/jquery.wikibase.entityselector.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js index 15cf97c..d9a5604 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js @@ -197,7 +197,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) }; } - + console.log(mw); $.ui.suggester.prototype._create.call( this ); this.element @@ -704,6 +704,8 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) * @param {Object} entityStub */ _select: function ( entityStub ) { + //conf = mw.config.get( 'wgWikibaseSync' ); + //console.log("conf",conf) var id = entityStub && entityStub.id; this._selectedEntity = entityStub; From 871fe9fae4e06dbdf24604bde2d14e8433c4c18e Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 1 Jun 2022 13:34:51 +0200 Subject: [PATCH 23/50] wikidata qid and pid sync --- main.py | 18 +- .../jquery.wikibase.statementgroupview.js | 329 ++++++++++++++++++ .../wikibase_source_files/templates.php | 1 + 3 files changed, 342 insertions(+), 6 deletions(-) create mode 100644 wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js diff --git a/main.py b/main.py index 316d8a8..e13a741 100644 --- a/main.py +++ b/main.py @@ -19,11 +19,17 @@ def get(self): # dummy class Sync(Resource): - def get(self, item_name, id): - return {"data": "Sync" + item_name} + def import_thread_spinner(self, query_id): + def handle(): + from api_import_one import mth_import_one, mth_import_one_without_statements + response = mth_import_one(query_id) + t = Thread(target=handle) + return t - def post(self): - return {"data": "Nothing posted for now "} + def get(self, q_id): + self.import_thread_spinner(q_id).start() + payload = {"status_code": 200, "message": "Import triggered"} + return payload # import one @@ -42,7 +48,7 @@ def get(self, q_id): from api_import_one import mth_import_one, mth_import_one_without_statements response = mth_import_one_without_statements(q_id) - print(response) + # print(response) if response: payload = {"status_code": 200, "message": "Import successful", "pid": response} else: @@ -94,7 +100,7 @@ def get(self, query_string): # ROUTES api.add_resource(Index, "/") -api.add_resource(Sync, "/sync//") +api.add_resource(Sync, "/sync/") api.add_resource(ImportOne, "/import-wikidata-item/") api.add_resource(WikiDataQuery, "/remote-wikidata-query//") api.add_resource(WikibaseQuery, "/local-wikibase-query/") diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js new file mode 100644 index 0000000..5d1c647 --- /dev/null +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js @@ -0,0 +1,329 @@ +function createSynButton(_context) { + btn = $("") + btn.css("margin-top",".5rem"); + btn.css("color","#0645ad"); + btn.css("background-color","white"); + btn.css("border-color","#0645ad"); + btn.css("border-radius","5px"); + + _context.$cloneBtn.append(btn); + + var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + self.wikibasePropertyValue = _wikibasePropertyValue; + + console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + + btn.on('click', function () { + //api call + var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log("sync process started",data); + + + } + }); + }); +} + +( function () { + 'use strict'; + + var PARENT = $.ui.TemplatedWidget, + datamodel = require( 'wikibase.datamodel' ); + + /** + * View for displaying `datamodel.Statement` objects grouped by their main `Snak`'s + * `Property` id by managing a list of `jQuery.wikibase.statementview` widgets encapsulated by a + * `jquery.wikibase.statementlistview` widget. + * + * @see datamodel.StatementGroup + * @extends jQuery.ui.TemplatedWidget + * @license GPL-2.0-or-later + * @author H. Snater < mediawiki@snater.com > + * + * @constructor + * + * @param {Object} options + * @param {datamodel.StatementGroup} [options.value=null] + * The `Statements` to be displayed by this view. If `null`, the view will only display an + * "add" button to add new `Statements`. + * @param {wikibase.entityIdFormatter.EntityIdHtmlFormatter} options.entityIdHtmlFormatter + * Required for dynamically rendering links to `Entity`s. + * @param {Function} options.buildStatementListView + */ + /** + * @event afterremove + * Triggered after a `statementview` was removed from the `statementlistview` encapsulated by this + * `statementgroupview`. + * @param {jQuery.Event} event + */ + $.widget( 'wikibase.statementgroupview', PARENT, { + /** + * @inheritdoc + * @protected + */ + wikibasePropertyKey: "", + wikibasePropertyValue: "", + options: { + template: 'wikibase-statementgroupview', + templateParams: [ + '', // label + '', // statementlistview widget + '', // html id attribute + '', // property id + '', // clone btn + ], + templateShortCuts: { + $property: '.wikibase-statementgroupview-property', + $propertyLabel: '.wikibase-statementgroupview-property-label', + $cloneBtn: '.wikibase-statementgroupview-property-clonebtn' + }, + value: null, + buildStatementListView: null, + entityIdHtmlFormatter: null, + htmlIdPrefix: '' + }, + + /** + * @property {jQuery.wikibase.statementlistview} + */ + statementlistview: null, + + /** + * @inheritdoc + * @protected + * + * @throws {Error} if a required option is not specified properly. + */ + _create: function () { + if ( !this.options.entityIdHtmlFormatter || !this.options.buildStatementListView ) { + throw new Error( 'Required option not specified properly' ); + } + + try { + PARENT.prototype._create.call( this ); + } catch (e) { + console.log('ERROR', e); + } + + if ( this.options.value ) { + this._updateId(); + this._updatePropertyId( this.options.value.getKey() ); + this._createPropertyLabel(); + } + + this._createStatementlistview(); + }, + + /** + * @inheritdoc + */ + destroy: function () { + if ( this.statementlistview ) { + this.statementlistview.element.off( this.widgetName ); + this.statementlistview.destroy(); + } + PARENT.prototype.destroy.call( this ); + }, + + /** + * @private + */ + _updateId: function () { + var propertyId = this.options.value.getKey(), + prefix = this.options.htmlIdPrefix, + prefixSeparator = '-'; + + if ( prefix !== '' ) { + prefix += prefixSeparator; + } + + this.element.attr( 'id', prefix + propertyId ); + }, + + /** + * @private + * + * @param {string} propertyId + */ + _updatePropertyId: function ( propertyId ) { + this.element.data( 'property-id', propertyId ); + }, + + /** + * @private + */ + _createPropertyLabel: function () { + if ( this.$propertyLabel.contents().length > 0 ) { + return; + } + + var self = this, + propertyId = this.options.value.getKey(); + + this.options.entityIdHtmlFormatter.format( propertyId ).done( function ( title ) { + self.$propertyLabel.append( title ); + } ); + }, + + /** + * @private + */ + _createStatementlistview: function () { + var self = this, + prefix; + + var $statementlistview = this.element.find( '.wikibase-statementlistview' ); + + if ( !$statementlistview.length ) { + $statementlistview = $( '
' ).appendTo( this.element ); + } + + this.statementlistview = this.options.buildStatementListView( + this.options.value ? this.options.value.getItemContainer() : new datamodel.StatementList(), + $statementlistview + ); + prefix = this.statementlistview.widgetEventPrefix; + + $statementlistview + .on( prefix + 'toggleerror.' + this.widgetName, function ( event, error ) { + self.$property.toggleClass( 'wb-error', Boolean( error ) ); + } ) + .on( prefix + 'afterstopediting.' + this.widgetName, function ( event, dropValue ) { + self.$property.removeClass( 'wb-error wb-edit' ); + self._trigger( 'afterstopediting', null, [ dropValue ] ); + } ) + .on( prefix + 'afterstartediting.' + this.widgetName, function ( event ) { + self.$property.addClass( 'wb-edit' ); + } ) + .on( prefix + 'afterremove.' + this.widgetName, function ( event ) { + self.$property.removeClass( 'wb-error wb-edit' ); + self._trigger( 'afterremove' ); + } ); + + //self.$cloneBtn.text('hello world'); + var _wikibasePropertyKey = self.value().getKey(); + + + if( _wikibasePropertyKey == "P1" || _wikibasePropertyKey == "P2"){ + self.wikibasePropertyKey = _wikibasePropertyKey; + // Only attach button for wikidata pid or qid properties which are always P1 and P2 + self.$cloneBtn.text(''); + createSynButton(self) + // btn = $("") + + // self.$cloneBtn.append(btn); + + // //console.log("val",self.value()); + // //var _wikibasePropertyValue = ""; + // var _wikibasePropertyValue = self.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + // self.wikibasePropertyValue = _wikibasePropertyValue; + + // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); + + // btn.on('click', function () { + // //api call + // var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; + // var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; + // $.ajax({ + // url: full_endpoint, + // crossDomain: true, + // headers: { + // // "accept": "application/json", + // "Access-Control-Allow-Origin": "*", + // "Access-Control-Request-Headers3": "x-requested-with" + // }, + // success: function (data) { + // console.log("sync process started",data); + + + // } + // }); + // }); + }else{ + self.$cloneBtn.text('') + } + // console.log(JSON.stringify(self.options, null, 2)); + }, + + /** + * Sets the widget's value or gets the widget's current value (including pending items). (The + * value the widget was initialized with may be retrieved via `.option( 'value' )`.) + * + * @param {datamodel.StatementGroup} [statementGroupView] + * @return {datamodel.StatementGroup|null|undefined} + */ + value: function ( statementGroupView ) { + if ( statementGroupView !== undefined ) { + return this.option( 'value', statementGroupView ); + } + + var statementList = this.statementlistview.value(); + if ( !statementList.length ) { + return null; + } + // Use the first statement's main snak property id as the statementgroupview may have + // been initialized without a value (as there is no initial value, the id cannot be + // retrieved from this.options.value). + return new datamodel.StatementGroup( + statementList.toArray()[ 0 ].getClaim().getMainSnak().getPropertyId(), + statementList + ); + }, + + /** + * @inheritdoc + * @protected + * + * @throws {Error} when trying to set the value passing something different than a + * `datamodel.StatementGroup´ object. + */ + _setOption: function ( key, value ) { + if ( key === 'value' && !!value ) { + if ( !( value instanceof datamodel.StatementGroup ) ) { + throw new Error( 'value needs to be a datamodel.StatementGroup instance' ); + } + this.statementlistview.value( value.getItemContainer() ); + } + + var response = PARENT.prototype._setOption.apply( this, arguments ); + + if ( key === 'disabled' ) { + this.statementlistview.option( key, value ); + } + + return response; + }, + + /** + * @inheritdoc + */ + focus: function () { + this.statementlistview.focus(); + }, + + /** + * Adds a new, pending `statementview` to the encapsulated `statementlistview`. + * + * @see jQuery.wikibase.statementlistview.enterNewItem + * + * @return {Object} jQuery.Promise + * @return {Function} return.done + * @return {jQuery} return.done.$statementview + */ + enterNewItem: function () { + return this.statementlistview.enterNewItem(); + } + + } ); + +}() ); diff --git a/wikibase-scripts/wikibase_source_files/templates.php b/wikibase-scripts/wikibase_source_files/templates.php index c5d8e31..b703e90 100644 --- a/wikibase-scripts/wikibase_source_files/templates.php +++ b/wikibase-scripts/wikibase_source_files/templates.php @@ -57,6 +57,7 @@
$1
+
$5
$2
From 4284aea4ad2a5de036859693289f60575c74a28c Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 3 Jun 2022 15:31:55 +0200 Subject: [PATCH 24/50] wikidata qid and pid sync update --- .../wikibase_source_files/jquery.wikibase.statementgroupview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js index 5d1c647..03ae09b 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js @@ -11,7 +11,7 @@ function createSynButton(_context) { var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; self.wikibasePropertyValue = _wikibasePropertyValue; - console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); btn.on('click', function () { //api call From a8e8fb4163c367c0fdf886f67f50d5aac83e5977 Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 3 Jun 2022 16:20:56 +0200 Subject: [PATCH 25/50] qid and pid sync method update --- main.py | 14 +++++++++++--- user-password.py | 2 +- .../jquery.wikibase.statementgroupview.js | 5 ++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index e13a741..66faf72 100644 --- a/main.py +++ b/main.py @@ -27,9 +27,17 @@ def handle(): return t def get(self, q_id): - self.import_thread_spinner(q_id).start() - payload = {"status_code": 200, "message": "Import triggered"} - return payload + t = self.import_thread_spinner(q_id) + t.start() + print("THREAD:::::") + print(t) + if not t.is_alive(): + print("THREAD:::::") + payload = {"status_code": 200, "completed": True, "message": "Import process complete"} + return payload + else: + payload = {"status_code": 500, "completed": True, "message": "Import process could not be completed"} + return payload # import one diff --git a/user-password.py b/user-password.py index c9dab66..0b7d9f6 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'0eqdnmid4gj8ev3r89nih2lokg2n1her')) \ No newline at end of file diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js index 03ae09b..509fd6d 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js @@ -14,6 +14,7 @@ function createSynButton(_context) { //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); btn.on('click', function () { + btn.text("syncing") //api call var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; @@ -26,7 +27,9 @@ function createSynButton(_context) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - console.log("sync process started",data); + if (data.completed) { + location.reload(); + } } From ecaa6f93fd294895d3fe943e603fc3933a5055ec Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 3 Jun 2022 16:21:50 +0200 Subject: [PATCH 26/50] qid and pid sync method update --- user-password.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user-password.py b/user-password.py index 0b7d9f6..c9dab66 100644 --- a/user-password.py +++ b/user-password.py @@ -1 +1 @@ -(u'admin', BotPassword(u'WikidataUpdater', u'0eqdnmid4gj8ev3r89nih2lokg2n1her')) \ No newline at end of file +(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword')) \ No newline at end of file From 0066076d48aea3162ea10fb5575095773e2d2703 Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 3 Jun 2022 16:25:59 +0200 Subject: [PATCH 27/50] qid and pid sync method update --- .../wikibase_source_files/jquery.wikibase.statementgroupview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js index 509fd6d..338b4bb 100644 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js +++ b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js @@ -14,7 +14,7 @@ function createSynButton(_context) { //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); btn.on('click', function () { - btn.text("syncing") + btn.text("syncing...") //api call var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; From cb5ef669276ab07f8f6356f4e3b553a3b7901d6a Mon Sep 17 00:00:00 2001 From: mez Date: Fri, 3 Jun 2022 16:53:43 +0200 Subject: [PATCH 28/50] qid and pid sync method update --- main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.py b/main.py index 66faf72..65ad085 100644 --- a/main.py +++ b/main.py @@ -29,8 +29,6 @@ def handle(): def get(self, q_id): t = self.import_thread_spinner(q_id) t.start() - print("THREAD:::::") - print(t) if not t.is_alive(): print("THREAD:::::") payload = {"status_code": 200, "completed": True, "message": "Import process complete"} From 8af7e8197e2cabd1e54133d8119bb1808711044f Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 21 Jun 2022 15:18:31 +0200 Subject: [PATCH 29/50] boilter plate extension changes --- main.py | 18 +- .../boilerplate-extension/Hooks.php | 45 +++ .../boilerplate-extension/extension.json | 53 +++ .../boilerplate-extension/init.js | 274 ++++++++++++++ .../boilerplate-extension/templates.php | 342 ++++++++++++++++++ 5 files changed, 725 insertions(+), 7 deletions(-) create mode 100644 wikibase-scripts/boilerplate-extension/Hooks.php create mode 100644 wikibase-scripts/boilerplate-extension/extension.json create mode 100644 wikibase-scripts/boilerplate-extension/init.js create mode 100644 wikibase-scripts/boilerplate-extension/templates.php diff --git a/main.py b/main.py index 65ad085..32e9e6d 100644 --- a/main.py +++ b/main.py @@ -29,13 +29,17 @@ def handle(): def get(self, q_id): t = self.import_thread_spinner(q_id) t.start() - if not t.is_alive(): - print("THREAD:::::") - payload = {"status_code": 200, "completed": True, "message": "Import process complete"} - return payload - else: - payload = {"status_code": 500, "completed": True, "message": "Import process could not be completed"} - return payload + t.join() + payload = {"status_code": 200, "completed": True, "message": "Import process complete"} + return payload + + # if not t.is_alive(): + # print("THREAD:::::") + # payload = {"status_code": 200, "completed": True, "message": "Import process complete"} + # return payload + # else: + # payload = {"status_code": 500, "completed": False, "message": "Import process could not be completed"} + # return payload # import one diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibase-scripts/boilerplate-extension/Hooks.php new file mode 100644 index 0000000..c795764 --- /dev/null +++ b/wikibase-scripts/boilerplate-extension/Hooks.php @@ -0,0 +1,45 @@ +addModules( 'ext.boilerPlate' ); + $config = $out->getConfig(); + if ( $config->get( 'BoilerPlateVandalizeEachPage' ) ) { + $out->addModules( 'oojs-ui-core' ); + $out->addHTML( \Html::element( 'p', [], 'BoilerPlate was here' ) ); + } + } + + public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { + $vars['wgVisualEditor'] = ["local_server_url" => "http://127.0.0.1:5000"]; + } +} + + diff --git a/wikibase-scripts/boilerplate-extension/extension.json b/wikibase-scripts/boilerplate-extension/extension.json new file mode 100644 index 0000000..cc7747d --- /dev/null +++ b/wikibase-scripts/boilerplate-extension/extension.json @@ -0,0 +1,53 @@ +{ + "name": "BoilerPlate", + "author": [ + "mez" + ], + "url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate", + "descriptionmsg": "boilerplate-desc", + "license-name": "GPL-2.0-or-later", + "type": "other", + "requires": { + "MediaWiki": ">= 1.35.0" + }, + "AutoloadNamespaces": { + "MediaWiki\\Extension\\BoilerPlate\\": "src/" + }, + "config": { + "BoilerPlateEnableFoo": { + "description": "Enable the Foo feature.", + "value": true + }, + "BoilerPlateVandalizeEachPage": { + "description": "Write 'BoilerPlate was here' on each page", + "value": false + } + }, + "HookHandlers": { + "BoilerPlateHooks": { + "class": "MediaWiki\\Extension\\BoilerPlate\\Hooks" + } + }, + "Hooks": { + "BeforePageDisplay": "BoilerPlateHooks", + "ResourceLoaderGetConfigVars": "BoilerPlateHooks" + }, + "MessagesDirs": { + "BoilerPlate": [ + "i18n" + ] + }, + "ResourceModules": { + "ext.boilerPlate": { + "localBasePath": "resources/ext.boilerPlate", + "remoteExtPath": "BoilerPlate/resources/ext.boilerPlate", + "dependencies": ["wikibase.view.ControllerViewFactory"], + "styles": [], + "packageFiles": [ + "init.js" + ], + "messages": [] + } + }, + "manifest_version": 2 +} diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js new file mode 100644 index 0000000..e0f6502 --- /dev/null +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -0,0 +1,274 @@ +/** + * @class mw.boilerPlate + * @singleton + */ + +var conf = mw.config.get('wgVisualEditor'); +mw.boilerPlate = {}; +var wikidataResults = []; +var WIKIBASE_SYNC_URL = conf.local_server_url; +//console.log(WIKIBASE_SYNC_URL); + +var datamodel = require( 'wikibase.datamodel' ); + +$.wikibase.statementgroupview.prototype._createStatementlistview = function () { + var self = this, + prefix; + + var $statementlistview = this.element.find('.wikibase-statementlistview'); + + if (!$statementlistview.length) { + $statementlistview = $('
').appendTo(this.element); + } + + this.statementlistview = this.options.buildStatementListView( + this.options.value ? this.options.value.getItemContainer() : new datamodel.StatementList(), + $statementlistview + ); + prefix = this.statementlistview.widgetEventPrefix; + + $statementlistview + .on(prefix + 'toggleerror.' + this.widgetName, function (event, error) { + self.$property.toggleClass('wb-error', Boolean(error)); + }) + .on(prefix + 'afterstopediting.' + this.widgetName, function (event, dropValue) { + self.$property.removeClass('wb-error wb-edit'); + self._trigger('afterstopediting', null, [dropValue]); + }) + .on(prefix + 'afterstartediting.' + this.widgetName, function (event) { + self.$property.addClass('wb-edit'); + }) + .on(prefix + 'afterremove.' + this.widgetName, function (event) { + self.$property.removeClass('wb-error wb-edit'); + self._trigger('afterremove'); + }); + + //self.$cloneBtn.text('hello world'); + var _wikibasePropertyKey = ""; + if (self.value()) { + _wikibasePropertyKey = self.value().getKey(); + } + + + if (_wikibasePropertyKey == "P1" || _wikibasePropertyKey == "P2") { + self.wikibasePropertyKey = _wikibasePropertyKey; + // Only attach button for wikidata pid or qid properties which are always P1 and P2 + self.$cloneBtn.text(''); + createSynButton(self) + // btn = $("") + + // self.$cloneBtn.append(btn); + + // //console.log("val",self.value()); + // //var _wikibasePropertyValue = ""; + // var _wikibasePropertyValue = self.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + // self.wikibasePropertyValue = _wikibasePropertyValue; + + // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); + + } else { + self.$cloneBtn.text('') + } + // console.log(JSON.stringify(self.options, null, 2)); +}; + +$.wikibase.entityselector.prototype._initDefaultSource = function () { + var self = this; + wikidataResults = []; + return function ( term ) { + var deferred = $.Deferred(), + hookResults = self._fireSearchHook( term ); + + // clear previous error + if ( self._error ) { + self._error = null; + self._cache.suggestions = null; + self._updateMenu( [] ); + } + + $.ajax( { + url: self.options.url, + timeout: self.options.timeout, + dataType: 'json', + data: self._getSearchApiParameters( term ), + success: function(data){ + $.ajax({ + url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type, + crossDomain: true, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + wikidataResults = data.response.search; + } + }); + } + } ) + .done( function ( response, statusText, jqXHR ) { + // T141955 + if ( response.error ) { + deferred.reject( response.error.info ); + return; + } + + // The default endpoint wbsearchentities responds with an array of errors. + if ( response.errors && self.options.responseErrorFactory ) { + var error = self.options.responseErrorFactory( response, 'search' ); + + if ( error && self.options.showErrorCodes.indexOf( error.code ) !== -1 ) { + self._error = error; + self._cache = {}; + self._updateMenu( [] ); + deferred.reject( error.message ); + return; + } + } + + //TODO MERGE THE WIKIDATA RESULTS WITH RESPONSE SEARCH + // console.log("hooksResults"); + // console.log(hookResults); + // console.log("wikidataResults"); + // console.log(wikidataResults); + // console.log("wikibase results"); + // console.log(response.search); + // UPDATE THE TITLE AND SOURCE TO REFELECT WIKIDATA + // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH + var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, response.search) + //console.log("updatedWikidataResults", updatedWikidataResults); + //self._combineResults( hookResults, response.search ).then( function ( results ) { + self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { + //console.log(results) + deferred.resolve( + results, + term, + response[ 'search-continue' ], + jqXHR.getResponseHeader( 'X-Search-ID' ) + ); + } ); + } ) + .fail( function ( jqXHR, textStatus ) { + deferred.reject( textStatus ); + } ); + + return deferred.promise(); + }; +}; + +$.wikibase.entityselector.prototype._select = function ( entityStub ) { + //conf = mw.config.get( 'wgWikibaseSync' ); + //console.log("conf",conf) + var id = entityStub && entityStub.id; + this._selectedEntity = entityStub; + + if ( id ) { + var self = this; + if (entityStub.repository !== "local") { + var cloningEl = '

importing...

'; + $(cloningEl).insertAfter(self.focused); + //remote source, clone + + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + if (data.pid) { + $(self.focused).siblings('p').remove(); + id = data.pid; + //console.log(self._selectedEntity); + + if (self.options.type.toLowerCase() == "property") { + self._selectedEntity.id = id; + self._selectedEntity.title = "Property:" + id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = "http://localhost/wiki/Property:" + id; + self._selectedEntity.pageid = null; + } else if (self.options.type.toLowerCase() == "item"){ + self._selectedEntity.id = id; + self._selectedEntity.title = id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = "http://localhost/wiki/" + id; + self._selectedEntity.pageid = null; + } + + //this._selectedEntity = { id: id }; + //TODO + self._trigger( 'selected', null, [ id ] ); + } + } + }); + } else { + this._trigger( 'selected', null, [ id ] ); + } + } +}; + +function createSynButton(_context) { + btn = $("") + btn.css("margin-top", ".5rem"); + btn.css("color", "#0645ad"); + btn.css("background-color", "white"); + btn.css("border-color", "#0645ad"); + btn.css("border-radius", "5px"); + + _context.$cloneBtn.append(btn); + + var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + self.wikibasePropertyValue = _wikibasePropertyValue; + + //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + + btn.on('click', function () { + btn.text("syncing..."); + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data.completed) { + console.log(data); + location.reload(); + } + + + } + }); + }); +}; + + +function removeExistingRecordsFromWikidataResults(wikidataResults, localResults){ + if (!wikidataResults || !localResults){ + return wikidataResults; + } + var updatedResults = []; + localResults.concat(wikidataResults).forEach(function (element) { + var index = updatedResults.findIndex(function(x){ + return x.label.toLowerCase().trim() == element.label.toLowerCase().trim() && x.description.toLowerCase().trim() == element.description.toLowerCase().trim() + }) + if (index == -1) { + if (element.repository.toLowerCase() !== "local") { + element.label = "[source: wikidata] " + element.label + } + updatedResults.push(element); + } + }) + return updatedResults + + +}; diff --git a/wikibase-scripts/boilerplate-extension/templates.php b/wikibase-scripts/boilerplate-extension/templates.php new file mode 100644 index 0000000..b703e90 --- /dev/null +++ b/wikibase-scripts/boilerplate-extension/templates.php @@ -0,0 +1,342 @@ + + * + * @return array templates + */ + +return call_user_func( function() { + $templates = []; + + $templates['wikibase-entityview'] = +<< +

$5
+
$6
+
+HTML; + + $templates['wb-entity-header-separator'] = +<< +HTML; + + $templates['wikibase-title'] = +<< + $2 + $3 + +HTML; + + $templates['wb-section-heading'] = +<<$1 +HTML; + + // empty toc to help MobileFrontend + $templates['wikibase-toc'] = +<<
+HTML; + + $templates['wikibase-statementgrouplistview'] = +<<$1 +HTML; + + $templates['wikibase-statementgroupview'] = +<< +
+
$1
+
$5
+
+ $2 + +HTML; + + $templates['wikibase-statementlistview'] = +<< +
+ $1 +
+ $2 + +HTML; + + $templates['wikibase-snakview'] = +<< +
+
$1
+
$5
+
+
+
+
+
$3
+
+
+
+ +HTML; + + $templates['wikibase-statementview'] = +<< +
$3
+
+
$4
+
$5
+
+ $6 +
+
$7
+
$8
+
+ +HTML; + + $templates['wikibase-rankselector'] = +<< + + +HTML; + + $templates['wikibase-referenceview'] = +<< +
+
$2
+ +HTML; + + $templates['wikibase-listview'] = +<<$1 +HTML; + + $templates['wikibase-snaklistview'] = +<< +
$1
+ +HTML; + + $templates['wikibase-labelview'] = +<< +
+ $2 + $3 +
+ +HTML; + + $templates['wikibase-descriptionview'] = +<< +
+ $2 + $3 +
+ +HTML; + + $templates['wikibase-aliasesview'] = +<< +
    $2
+ $3 + +HTML; + + $templates['wikibase-aliasesview-list-item'] = +<<$1 +HTML; + + $templates['wikibase-entitytermsview'] = +<< + $1 + $4 +
$2
+ +HTML; + + $templates['wikibase-entitytermsview-heading'] = +<< + $1 + +HTML; + + $templates['wikibase-entitytermsview-heading-part'] = +<<$3 +HTML; + + $templates['wikibase-entitytermsview-aliases'] = +<<$1 +HTML; + + $templates['wikibase-entitytermsview-aliases-alias'] = +<<$1 +HTML; + + $templates['wikibase-entitytermsforlanguagelistview'] = +<< + + + $1 + $2 + $3 + $4 + + + $5 + +HTML; + + $templates['wikibase-entitytermsforlanguageview'] = +<< + <$9 class="wikibase-entitytermsforlanguageview-language">$4 + <$2 class="wikibase-entitytermsforlanguageview-label">$5 + <$2 class="wikibase-entitytermsforlanguageview-description">$6 + <$2 class="wikibase-entitytermsforlanguageview-aliases">$7 + $8 + +HTML; + + $templates['wikibase-sitelinkgrouplistview'] = +<<$1 +HTML; + + $templates['wikibase-sitelinkgroupview'] = +<< +
+
+ + $6 +
+
+
+ $4 +
+ +HTML; + + $templates['wikibase-sitelinklistview'] = +<< +
    $1
+ +HTML; + + $templates['wikibase-sitelinkview'] = +<< + + $2 + $4 + +HTML; + + $templates['wikibase-sitelinkview-pagename'] = +<<$2$3 +HTML; + + $templates['wikibase-sitelinkview-unknown'] = +<< + $1 + $2 + +HTML; + + $templates['wb-badge'] = +<< +HTML; + + $templates['wikibase-badgeselector'] = +<<$1 +HTML; + + $templates['wikibase-propertyview-datatype'] = +<< +
$1
+ +HTML; + + $templates['wikibase-toolbar-item'] = +<<$1 +HTML; + + $templates['wikibase-toolbar-button'] = +<<$3 +HTML; + + $templates['wikibase-toolbar'] = +<<$2 +HTML; + + $templates['wikibase-toolbar-container'] = +<<$1 +HTML; + +// Helper template for styling +// TODO: Remove template + $templates['wikibase-toolbar-wrapper'] = +<<$1 +HTML; + + $templates['wikibase-toolbar-bracketed'] = +<< +
✕
+
$1
+ +HTML; + + $templates['wikibase-pageimage'] = +<< +
+   +
+ +HTML; + + return $templates; +} ); From cd937c4eb266caa044a1581937ce22f4929ffcc6 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 21 Jun 2022 15:31:53 +0200 Subject: [PATCH 30/50] boilter plate extension changes --- main.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/main.py b/main.py index 32e9e6d..aef3cee 100644 --- a/main.py +++ b/main.py @@ -33,14 +33,6 @@ def get(self, q_id): payload = {"status_code": 200, "completed": True, "message": "Import process complete"} return payload - # if not t.is_alive(): - # print("THREAD:::::") - # payload = {"status_code": 200, "completed": True, "message": "Import process complete"} - # return payload - # else: - # payload = {"status_code": 500, "completed": False, "message": "Import process could not be completed"} - # return payload - # import one class ImportOne(Resource): From 13c2a35849ba8efcc60d68d101d99491abd571dc Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 22 Jun 2022 11:35:09 +0200 Subject: [PATCH 31/50] Extension updates --- main.py | 15 - .../boilerplate-extension/Hooks.php | 2 +- .../boilerplate-extension/LocalSettings.php | 79 ++++ .../boilerplate-extension/extension.json | 4 + .../boilerplate-extension/init.js | 12 +- .../boilerplate-extension/templates.php | 342 ------------------ 6 files changed, 90 insertions(+), 364 deletions(-) create mode 100644 wikibase-scripts/boilerplate-extension/LocalSettings.php delete mode 100644 wikibase-scripts/boilerplate-extension/templates.php diff --git a/main.py b/main.py index aef3cee..65386e8 100644 --- a/main.py +++ b/main.py @@ -107,21 +107,6 @@ def get(self, query_string): api.add_resource(WikiDataQuery, "/remote-wikidata-query//") api.add_resource(WikibaseQuery, "/local-wikibase-query/") -# @app.route("/") -# def hello_world(): -# return "

Hello, World!

" -# -# -# @app.route("/syncc") -# def syncc(): -# return "Sync page" -# -# @app.route("/import-one/") -# def get(id): -# from import_one import mth_import_one -# mth_import_one(id) -# return {"message": "import complete"} - if __name__ == '__main__': app.run(host='0.0.0.0', debug=True) diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibase-scripts/boilerplate-extension/Hooks.php index c795764..3922352 100644 --- a/wikibase-scripts/boilerplate-extension/Hooks.php +++ b/wikibase-scripts/boilerplate-extension/Hooks.php @@ -38,7 +38,7 @@ public function onBeforePageDisplay( $out, $skin ): void { } public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { - $vars['wgVisualEditor'] = ["local_server_url" => "http://127.0.0.1:5000"]; + $vars['wgVisualEditor'] = $config->get( 'BoilerPlateWikibaseSyncConfig' ); } } diff --git a/wikibase-scripts/boilerplate-extension/LocalSettings.php b/wikibase-scripts/boilerplate-extension/LocalSettings.php new file mode 100644 index 0000000..f62a96d --- /dev/null +++ b/wikibase-scripts/boilerplate-extension/LocalSettings.php @@ -0,0 +1,79 @@ + '/var/log/mediawiki/resourceloader.log', + 'exception' => '/var/log/mediawiki/exception.log', + 'error' => '/var/log/mediawiki/error.log', +); + +## Site Settings +# TODO pass in the rest of this with env vars? +$wgServer = WebRequest::detectServer(); +$wgShellLocale = "en_US.utf8"; +$wgLanguageCode = "en"; +$wgSitename = "wikibase-docker"; +$wgMetaNamespace = "Project"; +# Configured web paths & short URLs +# This allows use of the /wiki/* path +## https://www.mediawiki.org/wiki/Manual:Short_URL +$wgScriptPath = "/w"; // this should already have been configured this way +$wgArticlePath = "/wiki/$1"; + + +#Set Secret +$wgSecretKey = "some-secret-key"; + +## RC Age +# https://www.mediawiki.org/wiki/Manual: +# Items in the recentchanges table are periodically purged; entries older than this many seconds will go. +# The query service (by default) loads data from recent changes +# Set this to 1 year to avoid any changes being removed from the RC table over a shorter period of time. +$wgRCMaxAge = 365 * 24 * 3600; + +wfLoadSkin( 'Vector' ); +wfLoadExtension( 'BoilerPlate' ); +// T276905 - default set in Dockerfile +$wgJobRunRate = 0; + +$wgEnableUploads = false; + +$wgUploadDirectory = "/var/www/html/images"; + +## Wikibase Repository +wfLoadExtension( 'WikibaseRepository', "$IP/extensions/Wikibase/extension-repo.json" ); +require_once "$IP/extensions/Wikibase/repo/ExampleSettings.php"; + +## Wikibase Client +wfLoadExtension( 'WikibaseClient', "$IP/extensions/Wikibase/extension-client.json" ); +require_once "$IP/extensions/Wikibase/client/ExampleSettings.php"; + +#Pingback +$wgWBRepoSettings['wikibasePingback'] = false; + +foreach (glob("LocalSettings.d/*.php") as $filename) +{ + include $filename; +} + +//IMPORTANT FOR DESCRIPTIVE ERROR MESSAGES WHERE APPLICABLE +$wgShowExceptionDetails = true; + +//IMPORTANT FOR BoilerPlate EXTENSION +$wgBoilerPlateWikibaseSyncConfig = ["local_server_url" => "http://127.0.0.1:5000", "PID" => "P1", "QID" => "P2"]; diff --git a/wikibase-scripts/boilerplate-extension/extension.json b/wikibase-scripts/boilerplate-extension/extension.json index cc7747d..fee609b 100644 --- a/wikibase-scripts/boilerplate-extension/extension.json +++ b/wikibase-scripts/boilerplate-extension/extension.json @@ -21,6 +21,10 @@ "BoilerPlateVandalizeEachPage": { "description": "Write 'BoilerPlate was here' on each page", "value": false + }, + "BoilerPlateWikibaseSyncConfig": { + "description": "Configuration settings for wikibasesync", + "value": true } }, "HookHandlers": { diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js index e0f6502..c023be1 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -7,7 +7,7 @@ var conf = mw.config.get('wgVisualEditor'); mw.boilerPlate = {}; var wikidataResults = []; var WIKIBASE_SYNC_URL = conf.local_server_url; -//console.log(WIKIBASE_SYNC_URL); +//console.log( conf); var datamodel = require( 'wikibase.datamodel' ); @@ -50,10 +50,10 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { } - if (_wikibasePropertyKey == "P1" || _wikibasePropertyKey == "P2") { + if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { self.wikibasePropertyKey = _wikibasePropertyKey; // Only attach button for wikidata pid or qid properties which are always P1 and P2 - self.$cloneBtn.text(''); + //self.$propertyLabel.text(''); createSynButton(self) // btn = $("") @@ -67,7 +67,7 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); } else { - self.$cloneBtn.text('') + //self.$propertyLabel.text('') } // console.log(JSON.stringify(self.options, null, 2)); }; @@ -220,7 +220,7 @@ function createSynButton(_context) { btn.css("border-color", "#0645ad"); btn.css("border-radius", "5px"); - _context.$cloneBtn.append(btn); + _context.$propertyLabel.append(btn); var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; self.wikibasePropertyValue = _wikibasePropertyValue; @@ -240,7 +240,7 @@ function createSynButton(_context) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - if (data.completed) { + if (data) { console.log(data); location.reload(); } diff --git a/wikibase-scripts/boilerplate-extension/templates.php b/wikibase-scripts/boilerplate-extension/templates.php deleted file mode 100644 index b703e90..0000000 --- a/wikibase-scripts/boilerplate-extension/templates.php +++ /dev/null @@ -1,342 +0,0 @@ - - * - * @return array templates - */ - -return call_user_func( function() { - $templates = []; - - $templates['wikibase-entityview'] = -<< -
$5
-
$6
- -HTML; - - $templates['wb-entity-header-separator'] = -<< -HTML; - - $templates['wikibase-title'] = -<< - $2 - $3 - -HTML; - - $templates['wb-section-heading'] = -<<$1 -HTML; - - // empty toc to help MobileFrontend - $templates['wikibase-toc'] = -<< -HTML; - - $templates['wikibase-statementgrouplistview'] = -<<$1 -HTML; - - $templates['wikibase-statementgroupview'] = -<< -
-
$1
-
$5
-
- $2 - -HTML; - - $templates['wikibase-statementlistview'] = -<< -
- $1 -
- $2 - -HTML; - - $templates['wikibase-snakview'] = -<< -
-
$1
-
$5
-
-
-
-
-
$3
-
-
-
- -HTML; - - $templates['wikibase-statementview'] = -<< -
$3
-
-
$4
-
$5
-
- $6 -
-
$7
-
$8
-
- -HTML; - - $templates['wikibase-rankselector'] = -<< - - -HTML; - - $templates['wikibase-referenceview'] = -<< -
-
$2
- -HTML; - - $templates['wikibase-listview'] = -<<$1 -HTML; - - $templates['wikibase-snaklistview'] = -<< -
$1
- -HTML; - - $templates['wikibase-labelview'] = -<< -
- $2 - $3 -
- -HTML; - - $templates['wikibase-descriptionview'] = -<< -
- $2 - $3 -
- -HTML; - - $templates['wikibase-aliasesview'] = -<< -
    $2
- $3 - -HTML; - - $templates['wikibase-aliasesview-list-item'] = -<<$1 -HTML; - - $templates['wikibase-entitytermsview'] = -<< - $1 - $4 -
$2
- -HTML; - - $templates['wikibase-entitytermsview-heading'] = -<< - $1 - -HTML; - - $templates['wikibase-entitytermsview-heading-part'] = -<<$3 -HTML; - - $templates['wikibase-entitytermsview-aliases'] = -<<$1 -HTML; - - $templates['wikibase-entitytermsview-aliases-alias'] = -<<$1 -HTML; - - $templates['wikibase-entitytermsforlanguagelistview'] = -<< - - - $1 - $2 - $3 - $4 - - - $5 - -HTML; - - $templates['wikibase-entitytermsforlanguageview'] = -<< - <$9 class="wikibase-entitytermsforlanguageview-language">$4 - <$2 class="wikibase-entitytermsforlanguageview-label">$5 - <$2 class="wikibase-entitytermsforlanguageview-description">$6 - <$2 class="wikibase-entitytermsforlanguageview-aliases">$7 - $8 - -HTML; - - $templates['wikibase-sitelinkgrouplistview'] = -<<$1 -HTML; - - $templates['wikibase-sitelinkgroupview'] = -<< -
-
- - $6 -
-
-
- $4 -
- -HTML; - - $templates['wikibase-sitelinklistview'] = -<< -
    $1
- -HTML; - - $templates['wikibase-sitelinkview'] = -<< - - $2 - $4 - -HTML; - - $templates['wikibase-sitelinkview-pagename'] = -<<$2$3 -HTML; - - $templates['wikibase-sitelinkview-unknown'] = -<< - $1 - $2 - -HTML; - - $templates['wb-badge'] = -<< -HTML; - - $templates['wikibase-badgeselector'] = -<<$1 -HTML; - - $templates['wikibase-propertyview-datatype'] = -<< -
$1
- -HTML; - - $templates['wikibase-toolbar-item'] = -<<$1 -HTML; - - $templates['wikibase-toolbar-button'] = -<<$3 -HTML; - - $templates['wikibase-toolbar'] = -<<$2 -HTML; - - $templates['wikibase-toolbar-container'] = -<<$1 -HTML; - -// Helper template for styling -// TODO: Remove template - $templates['wikibase-toolbar-wrapper'] = -<<$1 -HTML; - - $templates['wikibase-toolbar-bracketed'] = -<< -
✕
-
$1
- -HTML; - - $templates['wikibase-pageimage'] = -<< -
-   -
- -HTML; - - return $templates; -} ); From 8d46dfaf84340488c9d4943aceb52801eec643c1 Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 22 Jun 2022 11:49:10 +0200 Subject: [PATCH 32/50] Extension updates --- wikibase-scripts/boilerplate-extension/init.js | 1 + 1 file changed, 1 insertion(+) diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js index c023be1..4837b60 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -215,6 +215,7 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { function createSynButton(_context) { btn = $("") btn.css("margin-top", ".5rem"); + btn.css("margin-left", "5px"); btn.css("color", "#0645ad"); btn.css("background-color", "white"); btn.css("border-color", "#0645ad"); From 6f71afd0ef1c7980c75ccb3851885181b68cec53 Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 22 Jun 2022 13:30:33 +0200 Subject: [PATCH 33/50] Extension refactor --- wikibase-scripts/boilerplate-extension/Hooks.php | 6 +++++- .../boilerplate-extension/LocalSettings.php | 4 +++- .../boilerplate-extension/extension.json | 12 ++++++++++-- wikibase-scripts/boilerplate-extension/init.js | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibase-scripts/boilerplate-extension/Hooks.php index 3922352..18f20b1 100644 --- a/wikibase-scripts/boilerplate-extension/Hooks.php +++ b/wikibase-scripts/boilerplate-extension/Hooks.php @@ -38,7 +38,11 @@ public function onBeforePageDisplay( $out, $skin ): void { } public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { - $vars['wgVisualEditor'] = $config->get( 'BoilerPlateWikibaseSyncConfig' ); + $vars['wgVisualEditor'] =[ + "wikibasesync_server_url" => $config->get( 'WikibaseSyncUrl' ), + "PID" => $config->get( 'PID' ), + "QID" => $config->get( 'QID' ), + ]; } } diff --git a/wikibase-scripts/boilerplate-extension/LocalSettings.php b/wikibase-scripts/boilerplate-extension/LocalSettings.php index f62a96d..bbd3c27 100644 --- a/wikibase-scripts/boilerplate-extension/LocalSettings.php +++ b/wikibase-scripts/boilerplate-extension/LocalSettings.php @@ -76,4 +76,6 @@ $wgShowExceptionDetails = true; //IMPORTANT FOR BoilerPlate EXTENSION -$wgBoilerPlateWikibaseSyncConfig = ["local_server_url" => "http://127.0.0.1:5000", "PID" => "P1", "QID" => "P2"]; +$wgWikibaseSyncUrl = "http://127.0.0.1:5000"; +$wgPID = "P1"; +$wgQID = "P2"; diff --git a/wikibase-scripts/boilerplate-extension/extension.json b/wikibase-scripts/boilerplate-extension/extension.json index fee609b..0354699 100644 --- a/wikibase-scripts/boilerplate-extension/extension.json +++ b/wikibase-scripts/boilerplate-extension/extension.json @@ -22,8 +22,16 @@ "description": "Write 'BoilerPlate was here' on each page", "value": false }, - "BoilerPlateWikibaseSyncConfig": { - "description": "Configuration settings for wikibasesync", + "WikibaseSyncUrl": { + "description": "wikibasesync url", + "value": true + }, + "PID": { + "description": "PID", + "value": true + }, + "QID": { + "description": "QID", "value": true } }, diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js index 4837b60..563298a 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -6,7 +6,7 @@ var conf = mw.config.get('wgVisualEditor'); mw.boilerPlate = {}; var wikidataResults = []; -var WIKIBASE_SYNC_URL = conf.local_server_url; +var WIKIBASE_SYNC_URL = conf.wikibasesync_server_url; //console.log( conf); var datamodel = require( 'wikibase.datamodel' ); @@ -214,7 +214,7 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { function createSynButton(_context) { btn = $("") - btn.css("margin-top", ".5rem"); + //btn.css("margin-top", ".5rem"); btn.css("margin-left", "5px"); btn.css("color", "#0645ad"); btn.css("background-color", "white"); From 711e90d4ee995d13ddb29f10332770faf504bc2e Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 22 Jun 2022 13:57:46 +0200 Subject: [PATCH 34/50] only enable extension if user is logged in --- wikibase-scripts/boilerplate-extension/Hooks.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibase-scripts/boilerplate-extension/Hooks.php index 18f20b1..36b1a2e 100644 --- a/wikibase-scripts/boilerplate-extension/Hooks.php +++ b/wikibase-scripts/boilerplate-extension/Hooks.php @@ -29,7 +29,12 @@ class Hooks implements \MediaWiki\Hook\BeforePageDisplayHook{ * @param \Skin $skin */ public function onBeforePageDisplay( $out, $skin ): void { - $out->addModules( 'ext.boilerPlate' ); + $user = \RequestContext::getMain()->getUser(); + + //only enable extension if user is logged in + if(!empty($user) && $user->getId() != 0){ + $out->addModules( 'ext.boilerPlate' ); + } $config = $out->getConfig(); if ( $config->get( 'BoilerPlateVandalizeEachPage' ) ) { $out->addModules( 'oojs-ui-core' ); From 363af69c01c8bf5fec15eb50cfdedb698e4cc069 Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 6 Jul 2022 10:35:53 +0200 Subject: [PATCH 35/50] wikibase sync extension updates --- .../boilerplate-extension/Hooks.php | 16 +- .../boilerplate-extension/LocalSettings.php | 4 +- .../boilerplate-extension/extension.json | 29 +- .../boilerplate-extension/init.js | 112 +- wikibase-scripts/draft-clem-bk2.js | 201 ---- wikibase-scripts/draft-clem.js | 96 -- wikibase-scripts/draft.js | 195 ---- .../jquery.ui.TemplatedWidget.js | 226 ---- .../jquery.wikibase.entityselector.js | 828 --------------- .../jquery.wikibase.statementgroupview.js | 332 ------ .../wikibase_source_files/snakview.js | 967 ------------------ .../wikibase_source_files/templates.php | 342 ------- 12 files changed, 129 insertions(+), 3219 deletions(-) delete mode 100644 wikibase-scripts/draft-clem-bk2.js delete mode 100644 wikibase-scripts/draft-clem.js delete mode 100644 wikibase-scripts/draft.js delete mode 100644 wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js delete mode 100644 wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js delete mode 100644 wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js delete mode 100644 wikibase-scripts/wikibase_source_files/snakview.js delete mode 100644 wikibase-scripts/wikibase_source_files/templates.php diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibase-scripts/boilerplate-extension/Hooks.php index 36b1a2e..94e9d24 100644 --- a/wikibase-scripts/boilerplate-extension/Hooks.php +++ b/wikibase-scripts/boilerplate-extension/Hooks.php @@ -17,10 +17,12 @@ * @file */ -namespace MediaWiki\Extension\BoilerPlate; +namespace MediaWiki\Extension\WikibaseSync; use Config; use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook; +global $wgUser; + class Hooks implements \MediaWiki\Hook\BeforePageDisplayHook{ /** @@ -30,16 +32,12 @@ class Hooks implements \MediaWiki\Hook\BeforePageDisplayHook{ */ public function onBeforePageDisplay( $out, $skin ): void { $user = \RequestContext::getMain()->getUser(); - - //only enable extension if user is logged in if(!empty($user) && $user->getId() != 0){ - $out->addModules( 'ext.boilerPlate' ); + //var_dump(gettype($user)); + //var_dump($user->getId()); + $out->addModules( 'ext.wikibaseSync' ); } $config = $out->getConfig(); - if ( $config->get( 'BoilerPlateVandalizeEachPage' ) ) { - $out->addModules( 'oojs-ui-core' ); - $out->addHTML( \Html::element( 'p', [], 'BoilerPlate was here' ) ); - } } public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { @@ -50,5 +48,3 @@ public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $co ]; } } - - diff --git a/wikibase-scripts/boilerplate-extension/LocalSettings.php b/wikibase-scripts/boilerplate-extension/LocalSettings.php index bbd3c27..389186b 100644 --- a/wikibase-scripts/boilerplate-extension/LocalSettings.php +++ b/wikibase-scripts/boilerplate-extension/LocalSettings.php @@ -72,10 +72,10 @@ include $filename; } -//IMPORTANT FOR DESCRIPTIVE ERROR MESSAGES WHERE APPLICABLE +//EXTENSIONS SETTINGS $wgShowExceptionDetails = true; -//IMPORTANT FOR BoilerPlate EXTENSION +wfLoadExtension( 'WikibaseSync' ); $wgWikibaseSyncUrl = "http://127.0.0.1:5000"; $wgPID = "P1"; $wgQID = "P2"; diff --git a/wikibase-scripts/boilerplate-extension/extension.json b/wikibase-scripts/boilerplate-extension/extension.json index 0354699..6d3761f 100644 --- a/wikibase-scripts/boilerplate-extension/extension.json +++ b/wikibase-scripts/boilerplate-extension/extension.json @@ -1,27 +1,19 @@ { - "name": "BoilerPlate", + "name": "WikibaseSync", "author": [ "mez" ], "url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate", - "descriptionmsg": "boilerplate-desc", + "descriptionmsg": "This is a Wikibase extension to use and sync entities between Wikibases", "license-name": "GPL-2.0-or-later", "type": "other", "requires": { "MediaWiki": ">= 1.35.0" }, "AutoloadNamespaces": { - "MediaWiki\\Extension\\BoilerPlate\\": "src/" + "MediaWiki\\Extension\\WikibaseSync\\": "src/" }, "config": { - "BoilerPlateEnableFoo": { - "description": "Enable the Foo feature.", - "value": true - }, - "BoilerPlateVandalizeEachPage": { - "description": "Write 'BoilerPlate was here' on each page", - "value": false - }, "WikibaseSyncUrl": { "description": "wikibasesync url", "value": true @@ -36,13 +28,13 @@ } }, "HookHandlers": { - "BoilerPlateHooks": { - "class": "MediaWiki\\Extension\\BoilerPlate\\Hooks" + "WikibaseSyncHooks": { + "class": "MediaWiki\\Extension\\WikibaseSync\\Hooks" } }, "Hooks": { - "BeforePageDisplay": "BoilerPlateHooks", - "ResourceLoaderGetConfigVars": "BoilerPlateHooks" + "BeforePageDisplay": "WikibaseSyncHooks", + "ResourceLoaderGetConfigVars": "WikibaseSyncHooks" }, "MessagesDirs": { "BoilerPlate": [ @@ -50,9 +42,9 @@ ] }, "ResourceModules": { - "ext.boilerPlate": { - "localBasePath": "resources/ext.boilerPlate", - "remoteExtPath": "BoilerPlate/resources/ext.boilerPlate", + "ext.wikibaseSync": { + "localBasePath": "resources/ext.wikibaseSync", + "remoteExtPath": "WikibaseSync/resources/ext.wikibaseSync", "dependencies": ["wikibase.view.ControllerViewFactory"], "styles": [], "packageFiles": [ @@ -63,3 +55,4 @@ }, "manifest_version": 2 } + diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js index 563298a..aab6e60 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -100,7 +100,7 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - console.log(data); + //console.log(data); wikidataResults = data.response.search; } }); @@ -212,6 +212,113 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { } }; +// overwrite search result default behaviour +// $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { +// var PARENT = $.wikibase.entityselector; +// PARENT.prototype._initMenu.apply( this, arguments ); + +// if ( this.options.suggestionsPlaceholder ) { +// ooMenu.option( 'customItems' ).unshift( this.options.suggestionsPlaceholder ); +// } + +// ooMenu.element.addClass( 'wikibase-entitysearch-list' ); + +// $( ooMenu ) +// .off( 'selected' ) +// .on( 'selected.entitysearch', function ( event, item ) { +// event.preventDefault(); +// var itemEntityStub = item.getEntityStub(); + +// //clone if item is sourced from wikidata +// if (itemEntityStub.repository.toLowerCase() === "wikidata") { +// console.log("f: ",itemEntityStub); + +// //api call +// var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id; +// $.ajax({ +// url: full_endpoint, +// crossDomain: true, +// // async: false, +// headers: { +// "Access-Control-Allow-Origin": "*", +// "Access-Control-Request-Headers3": "x-requested-with" +// }, +// success: function (data) { +// console.log("response: ",data); +// window.location.href = 'http://localhost/wiki/item:'+data.pid; + +// } +// }); +// }else{ +// if ( event.originalEvent +// && /^key/.test( event.originalEvent.type ) +// && !( item instanceof $.ui.ooMenu.CustomItem ) +// ) { +// window.location.href = item.getEntityStub().url; +// } +// } +// } ); + +// return ooMenu; +// } + +// overwrite search result default behaviour sec +$.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { + var PARENT = $.wikibase.entityselector; + PARENT.prototype._initMenu.apply( this, arguments ); + + if ( this.options.suggestionsPlaceholder ) { + ooMenu.option( 'customItems' ).unshift( this.options.suggestionsPlaceholder ); + } + + ooMenu.element.addClass( 'wikibase-entitysearch-list' ); + + //console.log(ooMenu.element[0].querySelectorAll("a")); + $( ooMenu ) + .off( 'selected' ) + .on( 'selected.entitysearch', function ( event, item ) { + if ( event.originalEvent + // && /^key/.test( event.originalEvent.type ) + && !( item instanceof $.ui.ooMenu.CustomItem ) + ) { + var itemEntityStub = item.getEntityStub(); + if (itemEntityStub) { + if (itemEntityStub.repository.toLowerCase() === "wikidata") { + //console.log("f: ",itemEntityStub); + $("a[tabindex='-1']").click(function(e) { + e.preventDefault(); + }); + + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id; + $.ajax({ + url: full_endpoint, + crossDomain: true, + //async: false, + //global: false, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log("response: ",data); + //window.history.back(); + window.location.replace('http://localhost/wiki/item:'+data.pid); + //window.location.replace('https://gmail.com'); + + } + }); + }else{ + window.location.href = item.getEntityStub().url; + //window.location.replace('https://twitter.com'); + } + } + } + } ); + + return ooMenu; +} + function createSynButton(_context) { btn = $("") //btn.css("margin-top", ".5rem"); @@ -264,7 +371,7 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) }) if (index == -1) { if (element.repository.toLowerCase() !== "local") { - element.label = "[source: wikidata] " + element.label + element.label = "[clone from wikidata:] " + element.label } updatedResults.push(element); } @@ -273,3 +380,4 @@ function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) }; + diff --git a/wikibase-scripts/draft-clem-bk2.js b/wikibase-scripts/draft-clem-bk2.js deleted file mode 100644 index b517574..0000000 --- a/wikibase-scripts/draft-clem-bk2.js +++ /dev/null @@ -1,201 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -// var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -function insertStyle(){ - var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; - //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - - head.appendChild(style); - - style.type = 'text/css'; - if (style.styleSheet){ - // This is required for IE8 and below. - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } -} - -(function (mw, $) { - insertStyle() - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - var isLocallyAvailable = true - var isRemotelyAvailable = false - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var isStatement = added_node.classList && ['listview-item', 'wikibase-statementgroupview', 'wb-new'].every(function(c){return added_node.classList.contains(c)}) - var isReference = added_node.classList && ['listview-item', 'wikibase-snakview', 'wb-edit'].every(function(c){return added_node.classList.contains(c)}) - - var localList = added_node.classList && ['ui-ooMenu', 'ui-widget', 'ui-widget-content', 'ui-suggester-list', 'ui-entityselector-list'].every(function(c){return added_node.classList.contains(c)}) - var remoteList = added_node.classList && ['ui-autocomplete' 'ui-menu' 'ui-widget' 'ui-widget-content' 'ui-corner-all'].every(function(c){return added_node.classList.contains(c)}) - - - - var focusInput; - - if (isStatement || isReference) { - - // secondary wikidata autocomplete - - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - data_length = data.response.search.length - - if (data_length < 1) { - isRemotelyAvailable = false; - //$("ui-entityselector-notfound").hide(); -// var appendedButton = currentContext.siblings('.mez-appended-button') -// if((appendedButton.length > 0 && isLocallyAvailable) || -// if((appendedButton.length > 0 && isLocallyAvailable) || -// ( appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === "")){ -// currentContext.siblings('.mez-appended-button').remove() -// } - } - - if (data_length >= 1) { - isRemotelyAvailable = true; - //var appendedButton = currentContext.siblings('.mez-appended-button') - - //if (appendedButton.length === 0 && isLocallyAvailable == false) { -// if (appendedButton.length === 0) { -// $("").insertAfter($(currentContext)); -// } - } - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - - - }, - select: function (event, ui) { - - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - - } - }); - - - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - var currentContext = $(this) - var appendedButton = currentContext.siblings('.mez-appended-button') - if (isRemotelyAvailable) { - if (appendedButton.length === 0) { - $("").insertAfter($(currentContext)); - } - } - if (!isRemotelyAvailable) { - if (appendedButton.length === 0) { - $("").insertAfter($(currentContext)); - } - } - - if(appendedButton.length > 0 && $('.wikibase-snakview-property input').val() === ""){ - currentContext.siblings('.mez-appended-button').remove() - } - - //check if there's data found locally - - }); - } - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - var _myPropertyId = ele.getAttribute('item-id') - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; - $.ajax({ - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - ele.remove(); - console.log('clone button removed'); - - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} - -//TODO PENDING ISSUES -//ADDING ANOTHER DIRECT INPUT FIELD CAUSES STACKING PROBLEMS -//WHEN REMOTE AUTOCOMPLETE KICKS IN, CLONE BUTTON PERSISTS AFTER ALL INPUT IS CLEARED -//EVEN WHEN DATA LENGTH IS GREATER THAN 0, AUTOCOMPLETE DISPLAYS AND THIS LEADS TO THE PROBLEM BELOW -//WHEN AUTOCOMPLETE DISPLAYS TOGETHER WITH REMOTE SUGGESTIONS,REMOTE DISPLAYS ABOVE THE LOCAL SUGGESTIONS diff --git a/wikibase-scripts/draft-clem.js b/wikibase-scripts/draft-clem.js deleted file mode 100644 index 4b23938..0000000 --- a/wikibase-scripts/draft-clem.js +++ /dev/null @@ -1,96 +0,0 @@ -var STATEMENT_CLASSES = ['listview-item', 'wikibase-statementgroupview', 'wb-new']; -var REFERENCE_CLASSES = ['listview-item', 'wikibase-snakview', 'wb-edit']; -var REFERENCE_INPUT_CLASSES = ['ui-suggester-input', 'ui-entityselector-input']; -var AUTOCOMPLETE_CLASSES = ['ui-ooMenu', 'ui-widget', 'ui-widget-content', 'ui-suggester-list', 'ui-entityselector-list']; - -var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - -var nextId = 0; - -var lastAutocompleteElement = null; -var requestsResults = {}; // key=statementId, value=result -var lastResultStatementId = null; - -(function (mw, _$) { - - function makeWikidataCall (userInput, statementId) { - $.ajax({ - url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + userInput, - crossDomain: true, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - requestsResults[statementId] = data; - lastResultStatementId = statementId; - updateAutocompleteElement(statementId); - } - }); - } - - function updateAutocompleteElement (statementId) { - if (lastAutocompleteElement === null) return; - - var data = requestsResults[statementId]; - var children = Array.from(lastAutocompleteElement.children); - - if (children.length === 1 && children[0].matches('li.ui-entityselector-notfound')) { - // No match found - console.log('no match'); - } else { - // At least one match found - console.log('At least one match'); - // data.response.search.forEach(proposition => { - // // TODO - // }); - } - } - - function setLastAutocompleteElement (el) { - // Update the global var - lastAutocompleteElement = el; - - // Attach an observer to
    to monitor its children (detect a change) - var acObserver = new MutationObserver(function (mutationsList) { - mutationsList.forEach(function (mutation) { - if (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0) { - // Children have been removed/added - if (lastResultStatementId !== null) updateAutocompleteElement(lastResultStatementId); - } - }); - }); - acObserver.observe(el, { childList: true }); - } - - const observer = new MutationObserver(function (mutationsList) { - mutationsList.forEach(function (mutation) { - mutation.addedNodes.forEach(function (addedNode) { - // Check for new statement block - var isStatement = addedNode.classList && STATEMENT_CLASSES.every(function (c) { return addedNode.classList.contains(c) }); - if (isStatement) { - // A new statement block has been added - var statementId = nextId; - nextId += 1; - var input = addedNode.querySelector('input.' + REFERENCE_INPUT_CLASSES.join('.')); - lastInputElement = input; - input.addEventListener('input', function () { - makeWikidataCall(input.value, statementId); - }); - return; - } - - // Check for new autocomplete element - var isAutocomplete = addedNode.classList && AUTOCOMPLETE_CLASSES.every(function (c) { return addedNode.classList.contains(c) }); - if (isAutocomplete) { - // Keep track of the last one (which is the only one valid) - setLastAutocompleteElement(addedNode); - //uodate last autocomplete el with the last known result - if (lastResultStatementId !== null) updateAutocompleteElement(lastResultStatementId); - } - }); - }); - }); - observer.observe(document.body, { subtree: true, childList: true }); - -}(mediaWiki, jQuery)); diff --git a/wikibase-scripts/draft.js b/wikibase-scripts/draft.js deleted file mode 100644 index 23636e3..0000000 --- a/wikibase-scripts/draft.js +++ /dev/null @@ -1,195 +0,0 @@ -/* Any JavaScript here will be loaded for all users on every page load. */ -//final draftttt - - -var _propertyId = ""; -var _propertyLabel = ""; - -var cloneButtonCounter = 0; -var parentIDCounter = 0; -var autoInputIDCounter = 0; -var propertyDetailArray = []; -var cloneButtonIdPrefix = 'clone_btn_'; -var currentlyClickedCloneButtonId = ''; -var currentBtn = null; -// var localDataLength = 1; - -var _wikibasesync_base_url = "http://127.0.0.1:5000/"; - -function insertStyle(){ - var css = 'button.mez-appended-button:nth-child(2) {margin-top: 19px;}'; - //var css = '.wikibase-referenceview .wikibase-snaklistview-listview .wikibase-snakview-property input {position: relative !important;}'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - - head.appendChild(style); - - style.type = 'text/css'; - if (style.styleSheet){ - // This is required for IE8 and below. - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } -} - -(function (mw, $) { - insertStyle() - var _parentEl = document.getElementsByClassName('wikibase-entityview wb-item') - console.log(_parentEl) - - const observer = new MutationObserver(function (mutations_list) { - mutations_list.forEach(function (mutation) { - mutation.addedNodes.forEach(function (added_node) { - //console.log(Object.keys(added_node)); - var entries = Object.entries(added_node); - var focusInput; - - if (entries.length == 2) { - if (entries[0][1]) { - $('.wikibase-snakview-property input').on('keyup', function () { - //console.log("TYPED VALUE"); - var typedValue = $(this).val(); - //check if there's data found locally - $.ajax({ - url: _wikibasesync_base_url + 'local-wikibase-query/' + typedValue, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - //console.log("RECEIVED LOCAL DATA"); - //console.log(data.response.search.length); - data_length = data.response.search.length - - if (data_length < 1) { - console.log("No local data found"); - // localDataLength = 0; - - console.log('No found'); - // var notFoundEl = document.getElementsByClassName('ui-ooMenu-item ui-ooMenu-customItem ui-entityselector-notfound')[0]; - //console.log(notFoundEl); - - - focusInput = document.getElementsByClassName("ui-suggester-input ui-entityselector-input")[0].value; - //console.log(focusInput); - - //always remove clone button while typing - //var inputWithSuggestionParent = $('#new .ui-entityselector-input').parent(); - $('.wikibase-snakview-property input').on('keydown', function () { - //console.log($(this).closest('div').find(':button').index(this)); - console.log('input parent div'); - currentBtn = $(this).siblings('.mez-appended-button')[0] - if ($(this).siblings('.mez-appended-button').length === 0) { - $("").insertAfter($(this)); - } - - }); - - - - if (focusInput) { - console.log('in focus input'); - $('#new .ui-entityselector-input').autocomplete({ //This is the class Name of your desired input source: - source: function (request, response) { - console.log('Request term: ' + request.term); - $.ajax({ - // url: 'https://www.wikidata.org/w/api.php?action=wbsearchentities&search=' + request.term + '&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property', - url: _wikibasesync_base_url + 'remote-wikidata-query/' + request.term, - // data: {term: request.term}, - // dataType: "json", - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - - response($.map(data.response.search, function (item) { - _propertyId = item.id; - _propertyLabel = item.label; - return { - label: item.description, - value: item.label, - id: item.id - } - })); - } - }); - }, - select: function (event, ui) { - console.log("REMOTE OPTION SELECTED") - console.log($(event.target).siblings('button')); - $(event.target).siblings('button')[0].setAttribute('item-id', ui.item.id) - $(event.target).siblings('button')[0].setAttribute('item-description', ui.item.label) - $(event.target).siblings('button')[0].setAttribute('item-value', ui.item.value) - } - }); - - - - - } - } else { - // localDataLength = 1; - } - } - }); - }); - // if (localDataLength == 0) { - - - - // } - } - } - - - }); - }); - }); - - observer.observe(document.querySelector("body"), { subtree: true, childList: true }); -}(mediaWiki, jQuery)); - -//ui-menu-item. -//clone button clicked -function cloneAction(ele) { - //clone action called - console.log("Clone information: ") - console.log(ele.getAttribute('item-id')); - console.log(ele.getAttribute('item-description')); - console.log(ele.getAttribute('item-value')); - - var _myPropertyId = ele.getAttribute('item-id') - - //api call - var wikibaseSyncUrl = _wikibasesync_base_url + 'import-wikidata-item/' + _myPropertyId; - $.ajax({ - url: wikibaseSyncUrl, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - ele.remove(); - console.log('clone button removed'); - - } - }); -} - -function pushNewButtonInfo(buttonId, arrayKey) { - //add button info to array - propertyDetailArray[arrayKey] = buttonId; - - console.log(propertyDetailArray); -} diff --git a/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js b/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js deleted file mode 100644 index 40660b4..0000000 --- a/wikibase-scripts/wikibase_source_files/jquery.ui.TemplatedWidget.js +++ /dev/null @@ -1,226 +0,0 @@ -( function () { - 'use strict'; - - var PARENT = $.Widget; - - /** - * Base prototype for all widgets using the `mw.wbTemplate` templating system. - * Uses `jQuery.fn.applyTemplate`. - * @see mediaWiki.WbTemplate - * @class jQuery.ui.TemplatedWidget - * @abstract - * @extends jQuery.Widget - * @uses jQuery.fn - * @license GPL-2.0-or-later - * @author Daniel Werner < daniel.a.r.werner@gmail.com > - * - * @constructor - * - * @param {Object} options - * @param {string} options.template - * Name of a template to use. The template should feature a single root node which will - * be replaced by the widget's subject node. - * @param {*[]} [options.templateParams] - * Parameters injected into the template on its initial construction. A parameter can be - * what is compatible with `mw.wbTemplate` but can also be a function which will be - * executed in the widget's context and provide the parameter's value by its return - * value. - * @param {Object} [options.templateShortCuts] - * A map pointing from a short-cut name to a node within the widget's template. The map - * is used during the widget creation process to automatically add members to the widget - * object that may be accessed during the widget's life time. - * The location of the target node has to be given as a valid jQuery query expression, - * i.e. `{ $foo: li.example-class > .foo }` results in being able to access the selected - * node using `this.$foo` within the widget instance. - * @param {boolean} [options.encapsulate=false] - * Whether non-native `jQuery.Widget` events shall be triggered on the widget's node only - * and not bubble up the DOM tree (using `jQuery.triggerHandler()` instead of - * `jQuery.trigger()`). - */ - /** - * @event disable - * Triggered whenever the widget is disabled (after disabled state has been set). - * @param {jQuery.Event} - * @param {boolean} Whether widget has been dis- oder enabled. - */ - $.widget( 'ui.TemplatedWidget', PARENT, { - /** - * @see jQuery.Widget.options - */ - options: $.extend( true, {}, PARENT.prototype.options, { - template: null, - templateParams: [], - templateShortCuts: {}, - encapsulate: false - } ), - - /** - * Creates the DOM structure according to the template and assigns the template short-cuts. - * Consequently, when overriding `_create` in inheriting widgets, calling the parent's - * `_create` should be the first action in the overridden `_create`, as that ensures the - * basic template DOM is created and template short-cuts can be used. The function should - * be overridden only to perform DOM manipulation/creation while initializing should be - * performed in `_init`. - * - * @see jQuery.Widget._create - * @protected - * - * @throws {Error} if `template` option is not specified. - */ - _create: function () { - if ( !this.options.template ) { - throw new Error( 'template needs to be specified' ); - } - - // FIXME: Find sane way to detect that template is applied already. - if ( this.element.contents().length === 0 ) { - this._applyTemplate(); - } - - this._createTemplateShortCuts(); - - PARENT.prototype._create.apply( this ); - }, - - /** - * @see jQuery.fn.applyTemplate - * @private - */ - _applyTemplate: function () { - var templateParams = [], - self = this; - - // template params which are functions are callbacks to be called in the widget's context - this.options.templateParams.forEach( function ( value ) { - if ( typeof value === 'function' ) { - value = value.call( self ); - } - templateParams.push( value ); - } ); - - // the element node will be preserved, no matter whether it is of the same kind as the - // template's root node (it is assumed that the template has a root node) - this.element.addClass( this.widgetBaseClass ); - this.element.applyTemplate( this.option( 'template' ), templateParams ); - }, - - /** - * Creates the short-cuts to DOM nodes within the template's DOM structure as specified in - * the `templateShortCuts` option. - * - * @private - * - * @throws {Error} if no DOM node is found using a specified selector. - */ - _createTemplateShortCuts: function () { - var shortCuts = this.options.templateShortCuts, - shortCut, shortCutSelector, $shortCutTarget; - - for ( shortCut in shortCuts ) { - shortCutSelector = shortCuts[ shortCut ]; - $shortCutTarget = this.element.find( shortCutSelector ); - if ( $shortCutTarget.length < 1 ) { - throw new Error( 'Template "' + this.option( 'template' ) + '" has no DOM node ' - + ' selectable via the jQuery expression "' + shortCutSelector + '"' ); - } - this[ shortCut ] = $shortCutTarget; - - } - }, - - /** - * @see jQuery.Widget.destroy - */ - destroy: function () { - PARENT.prototype.destroy.call( this ); - - this.element.removeClass( this.widgetBaseClass ); - - // nullify references to short-cut DOM nodes - for ( var shortCut in this.options.templateShortCuts ) { - this[ shortCut ] = null; - } - }, - - /** - * @see jQuery.Widget._setOption - * @protected - * - * @param {string} key - * @param {*} value - * @return {jQuery.Widget} - * - * @throws {Error} when trying to set `template`, `templateParams` or `templateShortCuts` - * option. - */ - _setOption: function ( key, value ) { - switch ( key ) { - case 'template': - case 'templateParams': - case 'templateShortCuts': - throw new Error( 'Can not set template related options after initialization' ); - } - - var response = PARENT.prototype._setOption.apply( this, arguments ); - - if ( key === 'disabled' ) { - this._trigger( 'disable', null, [ value ] ); - } - - return response; - }, - - /** - * Applies focus to the widget. - */ - focus: function () { - this.element.trigger( 'focus' ); - }, - - /** - * Clone of jQuery.Widget._trigger with the difference that `$.triggerHandler()` instead of - * `$.trigger()` is used to trigger the event on `this.element` if `encapsulate` option is - * `true`. - * - * @see jQuery.Widget._trigger - * @protected - * - * @param {string} type - * @param {jQuery.Event|string} event - * @param {*} data - * @return {boolean} - */ - _trigger: function ( type, event, data ) { - var prop, - orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( - type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type - ).toLowerCase(); - // The original event may come from any element, so we need to reset the target on the - // new event: - event.target = this.element[ 0 ]; - - // Copy original event properties over to the new event: - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element[ this.options.encapsulate ? 'triggerHandler' : 'trigger' ]( event, data ); - return !( - typeof callback === 'function' - && callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false - || event.isDefaultPrevented() - ); - } - } ); - -}() ); diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js deleted file mode 100644 index d9a5604..0000000 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.entityselector.js +++ /dev/null @@ -1,828 +0,0 @@ -var wikidataResults = []; -var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - -function removeExistingRecordsFromWikidataResults(wikidataResults, localResults){ - if (!wikidataResults || !localResults){ - return wikidataResults; - } - var updatedResults = []; - localResults.concat(wikidataResults).forEach(function (element) { - var index = updatedResults.findIndex(function(x){ - return x.label.toLowerCase().trim() == element.label.toLowerCase().trim() && x.description.toLowerCase().trim() == element.description.toLowerCase().trim() - }) - if (index == -1) { - if (element.repository.toLowerCase() !== "local") { - element.label = "[source: wikidata] " + element.label - } - updatedResults.push(element); - } - }) - return updatedResults - - -} - -( function () { - 'use strict'; - - // TODO: Get rid of MediaWiki context detection by submitting a message provider as option. - - /** - * Whether loaded in MediaWiki context. - * - * @property {boolean} - * @ignore - */ - var IS_MW_CONTEXT = mw !== undefined && mw.msg; - var focused; - - /** - * Whether actual `entityselector` resource loader module is loaded. - * - * @property {boolean} - * @ignore - */ - var IS_MODULE_LOADED = ( - IS_MW_CONTEXT - && mw.loader.getModuleNames().indexOf( 'jquery.wikibase.entityselector' ) !== -1 - ); - - /** - * Returns a message from the MediaWiki context if the `entityselector` module has been loaded. - * If it has not been loaded, the corresponding string defined in the options will be returned. - * - * @ignore - * - * @param {string} msgKey - * @param {string} string - * @return {string} - */ - function mwMsgOrString( msgKey, string ) { - // eslint-disable-next-line mediawiki/msg-doc - return IS_MODULE_LOADED ? mw.msg( msgKey ) : string; - } - - /** - * Enhances an input box with auto-complete and auto-suggestion functionality for Wikibase entities. - * - * @example - * $( 'input' ).entityselector( { - * url: <{string} URL to the API of a MediaWiki instance running Wikibase repository>, - * language: <{string} language code of the language to fetch results in> - * } ); - * - * @class jQuery.wikibase.entityselector - * @extends jQuery.ui.suggester - * @uses jQuery.event.special.eachchange - * @uses jQuery.ui.ooMenu - * @license GPL-2.0-or-later - * @author H. Snater < mediawiki@snater.com > - * - * @constructor - * - * @param {Object} options - * @param {string} options.url - * URL to retrieve results from. - * @param {string} options.language - * (optional when in MediaWiki context) - * Language code of the language results shall be fetched in. - * Defaults to the user language (`mw.config.get( 'wgUserLanguage' )` when in MediaWiki - * context. - * @param {string} [options.type='item'] - * `Entity` type that will be queried for results. - * @param {number|null} [options.limit=null] - * Number of results to query the API for. Will pick limit specified server-side if ´null´. - * @param {boolean} [options.caseSensitive=false] - * Whether the widget shall consider letter case when determining if the first suggestion - * matches with the current input triggering the "select" mechanism. - * @param {number} [options.timeout=8000] - * Default AJAX timeout in milliseconds. - * @param {Object} [options.messages=Object] - * Strings used within the widget. - * Messages should be specified using `mwMsgOrString(, - * )` in order to use the messages specified in the resource loader module - * (if loaded). - * @param {string} [options.searchHookName='wikibase.entityselector.search'] - * Name of the hook that fires when searching for entities. - * @param {string} [options.messages.more='more'] - * Label of the link to display more suggestions. - * @param {string[]} [options.showErrorCodes=['failed-property-search']] - * Show errors with these error-codes in the ui. - * @param {Function} [options.responseErrorFactory=null] - * Optional Callback to parse error message from response object - * @see wikibase.api.RepoApiError.newFromApiResponse - */ - /** - * @event selected - * Triggered after having selected an entity. - * @param {jQuery.Event} event - * @param {string} entityId - */ - $.widget( 'wikibase.entityselector', $.ui.suggester, { - - /** - * @property {Object} - */ - options: { - url: null, - language: ( IS_MW_CONTEXT ) ? mw.config.get( 'wgUserLanguage' ) : null, - type: 'item', - limit: null, - caseSensitive: false, - timeout: 8000, - messages: { - more: mwMsgOrString( 'wikibase-entityselector-more', 'more' ), - notfound: mwMsgOrString( 'wikibase-entityselector-notfound', 'Nothing found' ), - error: null - }, - searchHookName: 'wikibase.entityselector.search', - searchApiParametersHookName: 'wikibase.entityselector.search.api-parameters', - showErrorCodes: [ 'failed-property-search' ], - responseErrorFactory: null - }, - - /** - * Caching the most current entity returned from the API. - * - * @property {Object} - * @private - */ - _selectedEntity: null, - - /** - * Caches retrieved results. - * - * Warning, PropertySuggester's EntitySelector accesses this! - * - * @property {Object} [_cache={}] - * @protected - */ - _cache: null, - - /** - * Error object from last search. - * - * @property {Object} [_error={}] - * @protected - */ - _error: null, - - /** - * Warning, PropertySuggester's EntitySelector overrides this! - * - * @inheritdoc - * @protected - */ - _create: function () { - var self = this; - - this._cache = {}; - - if ( !this.options.source ) { - if ( this.options.url === null ) { - throw new Error( 'When not specifying a dedicated source, URL option needs to be ' - + 'specified' ); - } else if ( this.options.language === null ) { - throw new Error( 'When not specifying a dedicated source, language option needs to ' - + 'be specified.' ); - } - this.options.source = this._initDefaultSource(); - } else if ( typeof this.options.source !== 'function' && !Array.isArray( this.options.source ) ) { - throw new Error( 'Source needs to be a function or an array' ); - } - - if ( !this.options.messages.error ) { - this.options.messages.error = function () { - return self._error && self._error.detailedMessage ? self._error.detailedMessage : null; - }; - } - - console.log(mw); - $.ui.suggester.prototype._create.call( this ); - - this.element - .addClass( 'ui-entityselector-input' ) - .prop( 'dir', $( document ).prop( 'dir' ) ); - - this.options.menu.element.addClass( 'ui-entityselector-list' ); - - this.element - .off( 'blur' ) - .on( 'eachchange.' + this.widgetName, function ( event ) { - self._search( event ); - } ) - .on( 'focusout', function () { - self._indicateRecognizedInput(); - } ) - .on( 'focusin', function () { - self._inEditMode(); - self._showDefaultSuggestions(); - } ); - }, - - _indicateRecognizedInput: function () { - this._resetInputHighlighting(); - - if ( this._selectedEntity !== null ) { - this.element.addClass( 'ui-entityselector-input-recognized' ); - } else if ( this.element.val() !== '' ) { - this.element.addClass( 'ui-entityselector-input-unrecognized' ); - } - }, - - _inEditMode: function () { - this._resetInputHighlighting(); - }, - - _resetInputHighlighting: function () { - this.element.removeClass( - 'ui-entityselector-input-recognized ui-entityselector-input-unrecognized' - ); - }, - - /** - * @inheritdoc - */ - destroy: function () { - this.element.removeClass( 'ui-entityselector-input' ); - - this._cache = {}; - - $.ui.suggester.prototype.destroy.call( this ); - }, - - /** - * @protected - * - * @param {jQuery.Event} event - */ - _search: function ( event ) { - var self = this; - - this._select( null ); - - clearTimeout( this._searching ); - this._searching = setTimeout( function () { - self.search( event ); - }, this.options.delay ); - }, - - /** - * Create and return the data object for the api call. - * - * Warning, PropertySuggester's EntitySelector overrides this! - * - * @protected - * @param {string} term - * @return {Object} - */ - _getSearchApiParameters: function ( term ) { - var data = { - action: 'wbsearchentities', - search: term, - format: 'json', - errorformat: 'plaintext', - language: this.options.language, - uselang: this.options.language, - type: this.options.type - }; - - if ( this._cache.term === term && this._cache.nextSuggestionOffset ) { - data.continue = this._cache.nextSuggestionOffset; - } - - if ( this.options.limit ) { - data.limit = this.options.limit; - } - - mw.hook( this.options.searchApiParametersHookName ).fire( data ); - - return data; - }, - - /** - * Initializes the default source pointing to the `wbsearchentities` API module via the URL - * provided in the options. - * - * @protected - * - * @return {Function} - */ - _initDefaultSource: function () { - var self = this; - wikidataResults = []; - return function ( term ) { - var deferred = $.Deferred(), - hookResults = self._fireSearchHook( term ); - - // clear previous error - if ( self._error ) { - self._error = null; - self._cache.suggestions = null; - self._updateMenu( [] ); - } - - $.ajax( { - url: self.options.url, - timeout: self.options.timeout, - dataType: 'json', - data: self._getSearchApiParameters( term ), - success: function(data){ - $.ajax({ - url: WIKIBASE_SYNC_URL + 'remote-wikidata-query/' + term + "/" + self.options.type, - crossDomain: true, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - wikidataResults = data.response.search; - } - }); - } - } ) - .done( function ( response, statusText, jqXHR ) { - // T141955 - if ( response.error ) { - deferred.reject( response.error.info ); - return; - } - - // The default endpoint wbsearchentities responds with an array of errors. - if ( response.errors && self.options.responseErrorFactory ) { - var error = self.options.responseErrorFactory( response, 'search' ); - - if ( error && self.options.showErrorCodes.indexOf( error.code ) !== -1 ) { - self._error = error; - self._cache = {}; - self._updateMenu( [] ); - deferred.reject( error.message ); - return; - } - } - - //TODO MERGE THE WIKIDATA RESULTS WITH RESPONSE SEARCH - // console.log("hooksResults"); - // console.log(hookResults); - // console.log("wikidataResults"); - // console.log(wikidataResults); - // console.log("wikibase results"); - // console.log(response.search); - // UPDATE THE TITLE AND SOURCE TO REFELECT WIKIDATA - // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH - var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, response.search) - //console.log("updatedWikidataResults", updatedWikidataResults); - //self._combineResults( hookResults, response.search ).then( function ( results ) { - self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { - //console.log(results) - deferred.resolve( - results, - term, - response[ 'search-continue' ], - jqXHR.getResponseHeader( 'X-Search-ID' ) - ); - } ); - } ) - .fail( function ( jqXHR, textStatus ) { - deferred.reject( textStatus ); - } ); - - return deferred.promise(); - }; - }, - /** - * @private - */ - _fireSearchHook: function ( term ) { - var hookResults = [], - addPromise = function ( p ) { - hookResults.push( p ); - }; - - if ( this._cache.term === term ) { - return hookResults; // Don't fire hook when paginating - } - - mw.hook( this.options.searchHookName ).fire( { - element: this.element, - term: term, - options: this.options - }, addPromise ); - - return hookResults; - }, - /** - * @private - */ - _combineResults: function ( hookResults, searchResults ) { - var self = this, - deferred = $.Deferred(), - ids = {}, - result = [], - uniqueFilter = function ( item ) { - if ( ids[ item.id ] ) { - return false; - } - ids[ item.id ] = true; - return true; - }, - ratingSorter = function ( item1, item2 ) { - if ( !item1.rating && !item2.rating ) { - return 0; - } - if ( !item1.rating ) { - return 1; - } - if ( !item2.rating ) { - return -1; - } - if ( item1.rating < item2.rating ) { - return 1; - } - if ( item1.rating === item2.rating ) { - return 0; - } - return -1; - }; - - searchResults = searchResults || []; - - $.when.apply( $, hookResults ).then( function () { - - var args = Array.prototype.slice.call( arguments ); - args.forEach( function ( data ) { - result = data.concat( result ); - } ); - - result = self._stableSort( result, ratingSorter ); - result = result.concat( searchResults ); - result = result.filter( uniqueFilter ); - deferred.resolve( result ); - } ); - - return deferred.promise(); - }, - - /** - * @private - */ - _stableSort: function stableSort( items, compareFn ) { - var indices = Object.keys( items ).map( Number ); - indices.sort( function ( index1, index2 ) { - var compare = compareFn( items[ index1 ], items[ index2 ] ); - if ( compare !== 0 ) { - return compare; - } - // fall back to comparing indices to ensure stability - if ( index1 < index2 ) { - return -1; - } - if ( index1 > index2 ) { - return 1; - } - return 0; - } ); - var sorted = indices.map( function ( index ) { - return items[ index ]; - } ); - return sorted; - }, - - /** - * @private - */ - _showDefaultSuggestions: function () { - if ( this.element.val() !== '' ) { - return; - } - - var self = this, - term = this.element.val(), - promises = this._fireSearchHook( term ); - - this._combineResults( promises, [] ).then( function ( suggestions ) { - if ( suggestions.length > 0 ) { - self._updateMenu( suggestions ); - } - } ); - - }, - - /** - * @inheritdoc - * @protected - */ - _updateMenu: function ( suggestions ) { - var scrollTop = this.options.menu.element.scrollTop(); - - $.ui.suggester.prototype._updateMenu.apply( this, arguments ); - - this.options.menu.element.scrollTop( scrollTop ); - }, - - /** - * Generates the label for a suggester entity. - * - * @protected - * - * @param {Object} entityStub - * @return {jQuery} - */ - _createLabelFromSuggestion: function ( entityStub ) { - var $suggestion = $( '' ).addClass( 'ui-entityselector-itemcontent' ), - $label = $( '' ).addClass( 'ui-entityselector-label' ).text( entityStub.label || entityStub.id ); - - if ( entityStub.aliases ) { - $label.append( - $( '' ).addClass( 'ui-entityselector-aliases' ).text( ' (' + entityStub.aliases.join( ', ' ) + ')' ) - ); - } - - $suggestion.append( $label ); - - if ( entityStub.description ) { - $suggestion.append( - $( '' ).addClass( 'ui-entityselector-description' ) - .text( entityStub.description ) - ); - } - - return $suggestion; - }, - - /** - * @see jQuery.ui.suggester._createMenuItemFromSuggestion - * @protected - * - * @param {Object} entityStub - * @return {jQuery.wikibase.entityselector.Item} - */ - _createMenuItemFromSuggestion: function ( entityStub ) { - var $label = this._createLabelFromSuggestion( entityStub ), - value = entityStub.label || entityStub.id; - - return new $.wikibase.entityselector.Item( $label, value, entityStub ); - }, - - /** - * @inheritdoc - * @protected - */ - _initMenu: function ( ooMenu ) { - var self = this; - $.ui.suggester.prototype._initMenu.apply( this, arguments ); - - $( this.options.menu ) - .off( 'selected.suggester' ) - .on( 'selected.entityselector', function ( event, item ) { - self.focused = $(':focus')[0]; - if ( item.getEntityStub ) { - if ( !self.options.caseSensitive - && item.getValue().toLowerCase() === self._term.toLowerCase() - ) { - self._term = item.getValue(); - } else { - self.element.val( item.getValue() ); - } - - self._close(); - self._trigger( 'change' ); - - var entityStub = item.getEntityStub(); - - if ( !self._selectedEntity || entityStub.id !== self._selectedEntity.id ) { - self._select( entityStub ); - } - } - } ); - - var customItems = ooMenu.option( 'customItems' ); - - customItems.unshift( new $.ui.ooMenu.CustomItem( - this.options.messages.more, - function () { - return self._cache.term === self._term && self._cache.nextSuggestionOffset; - }, - function () { - self.search( $.Event( 'programmatic' ) ); - }, - 'ui-entityselector-more' - ) ); - - customItems.unshift( new $.ui.ooMenu.CustomItem( - this.options.messages.notfound, - function () { - return !self._error && self._cache.suggestions && !self._cache.suggestions.length - && self.element.val().trim() !== ''; - }, - null, - 'ui-entityselector-notfound' - ) ); - - customItems.unshift( new $.ui.ooMenu.CustomItem( - this.options.messages.error, - function () { - return self._error !== null; - }, - null, - 'ui-entityselector-error' - ) ); - - ooMenu._evaluateVisibility = function ( customItem ) { - if ( customItem instanceof $.ui.ooMenu.CustomItem ) { - return customItem.getVisibility( ooMenu ); - } else { - return ooMenu._evaluateVisibility.apply( this, arguments ); - } - }; - - ooMenu.option( 'customItems', customItems ); - - return ooMenu; - }, - - /** - * @inheritdoc - * @protected - */ - _getSuggestions: function ( term ) { - var self = this; - - return $.ui.suggester.prototype._getSuggestions.apply( this, arguments ) - .then( function ( suggestions, searchTerm, nextSuggestionOffset, searchId ) { - var deferred = $.Deferred(); - - if ( self._cache.term === searchTerm && self._cache.nextSuggestionOffset ) { - self._cache.suggestions = self._cache.suggestions.concat( suggestions ); - self._cache.nextSuggestionOffset = nextSuggestionOffset; - } else { - self._cache = { - term: searchTerm, - suggestions: suggestions, - nextSuggestionOffset: nextSuggestionOffset - }; - } - if ( searchId ) { - self._cache.searchId = searchId; - } else { - delete self._cache.searchId; - } - - deferred.resolve( self._cache.suggestions, searchTerm ); - return deferred.promise(); - } ); - }, - - /** - * @inheritdoc - * @protected - */ - _getSuggestionsFromArray: function ( term, source ) { - var deferred = $.Deferred(), - matcher = new RegExp( this._escapeRegex( term ), 'i' ); - - deferred.resolve( source.filter( function ( item ) { - if ( item.aliases ) { - for ( var i = 0; i < item.aliases.length; i++ ) { - if ( matcher.test( item.aliases[ i ] ) ) { - return true; - } - } - } - - return matcher.test( item.label ) || matcher.test( item.id ); - } ), term ); - - return deferred.promise(); - }, - - /** - * Selects an entity. - * - * @protected - * - * @param {Object} entityStub - */ - _select: function ( entityStub ) { - //conf = mw.config.get( 'wgWikibaseSync' ); - //console.log("conf",conf) - var id = entityStub && entityStub.id; - this._selectedEntity = entityStub; - - if ( id ) { - var self = this; - if (entityStub.repository !== "local") { - var cloningEl = '

    importing...

    '; - $(cloningEl).insertAfter(self.focused); - //remote source, clone - - //api call - var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - var full_endpoint = WIKIBASE_SYNC_URL + 'import-wikidata-item/' + id; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - if (data.pid) { - $(self.focused).siblings('p').remove(); - id = data.pid; - //console.log(self._selectedEntity); - - if (self.options.type.toLowerCase() == "property") { - self._selectedEntity.id = id; - self._selectedEntity.title = "Property:" + id; - self._selectedEntity.repository = "local"; - self._selectedEntity.url = "http://localhost/wiki/Property:" + id; - self._selectedEntity.pageid = null; - } else if (self.options.type.toLowerCase() == "item"){ - self._selectedEntity.id = id; - self._selectedEntity.title = id; - self._selectedEntity.repository = "local"; - self._selectedEntity.url = "http://localhost/wiki/" + id; - self._selectedEntity.pageid = null; - } - - //this._selectedEntity = { id: id }; - //TODO - self._trigger( 'selected', null, [ id ] ); - } - } - }); - } else { - this._trigger( 'selected', null, [ id ] ); - } - } - }, - - /** - * Gets and sets the current state. The optional parameter can be used to let the initial - * state of the selector reflect what can be seen in the input field the selector is - * attached to. - * - * @param {string} [entityId] - * @return {Object} Plain object featuring `Entity` stub data. - */ - selectedEntity: function ( entityId ) { - if ( typeof entityId === 'string' ) { - this._selectedEntity = { id: entityId }; - } - - return this._selectedEntity; - } - } ); - - /** - * Default `entityselector` suggestion menu item. - * - * @class jQuery.wikibase.entityselector.Item - * @extends jQuery.ui.ooMenu.Item - * - * @constructor - * - * @param {jQuery|string} label - * @param {string} value - * @param {Object} entityStub - * - * @throws {Error} if a required parameter is not specified properly. - */ - var Item = function ( label, value, entityStub ) { - if ( !label || !value || !entityStub ) { - throw new Error( 'Required parameter(s) not specified properly' ); - } - - this._label = label; - this._value = value; - this._entityStub = entityStub; - this._link = entityStub.url; - }; - - Item = util.inherit( - $.ui.ooMenu.Item, - Item, - { - /** - * @property {Object} - * @protected - */ - _entityStub: null, - - /** - * @return {Object} - */ - getEntityStub: function () { - return this._entityStub; - } - } - ); - - $.extend( $.wikibase.entityselector, { - Item: Item - } ); - -}() ); diff --git a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js b/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js deleted file mode 100644 index 338b4bb..0000000 --- a/wikibase-scripts/wikibase_source_files/jquery.wikibase.statementgroupview.js +++ /dev/null @@ -1,332 +0,0 @@ -function createSynButton(_context) { - btn = $("") - btn.css("margin-top",".5rem"); - btn.css("color","#0645ad"); - btn.css("background-color","white"); - btn.css("border-color","#0645ad"); - btn.css("border-radius","5px"); - - _context.$cloneBtn.append(btn); - - var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; - self.wikibasePropertyValue = _wikibasePropertyValue; - - //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); - - btn.on('click', function () { - btn.text("syncing...") - //api call - var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - if (data.completed) { - location.reload(); - } - - - } - }); - }); -} - -( function () { - 'use strict'; - - var PARENT = $.ui.TemplatedWidget, - datamodel = require( 'wikibase.datamodel' ); - - /** - * View for displaying `datamodel.Statement` objects grouped by their main `Snak`'s - * `Property` id by managing a list of `jQuery.wikibase.statementview` widgets encapsulated by a - * `jquery.wikibase.statementlistview` widget. - * - * @see datamodel.StatementGroup - * @extends jQuery.ui.TemplatedWidget - * @license GPL-2.0-or-later - * @author H. Snater < mediawiki@snater.com > - * - * @constructor - * - * @param {Object} options - * @param {datamodel.StatementGroup} [options.value=null] - * The `Statements` to be displayed by this view. If `null`, the view will only display an - * "add" button to add new `Statements`. - * @param {wikibase.entityIdFormatter.EntityIdHtmlFormatter} options.entityIdHtmlFormatter - * Required for dynamically rendering links to `Entity`s. - * @param {Function} options.buildStatementListView - */ - /** - * @event afterremove - * Triggered after a `statementview` was removed from the `statementlistview` encapsulated by this - * `statementgroupview`. - * @param {jQuery.Event} event - */ - $.widget( 'wikibase.statementgroupview', PARENT, { - /** - * @inheritdoc - * @protected - */ - wikibasePropertyKey: "", - wikibasePropertyValue: "", - options: { - template: 'wikibase-statementgroupview', - templateParams: [ - '', // label - '', // statementlistview widget - '', // html id attribute - '', // property id - '', // clone btn - ], - templateShortCuts: { - $property: '.wikibase-statementgroupview-property', - $propertyLabel: '.wikibase-statementgroupview-property-label', - $cloneBtn: '.wikibase-statementgroupview-property-clonebtn' - }, - value: null, - buildStatementListView: null, - entityIdHtmlFormatter: null, - htmlIdPrefix: '' - }, - - /** - * @property {jQuery.wikibase.statementlistview} - */ - statementlistview: null, - - /** - * @inheritdoc - * @protected - * - * @throws {Error} if a required option is not specified properly. - */ - _create: function () { - if ( !this.options.entityIdHtmlFormatter || !this.options.buildStatementListView ) { - throw new Error( 'Required option not specified properly' ); - } - - try { - PARENT.prototype._create.call( this ); - } catch (e) { - console.log('ERROR', e); - } - - if ( this.options.value ) { - this._updateId(); - this._updatePropertyId( this.options.value.getKey() ); - this._createPropertyLabel(); - } - - this._createStatementlistview(); - }, - - /** - * @inheritdoc - */ - destroy: function () { - if ( this.statementlistview ) { - this.statementlistview.element.off( this.widgetName ); - this.statementlistview.destroy(); - } - PARENT.prototype.destroy.call( this ); - }, - - /** - * @private - */ - _updateId: function () { - var propertyId = this.options.value.getKey(), - prefix = this.options.htmlIdPrefix, - prefixSeparator = '-'; - - if ( prefix !== '' ) { - prefix += prefixSeparator; - } - - this.element.attr( 'id', prefix + propertyId ); - }, - - /** - * @private - * - * @param {string} propertyId - */ - _updatePropertyId: function ( propertyId ) { - this.element.data( 'property-id', propertyId ); - }, - - /** - * @private - */ - _createPropertyLabel: function () { - if ( this.$propertyLabel.contents().length > 0 ) { - return; - } - - var self = this, - propertyId = this.options.value.getKey(); - - this.options.entityIdHtmlFormatter.format( propertyId ).done( function ( title ) { - self.$propertyLabel.append( title ); - } ); - }, - - /** - * @private - */ - _createStatementlistview: function () { - var self = this, - prefix; - - var $statementlistview = this.element.find( '.wikibase-statementlistview' ); - - if ( !$statementlistview.length ) { - $statementlistview = $( '

    ' ).appendTo( this.element ); - } - - this.statementlistview = this.options.buildStatementListView( - this.options.value ? this.options.value.getItemContainer() : new datamodel.StatementList(), - $statementlistview - ); - prefix = this.statementlistview.widgetEventPrefix; - - $statementlistview - .on( prefix + 'toggleerror.' + this.widgetName, function ( event, error ) { - self.$property.toggleClass( 'wb-error', Boolean( error ) ); - } ) - .on( prefix + 'afterstopediting.' + this.widgetName, function ( event, dropValue ) { - self.$property.removeClass( 'wb-error wb-edit' ); - self._trigger( 'afterstopediting', null, [ dropValue ] ); - } ) - .on( prefix + 'afterstartediting.' + this.widgetName, function ( event ) { - self.$property.addClass( 'wb-edit' ); - } ) - .on( prefix + 'afterremove.' + this.widgetName, function ( event ) { - self.$property.removeClass( 'wb-error wb-edit' ); - self._trigger( 'afterremove' ); - } ); - - //self.$cloneBtn.text('hello world'); - var _wikibasePropertyKey = self.value().getKey(); - - - if( _wikibasePropertyKey == "P1" || _wikibasePropertyKey == "P2"){ - self.wikibasePropertyKey = _wikibasePropertyKey; - // Only attach button for wikidata pid or qid properties which are always P1 and P2 - self.$cloneBtn.text(''); - createSynButton(self) - // btn = $("") - - // self.$cloneBtn.append(btn); - - // //console.log("val",self.value()); - // //var _wikibasePropertyValue = ""; - // var _wikibasePropertyValue = self.value().getItemContainer()._items[0]._claim._mainSnak._value._value; - // self.wikibasePropertyValue = _wikibasePropertyValue; - - // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); - - // btn.on('click', function () { - // //api call - // var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - // var full_endpoint = WIKIBASE_SYNC_URL + 'sync/' + self.wikibasePropertyValue; - // $.ajax({ - // url: full_endpoint, - // crossDomain: true, - // headers: { - // // "accept": "application/json", - // "Access-Control-Allow-Origin": "*", - // "Access-Control-Request-Headers3": "x-requested-with" - // }, - // success: function (data) { - // console.log("sync process started",data); - - - // } - // }); - // }); - }else{ - self.$cloneBtn.text('') - } - // console.log(JSON.stringify(self.options, null, 2)); - }, - - /** - * Sets the widget's value or gets the widget's current value (including pending items). (The - * value the widget was initialized with may be retrieved via `.option( 'value' )`.) - * - * @param {datamodel.StatementGroup} [statementGroupView] - * @return {datamodel.StatementGroup|null|undefined} - */ - value: function ( statementGroupView ) { - if ( statementGroupView !== undefined ) { - return this.option( 'value', statementGroupView ); - } - - var statementList = this.statementlistview.value(); - if ( !statementList.length ) { - return null; - } - // Use the first statement's main snak property id as the statementgroupview may have - // been initialized without a value (as there is no initial value, the id cannot be - // retrieved from this.options.value). - return new datamodel.StatementGroup( - statementList.toArray()[ 0 ].getClaim().getMainSnak().getPropertyId(), - statementList - ); - }, - - /** - * @inheritdoc - * @protected - * - * @throws {Error} when trying to set the value passing something different than a - * `datamodel.StatementGroup´ object. - */ - _setOption: function ( key, value ) { - if ( key === 'value' && !!value ) { - if ( !( value instanceof datamodel.StatementGroup ) ) { - throw new Error( 'value needs to be a datamodel.StatementGroup instance' ); - } - this.statementlistview.value( value.getItemContainer() ); - } - - var response = PARENT.prototype._setOption.apply( this, arguments ); - - if ( key === 'disabled' ) { - this.statementlistview.option( key, value ); - } - - return response; - }, - - /** - * @inheritdoc - */ - focus: function () { - this.statementlistview.focus(); - }, - - /** - * Adds a new, pending `statementview` to the encapsulated `statementlistview`. - * - * @see jQuery.wikibase.statementlistview.enterNewItem - * - * @return {Object} jQuery.Promise - * @return {Function} return.done - * @return {jQuery} return.done.$statementview - */ - enterNewItem: function () { - return this.statementlistview.enterNewItem(); - } - - } ); - -}() ); diff --git a/wikibase-scripts/wikibase_source_files/snakview.js b/wikibase-scripts/wikibase_source_files/snakview.js deleted file mode 100644 index 4a7daaa..0000000 --- a/wikibase-scripts/wikibase_source_files/snakview.js +++ /dev/null @@ -1,967 +0,0 @@ -( function ( wb, dv ) { - 'use strict'; - - // Back-up components already initialized in the namespace to re-apply them after initializing - // the snakview widget. - $.wikibase = $.wikibase || {}; - var existingSnakview = $.wikibase.snakview || {}; - - // Erase existing object to prevent jQuery.Widget detecting an existing constructor: - delete $.wikibase.snakview; - - var PARENT = $.ui.EditableTemplatedWidget, - datamodel = require( 'wikibase.datamodel' ), - ViewState = require( './snakview.ViewState.js' ), - variations = require( './snakview.variations.js' ), - wbserialization = require( 'wikibase.serialization' ); - - /** - * View for displaying and editing `datamodel.Snak` objects. - * - * @see datamodel.Snak - * @class jQuery.wikibase.snakview - * @extends jQuery.ui.EditableTemplatedWidget - * @author Daniel Werner < daniel.a.r.werner@gmail.com > - * @author H. Snater < mediawiki@snater.com > - * - * @constructor - * - * @param {Object} options - * @param {Object|datamodel.Snak|null} [options.value] - * The `Snak` this `snakview` should represent initially. If omitted, an empty view will be - * served, ready to take some input by the user. The value may be overwritten later, by using - * the `value()` or the `snak()` function. - * Default: `{ snaktype: datamodel.PropertyValueSnak.TYPE }` - * @param {Object|boolean} [options.locked=false] - * Key-value pairs determining which `snakview` elements to lock from being edited by the - * user. May also be a boolean value enabling/disabling all elements. If `false`, no elements - * will be locked. - * @param {boolean} [options.autoStartEditing=true] - * Whether the `snakview` should switch to edit mode automatically upon initialization if its - * initial value is empty. - * @param {wikibase.entityIdFormatter.EntityIdHtmlFormatter} options.entityIdHtmlFormatter - * Required for dynamically rendering links to `Entity`s. - * @param {wikibase.entityIdFormatter.EntityIdPlainFormatter} options.entityIdPlainFormatter - * Required for dynamically rendering plain text references to `Entity`s. - * @param {PropertyDataTypeStore} options.propertyDataTypeStore - * Required for looking up the Snak's property's data type. - * @param {wikibase.ValueViewBuilder} options.valueViewBuilder - * Required to interfacing a `snakview` "value" `Variation` to `jQuery.valueview`. - * @param {wikibase.dataTypes.DataTypeStore} options.dataTypeStore - * Required to retrieve and evaluate a proper `wikibase.dataTypes.DataType` object when interacting on - * a "value" `Variation`. - * @param {boolean} [options.drawProperty=true] - * The `Property` part of the `snakview` is not rendered when `drawProperty` is false. - */ - /** - * @event afterstartediting - * Triggered after having started the widget's edit mode. - * @param {jQuery.Event} event - */ - /** - * @event afterstopediting - * Triggered after having stopped the widget's edit mode. - * @param {jQuery.Event} event - * @param {boolean} dropValue - */ - /** - * @event change - * Triggered whenever the widget's content or status is changed. - * @param {jQuery.Event} event - */ - $.widget( 'wikibase.snakview', PARENT, { - /** - * @inheritdoc - * @protected - */ - options: { - template: 'wikibase-snakview', - templateParams: [ '', '', '', '', '' ], - templateShortCuts: { - $property: '.wikibase-snakview-property', - $snakValue: '.wikibase-snakview-value', - $snakTypeSelector: '.wikibase-snakview-typeselector', - $cloneBtn: '.wikibase-snakview-clonebtn' - }, - value: { - snaktype: datamodel.PropertyValueSnak.TYPE - }, - locked: { - property: false, - snaktype: false - }, - autoStartEditing: true, - entityIdPlainFormatter: null, - entityIdHtmlFormatter: null, - valueViewBuilder: null, - dataTypeStore: null, - drawProperty: true, - getSnakRemover: null, - propertyDataTypeStore: null - }, - - /** - * `Variation` object responsible for presenting the essential parts of a certain kind of - * `Snak`. May be `null` if an unsupported `Snak` type is represented by the `snakview`. In this - * case, the `snakview` won't be able to display the `Snak` but displays an appropriate message - * instead. - * - * @property {Variation|null} - * @private - */ - _variation: null, - - /** - * Cache for the values of specific `variation`s used to have those - * values restored when toggling the `Snak` type. - * - * @property {Object} - * @private - */ - _cachedValues: null, - - /** - * Whether then `snakview`'s value is regarded "valid" at the moment. - * - * @property {boolean} - * @private - */ - _isValid: false, - - _isCloneBtnEnabled: false, - _item_id: "", - _item_description: "", - - /** - * @inheritdoc - * @protected - */ - _create: function () { - if ( this.options.locked === true || this.options.locked.property === true ) { - if ( !( - this.options.value instanceof datamodel.Snak || ( this.options.value && this.options.value.property ) - ) ) { - mw.log.warn( 'You cannot lock the property without specifying a property' ); - } - } - - PARENT.prototype._create.call( this ); - - this._cachedValues = {}; - - this.updateVariation(); - this.updateHash(); - - // Re-render on previously generated DOM should be avoided. However, when regenerating the - // whole snakview, every component needs to be drawn. - var propertyIsEmpty = !this.$property.contents().length, - snakValueIsEmpty = !this.$snakValue.contents().length; - - if ( propertyIsEmpty && this.options.drawProperty ) { - this.drawProperty(); - } - - if ( snakValueIsEmpty ) { - this.drawVariation(); - } - - if ( this.option( 'autoStartEditing' ) && !this.snak() ) { - // If no Snak is represented, offer UI to build one. - // This clearly implies draw() since it requires visual changes! - this.startEditing(); - } - }, - - /** - * @inheritdoc - * @protected - * - * @throws {Error} when trying to set an invalid value. - */ - _setOption: function ( key, value ) { - if ( key === 'value' ) { - if ( value !== null - && !$.isPlainObject( value ) - && !( value instanceof datamodel.Snak ) - ) { - throw new Error( 'The given value has to be a plain object, an instance of ' - + 'datamodel.Snak, or null' ); - } - } else if ( key === 'locked' && typeof value === 'boolean' ) { - var locked = value; - value = $.extend( {}, $.wikibase.snakview.prototype.options.locked ); - Object.keys( $.wikibase.snakview.prototype.options.locked ).forEach( function ( k ) { - value[ k ] = locked; - } ); - } - - var response = PARENT.prototype._setOption.apply( this, arguments ); - - if ( key === 'value' ) { - this.updateVariation(); - this.draw(); - } else if ( key === 'disabled' ) { - var propertySelector = this._getPropertySelector(), - snakTypeSelector = this._getSnakTypeSelector(); - - if ( propertySelector ) { - propertySelector.option( 'disabled', key ); - } - - if ( snakTypeSelector ) { - snakTypeSelector.option( 'disabled', key ); - } - - if ( this._snakRemover ) { - this._snakRemover[ value ? 'disable' : 'enable' ](); - } - - if ( this._variation ) { - this._variation[ value ? 'disable' : 'enable' ](); - } - } - - return response; - }, - - /** - * Returns an input element with initialized `entityselector` for selecting entities. - * - * @private - * - * @return {jQuery} - */ - _buildPropertySelector: function () { - var self = this, - repoConfig = mw.config.get( 'wbRepo' ), - repoApiUrl = repoConfig.url + repoConfig.scriptPath + '/api.php'; - var input = $( '' ); - input.on( 'input' , function ( event ) { - if (!input.value) { - self._isCloneBtnEnabled = false; - self.drawEntityCloneBtn(); - } - }); - return input.entityselector( { - url: repoApiUrl, - type: 'property', - responseErrorFactory: wb.api.RepoApiError.newFromApiResponse - } ) - .prop( 'placeholder', mw.msg( 'wikibase-snakview-property-input-placeholder' ) ) - .on( 'eachchange', function ( event, oldValue ) { - // remove out-dated variations - if ( self._variation ) { - self.drawSnakTypeSelector(); - self.updateVariation(); - self.drawVariation(); - self._trigger( 'change' ); - } - } ) - .on( 'entityselectorselected', function ( event, entityId ) { - self._selectProperty(); - var selectedItemData = self._getPropertySelector()._selectedEntity; - // console.log("source:",selectedItemData.repository.toLowerCase()); - if (selectedItemData.repository.toLowerCase() !== "local") { - //externally sourced data to be clone - self._isCloneBtnEnabled = true; - - self._item_id = selectedItemData.id; - self._item_description = selectedItemData.description; - }else{ - self._isCloneBtnEnabled = false; - // reset button information - self._item_id = ""; - self._item_description = ""; - } - // self._getPropertySelector()._selectedEntity - self.drawEntityCloneBtn(); - - } ); - }, - - /** - * @private - */ - _selectProperty: function () { - var self = this; - - // Display spinner as long as the ValueView is loading: - this.$snakValue.empty().append( - $( '
    ' ).append( $( '' ).addClass( 'mw-small-spinner' ) ) - ); - - // The "value" variation contains experts that depend on the property and value type. Must - // be recreated when the property changes. Would be better to do this in updateVariation, - // and only when the value type changes, but at this point we can't find out any more. - if ( this._variation ) { - this._variation.destroy(); - this._variation = null; - } - - this.updateVariation(); - this.drawSnakTypeSelector(); - - // Since it might take a while for the value view to gather its data from the API, - // the property might not be valid anymore aborting the rendering of the value - // view. - if ( this._variation ) { - $( this._variation ).one( 'afterstartediting', function () { - self._variation.focus(); - } ); - } - - this.drawVariation(); - - this._trigger( 'change' ); - }, - - /** - * @inheritdoc - */ - destroy: function () { - if ( this._snakRemover ) { - this._snakRemover.destroy(); - this._snakRemover = null; - } - var snakTypeSelector = this._getSnakTypeSelector(); - if ( snakTypeSelector ) { - snakTypeSelector.destroy(); - snakTypeSelector.element.remove(); - } - $.Widget.prototype.destroy.call( this ); - }, - - _startEditing: function () { - var deferred = $.Deferred(); - if ( this.options.getSnakRemover ) { - this._snakRemover = this.options.getSnakRemover( this.element ); - } - - if ( this._variation ) { - $( this._variation ).one( 'afterstartediting', function () { - deferred.resolve(); - } ); - this.draw(); - this._variation.startEditing(); - } else { - this.draw(); - deferred.resolve(); - } - return deferred.promise(); - }, - - /** - * @inheritdoc - */ - focus: function () { - if ( this._variation && this._variation.isFocusable() ) { - this._variation.focus(); - } else { - var propertySelector = this._getPropertySelector(); - if ( propertySelector ) { - propertySelector.element.trigger( 'focus' ); - } else { - this.element.trigger( 'focus' ); - } - } - }, - - /** - * Stops the widget's edit mode. - * - * @param {boolean} [dropValue=false] If `true`, the widget's value will be reset to the one - * from before edit mode was started. - */ - _stopEditing: function ( dropValue ) { - if ( this._snakRemover ) { - this._snakRemover.destroy(); - this._snakRemover = null; - } - - if ( this._variation ) { - this._variation.stopEditing( dropValue ); - } - this.drawSnakTypeSelector(); - - this.element.off( 'keydown.' + this.widgetName ); - - return $.Deferred().resolve().promise(); - }, - - /** - * Updates this `snakview`'s status. - * - * @param {string} status May either be 'valid' or 'invalid' - */ - updateStatus: function ( status ) { - if ( status === 'valid' ) { - this._isValid = true; - } else if ( status === 'invalid' ) { - this._isValid = false; - } - if ( this._variation ) { - this._trigger( 'change' ); - } - }, - - /** - * Returns the `entityselector` for choosing the `Snak`'s `Property`. Returns `null` if the - * `Snak` is created and has a `Property` already. (Once created, the `Property` is immutable.) - * - * @private - * - * @return {jQuery.wikibase.entityselector|null} - */ - _getPropertySelector: function () { - if ( this.$property ) { - return this.$property.children().first().data( 'entityselector' ) || null; - } - return null; - }, - - /** - * Returns the `snaktypeselector` for choosing the `Snak`'s type. Returns `null` if the `Snak` - * is created and has a `Property` already. (Once created, the `Property` is immutable.) - * - * @private - * - * @return {jQuery.wikibase.snakview.SnakTypeSelector|null} - */ - _getSnakTypeSelector: function () { - if ( this.$snakTypeSelector ) { - return this.$snakTypeSelector.children().first().data( 'snaktypeselector' ) || null; - } - return null; - }, - - /** - * Returns an object representing the currently displayed `Snak`. This is equivalent to the JSON - * structure of a `Snak`, except that it does not have to be complete. For example, for a - * `PropertyValueSnak` where only the `Property` and `Snak` type are specified, but the value - * has not yet been supplied, the returned object would not have a field for the value either. - * - * @param {Object|datamodel.Snak|null} [value] - * @return {datamodel.Snak|Object|undefined} `undefined` in case `value()` is called to - * set the value. - */ - value: function ( value ) { - if ( value !== undefined ) { - this.option( 'value', value ); - return; - } - - var snakSerializer = new wbserialization.SnakSerializer(), - serialization = this.options.value instanceof datamodel.Snak - ? snakSerializer.serialize( this.options.value ) - : this.options.value; - - if ( !this.isInEditMode() ) { - return serialization; - } - - value = {}; - - if ( this.options.locked.property && serialization.property !== undefined ) { - value.property = serialization.property; - } else if ( !this.options.locked.property ) { - var propertyStub = this._getSelectedProperty(); - - if ( propertyStub && propertyStub.id !== undefined ) { - value.property = propertyStub.id; - } - } - - if ( this.options.locked.snaktype && serialization.snaktype !== undefined ) { - value.snaktype = serialization.snaktype; - } else if ( !this.options.locked.snaktype ) { - var snakTypeSelector = this._getSnakTypeSelector(), - snakType = snakTypeSelector && snakTypeSelector.snakType(); - if ( snakType ) { - value.snaktype = snakType; - } - } - - if ( serialization.hash ) { - value.hash = serialization.hash; - } - - return this._variation ? $.extend( this._variation.value(), value ) : value; - }, - - /** - * If a `datamodel.Snak` instance is passed, the `snakview` is updated to represent the - * `Snak`. If no parameter is supplied, the current `Snak` represented by the `snakview` is - * returned. - * - * @param {datamodel.Snak|null} [snak] - * @return {datamodel.Snak|null|undefined} - */ - snak: function ( snak ) { - if ( snak !== undefined ) { - this.value( snak || {} ); - return; - } - - if ( !this._isValid ) { - return null; - } - - var value = this.value(); - if ( value.datavalue instanceof dv.DataValue ) { - value.datavalue = { - type: value.datavalue.getType(), - value: value.datavalue.toJSON() - }; - } - - var snakDeserializer = new wbserialization.SnakDeserializer(); - try { - return snakDeserializer.deserialize( value ); - } catch ( e ) { - return null; - } - }, - - /** - * Sets/Gets the ID of the `Property` for the `Snak` represented by the `snakview`. If no - * `Property` is set, `null` is returned. - * - * @since 0.3 (setter since 0.4) - * - * @param {string|null} [propertyId] - * @return {string|null|undefined} - */ - propertyId: function ( propertyId ) { - if ( propertyId === undefined ) { - return this.value().property || null; - } else { - var value = this.value(); - - if ( propertyId !== value.property ) { - if ( propertyId === null ) { - delete value.property; - } else { - value.property = propertyId; - } - this.option( 'value', value ); - } - } - }, - - /** - * Sets/Gets the ID of the `Snak` type for the `Snak` represented by the `snakview`. If no - * `Snak` type is set, `null` is returned. - * - * @see datamodel.Snak.TYPE - * - * @param {string|null} [snakType] - * @return {string|null|undefined} - */ - snakType: function ( snakType ) { - var value = this.value(); - - if ( snakType === undefined ) { - return value.snaktype || null; - } else if ( snakType === value.snaktype ) { - return; - } - - if ( snakType === null ) { - delete value.snaktype; - } else { - // TODO: check whether given snak type is actually valid! - value.snaktype = snakType; - } - - this.option( 'value', value ); - }, - - /** - * Returns the `snakview`'s `Variation` object required for presenting the current `Snak` type. - * If a `Snak` type has not been defined yet, `null` is returned. - * - * @return {Variation|null} - */ - variation: function () { - return this._variation; - }, - - /** - * Updates the `Variation` according to the widget's current value. - */ - updateVariation: function () { - var value = this.value(), - propertyId = value ? value.property : null, - snakType = value ? value.snaktype : null, - VariationConstructor = snakType ? variations.getVariation( snakType ) : null; - - this._setDataTypeForSelectedProperty(); - - if ( this._variation - && ( !propertyId || this._variation.constructor !== VariationConstructor ) - ) { - var variationValue = this._variation.value(); - - if ( variationValue.datavalue ) { - variationValue.datavalue = { - type: variationValue.datavalue.getType(), - value: variationValue.datavalue.toJSON() - }; - } - - this._cachedValues[ this._variation.variationSnakConstructor.TYPE ] = variationValue; - - this.$snakValue.empty(); - - // clean destruction of old variation in case variation will change or property not set - this._variation.destroy(); - this._variation = null; - } - - if ( !this._variation && propertyId && VariationConstructor ) { - // Snak type has changed so we need another variation Object! - this._variation = new VariationConstructor( - new ViewState( this ), - this.$snakValue, - this.options.propertyDataTypeStore, - this.options.valueViewBuilder, - this.options.dataTypeStore - ); - - if ( !value.datavalue - && this._cachedValues[ snakType ] && this._cachedValues[ snakType ].datavalue - ) { - value.datavalue = $.extend( {}, this._cachedValues[ snakType ].datavalue ); - } - - // Update Variation with fields not directly managed by the snakview. If necessary - // within the Variation, those fields should be accessed via the Variation's - // ViewState object. - var serializationCopy = $.extend( {}, value ); - delete serializationCopy.property; - delete serializationCopy.snaktype; - this._variation.value( serializationCopy ); - } - }, - - /** - * (Re-)renders the widget. - */ - draw: function () { - this.updateHash(); - this.drawProperty(); - this.drawSnakTypeSelector(); - this.drawEntityCloneBtn(); - this.drawVariation(); - }, - - /** - * Updates the class list of the DOM element - * to contain the right wikibase-snakview-{hash} class if a hash is configured, - * and no other wikibase-snakview-{otherHash} classes. - */ - updateHash: function () { - var hash; - this.element.removeClass( function ( index, className ) { - var matches = className.match( /\bwikibase-snakview-([0-9a-fA-F]{40})?(\s|$)/g ); - return matches ? matches.join( ' ' ) : ''; - } ); - hash = this.snak() && this.snak().getHash(); - if ( hash ) { - this.element.addClass( 'wikibase-snakview-' + hash ); - } - }, - - /** - * (Re-)renders the Property DOM structure according to the current value. The `Property` DOM - * is not (re-)rendered if changing the `Property` is locked via the `locked` option and - * previously generated HTML is detected. - * - * @return {Object} jQuery.Promise - * @return {Function} return.done - * @return {Function} return.fail - */ - drawProperty: function () { - var self = this, - deferred = $.Deferred(), - propertyId = this.value().property; - - if ( this.options.locked.property - && ( this.$property.contents().length || !this.options.drawProperty ) - ) { - return deferred.resolve().promise(); - } - - this._getPropertyDOM( propertyId ) - .done( function ( $property ) { - self.$property.empty().append( $property ); - deferred.resolve(); - } ) - .fail( function () { - self.$property.empty().text( propertyId ); - deferred.reject(); - } ); - - return deferred.promise(); - }, - - /** - * Retrieves the DOM structure representing the `Property` of the `Snak` represented by the - * `snakview`. - * - * @private - * - * @param {string} [propertyId] - * @return {Object} jQuery.Promise - * @return {Function} return.done - * @return {jQuery} return.$property - * @return {Function} return.fail - */ - _getPropertyDOM: function ( propertyId ) { - var self = this, - deferred = $.Deferred(), - editable = !this.options.locked.property && this.isInEditMode(); - - if ( !propertyId ) { - if ( editable ) { - deferred.resolve( this._createPropertyDOM( '' ) ); - } else { - deferred.resolve( '' ); - } - } else { - if ( editable ) { - this.options.entityIdPlainFormatter.format( propertyId ).done( function ( propertyLabel ) { - deferred.resolve( self._createPropertyDOM( propertyLabel ) ); - } ); - } else { - // Property is set already and cannot be changed, display label only: - return this.options.entityIdHtmlFormatter.format( propertyId ); - } - } - return deferred.promise(); - }, - - /** - * Creates the DOM structure specific for a `Property`, a generic DOM - * structure or an input element. - * - * @private - * - * @param {string} propertyLabel Rendered label for the `Property` - * @return {jQuery|null} - */ - _createPropertyDOM: function ( propertyLabel ) { - var $propertyDom; - - // No Property set for this Snak, serve edit view to specify it: - var propertySelector = this._getPropertySelector(); - - // TODO: use selectedEntity() or other command to set selected entity in both cases! - if ( propertySelector ) { - // property selector in DOM already, just replace current value - var currentValue = propertySelector.widget().val(); - // Impose case-insensitivity: - if ( propertyLabel.toLowerCase() !== currentValue.toLocaleLowerCase() ) { - propertySelector.widget().val( propertyLabel ); - } - } else { - $propertyDom = this._buildPropertySelector().val( propertyLabel ); - - // propagate snakview state: - $propertyDom.data( 'entityselector' ).option( 'disabled', this.options.disabled ); - } - return $propertyDom; - }, - - drawEntityCloneBtn: function () { - var self = this; - var firstChild = this.$cloneBtn.children().first(); - var isBtnMounted = firstChild.length > 0; - - var btn; - - if ( isBtnMounted ) { - btn = firstChild; - } else { - //btn = $('') - btn = $("") - this.$cloneBtn.append(btn); - } - btn.attr('item-id',self._item_id); - btn.css("margin-left","0.5rem"); - btn.css("margin-top","1.5rem"); - btn.css("color","#0645ad"); - btn.css("background-color","white"); - btn.css("border-color","#0645ad"); - btn.css("border-radius","5px"); - btn.on('click', function () { - //api call - var WIKIBASE_SYNC_URL = "http://127.0.0.1:5000/"; - var full_endpoint = WIKIBASE_SYNC_URL + 'import-wikidata-item/' + self._item_id; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - //remove clone button - self._isCloneBtnEnabled = false; - self._item_id = ""; - self._item_description = ""; - btn.remove(); - console.log('clone button removed'); - - } - }); - }); - - if ( this._isCloneBtnEnabled ) { - btn.show(); - } else { - btn.hide(); - } - }, - - /** - * Updates the `SnakTypeSelector` for choosing the `Snak` type. The `SnakTypeSelector` DOM - * is not (re-)rendered if changing the `Snak` type is locked via the `locked` option and - * previously generated HTML is detected. - */ - drawSnakTypeSelector: function () { - if ( this.options.locked.snaktype && this.$snakTypeSelector.contents().length ) { - return; - } - - var snakTypes = variations.getCoveredSnakTypes(), - selector = this._getSnakTypeSelector(); - - if ( !this.isInEditMode() - || snakTypes.length <= 1 - || this.options.locked.snaktype - ) { - if ( selector ) { - selector.destroy(); - } - this.$snakTypeSelector.empty(); - return; // No type selector required! - } - - var snakType = this.options.value instanceof datamodel.Snak - ? this.options.value.getType() - : this.options.value.snaktype; - - if ( selector ) { - // mark current Snak type as chosen one in the menu: - selector.snakType( snakType ); - } else { - var $selector = this._buildSnakTypeSelector( snakType ); - this.$snakTypeSelector.empty().append( $selector ); - selector = $selector.data( 'snaktypeselector' ); - } - - // only show selector if a property is chosen: - this.$snakTypeSelector[ ( this.value().property ? 'show' : 'hide' ) ](); - - // propagate snakview state: - selector.option( 'disabled', this.options.disabled ); - }, - - /** - * Renders the `Variation` or placeholder text if no proper `Variation` is available. - */ - drawVariation: function () { - // property ID will be null if not in edit mode and no Snak set or if in edit mode and user - // didn't choose property yet. - var self = this, - value = this.value(), - propertyId = value ? value.property : null; - - if ( propertyId && this._variation ) { - $( this._variation ).one( 'afterdraw', function () { - if ( self.isInEditMode() ) { - self.variation().startEditing(); - } - } ); - this.variation().draw(); - } else { - // remove any remains from previous rendering or initial template (e.g. '$4') - this.$snakValue.empty(); - - if ( propertyId ) { - // property ID selected but apparently no variation available to handle it - $( '' ).text( mw.msg( 'wikibase-snakview-choosesnaktype' ) ) - .addClass( this.widgetBaseClass + '-unsupportedsnaktype' ) - .appendTo( this.$snakValue ); - // NOTE: instead of doing this here and checking everywhere whether this._variation - // is set, we could as well use variations for displaying system messages like - // this, e.g. having a UnsupportedSnakType variation which is not registered for a - // specific snak type but is known to updateVariation(). - } - } - }, - - /** - * @private - * - * @param {string|null} snakType - * @return {jQuery} - */ - _buildSnakTypeSelector: function ( snakType ) { - var self = this, - $anchor = $( '' ), - // initiate snak type selector widget which is a normal widget just without a - // jQuery.widget.bridge... - selector = new $.wikibase.snakview.SnakTypeSelector( {}, $anchor ); - - // ...add the data information nevertheless: - $anchor.data( 'snaktypeselector', selector ); - - // Set value before binding the change event handler to avoid handling first - // useless change event - selector.snakType( snakType ); - - var changeEvent = ( selector.widgetEventPrefix + 'change' ).toLowerCase(); - - // bind user interaction on selector to snakview's state: - $anchor.on( changeEvent + '.' + this.widgetName, function ( event ) { - self.updateVariation(); - self.drawVariation(); - if ( self._variation ) { - self._variation.focus(); - } - self._trigger( 'change' ); - } ); - - return $anchor; - }, - - hidePropertyLabel: function () { - this.$property.hide(); - }, - - showPropertyLabel: function () { - this.$property.show(); - }, - - _getSelectedProperty: function () { - var propertySelector = this._getPropertySelector(); - - return propertySelector && propertySelector.selectedEntity(); - }, - - _setDataTypeForSelectedProperty: function () { - var property = this._getSelectedProperty(); - - if ( property && property.datatype ) { - this.options.propertyDataTypeStore.setDataTypeForProperty( property.id, property.datatype ); - } - } - } ); - - $.extend( $.wikibase.snakview, existingSnakview ); - -}( wikibase, dataValues ) ); diff --git a/wikibase-scripts/wikibase_source_files/templates.php b/wikibase-scripts/wikibase_source_files/templates.php deleted file mode 100644 index b703e90..0000000 --- a/wikibase-scripts/wikibase_source_files/templates.php +++ /dev/null @@ -1,342 +0,0 @@ - - * - * @return array templates - */ - -return call_user_func( function() { - $templates = []; - - $templates['wikibase-entityview'] = -<< -
    $5
    -
    $6
    -
    -HTML; - - $templates['wb-entity-header-separator'] = -<< -HTML; - - $templates['wikibase-title'] = -<< - $2 - $3 - -HTML; - - $templates['wb-section-heading'] = -<<$1 -HTML; - - // empty toc to help MobileFrontend - $templates['wikibase-toc'] = -<<
    -HTML; - - $templates['wikibase-statementgrouplistview'] = -<<$1 -HTML; - - $templates['wikibase-statementgroupview'] = -<< -
    -
    $1
    -
    $5
    -
    - $2 - -HTML; - - $templates['wikibase-statementlistview'] = -<< -
    - $1 -
    - $2 - -HTML; - - $templates['wikibase-snakview'] = -<< -
    -
    $1
    -
    $5
    -
    -
    -
    -
    -
    $3
    -
    -
    -
    - -HTML; - - $templates['wikibase-statementview'] = -<< -
    $3
    -
    -
    $4
    -
    $5
    -
    - $6 -
    -
    $7
    -
    $8
    -
    - -HTML; - - $templates['wikibase-rankselector'] = -<< - - -HTML; - - $templates['wikibase-referenceview'] = -<< -
    -
    $2
    - -HTML; - - $templates['wikibase-listview'] = -<<$1 -HTML; - - $templates['wikibase-snaklistview'] = -<< -
    $1
    - -HTML; - - $templates['wikibase-labelview'] = -<< -
    - $2 - $3 -
    - -HTML; - - $templates['wikibase-descriptionview'] = -<< -
    - $2 - $3 -
    - -HTML; - - $templates['wikibase-aliasesview'] = -<< -
      $2
    - $3 - -HTML; - - $templates['wikibase-aliasesview-list-item'] = -<<$1 -HTML; - - $templates['wikibase-entitytermsview'] = -<< - $1 - $4 -
    $2
    - -HTML; - - $templates['wikibase-entitytermsview-heading'] = -<< - $1 - -HTML; - - $templates['wikibase-entitytermsview-heading-part'] = -<<$3 -HTML; - - $templates['wikibase-entitytermsview-aliases'] = -<<$1
-HTML; - - $templates['wikibase-entitytermsview-aliases-alias'] = -<<$1 -HTML; - - $templates['wikibase-entitytermsforlanguagelistview'] = -<< - - - $1 - $2 - $3 - $4 - - - $5 - -HTML; - - $templates['wikibase-entitytermsforlanguageview'] = -<< - <$9 class="wikibase-entitytermsforlanguageview-language">$4 - <$2 class="wikibase-entitytermsforlanguageview-label">$5 - <$2 class="wikibase-entitytermsforlanguageview-description">$6 - <$2 class="wikibase-entitytermsforlanguageview-aliases">$7 - $8 - -HTML; - - $templates['wikibase-sitelinkgrouplistview'] = -<<$1 -HTML; - - $templates['wikibase-sitelinkgroupview'] = -<< -
-
- - $6 -
-
-
- $4 -
- -HTML; - - $templates['wikibase-sitelinklistview'] = -<< -
    $1
- -HTML; - - $templates['wikibase-sitelinkview'] = -<< - - $2 - $4 - -HTML; - - $templates['wikibase-sitelinkview-pagename'] = -<<$2$3 -HTML; - - $templates['wikibase-sitelinkview-unknown'] = -<< - $1 - $2 - -HTML; - - $templates['wb-badge'] = -<< -HTML; - - $templates['wikibase-badgeselector'] = -<<$1 -HTML; - - $templates['wikibase-propertyview-datatype'] = -<< -
$1
- -HTML; - - $templates['wikibase-toolbar-item'] = -<<$1 -HTML; - - $templates['wikibase-toolbar-button'] = -<<$3 -HTML; - - $templates['wikibase-toolbar'] = -<<$2 -HTML; - - $templates['wikibase-toolbar-container'] = -<<$1 -HTML; - -// Helper template for styling -// TODO: Remove template - $templates['wikibase-toolbar-wrapper'] = -<<$1 -HTML; - - $templates['wikibase-toolbar-bracketed'] = -<< -
✕
-
$1
- -HTML; - - $templates['wikibase-pageimage'] = -<< -
-   -
- -HTML; - - return $templates; -} ); From 4f63bf8f7acdfffb9f8ad9039034fd64d9c26166 Mon Sep 17 00:00:00 2001 From: mez Date: Wed, 6 Jul 2022 10:39:30 +0200 Subject: [PATCH 36/50] clear console logs --- main.py | 2 +- wikibase-scripts/boilerplate-extension/init.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 65386e8..6e47026 100644 --- a/main.py +++ b/main.py @@ -50,7 +50,7 @@ def get(self, q_id): from api_import_one import mth_import_one, mth_import_one_without_statements response = mth_import_one_without_statements(q_id) - # print(response) + # print(response) if response: payload = {"status_code": 200, "message": "Import successful", "pid": response} else: diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibase-scripts/boilerplate-extension/init.js index aab6e60..6a2bae3 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibase-scripts/boilerplate-extension/init.js @@ -180,7 +180,7 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - console.log(data); + //console.log(data); if (data.pid) { $(self.focused).siblings('p').remove(); id = data.pid; @@ -301,7 +301,7 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - console.log("response: ",data); + //console.log("response: ",data); //window.history.back(); window.location.replace('http://localhost/wiki/item:'+data.pid); //window.location.replace('https://gmail.com'); @@ -349,7 +349,7 @@ function createSynButton(_context) { }, success: function (data) { if (data) { - console.log(data); + //console.log(data); location.reload(); } From fcb16bc120891579fd3269cfd896e4c37fa5b8dd Mon Sep 17 00:00:00 2001 From: mez Date: Mon, 11 Jul 2022 15:40:36 +0200 Subject: [PATCH 37/50] extension updates --- main.py | 92 ++++++----- user-config.py | 1 + .../boilerplate-extension/LocalSettings.php | 81 ---------- .../Hooks.php | 5 +- .../extension.json | 10 +- .../init.js | 148 +++++++----------- 6 files changed, 116 insertions(+), 221 deletions(-) delete mode 100644 wikibase-scripts/boilerplate-extension/LocalSettings.php rename {wikibase-scripts/boilerplate-extension => wikibasesync-extension}/Hooks.php (93%) rename {wikibase-scripts/boilerplate-extension => wikibasesync-extension}/extension.json (84%) rename {wikibase-scripts/boilerplate-extension => wikibasesync-extension}/init.js (72%) diff --git a/main.py b/main.py index 6e47026..ef7896a 100644 --- a/main.py +++ b/main.py @@ -1,10 +1,14 @@ import socket +import sys + import requests from flask import Flask from flask_restful import Api, Resource from flask_cors import CORS, cross_origin from threading import Thread +user_config = __import__("user-config") + app = Flask(__name__) CORS(app) @@ -26,11 +30,14 @@ def handle(): t = Thread(target=handle) return t - def get(self, q_id): - t = self.import_thread_spinner(q_id) - t.start() - t.join() - payload = {"status_code": 200, "completed": True, "message": "Import process complete"} + def get(self, q_id, api_key): + if is_authorised(api_key): + t = self.import_thread_spinner(q_id) + t.start() + t.join() + payload = {"status_code": 200, "completed": True, "message": "Import process complete"} + else: + payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload @@ -43,24 +50,27 @@ def handle(): response = mth_import_one_without_statements(query_id) t = Thread(target=handle) return t - def get(self, q_id): + def get(self, q_id, api_key): # #from api_import_one import mth_import_one # self.import_thread_spinner(q_id).start() # #response = mth_import_one(q_id) - from api_import_one import mth_import_one, mth_import_one_without_statements - response = mth_import_one_without_statements(q_id) - # print(response) - if response: - payload = {"status_code": 200, "message": "Import successful", "pid": response} + if is_authorised(api_key): + from api_import_one import mth_import_one, mth_import_one_without_statements + response = mth_import_one_without_statements(q_id) + # print(response) + if response: + payload = {"status_code": 200, "message": "Import successful", "pid": response} + else: + payload = {"status_code": 500, + "message": "Import could not be completed"} else: - payload = {"status_code": 500, - "message": "Import could not be completed"} + payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload class WikiDataQuery(Resource): - def get(self, query_string, query_type): + def get(self, query_string, query_type, api_key): # general english # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ @@ -70,42 +80,52 @@ def get(self, query_string, query_type): # british english # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" - - response = requests.get(url) - response = response.json() - if response: - payload = {"status_code": 200, "response": response} + if is_authorised(api_key): + response = requests.get(url) + response = response.json() + if response: + payload = {"status_code": 200, "response": response} + else: + payload = {"status_code": 500, + "message": "Import could not be completed"} else: - payload = {"status_code": 500, - "message": "Import could not be completed"} + payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload class WikibaseQuery(Resource): - def get(self, query_string): + def get(self, query_string, api_key): # general english url = "http://localhost/w/api.php?action=wbsearchentities&search=" + \ query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" - - # british english - # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" - - response = requests.get(url) - response = response.json() - if response: - payload = {"status_code": 200, "response": response} + if is_authorised(api_key): + # british english + # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" + + response = requests.get(url) + response = response.json() + if response: + payload = {"status_code": 200, "response": response} + else: + payload = {"status_code": 500, + "message": "Import could not be completed"} else: - payload = {"status_code": 500, - "message": "Import could not be completed"} + payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload +def is_authorised(api_key): + if str(user_config.apiKey) == api_key: + return True + else: + return False + # ROUTES api.add_resource(Index, "/") -api.add_resource(Sync, "/sync/") -api.add_resource(ImportOne, "/import-wikidata-item/") -api.add_resource(WikiDataQuery, "/remote-wikidata-query//") -api.add_resource(WikibaseQuery, "/local-wikibase-query/") +api.add_resource(Sync, "/sync//") +api.add_resource(ImportOne, "/import-wikidata-item//") +api.add_resource(WikiDataQuery, "/remote-wikidata-query///") +api.add_resource(WikibaseQuery, "/local-wikibase-query//") if __name__ == '__main__': diff --git a/user-config.py b/user-config.py index 0476818..7bc4374 100644 --- a/user-config.py +++ b/user-config.py @@ -9,3 +9,4 @@ maxthrottle = 0 max_retries = 100 #verbose_output = True +apiKey = 123456 diff --git a/wikibase-scripts/boilerplate-extension/LocalSettings.php b/wikibase-scripts/boilerplate-extension/LocalSettings.php deleted file mode 100644 index 389186b..0000000 --- a/wikibase-scripts/boilerplate-extension/LocalSettings.php +++ /dev/null @@ -1,81 +0,0 @@ - '/var/log/mediawiki/resourceloader.log', - 'exception' => '/var/log/mediawiki/exception.log', - 'error' => '/var/log/mediawiki/error.log', -); - -## Site Settings -# TODO pass in the rest of this with env vars? -$wgServer = WebRequest::detectServer(); -$wgShellLocale = "en_US.utf8"; -$wgLanguageCode = "en"; -$wgSitename = "wikibase-docker"; -$wgMetaNamespace = "Project"; -# Configured web paths & short URLs -# This allows use of the /wiki/* path -## https://www.mediawiki.org/wiki/Manual:Short_URL -$wgScriptPath = "/w"; // this should already have been configured this way -$wgArticlePath = "/wiki/$1"; - - -#Set Secret -$wgSecretKey = "some-secret-key"; - -## RC Age -# https://www.mediawiki.org/wiki/Manual: -# Items in the recentchanges table are periodically purged; entries older than this many seconds will go. -# The query service (by default) loads data from recent changes -# Set this to 1 year to avoid any changes being removed from the RC table over a shorter period of time. -$wgRCMaxAge = 365 * 24 * 3600; - -wfLoadSkin( 'Vector' ); -wfLoadExtension( 'BoilerPlate' ); -// T276905 - default set in Dockerfile -$wgJobRunRate = 0; - -$wgEnableUploads = false; - -$wgUploadDirectory = "/var/www/html/images"; - -## Wikibase Repository -wfLoadExtension( 'WikibaseRepository', "$IP/extensions/Wikibase/extension-repo.json" ); -require_once "$IP/extensions/Wikibase/repo/ExampleSettings.php"; - -## Wikibase Client -wfLoadExtension( 'WikibaseClient', "$IP/extensions/Wikibase/extension-client.json" ); -require_once "$IP/extensions/Wikibase/client/ExampleSettings.php"; - -#Pingback -$wgWBRepoSettings['wikibasePingback'] = false; - -foreach (glob("LocalSettings.d/*.php") as $filename) -{ - include $filename; -} - -//EXTENSIONS SETTINGS -$wgShowExceptionDetails = true; - -wfLoadExtension( 'WikibaseSync' ); -$wgWikibaseSyncUrl = "http://127.0.0.1:5000"; -$wgPID = "P1"; -$wgQID = "P2"; diff --git a/wikibase-scripts/boilerplate-extension/Hooks.php b/wikibasesync-extension/Hooks.php similarity index 93% rename from wikibase-scripts/boilerplate-extension/Hooks.php rename to wikibasesync-extension/Hooks.php index 94e9d24..ccf525e 100644 --- a/wikibase-scripts/boilerplate-extension/Hooks.php +++ b/wikibasesync-extension/Hooks.php @@ -43,8 +43,9 @@ public function onBeforePageDisplay( $out, $skin ): void { public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { $vars['wgVisualEditor'] =[ "wikibasesync_server_url" => $config->get( 'WikibaseSyncUrl' ), - "PID" => $config->get( 'PID' ), - "QID" => $config->get( 'QID' ), + "api_key" => $config->get('ApiKey') + // "PID" => $config->get( 'PID' ), + // "QID" => $config->get( 'QID' ), ]; } } diff --git a/wikibase-scripts/boilerplate-extension/extension.json b/wikibasesync-extension/extension.json similarity index 84% rename from wikibase-scripts/boilerplate-extension/extension.json rename to wikibasesync-extension/extension.json index 6d3761f..0eddc11 100644 --- a/wikibase-scripts/boilerplate-extension/extension.json +++ b/wikibasesync-extension/extension.json @@ -4,7 +4,7 @@ "mez" ], "url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate", - "descriptionmsg": "This is a Wikibase extension to use and sync entities between Wikibases", + "descriptionmsg": "This is a Wikibase extentsion to use and sync entities between Wikibases", "license-name": "GPL-2.0-or-later", "type": "other", "requires": { @@ -18,12 +18,8 @@ "description": "wikibasesync url", "value": true }, - "PID": { - "description": "PID", - "value": true - }, - "QID": { - "description": "QID", + "apiKey": { + "description": "API Key to wikibase sync", "value": true } }, diff --git a/wikibase-scripts/boilerplate-extension/init.js b/wikibasesync-extension/init.js similarity index 72% rename from wikibase-scripts/boilerplate-extension/init.js rename to wikibasesync-extension/init.js index 6a2bae3..8228406 100644 --- a/wikibase-scripts/boilerplate-extension/init.js +++ b/wikibasesync-extension/init.js @@ -7,8 +7,11 @@ var conf = mw.config.get('wgVisualEditor'); mw.boilerPlate = {}; var wikidataResults = []; var WIKIBASE_SYNC_URL = conf.wikibasesync_server_url; +var API_KEY = conf.api_key; //console.log( conf); +var count = 0; + var datamodel = require( 'wikibase.datamodel' ); $.wikibase.statementgroupview.prototype._createStatementlistview = function () { @@ -43,33 +46,20 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { self._trigger('afterremove'); }); - //self.$cloneBtn.text('hello world'); + var _wikibasePropertyKey = ""; if (self.value()) { _wikibasePropertyKey = self.value().getKey(); - } - - - if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { - self.wikibasePropertyKey = _wikibasePropertyKey; - // Only attach button for wikidata pid or qid properties which are always P1 and P2 - //self.$propertyLabel.text(''); - createSynButton(self) - // btn = $("") - // self.$cloneBtn.append(btn); - - // //console.log("val",self.value()); - // //var _wikibasePropertyValue = ""; - // var _wikibasePropertyValue = self.value().getItemContainer()._items[0]._claim._mainSnak._value._value; - // self.wikibasePropertyValue = _wikibasePropertyValue; - - // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); - - } else { - //self.$propertyLabel.text('') + //PREFERRED APPROACH + if ($("a:contains('Wikidata QID')")) { + if (count == 0){ + createSyncButtons(self); + count = count + 1; + } + }; } - // console.log(JSON.stringify(self.options, null, 2)); + }; $.wikibase.entityselector.prototype._initDefaultSource = function () { @@ -93,7 +83,7 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { data: self._getSearchApiParameters( term ), success: function(data){ $.ajax({ - url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type, + url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type + "/" + API_KEY, crossDomain: true, headers: { "Access-Control-Allow-Origin": "*", @@ -126,18 +116,11 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { } } - //TODO MERGE THE WIKIDATA RESULTS WITH RESPONSE SEARCH - // console.log("hooksResults"); - // console.log(hookResults); - // console.log("wikidataResults"); - // console.log(wikidataResults); - // console.log("wikibase results"); - // console.log(response.search); - // UPDATE THE TITLE AND SOURCE TO REFELECT WIKIDATA + + // UPDATE THE TITLE AND SOURCE TO REFLECT WIKIDATA // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, response.search) //console.log("updatedWikidataResults", updatedWikidataResults); - //self._combineResults( hookResults, response.search ).then( function ( results ) { self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { //console.log(results) deferred.resolve( @@ -157,8 +140,6 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { }; $.wikibase.entityselector.prototype._select = function ( entityStub ) { - //conf = mw.config.get( 'wgWikibaseSync' ); - //console.log("conf",conf) var id = entityStub && entityStub.id; this._selectedEntity = entityStub; @@ -170,7 +151,7 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { //remote source, clone //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id + "/" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -180,11 +161,10 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - //console.log(data); + console.log(data); if (data.pid) { $(self.focused).siblings('p').remove(); id = data.pid; - //console.log(self._selectedEntity); if (self.options.type.toLowerCase() == "property") { self._selectedEntity.id = id; @@ -200,8 +180,6 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { self._selectedEntity.pageid = null; } - //this._selectedEntity = { id: id }; - //TODO self._trigger( 'selected', null, [ id ] ); } } @@ -212,55 +190,6 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { } }; -// overwrite search result default behaviour -// $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { -// var PARENT = $.wikibase.entityselector; -// PARENT.prototype._initMenu.apply( this, arguments ); - -// if ( this.options.suggestionsPlaceholder ) { -// ooMenu.option( 'customItems' ).unshift( this.options.suggestionsPlaceholder ); -// } - -// ooMenu.element.addClass( 'wikibase-entitysearch-list' ); - -// $( ooMenu ) -// .off( 'selected' ) -// .on( 'selected.entitysearch', function ( event, item ) { -// event.preventDefault(); -// var itemEntityStub = item.getEntityStub(); - -// //clone if item is sourced from wikidata -// if (itemEntityStub.repository.toLowerCase() === "wikidata") { -// console.log("f: ",itemEntityStub); - -// //api call -// var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id; -// $.ajax({ -// url: full_endpoint, -// crossDomain: true, -// // async: false, -// headers: { -// "Access-Control-Allow-Origin": "*", -// "Access-Control-Request-Headers3": "x-requested-with" -// }, -// success: function (data) { -// console.log("response: ",data); -// window.location.href = 'http://localhost/wiki/item:'+data.pid; - -// } -// }); -// }else{ -// if ( event.originalEvent -// && /^key/.test( event.originalEvent.type ) -// && !( item instanceof $.ui.ooMenu.CustomItem ) -// ) { -// window.location.href = item.getEntityStub().url; -// } -// } -// } ); - -// return ooMenu; -// } // overwrite search result default behaviour sec $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { @@ -284,13 +213,13 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { var itemEntityStub = item.getEntityStub(); if (itemEntityStub) { if (itemEntityStub.repository.toLowerCase() === "wikidata") { - //console.log("f: ",itemEntityStub); + $("a[tabindex='-1']").click(function(e) { e.preventDefault(); }); //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id + "/" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -301,16 +230,14 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { "Access-Control-Request-Headers3": "x-requested-with" }, success: function (data) { - //console.log("response: ",data); + console.log("response: ",data); //window.history.back(); window.location.replace('http://localhost/wiki/item:'+data.pid); - //window.location.replace('https://gmail.com'); } }); }else{ window.location.href = item.getEntityStub().url; - //window.location.replace('https://twitter.com'); } } } @@ -319,8 +246,9 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { return ooMenu; } -function createSynButton(_context) { +function createSyncButtons(_context) { btn = $("") + btn2 = $("") //btn.css("margin-top", ".5rem"); btn.css("margin-left", "5px"); btn.css("color", "#0645ad"); @@ -328,7 +256,14 @@ function createSynButton(_context) { btn.css("border-color", "#0645ad"); btn.css("border-radius", "5px"); + //btn2.css("margin-left", "5px"); + btn2.css("color", "#0645ad"); + btn2.css("background-color", "white"); + btn2.css("border-color", "#0645ad"); + btn2.css("border-radius", "5px"); + _context.$propertyLabel.append(btn); + _context.$propertyLabel.append(btn2); var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; self.wikibasePropertyValue = _wikibasePropertyValue; @@ -338,7 +273,30 @@ function createSynButton(_context) { btn.on('click', function () { btn.text("syncing..."); //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue; + full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data) { + //console.log(data); + location.reload(); + } + + + } + }); + }); + + btn2.on('click', function () { + btn2.text("syncing..."); + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, From f32c0fafab574abe57031d472041ea0f69244f1e Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 12 Jul 2022 11:12:10 +0200 Subject: [PATCH 38/50] refactor and updates --- main.py | 32 ++++++++++++++++++++++---------- wikibasesync-extension/init.js | 20 ++++++++++++++------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index ef7896a..526367a 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import sys import requests -from flask import Flask +from flask import Flask, request from flask_restful import Api, Resource from flask_cors import CORS, cross_origin from threading import Thread @@ -30,14 +30,16 @@ def handle(): t = Thread(target=handle) return t - def get(self, q_id, api_key): + def get(self): + q_id = request.args.get('q_id') + api_key = request.args.get('api_key') if is_authorised(api_key): t = self.import_thread_spinner(q_id) t.start() t.join() payload = {"status_code": 200, "completed": True, "message": "Import process complete"} else: - payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} + payload = {"status_code": 403, "completed": False, "message": "Unauthorised Access"} return payload @@ -50,7 +52,10 @@ def handle(): response = mth_import_one_without_statements(query_id) t = Thread(target=handle) return t - def get(self, q_id, api_key): + def get(self): + q_id = request.args.get('q_id') + api_key = request.args.get('api_key') + # #from api_import_one import mth_import_one # self.import_thread_spinner(q_id).start() # #response = mth_import_one(q_id) @@ -70,7 +75,10 @@ def get(self, q_id, api_key): class WikiDataQuery(Resource): - def get(self, query_string, query_type, api_key): + def get(self): + query_string = request.args.get('query_string') + query_type = request.args.get('query_type') + api_key = request.args.get('api_key') # general english # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ @@ -93,7 +101,9 @@ def get(self, query_string, query_type, api_key): return payload class WikibaseQuery(Resource): - def get(self, query_string, api_key): + def get(self): + query_string = request.args.get('q_id') + api_key = request.args.get('api_key') # general english url = "http://localhost/w/api.php?action=wbsearchentities&search=" + \ @@ -122,10 +132,12 @@ def is_authorised(api_key): # ROUTES api.add_resource(Index, "/") -api.add_resource(Sync, "/sync//") -api.add_resource(ImportOne, "/import-wikidata-item//") -api.add_resource(WikiDataQuery, "/remote-wikidata-query///") -api.add_resource(WikibaseQuery, "/local-wikibase-query//") +# api.add_resource(WikiDataQuery, "/remote-wikidata-query///") + +api.add_resource(Sync, "/sync") +api.add_resource(ImportOne, "/import-wikidata-item") +api.add_resource(WikiDataQuery, "/remote-wikidata-query") +api.add_resource(WikibaseQuery, "/local-wikibase-query") if __name__ == '__main__': diff --git a/wikibasesync-extension/init.js b/wikibasesync-extension/init.js index 8228406..628bcd5 100644 --- a/wikibasesync-extension/init.js +++ b/wikibasesync-extension/init.js @@ -83,7 +83,8 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { data: self._getSearchApiParameters( term ), success: function(data){ $.ajax({ - url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type + "/" + API_KEY, + // url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type + "/" + API_KEY, + url: WIKIBASE_SYNC_URL + '/remote-wikidata-query?query_string=' + term + "&query_type=" + self.options.type + "&api_key=" + API_KEY, crossDomain: true, headers: { "Access-Control-Allow-Origin": "*", @@ -151,7 +152,8 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { //remote source, clone //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id + "/" + API_KEY; + // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id + "/" + API_KEY; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + id + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -219,7 +221,8 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { }); //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id + "/" + API_KEY; + // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id + "/" + API_KEY; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + itemEntityStub.id + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -250,13 +253,16 @@ function createSyncButtons(_context) { btn = $("") btn2 = $("") //btn.css("margin-top", ".5rem"); - btn.css("margin-left", "5px"); + btn.css("display", "block"); + //btn.css("margin-left", "5px"); btn.css("color", "#0645ad"); btn.css("background-color", "white"); btn.css("border-color", "#0645ad"); btn.css("border-radius", "5px"); //btn2.css("margin-left", "5px"); + btn2.css("margin-top", ".3rem"); + btn2.css("display", "block"); btn2.css("color", "#0645ad"); btn2.css("background-color", "white"); btn2.css("border-color", "#0645ad"); @@ -273,7 +279,8 @@ function createSyncButtons(_context) { btn.on('click', function () { btn.text("syncing..."); //api call - full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; + // full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; + full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -296,7 +303,8 @@ function createSyncButtons(_context) { btn2.on('click', function () { btn2.text("syncing..."); //api call - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; + // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, From 607edde842187be45b6b7becf289d8f785bc7eb5 Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 19 Jul 2022 16:03:09 +0200 Subject: [PATCH 39/50] wikibase extension reversal and updates --- wikibasesync-extension/Hooks.php | 4 +- wikibasesync-extension/extension.json | 10 ++- wikibasesync-extension/init.js | 119 ++++++++++++++++++++++++-- 3 files changed, 124 insertions(+), 9 deletions(-) diff --git a/wikibasesync-extension/Hooks.php b/wikibasesync-extension/Hooks.php index ccf525e..6d9d5f7 100644 --- a/wikibasesync-extension/Hooks.php +++ b/wikibasesync-extension/Hooks.php @@ -44,8 +44,8 @@ public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $co $vars['wgVisualEditor'] =[ "wikibasesync_server_url" => $config->get( 'WikibaseSyncUrl' ), "api_key" => $config->get('ApiKey') - // "PID" => $config->get( 'PID' ), - // "QID" => $config->get( 'QID' ), + "PID" => $config->get( 'PID' ), + "QID" => $config->get( 'QID' ), ]; } } diff --git a/wikibasesync-extension/extension.json b/wikibasesync-extension/extension.json index 0eddc11..7d152a1 100644 --- a/wikibasesync-extension/extension.json +++ b/wikibasesync-extension/extension.json @@ -21,7 +21,15 @@ "apiKey": { "description": "API Key to wikibase sync", "value": true - } + }, + "PID": { + "description": "PID", + "value": true + }, + "QID": { + "description": "QID", + "value": true + } }, "HookHandlers": { "WikibaseSyncHooks": { diff --git a/wikibasesync-extension/init.js b/wikibasesync-extension/init.js index 628bcd5..f25bf55 100644 --- a/wikibasesync-extension/init.js +++ b/wikibasesync-extension/init.js @@ -52,14 +52,30 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { _wikibasePropertyKey = self.value().getKey(); //PREFERRED APPROACH - if ($("a:contains('Wikidata QID')")) { - if (count == 0){ - createSyncButtons(self); - count = count + 1; - } - }; + // if ($("a:contains('Wikidata QID')")) { + // if (count == 0){ + // createSyncButtons(self); + // count = count + 1; + // } + // }; } + //ALTERNATIVE APPROACH + if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { + self.wikibasePropertyKey = _wikibasePropertyKey; + // Only attach button for wikidata pid or qid properties which are always P1 and P2 + //self.$propertyLabel.text(''); + createSyncButton(self); + createSyncLabelButton(self); + + + // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); + + } else { + //self.$propertyLabel.text('') + } + // console.log(JSON.stringify(self.options, null, 2)); + }; $.wikibase.entityselector.prototype._initDefaultSource = function () { @@ -325,6 +341,97 @@ function createSyncButtons(_context) { }); }; +function createSyncButton(_context) { + btn = $("") + //btn.css("margin-top", ".5rem"); + btn.css("display", "block"); + //btn.css("margin-left", "5px"); + btn.css("color", "#0645ad"); + btn.css("background-color", "white"); + btn.css("border-color", "#0645ad"); + btn.css("border-radius", "5px"); + + _context.$propertyLabel.append(btn); + + var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + self.wikibasePropertyValue = _wikibasePropertyValue; + + //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + + btn.on('click', function () { + btn.text("syncing..."); + btn.prop("disabled",true); + //disable other sync button + $('#wbsynclabel').prop("disabled",true); + //api call + // full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; + full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data) { + console.log(data); + location.reload(); + } + + + } + }); + }); +}; + +function createSyncLabelButton(_context) { + btn2 = $("") + //btn2.css("margin-left", "5px"); + btn2.css("margin-top", ".3rem"); + btn2.css("display", "block"); + btn2.css("color", "#0645ad"); + btn2.css("background-color", "white"); + btn2.css("border-color", "#0645ad"); + btn2.css("border-radius", "5px"); + + _context.$propertyLabel.append(btn2); + + var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + self.wikibasePropertyValue = _wikibasePropertyValue; + + //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + + btn2.on('click', function () { + btn2.text("syncing..."); + btn2.prop("disabled",true); + //disable other sync button + $('#wbsync').prop("disabled",true); + //api call + // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data) { + console.log(data); + location.reload(); + } + + + } + }); + }); +}; + + function removeExistingRecordsFromWikidataResults(wikidataResults, localResults){ if (!wikidataResults || !localResults){ From 7267504f4264ca35eeb03798d3d490325cf466b9 Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Tue, 19 Jul 2022 17:15:29 +0200 Subject: [PATCH 40/50] Clean code that is not needed --- main.py | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/main.py b/main.py index 526367a..455b79b 100644 --- a/main.py +++ b/main.py @@ -21,7 +21,7 @@ def get(self): return {"data": "Welcome to the index"} -# dummy +# class that imports all statements from Wikidata class Sync(Resource): def import_thread_spinner(self, query_id): def handle(): @@ -100,29 +100,6 @@ def get(self): payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload -class WikibaseQuery(Resource): - def get(self): - query_string = request.args.get('q_id') - api_key = request.args.get('api_key') - - # general english - url = "http://localhost/w/api.php?action=wbsearchentities&search=" + \ - query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" - if is_authorised(api_key): - # british english - # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" - - response = requests.get(url) - response = response.json() - if response: - payload = {"status_code": 200, "response": response} - else: - payload = {"status_code": 500, - "message": "Import could not be completed"} - else: - payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} - return payload - def is_authorised(api_key): if str(user_config.apiKey) == api_key: return True @@ -132,15 +109,10 @@ def is_authorised(api_key): # ROUTES api.add_resource(Index, "/") -# api.add_resource(WikiDataQuery, "/remote-wikidata-query///") - api.add_resource(Sync, "/sync") api.add_resource(ImportOne, "/import-wikidata-item") api.add_resource(WikiDataQuery, "/remote-wikidata-query") -api.add_resource(WikibaseQuery, "/local-wikibase-query") if __name__ == '__main__': app.run(host='0.0.0.0', debug=True) - -# See PyCharm help at https://www.jetbrains.com/help/pycharm/ From 5cbd6e6d7aaae1eaee34da11c91e744caebb120b Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Tue, 19 Jul 2022 17:30:04 +0200 Subject: [PATCH 41/50] Refactoring code --- api_import_one.py | 61 ------------------------------ import_one.py | 46 +++++++++++----------- main.py | 14 ++----- util/PropertyWikidataIdentifier.py | 2 - util/util.py | 16 ++------ 5 files changed, 30 insertions(+), 109 deletions(-) delete mode 100644 api_import_one.py diff --git a/api_import_one.py b/api_import_one.py deleted file mode 100644 index 635be1b..0000000 --- a/api_import_one.py +++ /dev/null @@ -1,61 +0,0 @@ -# configuration for pywikibot -import sys - -import pywikibot - - -def mth_import_one(arg): - # connect to the wikibase - wikibase = pywikibot.Site("my", "my") - wikibase_repo = wikibase.data_repository() - wikibase_repo.login() - - # connect to wikidata - wikidata = pywikibot.Site("wikidata", "wikidata") - wikidata_repo = wikidata.data_repository() - - from util.util import WikibaseImporter - wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) - - # import a single item or property - print(f"Importing {arg}") - if arg.startswith("Q"): - print("before get") - wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) - wikidata_item.get() - print("after get") - wikibase_importer.change_item(wikidata_item, wikibase_repo, True) - elif arg.startswith("P"): - wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) - wikidata_property.get() - wikibase_importer.change_property(wikidata_property, wikibase_repo, True) - return True - -def mth_import_one_without_statements(arg): - # connect to the wikibase - wikibase = pywikibot.Site("my", "my") - wikibase_repo = wikibase.data_repository() - wikibase_repo.login() - - # connect to wikidata - wikidata = pywikibot.Site("wikidata", "wikidata") - wikidata_repo = wikidata.data_repository() - - from util.util import WikibaseImporter - wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) - - # import a single item or property - print(f"Importing {arg}") - if arg.startswith("Q"): - print("before get") - wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) - wikidata_item.get() - print("after get") - item = wikibase_importer.change_item(wikidata_item, wikibase_repo, False) - elif arg.startswith("P"): - wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) - wikidata_property.get() - item = wikibase_importer.change_property(wikidata_property, wikibase_repo, False) - if item: - return item - return True \ No newline at end of file diff --git a/import_one.py b/import_one.py index 74be650..94cebbc 100644 --- a/import_one.py +++ b/import_one.py @@ -3,29 +3,31 @@ import pywikibot +def import_one(arg, import_statements = True): + # connect to the wikibase + wikibase = pywikibot.Site("my", "my") + wikibase_repo = wikibase.data_repository() + wikibase_repo.login() -#connect to the wikibase -wikibase = pywikibot.Site("my", "my") -wikibase_repo = wikibase.data_repository() -wikibase_repo.login() + # connect to wikidata + wikidata = pywikibot.Site("wikidata", "wikidata") + wikidata_repo = wikidata.data_repository() -#connect to wikidata -wikidata = pywikibot.Site("wikidata", "wikidata") -wikidata_repo = wikidata.data_repository() + from util.util import WikibaseImporter + wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) -from util.util import WikibaseImporter -wikibase_importer = WikibaseImporter(wikibase_repo,wikidata_repo) + # import a single item or property + print(f"Importing {arg}") + if arg.startswith("Q"): + print("before get") + wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) + wikidata_item.get() + print("after get") + return wikibase_importer.change_item(wikidata_item, wikibase_repo, import_statements) + elif arg.startswith("P"): + wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) + wikidata_property.get() + return wikibase_importer.change_property(wikidata_property, wikibase_repo, import_statements) -#import a single item or property -arg = sys.argv[1] -print(f"Importing {arg}") -if arg.startswith("Q"): - print("before get") - wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) - wikidata_item.get() - print("after get") - wikibase_importer.change_item(wikidata_item, wikibase_repo, True) -elif arg.startswith("P"): - wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) - wikidata_property.get() - wikibase_importer.change_property(wikidata_property, wikibase_repo, True) +print(f"Importing {arg}", sys.argv[1]) +import_one(args) \ No newline at end of file diff --git a/main.py b/main.py index 455b79b..f170cf1 100644 --- a/main.py +++ b/main.py @@ -14,8 +14,6 @@ api = Api(app) - -# RESOURCES: CONTROLLERS AND ACTIONS class Index(Resource): def get(self): return {"data": "Welcome to the index"} @@ -25,8 +23,7 @@ def get(self): class Sync(Resource): def import_thread_spinner(self, query_id): def handle(): - from api_import_one import mth_import_one, mth_import_one_without_statements - response = mth_import_one(query_id) + response = import_one(query_id).getID() t = Thread(target=handle) return t @@ -48,21 +45,16 @@ class ImportOne(Resource): def import_thread_spinner(self, query_id): def handle(): - from api_import_one import mth_import_one, mth_import_one_without_statements - response = mth_import_one_without_statements(query_id) + response = import_one(query_id, import_statements = False) t = Thread(target=handle) return t def get(self): q_id = request.args.get('q_id') api_key = request.args.get('api_key') - # #from api_import_one import mth_import_one - # self.import_thread_spinner(q_id).start() - # #response = mth_import_one(q_id) - if is_authorised(api_key): from api_import_one import mth_import_one, mth_import_one_without_statements - response = mth_import_one_without_statements(q_id) + response = mth_import_one_without_statements(q_id).getID() # print(response) if response: payload = {"status_code": 200, "message": "Import successful", "pid": response} diff --git a/util/PropertyWikidataIdentifier.py b/util/PropertyWikidataIdentifier.py index 28dc41c..8ad6bba 100644 --- a/util/PropertyWikidataIdentifier.py +++ b/util/PropertyWikidataIdentifier.py @@ -8,10 +8,8 @@ def wiki_item_exists(wikibase_repo, label): params = {'action': 'wbsearchentities', 'format': 'json', 'language': 'en', 'type': 'property', 'limit':1, 'search': label} - print(params) request = api.Request(site=wikibase_repo, parameters=params) result = request.submit() - print(result) return result['search'] diff --git a/util/util.py b/util/util.py index 9f02bb6..d667b0f 100644 --- a/util/util.py +++ b/util/util.py @@ -1074,7 +1074,7 @@ def change_claims(self, wikidata_item, wikibase_item): wikidata_claim = c.toJSON() found_equal_value = False wikidata_property_id = wikidata_claim.get('mainsnak').get('property') - print(wikidata_property_id) + # print(wikidata_property_id) if wikibase_item.getID().startswith("Q") or wikibase_item.getID().startswith("P"): for wikibase_claims in wikibase_item.claims: for wikibase_c in wikibase_item.claims.get(wikibase_claims): @@ -1086,7 +1086,7 @@ def change_claims(self, wikidata_item, wikibase_item): True) if (claim_found_equal_value == True): found_equal_value = True - print(found_equal_value) + # print(found_equal_value) if found_equal_value == False: # print("This claim is added ", wikidata_claim) # import the property if it does not exist @@ -1167,8 +1167,6 @@ def change_item(self, wikidata_item, wikibase_repo, statements): new_id = self.import_item(wikidata_item) wikibase_item = pywikibot.ItemPage(wikibase_repo, new_id) wikibase_item.get() - if not statements: - return new_id else: print("This entity corresponds to ", self.id.get_id(wikidata_item.getID())) wikibase_item = pywikibot.ItemPage(wikibase_repo, self.id.get_id(wikidata_item.getID())) @@ -1177,8 +1175,6 @@ def change_item(self, wikidata_item, wikibase_repo, statements): self.change_aliases(wikidata_item, wikibase_item) self.change_descriptions(wikidata_item, wikibase_item) self.wikidata_link(wikibase_item, wikidata_item) - if not statements: - return self.id.get_id(wikidata_item.getID()) if statements: self.change_site_links(wikidata_item, wikibase_item) self.change_claims(wikidata_item, wikibase_item) @@ -1196,18 +1192,14 @@ def change_item_given_id(self, wikidata_item, id, wikibase_repo, statements): self.change_site_links(wikidata_item, wikibase_item) self.change_claims(wikidata_item, wikibase_item) - def change_property(self, wikidata_item, wikibase_repo, statements, ): + def change_property(self, wikidata_item, wikibase_repo, statements): print("Change Property", wikidata_item.getID()) wikidata_item.get() wikibase_item = None if not self.id.contains_id(wikidata_item.getID()): new_id = self.importProperty(wikidata_item) - # if not statements: - # return new_id # import done from front end clone wikibase_item = pywikibot.PropertyPage(wikibase_repo, new_id, datatype=wikidata_item.type) wikibase_item.get() - if not statements: - return new_id else: print("Entering here") # if not statements: @@ -1219,8 +1211,6 @@ def change_property(self, wikidata_item, wikibase_repo, statements, ): self.change_labels(wikidata_item, wikibase_item) self.change_aliases(wikidata_item, wikibase_item) self.change_descriptions(wikidata_item, wikibase_item) - if not statements: - return self.id.get_id(wikidata_item.getID()) if statements: self.change_claims(wikidata_item, wikibase_item) return wikibase_item From a956a4c11c3e7505e0cbf0f9017f89d8ea45d54f Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Tue, 19 Jul 2022 17:32:02 +0200 Subject: [PATCH 42/50] Clean unnecessary comment --- util/util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/util/util.py b/util/util.py index d667b0f..35988c5 100644 --- a/util/util.py +++ b/util/util.py @@ -1202,8 +1202,6 @@ def change_property(self, wikidata_item, wikibase_repo, statements): wikibase_item.get() else: print("Entering here") - # if not statements: - # return self.id.get_id(wikidata_item.getID()) # import done from front end clone wikibase_item = pywikibot.PropertyPage(wikibase_repo, self.id.get_id(wikidata_item.getID()), datatype=wikidata_item.type) wikibase_item.get() From ff37c4990be5fe82474a165a926b83714214f83c Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Tue, 19 Jul 2022 17:47:13 +0200 Subject: [PATCH 43/50] Refactoring the code --- import_one.py | 33 ++++----------------------------- main.py | 29 +++++------------------------ util/util.py | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 53 deletions(-) diff --git a/import_one.py b/import_one.py index 94cebbc..0498488 100644 --- a/import_one.py +++ b/import_one.py @@ -1,33 +1,8 @@ #configuration for pywikibot import sys -import pywikibot +from util.util import import_one -def import_one(arg, import_statements = True): - # connect to the wikibase - wikibase = pywikibot.Site("my", "my") - wikibase_repo = wikibase.data_repository() - wikibase_repo.login() - - # connect to wikidata - wikidata = pywikibot.Site("wikidata", "wikidata") - wikidata_repo = wikidata.data_repository() - - from util.util import WikibaseImporter - wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) - - # import a single item or property - print(f"Importing {arg}") - if arg.startswith("Q"): - print("before get") - wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) - wikidata_item.get() - print("after get") - return wikibase_importer.change_item(wikidata_item, wikibase_repo, import_statements) - elif arg.startswith("P"): - wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) - wikidata_property.get() - return wikibase_importer.change_property(wikidata_property, wikibase_repo, import_statements) - -print(f"Importing {arg}", sys.argv[1]) -import_one(args) \ No newline at end of file +arg = sys.argv[1] +print(f"Importing {arg}") +import_one(arg) \ No newline at end of file diff --git a/main.py b/main.py index f170cf1..7615661 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,8 @@ from flask_cors import CORS, cross_origin from threading import Thread +from util.util import import_one + user_config = __import__("user-config") app = Flask(__name__) @@ -18,43 +20,26 @@ class Index(Resource): def get(self): return {"data": "Welcome to the index"} - # class that imports all statements from Wikidata class Sync(Resource): - def import_thread_spinner(self, query_id): - def handle(): - response = import_one(query_id).getID() - t = Thread(target=handle) - return t - def get(self): q_id = request.args.get('q_id') api_key = request.args.get('api_key') if is_authorised(api_key): - t = self.import_thread_spinner(q_id) - t.start() - t.join() + import_one(q_id).getID() payload = {"status_code": 200, "completed": True, "message": "Import process complete"} else: payload = {"status_code": 403, "completed": False, "message": "Unauthorised Access"} return payload - # import one class ImportOne(Resource): - - def import_thread_spinner(self, query_id): - def handle(): - response = import_one(query_id, import_statements = False) - t = Thread(target=handle) - return t def get(self): q_id = request.args.get('q_id') api_key = request.args.get('api_key') if is_authorised(api_key): - from api_import_one import mth_import_one, mth_import_one_without_statements - response = mth_import_one_without_statements(q_id).getID() + response = import_one(q_id, import_statements = False).getID() # print(response) if response: payload = {"status_code": 200, "message": "Import successful", "pid": response} @@ -72,14 +57,9 @@ def get(self): query_type = request.args.get('query_type') api_key = request.args.get('api_key') - # general english - # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ - # query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=property" url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \ query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=" + query_type - # british english - # url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + query_string + "&format=json&errorformat=plaintext&language=en-gb&uselang=en-gb&type=property" if is_authorised(api_key): response = requests.get(url) response = response.json() @@ -92,6 +72,7 @@ def get(self): payload = {"status_code": 403, "completed": False, "message": "Unathorised Access"} return payload + def is_authorised(api_key): if str(user_config.apiKey) == api_key: return True diff --git a/util/util.py b/util/util.py index 35988c5..07f035e 100644 --- a/util/util.py +++ b/util/util.py @@ -1213,6 +1213,31 @@ def change_property(self, wikidata_item, wikibase_repo, statements): self.change_claims(wikidata_item, wikibase_item) return wikibase_item +def import_one(arg, import_statements = True): + # connect to the wikibase + wikibase = pywikibot.Site("my", "my") + wikibase_repo = wikibase.data_repository() + wikibase_repo.login() + + # connect to wikidata + wikidata = pywikibot.Site("wikidata", "wikidata") + wikidata_repo = wikidata.data_repository() + + from util.util import WikibaseImporter + wikibase_importer = WikibaseImporter(wikibase_repo, wikidata_repo) + + # import a single item or property + print(f"Importing {arg}") + if arg.startswith("Q"): + print("before get") + wikidata_item = pywikibot.ItemPage(wikidata_repo, arg) + wikidata_item.get() + print("after get") + return wikibase_importer.change_item(wikidata_item, wikibase_repo, import_statements) + elif arg.startswith("P"): + wikidata_property = pywikibot.PropertyPage(wikidata_repo, arg) + wikidata_property.get() + return wikibase_importer.change_property(wikidata_property, wikibase_repo, import_statements) def chunks(l, n): """Yield successive n-sized chunks from l.""" From 55e4011177d1f529f85e19fdb710d76a9011e25a Mon Sep 17 00:00:00 2001 From: mez Date: Tue, 26 Jul 2022 11:51:17 +0200 Subject: [PATCH 44/50] change sparql class to singleton --- import_recent_changes.py | 3 +-- util/IdSparql.py | 41 +++++++++++++++++++++++++++++----------- util/util.py | 10 ++++------ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/import_recent_changes.py b/import_recent_changes.py index 6994407..85664ae 100644 --- a/import_recent_changes.py +++ b/import_recent_changes.py @@ -27,8 +27,7 @@ identifier.get(wikibase_repo) print('Wikidata Item Identifier',identifier.itemIdentifier) -idSparql = IdSparql(app_config.get('wikibase', 'sparqlEndPoint'), identifier.itemIdentifier, identifier.propertyIdentifier) -idSparql.load() +idSparql = IdSparql() #grab all entities that changed recent = get_wikidata_changes(None, 15) diff --git a/util/IdSparql.py b/util/IdSparql.py index 26433c6..864cc60 100644 --- a/util/IdSparql.py +++ b/util/IdSparql.py @@ -1,24 +1,42 @@ # this class makes the correspondence between Wikidata entities and entities in the Wikibase using the external # identifier for Wikidata +import pywikibot from SPARQLWrapper import SPARQLWrapper, JSON import configparser +from util.PropertyWikidataIdentifier import PropertyWikidataIdentifier + class IdSparql: - def __init__(self, endpoint, item_identifier, property_identifier): + _instance = None + + def __new__(class_, *args, **kwargs): + if not isinstance(class_._instance, class_): + class_._instance = object.__new__(class_, *args, **kwargs) + + return class_._instance + + def __init__(self): self.mapEntity = {} self.mapProperty = {} - self.endpoint = endpoint - self.item_identifier = item_identifier - self.property_identifier = property_identifier + wikibase = pywikibot.Site("my", "my") + wikibase_repo = wikibase.data_repository() + wikibase_repo.login() + identifier = PropertyWikidataIdentifier() + identifier.get(wikibase_repo) + self.item_identifier = identifier.itemIdentifier + self.property_identifier = identifier.propertyIdentifier self.app_config = configparser.ConfigParser() self.app_config.read('config/application.config.ini') + self.endpoint = self.app_config.get('wikibase', 'sparqlEndPoint') + self.load() def load(self): sparql = SPARQLWrapper(self.endpoint) query = """ select ?item ?id where { - ?item <""" + self.app_config.get('wikibase','propertyUri') + """/direct/""" + self.item_identifier + """> ?id + ?item <""" + self.app_config.get('wikibase', + 'propertyUri') + """/direct/""" + self.item_identifier + """> ?id } """ sparql.setQuery(query) @@ -26,12 +44,13 @@ def load(self): results = sparql.query().convert() for result in results['results']['bindings']: split = result['item']['value'].split('/') - id = split[len(split)-1] + id = split[len(split) - 1] if id.startswith('Q'): self.mapEntity[result['id']['value']] = id query = """ select ?item ?id where { - ?item <""" + self.app_config.get('wikibase','propertyUri') + """/direct/""" + self.property_identifier + """> ?id + ?item <""" + self.app_config.get('wikibase', + 'propertyUri') + """/direct/""" + self.property_identifier + """> ?id } """ sparql.setQuery(query) @@ -45,7 +64,7 @@ def load(self): else: print("This should not happen") - def get_id(self,id): + def get_id(self, id): if id.startswith("Q"): return self.mapEntity[id] elif id.startswith("P"): @@ -53,7 +72,7 @@ def get_id(self,id): else: raise NameError('This should not happen') - def save_id(self,id,new_id): + def save_id(self, id, new_id): if id.startswith("Q"): self.mapEntity[id] = str(new_id) elif id.startswith("P"): @@ -61,10 +80,10 @@ def save_id(self,id,new_id): else: raise NameError('This should not happen') - def contains_id(self,id): + def contains_id(self, id): if id.startswith("Q"): return id in self.mapEntity elif id.startswith("P"): return id in self.mapProperty else: - print('This should not happen') \ No newline at end of file + print('This should not happen') diff --git a/util/util.py b/util/util.py index 07f035e..4273258 100644 --- a/util/util.py +++ b/util/util.py @@ -20,11 +20,9 @@ def __init__(self, wikibase_repo, wikidata_repo): self.wikidata_repo = wikidata_repo self.identifier = PropertyWikidataIdentifier() self.identifier.get(wikibase_repo) - self.appConfig = configparser.ConfigParser() - self.appConfig.read('config/application.config.ini') - endpoint = self.appConfig.get('wikibase', 'sparqlEndPoint') - self.id = IdSparql(endpoint, self.identifier.itemIdentifier, self.identifier.propertyIdentifier) - self.id.load() + self.id = IdSparql() + self.app_config = configparser.ConfigParser() + self.app_config.read('config/application.config.ini') # transforms the json to an item def json_to_item(self, wikibase_repo, json_object): @@ -1051,7 +1049,7 @@ def change_claims(self, wikidata_item, wikibase_item): break # print("User that added this claim ", revisions[edit_where_claim_was_added]['user']) - if revisions[edit_where_claim_was_added]['user'].lower() != self.appConfig.get('wikibase', 'user').lower(): + if revisions[edit_where_claim_was_added]['user'].lower() != self.app_config.get('wikibase', 'user').lower(): not_remove.append(claimToRemove) for c in not_remove: claims_to_remove.remove(c) From 7af2417a52e58dc36502991d7fc3af7911625fb2 Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Mon, 8 Aug 2022 08:25:09 +0000 Subject: [PATCH 45/50] Refactoring matching the extention layout and wgServer property grabbed --- .../{ => resources/ext.wikibaseSync}/init.js | 12 ++++++++---- wikibasesync-extension/{ => src}/Hooks.php | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) rename wikibasesync-extension/{ => resources/ext.wikibaseSync}/init.js (97%) rename wikibasesync-extension/{ => src}/Hooks.php (95%) diff --git a/wikibasesync-extension/init.js b/wikibasesync-extension/resources/ext.wikibaseSync/init.js similarity index 97% rename from wikibasesync-extension/init.js rename to wikibasesync-extension/resources/ext.wikibaseSync/init.js index f25bf55..f2d517a 100644 --- a/wikibasesync-extension/init.js +++ b/wikibasesync-extension/resources/ext.wikibaseSync/init.js @@ -8,7 +8,8 @@ mw.boilerPlate = {}; var wikidataResults = []; var WIKIBASE_SYNC_URL = conf.wikibasesync_server_url; var API_KEY = conf.api_key; -//console.log( conf); +var SERVER = conf.Server; +console.log("SERVER ",SERVER); var count = 0; @@ -61,6 +62,9 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { } //ALTERNATIVE APPROACH + console.log(_wikibasePropertyKey,' --- ', conf.PID) + console.log(_wikibasePropertyKey == conf.PID) + console.log(_wikibasePropertyKey == conf.QID) if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { self.wikibasePropertyKey = _wikibasePropertyKey; // Only attach button for wikidata pid or qid properties which are always P1 and P2 @@ -188,13 +192,13 @@ $.wikibase.entityselector.prototype._select = function ( entityStub ) { self._selectedEntity.id = id; self._selectedEntity.title = "Property:" + id; self._selectedEntity.repository = "local"; - self._selectedEntity.url = "http://localhost/wiki/Property:" + id; + self._selectedEntity.url = SERVER+"/wiki/Property:" + id; self._selectedEntity.pageid = null; } else if (self.options.type.toLowerCase() == "item"){ self._selectedEntity.id = id; self._selectedEntity.title = id; self._selectedEntity.repository = "local"; - self._selectedEntity.url = "http://localhost/wiki/" + id; + self._selectedEntity.url = SERVER+"/wiki/" + id; self._selectedEntity.pageid = null; } @@ -251,7 +255,7 @@ $.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { success: function (data) { console.log("response: ",data); //window.history.back(); - window.location.replace('http://localhost/wiki/item:'+data.pid); + window.location.replace(SERVER+'/wiki/item:'+data.pid); } }); diff --git a/wikibasesync-extension/Hooks.php b/wikibasesync-extension/src/Hooks.php similarity index 95% rename from wikibasesync-extension/Hooks.php rename to wikibasesync-extension/src/Hooks.php index 6d9d5f7..3aa595b 100644 --- a/wikibasesync-extension/Hooks.php +++ b/wikibasesync-extension/src/Hooks.php @@ -43,9 +43,10 @@ public function onBeforePageDisplay( $out, $skin ): void { public function onResourceLoaderGetConfigVars( array &$vars, $string, Config $config ): void { $vars['wgVisualEditor'] =[ "wikibasesync_server_url" => $config->get( 'WikibaseSyncUrl' ), - "api_key" => $config->get('ApiKey') + "api_key" => $config->get('ApiKey'), "PID" => $config->get( 'PID' ), "QID" => $config->get( 'QID' ), + "Server" => $config->get( 'Server' ), ]; } } From 6cf20054b5367fbc61141b95d55f1907d715ce86 Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Mon, 8 Aug 2022 20:37:57 +0000 Subject: [PATCH 46/50] Fix bug related to deplayed autocompletion --- .../resources/ext.wikibaseSync/init.js | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/wikibasesync-extension/resources/ext.wikibaseSync/init.js b/wikibasesync-extension/resources/ext.wikibaseSync/init.js index f2d517a..f67e37e 100644 --- a/wikibasesync-extension/resources/ext.wikibaseSync/init.js +++ b/wikibasesync-extension/resources/ext.wikibaseSync/init.js @@ -49,6 +49,7 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { var _wikibasePropertyKey = ""; + console.log('self.value()',self.value()) if (self.value()) { _wikibasePropertyKey = self.value().getKey(); @@ -62,15 +63,12 @@ $.wikibase.statementgroupview.prototype._createStatementlistview = function () { } //ALTERNATIVE APPROACH - console.log(_wikibasePropertyKey,' --- ', conf.PID) - console.log(_wikibasePropertyKey == conf.PID) - console.log(_wikibasePropertyKey == conf.QID) - if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { - self.wikibasePropertyKey = _wikibasePropertyKey; - // Only attach button for wikidata pid or qid properties which are always P1 and P2 - //self.$propertyLabel.text(''); - createSyncButton(self); - createSyncLabelButton(self); + if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { + self.wikibasePropertyKey = _wikibasePropertyKey; + // Only attach button for wikidata pid or qid properties which are always P1 and P2 + //self.$propertyLabel.text(''); + createSyncButton(self); + createSyncLabelButton(self); // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); @@ -110,13 +108,10 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { "Access-Control-Allow-Origin": "*", "Access-Control-Request-Headers3": "x-requested-with" }, - success: function (data) { - //console.log(data); - wikidataResults = data.response.search; + success: function (data2) { + wikidataResults = data2.response.search; } - }); - } - } ) + }) .done( function ( response, statusText, jqXHR ) { // T141955 if ( response.error ) { @@ -140,10 +135,9 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { // UPDATE THE TITLE AND SOURCE TO REFLECT WIKIDATA // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH - var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, response.search) + var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, data.search) //console.log("updatedWikidataResults", updatedWikidataResults); self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { - //console.log(results) deferred.resolve( results, term, @@ -155,6 +149,8 @@ $.wikibase.entityselector.prototype._initDefaultSource = function () { .fail( function ( jqXHR, textStatus ) { deferred.reject( textStatus ); } ); + } + } ) return deferred.promise(); }; From c917ee93464a945e3b64ffd27cb3539119c0dff0 Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Mon, 8 Aug 2022 22:43:10 +0200 Subject: [PATCH 47/50] Clean code --- .../resources/ext.wikibaseSync/init.js | 687 +++++++++--------- 1 file changed, 329 insertions(+), 358 deletions(-) diff --git a/wikibasesync-extension/resources/ext.wikibaseSync/init.js b/wikibasesync-extension/resources/ext.wikibaseSync/init.js index f67e37e..22456e9 100644 --- a/wikibasesync-extension/resources/ext.wikibaseSync/init.js +++ b/wikibasesync-extension/resources/ext.wikibaseSync/init.js @@ -9,363 +9,337 @@ var wikidataResults = []; var WIKIBASE_SYNC_URL = conf.wikibasesync_server_url; var API_KEY = conf.api_key; var SERVER = conf.Server; -console.log("SERVER ",SERVER); -var count = 0; - -var datamodel = require( 'wikibase.datamodel' ); +var datamodel = require('wikibase.datamodel'); $.wikibase.statementgroupview.prototype._createStatementlistview = function () { - var self = this, - prefix; - - var $statementlistview = this.element.find('.wikibase-statementlistview'); - - if (!$statementlistview.length) { - $statementlistview = $('
').appendTo(this.element); - } - - this.statementlistview = this.options.buildStatementListView( - this.options.value ? this.options.value.getItemContainer() : new datamodel.StatementList(), - $statementlistview - ); - prefix = this.statementlistview.widgetEventPrefix; - - $statementlistview - .on(prefix + 'toggleerror.' + this.widgetName, function (event, error) { - self.$property.toggleClass('wb-error', Boolean(error)); - }) - .on(prefix + 'afterstopediting.' + this.widgetName, function (event, dropValue) { - self.$property.removeClass('wb-error wb-edit'); - self._trigger('afterstopediting', null, [dropValue]); - }) - .on(prefix + 'afterstartediting.' + this.widgetName, function (event) { - self.$property.addClass('wb-edit'); - }) - .on(prefix + 'afterremove.' + this.widgetName, function (event) { - self.$property.removeClass('wb-error wb-edit'); - self._trigger('afterremove'); - }); - - - var _wikibasePropertyKey = ""; - console.log('self.value()',self.value()) - if (self.value()) { - _wikibasePropertyKey = self.value().getKey(); - - //PREFERRED APPROACH - // if ($("a:contains('Wikidata QID')")) { - // if (count == 0){ - // createSyncButtons(self); - // count = count + 1; - // } - // }; - } - - //ALTERNATIVE APPROACH - if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { - self.wikibasePropertyKey = _wikibasePropertyKey; - // Only attach button for wikidata pid or qid properties which are always P1 and P2 - //self.$propertyLabel.text(''); - createSyncButton(self); - createSyncLabelButton(self); - - - // console.log(self.wikibasePropertyKey,self.wikibasePropertyValue); - - } else { - //self.$propertyLabel.text('') + var self = this, + prefix; + + var $statementlistview = this.element.find('.wikibase-statementlistview'); + + if (!$statementlistview.length) { + $statementlistview = $('
').appendTo(this.element); } - // console.log(JSON.stringify(self.options, null, 2)); + this.statementlistview = this.options.buildStatementListView( + this.options.value ? this.options.value.getItemContainer() : new datamodel.StatementList(), + $statementlistview + ); + prefix = this.statementlistview.widgetEventPrefix; + + $statementlistview + .on(prefix + 'toggleerror.' + this.widgetName, function (event, error) { + self.$property.toggleClass('wb-error', Boolean(error)); + }) + .on(prefix + 'afterstopediting.' + this.widgetName, function (event, dropValue) { + self.$property.removeClass('wb-error wb-edit'); + self._trigger('afterstopediting', null, [dropValue]); + }) + .on(prefix + 'afterstartediting.' + this.widgetName, function (event) { + self.$property.addClass('wb-edit'); + }) + .on(prefix + 'afterremove.' + this.widgetName, function (event) { + self.$property.removeClass('wb-error wb-edit'); + self._trigger('afterremove'); + }); + + + var _wikibasePropertyKey = ""; + console.log('self.value()', self.value()) + if (self.value()) { + _wikibasePropertyKey = self.value().getKey(); + + //PREFERRED APPROACH + // if ($("a:contains('Wikidata QID')")) { + // if (count == 0){ + // createSyncButtons(self); + // count = count + 1; + // } + // }; + } + + //ALTERNATIVE APPROACH + if (_wikibasePropertyKey == conf.PID || _wikibasePropertyKey == conf.QID) { + self.wikibasePropertyKey = _wikibasePropertyKey; + createSyncButton(self); + createSyncLabelButton(self); + } }; $.wikibase.entityselector.prototype._initDefaultSource = function () { - var self = this; - wikidataResults = []; - return function ( term ) { - var deferred = $.Deferred(), - hookResults = self._fireSearchHook( term ); - - // clear previous error - if ( self._error ) { - self._error = null; - self._cache.suggestions = null; - self._updateMenu( [] ); - } - - $.ajax( { - url: self.options.url, - timeout: self.options.timeout, - dataType: 'json', - data: self._getSearchApiParameters( term ), - success: function(data){ - $.ajax({ - // url: WIKIBASE_SYNC_URL + '/remote-wikidata-query/' + term + "/" + self.options.type + "/" + API_KEY, - url: WIKIBASE_SYNC_URL + '/remote-wikidata-query?query_string=' + term + "&query_type=" + self.options.type + "&api_key=" + API_KEY, - crossDomain: true, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data2) { - wikidataResults = data2.response.search; - } - }) - .done( function ( response, statusText, jqXHR ) { - // T141955 - if ( response.error ) { - deferred.reject( response.error.info ); - return; - } - - // The default endpoint wbsearchentities responds with an array of errors. - if ( response.errors && self.options.responseErrorFactory ) { - var error = self.options.responseErrorFactory( response, 'search' ); - - if ( error && self.options.showErrorCodes.indexOf( error.code ) !== -1 ) { - self._error = error; - self._cache = {}; - self._updateMenu( [] ); - deferred.reject( error.message ); - return; - } - } - - - // UPDATE THE TITLE AND SOURCE TO REFLECT WIKIDATA - // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH - var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, data.search) - //console.log("updatedWikidataResults", updatedWikidataResults); - self._combineResults( hookResults, updatedWikidataResults ).then( function ( results ) { - deferred.resolve( - results, - term, - response[ 'search-continue' ], - jqXHR.getResponseHeader( 'X-Search-ID' ) - ); - } ); - } ) - .fail( function ( jqXHR, textStatus ) { - deferred.reject( textStatus ); - } ); - } - } ) - - return deferred.promise(); - }; + var self = this; + wikidataResults = []; + return function (term) { + var deferred = $.Deferred(), + hookResults = self._fireSearchHook(term); + + // clear previous error + if (self._error) { + self._error = null; + self._cache.suggestions = null; + self._updateMenu([]); + } + + $.ajax({ + url: self.options.url, + timeout: self.options.timeout, + dataType: 'json', + data: self._getSearchApiParameters(term), + success: function (data) { + $.ajax({ + url: WIKIBASE_SYNC_URL + '/remote-wikidata-query?query_string=' + term + "&query_type=" + self.options.type + "&api_key=" + API_KEY, + crossDomain: true, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data2) { + wikidataResults = data2.response.search; + } + }) + .done(function (response, statusText, jqXHR) { + // T141955 + if (response.error) { + deferred.reject(response.error.info); + return; + } + + // The default endpoint wbsearchentities responds with an array of errors. + if (response.errors && self.options.responseErrorFactory) { + var error = self.options.responseErrorFactory(response, 'search'); + + if (error && self.options.showErrorCodes.indexOf(error.code) !== -1) { + self._error = error; + self._cache = {}; + self._updateMenu([]); + deferred.reject(error.message); + return; + } + } + + + // UPDATE THE TITLE AND SOURCE TO REFLECT WIKIDATA + // REMOVE WIKIDATA RESULTS THAT ALREADY EXIST IN WIKIBASE USING FOREACH + var updatedWikidataResults = removeExistingRecordsFromWikidataResults(wikidataResults, data.search) + self._combineResults(hookResults, updatedWikidataResults).then(function (results) { + deferred.resolve( + results, + term, + response['search-continue'], + jqXHR.getResponseHeader('X-Search-ID') + ); + }); + }) + .fail(function (jqXHR, textStatus) { + deferred.reject(textStatus); + }); + } + }) + + return deferred.promise(); + }; }; -$.wikibase.entityselector.prototype._select = function ( entityStub ) { - var id = entityStub && entityStub.id; - this._selectedEntity = entityStub; - - if ( id ) { - var self = this; - if (entityStub.repository !== "local") { - var cloningEl = '

importing...

'; - $(cloningEl).insertAfter(self.focused); - //remote source, clone - - //api call - // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + id + "/" + API_KEY; - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + id + "&api_key=" + API_KEY; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log(data); - if (data.pid) { - $(self.focused).siblings('p').remove(); - id = data.pid; - - if (self.options.type.toLowerCase() == "property") { - self._selectedEntity.id = id; - self._selectedEntity.title = "Property:" + id; - self._selectedEntity.repository = "local"; - self._selectedEntity.url = SERVER+"/wiki/Property:" + id; - self._selectedEntity.pageid = null; - } else if (self.options.type.toLowerCase() == "item"){ - self._selectedEntity.id = id; - self._selectedEntity.title = id; - self._selectedEntity.repository = "local"; - self._selectedEntity.url = SERVER+"/wiki/" + id; - self._selectedEntity.pageid = null; - } - - self._trigger( 'selected', null, [ id ] ); - } - } - }); - } else { - this._trigger( 'selected', null, [ id ] ); - } - } +$.wikibase.entityselector.prototype._select = function (entityStub) { + var id = entityStub && entityStub.id; + this._selectedEntity = entityStub; + + if (id) { + var self = this; + if (entityStub.repository !== "local") { + var cloningEl = '

importing...

'; + $(cloningEl).insertAfter(self.focused); + //remote source, clone + + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + id + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log(data); + if (data.pid) { + $(self.focused).siblings('p').remove(); + id = data.pid; + + if (self.options.type.toLowerCase() == "property") { + self._selectedEntity.id = id; + self._selectedEntity.title = "Property:" + id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = SERVER + "/wiki/Property:" + id; + self._selectedEntity.pageid = null; + } else if (self.options.type.toLowerCase() == "item") { + self._selectedEntity.id = id; + self._selectedEntity.title = id; + self._selectedEntity.repository = "local"; + self._selectedEntity.url = SERVER + "/wiki/" + id; + self._selectedEntity.pageid = null; + } + + self._trigger('selected', null, [id]); + } + } + }); + } else { + this._trigger('selected', null, [id]); + } + } }; // overwrite search result default behaviour sec -$.wikibase.entitysearch.prototype._initMenu = function ( ooMenu ) { - var PARENT = $.wikibase.entityselector; - PARENT.prototype._initMenu.apply( this, arguments ); - - if ( this.options.suggestionsPlaceholder ) { - ooMenu.option( 'customItems' ).unshift( this.options.suggestionsPlaceholder ); - } - - ooMenu.element.addClass( 'wikibase-entitysearch-list' ); - - //console.log(ooMenu.element[0].querySelectorAll("a")); - $( ooMenu ) - .off( 'selected' ) - .on( 'selected.entitysearch', function ( event, item ) { - if ( event.originalEvent - // && /^key/.test( event.originalEvent.type ) - && !( item instanceof $.ui.ooMenu.CustomItem ) - ) { - var itemEntityStub = item.getEntityStub(); - if (itemEntityStub) { - if (itemEntityStub.repository.toLowerCase() === "wikidata") { - - $("a[tabindex='-1']").click(function(e) { - e.preventDefault(); - }); - - //api call - // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + itemEntityStub.id + "/" + API_KEY; - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + itemEntityStub.id + "&api_key=" + API_KEY; - $.ajax({ - url: full_endpoint, - crossDomain: true, - //async: false, - //global: false, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - console.log("response: ",data); - //window.history.back(); - window.location.replace(SERVER+'/wiki/item:'+data.pid); - - } - }); - }else{ - window.location.href = item.getEntityStub().url; - } - } - } - } ); - - return ooMenu; +$.wikibase.entitysearch.prototype._initMenu = function (ooMenu) { + var PARENT = $.wikibase.entityselector; + PARENT.prototype._initMenu.apply(this, arguments); + + if (this.options.suggestionsPlaceholder) { + ooMenu.option('customItems').unshift(this.options.suggestionsPlaceholder); + } + + ooMenu.element.addClass('wikibase-entitysearch-list'); + + $(ooMenu) + .off('selected') + .on('selected.entitysearch', function (event, item) { + if (event.originalEvent + // && /^key/.test( event.originalEvent.type ) + && !(item instanceof $.ui.ooMenu.CustomItem) + ) { + var itemEntityStub = item.getEntityStub(); + if (itemEntityStub) { + if (itemEntityStub.repository.toLowerCase() === "wikidata") { + + $("a[tabindex='-1']").click(function (e) { + e.preventDefault(); + }); + + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + itemEntityStub.id + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + //async: false, + //global: false, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + console.log("response: ", data); + //window.history.back(); + window.location.replace(SERVER + '/wiki/item:' + data.pid); + + } + }); + } else { + window.location.href = item.getEntityStub().url; + } + } + } + }); + + return ooMenu; } function createSyncButtons(_context) { - btn = $("") - btn2 = $("") - //btn.css("margin-top", ".5rem"); - btn.css("display", "block"); - //btn.css("margin-left", "5px"); - btn.css("color", "#0645ad"); - btn.css("background-color", "white"); - btn.css("border-color", "#0645ad"); - btn.css("border-radius", "5px"); - - //btn2.css("margin-left", "5px"); - btn2.css("margin-top", ".3rem"); - btn2.css("display", "block"); - btn2.css("color", "#0645ad"); - btn2.css("background-color", "white"); - btn2.css("border-color", "#0645ad"); - btn2.css("border-radius", "5px"); - - _context.$propertyLabel.append(btn); - _context.$propertyLabel.append(btn2); - - var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; - self.wikibasePropertyValue = _wikibasePropertyValue; - - //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); - - btn.on('click', function () { - btn.text("syncing..."); - //api call - // full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; - full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - if (data) { - //console.log(data); - location.reload(); - } - - - } - }); - }); - - btn2.on('click', function () { - btn2.text("syncing..."); - //api call - // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; - $.ajax({ - url: full_endpoint, - crossDomain: true, - headers: { - // "accept": "application/json", - "Access-Control-Allow-Origin": "*", - "Access-Control-Request-Headers3": "x-requested-with" - }, - success: function (data) { - if (data) { - //console.log(data); - location.reload(); - } - - - } - }); - }); + btn = $("") + btn2 = $("") + //btn.css("margin-top", ".5rem"); + btn.css("display", "block"); + //btn.css("margin-left", "5px"); + btn.css("color", "#0645ad"); + btn.css("background-color", "white"); + btn.css("border-color", "#0645ad"); + btn.css("border-radius", "5px"); + + //btn2.css("margin-left", "5px"); + btn2.css("margin-top", ".3rem"); + btn2.css("display", "block"); + btn2.css("color", "#0645ad"); + btn2.css("background-color", "white"); + btn2.css("border-color", "#0645ad"); + btn2.css("border-radius", "5px"); + + _context.$propertyLabel.append(btn); + _context.$propertyLabel.append(btn2); + + var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; + self.wikibasePropertyValue = _wikibasePropertyValue; + + //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); + + btn.on('click', function () { + btn.text("syncing..."); + //api call + full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data) { + location.reload(); + } + + + } + }); + }); + + btn2.on('click', function () { + btn2.text("syncing..."); + //api call + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + $.ajax({ + url: full_endpoint, + crossDomain: true, + headers: { + // "accept": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Request-Headers3": "x-requested-with" + }, + success: function (data) { + if (data) { + //console.log(data); + location.reload(); + } + + + } + }); + }); }; function createSyncButton(_context) { btn = $("") - //btn.css("margin-top", ".5rem"); - btn.css("display", "block"); - //btn.css("margin-left", "5px"); - btn.css("color", "#0645ad"); - btn.css("background-color", "white"); - btn.css("border-color", "#0645ad"); - btn.css("border-radius", "5px"); + btn.css("display", "block"); + btn.css("color", "#0645ad"); + btn.css("background-color", "white"); + btn.css("border-color", "#0645ad"); + btn.css("border-radius", "5px"); _context.$propertyLabel.append(btn); var _wikibasePropertyValue = _context.value().getItemContainer()._items[0]._claim._mainSnak._value._value; self.wikibasePropertyValue = _wikibasePropertyValue; - //console.log(_context.wikibasePropertyKey,_context.wikibasePropertyValue); - btn.on('click', function () { btn.text("syncing..."); - btn.prop("disabled",true); - //disable other sync button - $('#wbsynclabel').prop("disabled",true); + btn.prop("disabled", true); + //disable other sync button + $('#wbsynclabel').prop("disabled", true); //api call - // full_endpoint = WIKIBASE_SYNC_URL + '/sync/' + self.wikibasePropertyValue + "/" + API_KEY; - full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + full_endpoint = WIKIBASE_SYNC_URL + '/sync?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -389,12 +363,12 @@ function createSyncButton(_context) { function createSyncLabelButton(_context) { btn2 = $("") //btn2.css("margin-left", "5px"); - btn2.css("margin-top", ".3rem"); - btn2.css("display", "block"); - btn2.css("color", "#0645ad"); - btn2.css("background-color", "white"); - btn2.css("border-color", "#0645ad"); - btn2.css("border-radius", "5px"); + btn2.css("margin-top", ".3rem"); + btn2.css("display", "block"); + btn2.css("color", "#0645ad"); + btn2.css("background-color", "white"); + btn2.css("border-color", "#0645ad"); + btn2.css("border-radius", "5px"); _context.$propertyLabel.append(btn2); @@ -405,12 +379,11 @@ function createSyncLabelButton(_context) { btn2.on('click', function () { btn2.text("syncing..."); - btn2.prop("disabled",true); - //disable other sync button - $('#wbsync').prop("disabled",true); + btn2.prop("disabled", true); + //disable other sync button + $('#wbsync').prop("disabled", true); //api call - // var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item/' + self.wikibasePropertyValue + "/" + API_KEY; - var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; + var full_endpoint = WIKIBASE_SYNC_URL + '/import-wikidata-item?q_id=' + self.wikibasePropertyValue + "&api_key=" + API_KEY; $.ajax({ url: full_endpoint, crossDomain: true, @@ -432,25 +405,23 @@ function createSyncLabelButton(_context) { }; - -function removeExistingRecordsFromWikidataResults(wikidataResults, localResults){ - if (!wikidataResults || !localResults){ - return wikidataResults; - } - var updatedResults = []; - localResults.concat(wikidataResults).forEach(function (element) { - var index = updatedResults.findIndex(function(x){ - return x.label.toLowerCase().trim() == element.label.toLowerCase().trim() && x.description.toLowerCase().trim() == element.description.toLowerCase().trim() - }) - if (index == -1) { - if (element.repository.toLowerCase() !== "local") { - element.label = "[clone from wikidata:] " + element.label - } - updatedResults.push(element); - } - }) - return updatedResults - - +function removeExistingRecordsFromWikidataResults(wikidataResults, localResults) { + if (!wikidataResults || !localResults) { + return wikidataResults; + } + var updatedResults = []; + localResults.concat(wikidataResults).forEach(function (element) { + var index = updatedResults.findIndex(function (x) { + return x.label.toLowerCase().trim() == element.label.toLowerCase().trim() && x.description.toLowerCase().trim() == element.description.toLowerCase().trim() + }) + if (index == -1) { + if (element.repository.toLowerCase() !== "local") { + element.label = "[clone from wikidata:] " + element.label + } + updatedResults.push(element); + } + }) + return updatedResults + }; From 4367d10745cb824b5e146c6d25681c37daa87a41 Mon Sep 17 00:00:00 2001 From: Dennis Diefenbach Date: Tue, 23 May 2023 20:04:05 +0200 Subject: [PATCH 48/50] Update util.py --- util/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/util.py b/util/util.py index 11fa3e2..6e35500 100644 --- a/util/util.py +++ b/util/util.py @@ -124,7 +124,7 @@ def diffLabels(self, wikidata_item, wikibase_item): # no update has been done on label, accept remote update mylabels[label] = wikidata_item.labels.get(label) else: - if self.appConfig.get('wikibase', 'overwriteLocalChanges').lower() == 'false': + if self.app_config.get('wikibase', 'overwriteLocalChanges').lower() == 'false': last_update_revision_on_label = self.get_last_label_update(revisions, label) if last_update_revision_on_label is None: # no update has been done on label, accept remote update From 918a646d8f5fddb51582c39a2065f769376a700c Mon Sep 17 00:00:00 2001 From: "J.M" Date: Fri, 13 Oct 2023 15:02:24 +0200 Subject: [PATCH 49/50] Clean .DS_Store --- .DS_Store | Bin 8196 -> 0 bytes .gitignore | 1 + 2 files changed, 1 insertion(+) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 027cf8295f8f70c3f98344748514d4a2b0bbd591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM!EVz)5S?v9<0_;I5*4{1SwiB}mO@Jf;*zHAp%QRt5F7v*I}WW?*ABMRfU2UL z;UD+~u6zmq!U^82x53_|R9p~Jcca}|+w*2;o@ecjOGKhQ@b3~eiO51{*{ETd()c>} zi8iCo+<+9o6LrZ&KcF5t6WZp4VZbn87%&VN1`GrL0|R(xbFo%)Hwv-&@ zGKZ7M;Uv_`LRBb2t`3|n)k(B+X-30>)*b58hf@9S?1pjI3u6x&ys0+P zSANQd8PPS=`h5z34Cn~6m=elx6jOxye}(O77QSj0t||+^zZxt{FV@O9aZ|(1!B1Z0 zEmq#wbU$mli<);Xh4?x0D}@Ui`|vfL=B@alSz6F6g*Z+T@svns_BCu>!=BF(v;3vN za#KSl@VAQ|Nv`=@%O9g4=DcXHN{?xmwrGc*Qipal_L%9Sb_HC?C^bE1xu{n~2Ds3S zrm-QJENb6|HZu?)2F@CXhL|6s`>>Lsb58jx%0S-dp47WAUdeoMt-8#pGy5La<2x2& z#eO*^&Tp|$V1AzVz|tmd(-X)Q`0Q&4a9ct&;A4;8(E#4_>_|nx`IXUo%F1}o>k_^W ztpgz0#|%F5F6v^IP^clne+jvOHB;y(v|QX9z)$Q#z8fWMqk!#$`xL*Syf6MVJTqLv zSAfqDvF4-X^J9U}3LQ&6j?1xdhKizIW1J11^rnZHQbd(tjXqXN%XrD+U*WxB+E>rD zZ(ctP(rk70yO^1+T$!s{RjX#b?i|F!PUdEVwCyG@`RG|3hu+!T^_~a4q0_j&6-SvH zM7=};0>1~9S1*FdkB9Ae5c#RZcJd3>yfyDMnkOgg8~2y&^#>cLOZLgbd#jkQZJeIY zTZ^~uJlb;(!=otvg#Cpk)E_%k&yU9=@4pLqI_@M<7)SgpIXG37XzZQ-Pvv<=JQ??Tx;9tZ_v51-YAz6f6% VCC;Gz^A7>3dH+k|&2Xt1_ywqd)VTlv diff --git a/.gitignore b/.gitignore index e7400da..bc5cbed 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ venv *log* *sh src/ +**/.DS_Store \ No newline at end of file From 86af1d144d52e7c87b2b338a72dcd4620f51c73f Mon Sep 17 00:00:00 2001 From: "J.M" Date: Fri, 13 Oct 2023 16:06:29 +0200 Subject: [PATCH 50/50] Adding docker --- .dockerignore | 34 ++++++++++++++++++++++++++++++++++ Dockerfile | 23 ++++++++++++++++++----- Dockerfile.old | 13 +++++++++++++ compose.yaml | 7 +++++++ requirements.txt | 2 ++ user-config.py | 2 +- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile.old create mode 100644 compose.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3edb0b5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/Dockerfile b/Dockerfile index 0a705e7..9c65490 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,26 @@ -FROM python:3.8-slim-buster -RUN apt-get update && apt-get install -y git -RUN apt-get install -y procps +ARG PYTHON_VERSION=3.9.13 +FROM python:${PYTHON_VERSION}-slim as base + +# Prevents Python from writing pyc files. +ENV PYTHONDONTWRITEBYTECODE=1 + +# Keeps Python from buffering stdout and stderr to avoid situations where +# the application crashes without emitting any logs due to buffering. +ENV PYTHONUNBUFFERED=1 WORKDIR /app COPY requirements.txt requirements.txt -RUN pip3 install -r requirements.txt +RUN pip install -r requirements.txt +# Copy the source code into the container. COPY . . -CMD "./script.sh" \ No newline at end of file +# Expose the port that the application listens on. +EXPOSE 5000 + +# Run the application. +#CMD gunicorn 'venv.lib.python3.11.site-packages.werkzeug.wsgi' --bind=0.0.0.0:5000 +#CMD gunicorn main:app --access-logfile ./server.log --timeout 300 +CMD python main.py \ No newline at end of file diff --git a/Dockerfile.old b/Dockerfile.old new file mode 100644 index 0000000..0a705e7 --- /dev/null +++ b/Dockerfile.old @@ -0,0 +1,13 @@ +FROM python:3.8-slim-buster + +RUN apt-get update && apt-get install -y git +RUN apt-get install -y procps + +WORKDIR /app + +COPY requirements.txt requirements.txt +RUN pip3 install -r requirements.txt + +COPY . . + +CMD "./script.sh" \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..b997f23 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,7 @@ +services: + server: + build: + context: . + ports: + - 5000:5000 + restart: always diff --git a/requirements.txt b/requirements.txt index 4a3cb11..dc832e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,3 +15,5 @@ Flask-Restful==0.3.9 Flask-Cors==3.0.10 pywikibot~=7.7.2 mwparserfromhell>=0.5.0 +gunicorn==20.1.0 +werkzeug==2.3.7 \ No newline at end of file diff --git a/user-config.py b/user-config.py index 7bc4374..b056f43 100644 --- a/user-config.py +++ b/user-config.py @@ -1,4 +1,4 @@ -from pywikibot.config2 import usernames +from pywikibot.config import usernames user_families_paths = ['./config'] mylang = "wikidata"