Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #19

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open

Dev #19

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
e824a8d
flask server and apis
Jan 28, 2022
072f605
query update
Jan 31, 2022
601d13a
clone button updates
Feb 1, 2022
190e9d3
working copy update draft
mezez Feb 8, 2022
73cf1ab
new working copy
mezez Feb 23, 2022
e3c998b
draft-wip
mezez Feb 24, 2022
b34ad73
remote wikidata clone and scripts update
mezez Mar 3, 2022
86f5579
clone button spacing
mezez Mar 15, 2022
7157a48
additional comments
mezez Apr 4, 2022
e96102b
algorithm updates
mezez Apr 14, 2022
3f54a75
algorithm updates optimised
mezez Apr 14, 2022
b0ccba6
code base cleanup
mezez Apr 19, 2022
4f5f3e7
Merge branch 'master' into remote-autocomplete-and-clone
mezez Apr 19, 2022
74919a3
autocomplete redesign
mezez Apr 26, 2022
e6c63a5
autocomplete redesign fixes
mezez Apr 26, 2022
de4c3d9
remote-autocomplete-and-clone
mezez May 3, 2022
5b370a4
ui enhancement and bug fix
mezez May 9, 2022
9734e2f
api updates and frontend scripts update
mezez May 17, 2022
289fa52
frontend scripts update
mezez May 17, 2022
423a4bb
frontend scripts update
mezez May 17, 2022
43b10ea
frontend scripts update
mezez May 17, 2022
5958e00
bug fix
mezez May 20, 2022
d48f970
add loader
mezez May 30, 2022
871fe9f
wikidata qid and pid sync
mezez Jun 1, 2022
4284aea
wikidata qid and pid sync update
mezez Jun 3, 2022
a8e8fb4
qid and pid sync method update
mezez Jun 3, 2022
ecaa6f9
qid and pid sync method update
mezez Jun 3, 2022
0066076
qid and pid sync method update
mezez Jun 3, 2022
cb5ef66
qid and pid sync method update
mezez Jun 3, 2022
8af7e81
boilter plate extension changes
mezez Jun 21, 2022
cd937c4
boilter plate extension changes
mezez Jun 21, 2022
13c2a35
Extension updates
mezez Jun 22, 2022
8d46dfa
Extension updates
mezez Jun 22, 2022
6f71afd
Extension refactor
mezez Jun 22, 2022
711e90d
only enable extension if user is logged in
mezez Jun 22, 2022
4995775
Merge branch 'master' into remote-autocomplete-and-clone
mezez Jul 6, 2022
363af69
wikibase sync extension updates
mezez Jul 6, 2022
4f63bf8
clear console logs
mezez Jul 6, 2022
fcb16bc
extension updates
mezez Jul 11, 2022
f32c0fa
refactor and updates
mezez Jul 12, 2022
607edde
wikibase extension reversal and updates
mezez Jul 19, 2022
4497a5c
Merge branch 'remote-autocomplete-and-clone' into dev
D063520 Jul 19, 2022
487d6b9
Merge branch 'remote-autocomplete-and-clone' into dev
D063520 Jul 19, 2022
7267504
Clean code that is not needed
D063520 Jul 19, 2022
5cbd6e6
Refactoring code
D063520 Jul 19, 2022
a956a4c
Clean unnecessary comment
D063520 Jul 19, 2022
ff37c49
Refactoring the code
D063520 Jul 19, 2022
55e4011
change sparql class to singleton
mezez Jul 26, 2022
7af2417
Refactoring matching the extention layout and wgServer property grabbed
D063520 Aug 8, 2022
6cf2005
Fix bug related to deplayed autocompletion
D063520 Aug 8, 2022
c917ee9
Clean code
D063520 Aug 8, 2022
32cebf5
Move to new verison of Pywikibot
D063520 Feb 14, 2023
4367d10
Update util.py
D063520 May 23, 2023
918a646
Clean .DS_Store
DiaZork Oct 13, 2023
86af1d1
Adding docker
DiaZork Oct 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ venv
*log*
*sh
src/
**/.DS_Store
23 changes: 18 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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"
# 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
13 changes: 13 additions & 0 deletions Dockerfile.old
Original file line number Diff line number Diff line change
@@ -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"
7 changes: 7 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
server:
build:
context: .
ports:
- 5000:5000
restart: always
13 changes: 2 additions & 11 deletions import_one.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# configuration for pywikibot
import sys

import pywikibot
from util.util import import_one

# connect to the wikibase
wikibase = pywikibot.Site("my", "my")
Expand All @@ -19,13 +19,4 @@
# 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)
import_one(arg)
3 changes: 1 addition & 2 deletions import_recent_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
91 changes: 91 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import socket
import sys

import requests
from flask import Flask, request
from flask_restful import Api, Resource
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__)
CORS(app)

api = Api(app)

class Index(Resource):
def get(self):
return {"data": "Welcome to the index"}

# class that imports all statements from Wikidata
class Sync(Resource):
def get(self):
q_id = request.args.get('q_id')
api_key = request.args.get('api_key')
if is_authorised(api_key):
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 get(self):
q_id = request.args.get('q_id')
api_key = request.args.get('api_key')

if is_authorised(api_key):
response = import_one(q_id, import_statements = False).getID()
# 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": 403, "completed": False, "message": "Unathorised Access"}
return payload


class WikiDataQuery(Resource):
def get(self):
query_string = request.args.get('query_string')
query_type = request.args.get('query_type')
api_key = request.args.get('api_key')

url = "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + \
query_string + "&format=json&errorformat=plaintext&language=en&uselang=en&type=" + query_type

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": 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")


if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
7 changes: 6 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,10 @@ 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
pywikibot~=7.7.2
mwparserfromhell>=0.5.0
mwparserfromhell>=0.5.0
gunicorn==20.1.0
werkzeug==2.3.7
3 changes: 2 additions & 1 deletion user-config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pywikibot.config2 import usernames
from pywikibot.config import usernames

user_families_paths = ['./config']
mylang = "wikidata"
Expand All @@ -9,3 +9,4 @@
maxthrottle = 0
max_retries = 100
#verbose_output = True
apiKey = 123456
2 changes: 1 addition & 1 deletion user-password.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword'))
(u'admin', BotPassword(u'WikidataUpdater', u'BotPassword'))
41 changes: 30 additions & 11 deletions util/IdSparql.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,56 @@
# 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)
sparql.setReturnFormat(JSON)
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)
Expand All @@ -45,26 +64,26 @@ 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"):
return self.mapProperty[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"):
self.mapProperty[id] = str(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')
print('This should not happen')
Loading