usage: wikinuke.py [-h] [-d] [-V] [-f] [-q QUERY] [-qf QUERYFIELD] -t TARGET [-p PAGES [PAGES ...]]
Created on 2020-11-12
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
-f, --force force to delete pages - default is 'dry' run only listing pages
-q QUERY, --query QUERY
select pages with given SMW ask query
-qf QUERYFIELD, --queryField QUERYFIELD
query result field which contains page
-t TARGET, --target TARGET
target wiki id
-p PAGES [PAGES ...], --pages PAGES [PAGES ...]
list of page Titles to be pushed
The default behavior is a dry run only listing whether the pages exist
wikinuke -t test -p deleteMe1 deleteMe2 deleteMe3
deleting 3 pages in test (dry run)
1/3 ( 33%): deleting deleteMe1 ...👍
2/3 ( 67%): deleting deleteMe2 ...👍
3/3 ( 100%): deleting deleteMe3 ...👍
After checking you might want to (carefully) use the "-f" option to actually force the deletion:
wikinuke -t test -p deleteMe1 deleteMe2 deleteMe3 -f
deleting 3 pages in test (forced)
1/3 ( 33%): deleting deleteMe1 ...✅
2/3 ( 67%): deleting deleteMe2 ...✅
3/3 ( 100%): deleting deleteMe3 ...✅
wikiedit.py allows mass editing of pages using python regular expressions
wikiedit -h
usage: wikiedit.py [-h] [-d] [-V] --search SEARCH --replace REPLACE [-f] [-q QUERY] [-qf QUERYFIELD] -t TARGET
[-p PAGES [PAGES ...]]
Created on 2020-11-12
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
--search SEARCH search pattern
--replace REPLACE replace pattern
-f, --force force to edit pages - default is 'dry' run only listing pages
-q QUERY, --query QUERY
select pages with given SMW ask query
-qf QUERYFIELD, --queryField QUERYFIELD
query result field which contains page
-t TARGET, --target TARGET
target wiki id
-p PAGES [PAGES ...], --pages PAGES [PAGES ...]
list of page Titles to be pushed
wikiedit -t test -q "[[isA::CFP]]" --search "CALL FOR PAPER" --replace "CFP"
editing 1 pages in test (dry run)
1/1 ( 100%): editing CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ) ...👍 |isA=CFP
-|Acronym=CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ)
-|Title=CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ)
+|Acronym=CFP Journal: Advances in Multimedia - An International Journal (AMIJ)
+|Title=CFP Journal: Advances in Multimedia - An International Journal (AMIJ)
|Start date=2010/11/01
}}
-CALL FOR PAPER
+CFP
Journal: Advances in Multimedia - An International Journal (AMIJ)
wikiedit -h
usage: wikiedit.py [-h] [-d] [-V] --search SEARCH --replace REPLACE [-f] [-q QUERY] [-qf QUERYFIELD] -t TARGET
[-p PAGES [PAGES ...]]
Created on 2020-11-12
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
--search SEARCH search pattern
--replace REPLACE replace pattern
-f, --force force to edit pages - default is 'dry' run only listing pages
-q QUERY, --query QUERY
select pages with given SMW ask query
-qf QUERYFIELD, --queryField QUERYFIELD
query result field which contains page
-t TARGET, --target TARGET
target wiki id
-p PAGES [PAGES ...], --pages PAGES [PAGES ...]
list of page Titles to be pushed
wikiedit -t test -q "[[isA::CFP]]" --search "CALL FOR PAPER" --replace "CFP"
editing 1 pages in test (dry run)
1/1 ( 100%): editing CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ) ...👍 |isA=CFP
-|Acronym=CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ)
-|Title=CALL FOR PAPER Journal: Advances in Multimedia - An International Journal (AMIJ)
+|Acronym=CFP Journal: Advances in Multimedia - An International Journal (AMIJ)
+|Title=CFP Journal: Advances in Multimedia - An International Journal (AMIJ)
|Start date=2010/11/01
}}
-CALL FOR PAPER
+CFP
Journal: Advances in Multimedia - An International Journal (AMIJ)
#!/bin/zsh
# WF 2023-02-27
#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0,34m'
red='\033[0,31m'
green='\033[0,32m' # '\e[1,32m' is too bright for white bg.
endColor='\033[0m'
#
# a colored message
# params:
# 1: l_color - the color of the message
# 2: l_msg - the message to display
#
color_msg() {
local l_color="$1"
local l_msg="$2"
echo -e "${l_color}$l_msg${endColor}"
}
#
# error
#
# show the given error message on stderr and exit
#
# params:
# 1: l_msg - the error message to display
#
error() {
local l_msg="$1"
# use ansi red for error
color_msg $red "Error:" 1>&2
color_msg $red "\t$l_msg" 1>&2
exit 1
}
#
# list of scholar properties
#
props() {
cat << EOF
dblp,P2456,dblpId,DBLP author ID
gnd,P227,gndId,GND ID
google,P1960,googleScholarUser,Google Scholar author ID
homepage,P856,homepage,official website
linkedin,P6634,linkedInId,LinkedIn personal profile ID
orcid,P496,orcid,ORCID ID
research,P2038,researchGate,ResearchGate profile ID
EOF
}
#
# get the ask query
#
ask_query() {
cat << EOF
{{#ask: [[Concept:Scholar]]
| mainLabel=scholar
| ?Scholar wikiDataId = item
| ?Scholar description = description
| ?Scholar name = name
| ?Scholar firstName = firstName
EOF
props | while IFS=, read -r option prop field prop_label
do
echo "| ?Scholar $field=$field"
done
cat << EOF
| ?Scholar smartCRMId = smartCRMId
| ?Creation date=creation Date
|sort=Scholar name,Scholar firstName
|order=ascending,ascending
}}
EOF
}
#
# query scholars from the given wikiId in the given FlorianMatthes
#
# params
# 1: wikiId
# 2: format e.g. -j/--json or -c/--csv
#
scholars() {
local l_wikiId="$1"
local l_option="$2"
qf=/tmp/scholars$$
json=/tmp/scholar.json$$
csv=/tmp/scholar.csv$$
ask_query>$qf
#https://stackoverflow.com/questions/32960857/how-to-convert-arbitrary-simple-json-to-csv-using-jq
wikiquery -l -s ${l_wikiId} --queryFile $qf > $json
cat $json | jq '.data | (map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | join(";")' > $csv
case $l_option in
-j|--json) cat $json;;
-c|--csv) cat $csv | sed -e 's/"//g';;
esac
rm $json
rm $csv
rm $qf
}
# show usage
#
usage() {
echo "$0 [-h|--help|--verbose]"
echo -n "["
local delim=""
props | while IFS=, read -r option prop field prop_label
do
echo -n "$delim$option"
delim="|"
done
echo "]"
echo "[Q*]*"
echo "-h |--help: show this usage"
echo "-u |--update: update the scholars json cache"
echo "-w |--wikiId wikiId: set the wikiId to query"
echo "desc: wikidata description"
props | while IFS=, read -r option prop field prop_label
do
echo "$option: $prop_label"
done
echo "Q*: any list of wikidata identifiers to be filtered"
exit 1
}
#
# update the scholars list from the wiki
#
update_scholars() {
local l_wikiId="$1"
if [ ! -f "$jscholars" ]
then
color_msg $blue "getting scholars from wiki $l_wikiId"
scholars "$l_wikiId" -j > $jscholars
else
color_msg $green "$jscholars exists"
fi
scount=$(jq ".data[]| [.item] | @csv" $jscholars | wc -l)
color_msg $green "$scount scholars available"
}
#
# filter the scholars
#
# params:
# jscholars: the input json file to operate on
# field: the field to read and modify
# qlist: the list of q identifiers to filter for
# limit: the number of scholars to maximally read
#
filter_scholars() {
local jscholars="$1"
local field="$2"
local qlist="$3"
local limit="$4"
local csv="/tmp/scholars_$$.csv"
jq -r ".data[]| select (.item!=null) | [ .scholar, .item, .$field ] | @csv" $jscholars \
| head -$limit > $csv
if [ "$qlist" = "" ]
then
pattern=".*"
else
pattern="$qlist"
fi
cat $csv | grep -E $pattern
}
#
# update the wiki
#
update_wiki() {
local l_wikiId="$1"
local prop="$2"
local field="$3"
local prop_label="$4"
local qlist="$5"
color_msg "updating wiki $l_wikiId for $field $prop $prop_label"
case $prop in
desc)
;;
*)
wd props | grep "'"$prop"'"
;;
esac
filter_scholars $jscholars $field "$qlist" 10000 | while IFS=, read -r page qid value
do
qid=$(echo $qid | sed 's#"##g')
page=$(echo $page | sed 's#"##g')
value=$(echo $value | sed 's#"##g')
if [ "$verbose" = "true" ]
then
echo "$page ($qid) $field=$value"
fi
if [ "$value" = "" ]
then
case $prop in
desc)
#color_msg $blue "getting $field for $qid"
wdValue=$(wd desc $qid 2>&1)
#echo $wdValue
;;
*)
wdValue=$(wb query -s "$qid" -p $prop 2>&1)
;;
esac
if [ $? -eq 0 ]
then
case $wdValue in
"*error*"|"no result found")
;;
*)
color_msg $blue "updating $page $field to $wdValue from wikidata $qid"
wikiedit -t $l_wikiId -p "$page" --template Scholar --property $field --value "$wdValue" -f
esac
fi
fi
done
}
verbose="false"
qlist=""
delim=""
wikiId="ceur-ws"
jscholars=/tmp/${wikiId}_scholars.json
if [ $# -lt 1 ]
then
usage
else
while [ "$1" != "" ]
do
option="$1"
case $option in
-d|--debug)
set -x
;;
-h|--help)
usage
;;
desc)
prop="desc"
field="description"
prop_label="description"
update_wiki $wikiId $prop $field $prop_label $qlist
;;
Q*)
qlist="$qlist$delim$option"
delim="|"
shift
continue
;;
--props)
props | while IFS=, read -r option prop field prop_label
do
echo "$option:$prop:$field:$prop_label"
done
shift
continue
;;
-u|--update)
update_scholars $wikiId
;;
--verbose)
verbose="true"
;;
-w|--wikiId)
shift
if [ $# -lt 1 ]
then
usage
fi
wikiId=$1;
jscholars=/tmp/${wikiId}_scholars.json
;;
*)
found="false"
props | while IFS=, read -r l_option l_prop l_field l_prop_label
do
if [ "$option" = "$l_option" ]
then
shift
prop=$l_prop
field=$l_field
update_wiki $wikiId $prop $field $l_prop_label $qlist
found="true"
break
fi
done
if [ "$found" = "true" ]
then
continue
fi
echo "unknown field $1"
exit 1
;;
esac
shift
done
fi
qscholars desc
updating wiki ceur-ws for description desc description
updating Sören Auer description to founder of OntoWiki from wikidata Q27453085
editing 1 pages in ceur-ws (forced)
1/1 (100.00%): editing Sören Auer ...:weißes_häkchen:
updating Tim Berners-Lee description to English computer scientist, inventor of the World Wide Web (born 1955) from wikidata Q80
editing 1 pages in ceur-ws (forced)
1/1 (100.00%): editing Tim Berners-Lee ...:weißes_häkchen:
updating Christian Bizer description to researcher from wikidata Q17744291
editing 1 pages in ceur-ws (forced)
...
Tool to restore wiki pages from an local backup, created with wikibackup, to an destination wiki.
Argument | Description |
---|---|
-s | Source wiki - Only used to query page names. The queried page names will then be looked up in the backup. |
-t | Target wiki - The backup is restored in this wiki |
-q | SMW query to select the pages to be restored. Note that the query is only used to select the page names the actual backup is then restored from the local backup. |
-p | Names of the pages to be restored |
--backupPath | define location of the backup. Default is the default backup location of the target wiki. |
If argument -s is used a page query is executed therefore all arguments related to an page query can be used such as -ui and --limit.
Argument | Description |
---|---|
-s | Source wiki - Only used to query page names. The queried page names will then be looked up in the backup. |
-t | Target wiki - The backup is restored in this wiki |
-q | SMW query to select the pages to be restored. Note that the query is only used to select the page names the actual backup is then restored from the local backup. |
-p | Names of the pages to be restored |
--backupPath | define location of the backup. Default is the default backup location of the target wiki. |
If argument -s is used a page query is executed therefore all arguments related to an page query can be used such as -ui and --limit.
Use this argument to define a different backup folder
1$ wikibackup -s orth --backupPath "/home/user/wikibackup/orth_copy" -q "[[isA::Event]]" --limit 10
2
3downloading 10 pages from orth to /home/user/wikibackup/orth_copy
41/10 ( 10%): downloading " DBKDA 2021" ...✅
52/10 ( 20%): downloading "ENERGY 2021" ...✅
63/10 ( 30%): downloading "ICAS 2021" ...✅
74/10 ( 40%): downloading "ICNS 2021" ...✅
85/10 ( 50%): downloading 2021 ICIMP ...✅
96/10 ( 60%): downloading 3DUI 2020 ...✅
107/10 ( 70%): downloading 3IA 2009 ...✅
118/10 ( 80%): downloading 3PGIC 2010 ...✅
129/10 ( 90%): downloading 4S4D 2017 ...✅
1310/10 ( 100%): downloading 5GU 2017 ...✅
$ wikirestore -t orth --backupPath "/home/user/wikibackup/orth_copy"
restoring 10 pages from /home/user/wikibackup/orth_copy to orth
1/10 ( 10%): restore 2021 ICIMP ...✅
2/10 ( 20%): restore "ICNS 2021" ...✅
3/10 ( 30%): restore 3PGIC 2010 ...✅
4/10 ( 40%): restore 4S4D 2017 ...✅
5/10 ( 50%): restore "ENERGY 2021" ...✅
6/10 ( 60%): restore 3DUI 2020 ...✅
7/10 ( 70%): restore " DBKDA 2021" ...✅
8/10 ( 80%): restore 3IA 2009 ...✅
9/10 ( 90%): restore "ICAS 2021" ...✅
10/10 ( 100%): restore 5GU 2017 ...✅
$ wikirestore -s or -q "[[isA:Event]]" -t orth --backupPath "/home/user/wikibackup/orth_copy"
With this command we query all page names that are an Event from the wiki or and restore them in the wiki orth with the version of the page that is stored in /home/user/wikibackup/orth_copy.
wikiupload.py allows to mass upload files
wikiupload -h
usage: wikiupload.py [-h] [-d] [-V] --files FILES [FILES ...] [-f] -t TARGET
Created on 2020-11-12
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
--files FILES [FILES ...]
list of files to be uploaded
-f, --force force to (re)upload existing files - default is false
-t TARGET, --target TARGET
target wiki id
wikiupload -t test --files car.png
uploading 1 files to test
1/1 ( 100%): uploading car.png ...✅
wikiupload -h
usage: wikiupload.py [-h] [-d] [-V] --files FILES [FILES ...] [-f] -t TARGET
Created on 2020-11-12
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
--files FILES [FILES ...]
list of files to be uploaded
-f, --force force to (re)upload existing files - default is false
-t TARGET, --target TARGET
target wiki id
wikiupload -t test --files car.png
uploading 1 files to test
1/1 ( 100%): uploading car.png ...✅
wikiuser.py creates credential files and assigns a WikiId under which you can now operate. This simplifies access to your wiki. The credential file is compatible to the Java Mediawiki-Japi see CommandLine#Credential_mode
wikiuser -h
usage: wikiuser.py [-h] [-d] [-V] [-e EMAIL] [-f FILEPATH] [-l URL]
[-s SCRIPTPATH] [-p PASSWORD] [-u USER] [-v VERSION]
[-w WIKIID] [-y]
WikiUser credential handling
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
-e EMAIL, --email EMAIL
email of the user
-f FILEPATH, --file FILEPATH
ini-file path
-l URL, --url URL url of the wiki
-s SCRIPTPATH, --scriptPath SCRIPTPATH
script path
-p PASSWORD, --password PASSWORD
password
-u USER, --user USER os user id
-v VERSION, --wikiVersion VERSION
version of the wiki
-w WIKIID, --wikiId WIKIID
wiki Id
-y, --yes immediately store without asking
wikiuser -h
usage: wikiuser.py [-h] [-d] [-V] [-e EMAIL] [-f FILEPATH] [-l URL]
[-s SCRIPTPATH] [-p PASSWORD] [-u USER] [-v VERSION]
[-w WIKIID] [-y]
WikiUser credential handling
Created by Wolfgang Fahl on 2020-10-31.
Copyright 2020 Wolfgang Fahl. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
optional arguments:
-h, --help show this help message and exit
-d, --debug set debug level [default: None]
-V, --version show program's version number and exit
-e EMAIL, --email EMAIL
email of the user
-f FILEPATH, --file FILEPATH
ini-file path
-l URL, --url URL url of the wiki
-s SCRIPTPATH, --scriptPath SCRIPTPATH
script path
-p PASSWORD, --password PASSWORD
password
-u USER, --user USER os user id
-v VERSION, --wikiVersion VERSION
version of the wiki
-w WIKIID, --wikiId WIKIID
wiki Id
-y, --yes immediately store without asking
E.g. if you have an account on www.semantic-mediawiki.org you can start wikiuser in interactive mode.
wikiuser
email: john@doe.com
scriptPath: /w
user: jd
url: http://www.semantic-mediawiki.org
version: Mediawiki 1.33
wikiId: smw
password: *****
shall i store jd smw? yes/no y/ny
Now you can e.g. use "smw" as the wikiid for this wiki when using wikipush
You might want to prepare some credential ini files with the wikiuser script or Mediawiki-Japi CommandLine.
pywikibot expects a user-config.py file. The minimum recommended file for intranet usecases is:
# https://stackoverflow.com/a/60885381/1497139
# Slow down the robot such that it never makes a second page edit within
# 'put_throttle' seconds.
put_throttle = 0
# avoid warnings ...
family='bitplan'
mylang='en'
The easiest way is to put it at $HOME/.pywikibot/user-config.py
pywikibot expects a user-config.py file. The minimum recommended file for intranet usecases is:
# https://stackoverflow.com/a/60885381/1497139
# Slow down the robot such that it never makes a second page edit within
# 'put_throttle' seconds.
put_throttle = 0
# avoid warnings ...
family='bitplan'
mylang='en'
The easiest way is to put it at $HOME/.pywikibot/user-config.py
Py-3rdparty-mediawiki allows using pywikibot by simply giving each wiki an id and using the credential information created by MediaWiki-Japi. The needed family file is automatically created and registered. If you'd like to get a pure python solution for credential handling please file an issue on github - it's no big deal but i personally don't need it yet since i'm fine with the new CommandLine feature added recently.
see https://github.com/WolfgangFahl/py-3rdparty-mediawiki/issues/1
from wikibot.wikibot import WikiBot
wikibot=WikiBot.ofWikiId("test2")
wikibot.site ...
Py-3rdparty-mediawiki allows using pywikibot by simply giving each wiki an id and using the credential information created by MediaWiki-Japi. The needed family file is automatically created and registered. If you'd like to get a pure python solution for credential handling please file an issue on github - it's no big deal but i personally don't need it yet since i'm fine with the new CommandLine feature added recently.
see https://github.com/WolfgangFahl/py-3rdparty-mediawiki/issues/1
from wikibot.wikibot import WikiBot
wikibot=WikiBot.ofWikiId("test2")
wikibot.site ...