diff --git a/scholia/app/templates/wikiproject.html b/scholia/app/templates/wikiproject.html new file mode 100644 index 000000000..bf4fa0ef9 --- /dev/null +++ b/scholia/app/templates/wikiproject.html @@ -0,0 +1,92 @@ +{% extends "base.html" %} + +{% set aspect = 'wikiproject' %} + +{% block in_ready %} + +{{ sparql_to_table("maintained") }} +{{ sparql_to_table("focus") }} + +{{ sparql_to_iframe('context') }} +{{ sparql_to_table('recently-published-works') }} +{{ sparql_to_iframe('publications-per-year') }} +{{ sparql_to_table('earliest-published-works') }} +{{ sparql_to_table('authors') }} +{{ sparql_to_table('author-awards') }} +{{ sparql_to_table('topics') }} +{{ sparql_to_table('venues') }} +{{ sparql_to_iframe('organization-map') }} + +{% endblock %} + + + +{% block page_content %} + +

WikiProject

+ +
+ +

Types of items maintained by this WikiProject

+ +
+ +

Types of items on focus list of this WikiProject

+ +
+ +

The topic in context

+ +
+ +
+ +

Works

+ +

Recently published worksRSS icon

+ +
+ +

Publications per year

+ +
+ +
+ +

Earliest published works

+ +
+ +

Authors

+ +

Related authors

+ +
+ +

Awards received by authors

+ +
+ +

Topics

+ +

From random sample

+ +
+ +

Related venues and series

+ +
+ +

Map of organizations associated with related works

+ +The colours indicate how many publications on the topic are associated with organizations in the given location, as +detailed in the legend (top right). + +
+ +
+ +{% endblock %} \ No newline at end of file diff --git a/scholia/app/templates/wikiproject_author-awards.sparql b/scholia/app/templates/wikiproject_author-awards.sparql new file mode 100644 index 000000000..f793d204f --- /dev/null +++ b/scholia/app/templates/wikiproject_author-awards.sparql @@ -0,0 +1,31 @@ +PREFIX target: + +SELECT ?count +?award ?awardLabel (CONCAT("/award/", SUBSTR(STR(?award), 32)) AS ?awardUrl) +?recipients ?recipientsUrl +WITH { + SELECT (COUNT(?researcher) AS ?count) ?award + (GROUP_CONCAT(DISTINCT ?researcher_label; separator=", ") AS ?recipients) + (CONCAT("../authors/", GROUP_CONCAT(DISTINCT SUBSTR(STR(?researcher), 32); separator=",")) AS ?recipientsUrl) + WHERE { + { + SELECT DISTINCT ?researcher ?award WHERE { + hint:Query hint:optimizer "None" . + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + ?work wdt:P50 ?researcher . + ?researcher wdt:P166 ?award . + } + LIMIT 100 + } + ?researcher rdfs:label ?researcher_label . FILTER (LANG(?researcher_label) = 'en') + } + GROUP BY ?award +} AS %result +WHERE { + INCLUDE %result + ?award rdfs:label ?awardLabel . FILTER (LANG(?awardLabel) = 'en') +} +GROUP BY ?count ?award ?awardLabel ?recipients ?recipientsUrl +ORDER BY DESC(?count) diff --git a/scholia/app/templates/wikiproject_authors.sparql b/scholia/app/templates/wikiproject_authors.sparql new file mode 100644 index 000000000..c0a700d82 --- /dev/null +++ b/scholia/app/templates/wikiproject_authors.sparql @@ -0,0 +1,30 @@ +#defaultView:Table + +PREFIX target: + +SELECT + ?count + ?author ?authorLabel ?authorDescription (CONCAT("/author/", SUBSTR(STR(?author), 32)) AS ?authorUrl) + (COALESCE(?orcid_, CONCAT("orcid-search/quick-search/?searchQuery=", ?authorLabel)) AS ?orcid) +WITH { + SELECT + ?author + (count(?work) as ?count) + WHERE { + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + ?work wdt:P50 ?author . + } + GROUP BY ?author + ORDER BY DESC(?count) + LIMIT 200 +} AS %result +WHERE { + INCLUDE %result + + # Include optional ORCID iD + OPTIONAL { ?author wdt:P496 ?orcid_ . } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } +} +ORDER BY DESC(?count) diff --git a/scholia/app/templates/wikiproject_context.sparql b/scholia/app/templates/wikiproject_context.sparql new file mode 100644 index 000000000..00fa623b8 --- /dev/null +++ b/scholia/app/templates/wikiproject_context.sparql @@ -0,0 +1,54 @@ +PREFIX target: +#defaultView:Graph +SELECT ?node ?nodeLabel ?nodeImage ?childNode ?childNodeLabel ?childNodeImage ?rgb +WITH { + SELECT DISTINCT ?property WHERE { + ?property a wikibase:Property; + wdt:P31 wd:Q18610173 ; + wdt:P31 wd:Q26940804 . + } +} AS %properties +WITH { + SELECT DISTINCT ?node ?childNode WHERE { + BIND(target: AS ?node) + ?node ?p ?i. + ?childNode ?x ?p. + ?childNode rdf:type wikibase:Property. + FILTER(STRSTARTS(STR(?i), "http://www.wikidata.org/entity/Q")) + FILTER(STRSTARTS(STR(?childNode), "http://www.wikidata.org/entity/P")) + } + LIMIT 5000 +} AS %nodes +WITH { + SELECT DISTINCT ?childNode ?node ?rgb WHERE { + BIND("EFFBD8" AS ?rgb) + target: ?p ?childNode. + ?node ?x ?p. + ?node rdf:type wikibase:Property. + FILTER(STRSTARTS(STR(?childNode), "http://www.wikidata.org/entity/Q")) + } + LIMIT 5000 +} AS %childNodes +WHERE { + { + INCLUDE %nodes + } + UNION + { + INCLUDE %childNodes + } + + OPTIONAL { + INCLUDE %properties + ?property wikibase:directClaim ?nodeclaim. + ?node ?nodeclaim ?nodeImage. + } + + OPTIONAL { + INCLUDE %properties + ?property wikibase:directClaim ?childNodeclaim. + ?childNode ?childNodeclaim ?childNodeImage. + } + + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } +} diff --git a/scholia/app/templates/wikiproject_earliest-published-works.sparql b/scholia/app/templates/wikiproject_earliest-published-works.sparql new file mode 100644 index 000000000..b130562d5 --- /dev/null +++ b/scholia/app/templates/wikiproject_earliest-published-works.sparql @@ -0,0 +1,35 @@ +PREFIX target: + +SELECT ?date ?work ?workLabel (CONCAT("/work/", SUBSTR(STR(?work), 32)) AS ?workUrl) +?topicsUrl ?topics +WITH { + SELECT DISTINCT ?work WHERE { + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + } +} AS %works +WITH { + SELECT (MAX(?dates) as ?datetime) ?work (GROUP_CONCAT(DISTINCT ?topic_label; separator=" // ") AS ?topics) + (CONCAT("../topics/", GROUP_CONCAT(DISTINCT SUBSTR(STR(?topic), 32); separator=",")) AS ?topicsUrl) + WHERE { + INCLUDE %works + ?work wdt:P921 ?topic . + ?work wdt:P577 ?dates . + FILTER (!isBLANK(?dates)) . + ?topic rdfs:label ?topic_label . FILTER (lang(?topic_label) = 'en') + } + GROUP BY ?work +} AS %result +WHERE { + INCLUDE %result + + # There is a problem with BC dates + # BIND(xsd:date(?datetime) AS ?date) + BIND(REPLACE(STR(?datetime), 'T.*', '') AS ?date) + + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } +} +GROUP BY ?date ?work ?workLabel ?topicsUrl ?topics +ORDER BY ASC(?date) +LIMIT 500 diff --git a/scholia/app/templates/wikiproject_focus.sparql b/scholia/app/templates/wikiproject_focus.sparql new file mode 100644 index 000000000..7e564bea9 --- /dev/null +++ b/scholia/app/templates/wikiproject_focus.sparql @@ -0,0 +1,13 @@ +SELECT ?type ?typeLabel ?count WITH { + SELECT DISTINCT ?type (COUNT(?item) AS ?count) WHERE { + ?item wdt:P5008 wd:{{ q }}; + (wdt:P31|wdt:P279) ?type. + } + GROUP BY ?type ?count + ORDER BY DESC (?count) +} AS %result +WHERE { + INCLUDE %result + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en,da,de,es,fr,it,sv,uk,zh". } +} +ORDER BY DESC (?count) \ No newline at end of file diff --git a/scholia/app/templates/wikiproject_maintained.sparql b/scholia/app/templates/wikiproject_maintained.sparql new file mode 100644 index 000000000..2afb622f0 --- /dev/null +++ b/scholia/app/templates/wikiproject_maintained.sparql @@ -0,0 +1,13 @@ +SELECT ?type ?typeLabel ?count WITH { + SELECT DISTINCT ?type (COUNT(?item) AS ?count) WHERE { + ?item wdt:P6104 wd:{{ q }}; + (wdt:P31|wdt:P279) ?type. + } + GROUP BY ?type ?count + ORDER BY DESC (?count) +} AS %result +WHERE { + INCLUDE %result + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en,da,de,es,fr,it,sv,uk,zh". } +} +ORDER BY DESC (?count) \ No newline at end of file diff --git a/scholia/app/templates/wikiproject_organization-map.sparql b/scholia/app/templates/wikiproject_organization-map.sparql new file mode 100644 index 000000000..b86d07c5b --- /dev/null +++ b/scholia/app/templates/wikiproject_organization-map.sparql @@ -0,0 +1,37 @@ +#defaultView:Map + +PREFIX target: + +SELECT ?organization ?organizationLabel ?geo ?count ?layer +WITH { + SELECT DISTINCT ?work WHERE { + # Works on the topic + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + ?work wdt:P50 []. + } + LIMIT 20000 +} AS %works +WITH { + SELECT DISTINCT ?organization ?geo (COUNT(DISTINCT ?work) AS ?count) WHERE { + INCLUDE %works + # Authors who have published works on the topic + ?work wdt:P50 ?author . + ?author ( wdt:P108 | wdt:P463 | wdt:P1416 ) / wdt:P361* ?organization . + # Use the headquarters location by default but keep the coordinate location as a fallback + OPTIONAL{?organization p:P159/pq:P625 ?hq_geo} + OPTIONAL{?organization wdt:P625 ?coord_geo} + BIND(IF(BOUND(?hq_geo), ?hq_geo, ?coord_geo) AS ?geo) . + FILTER(BOUND(?geo)) . + } + GROUP BY ?organization ?geo + ORDER BY DESC (?count) + LIMIT 2000 +} AS %organizations +WHERE { + INCLUDE %organizations + BIND(IF( (?count < 1), "No results", IF((?count < 2), "1 result", IF((?count < 11), "1 < results ≤ 10", IF((?count < 101), "10 < results ≤ 100", IF((?count < 1001), "100 < results ≤ 1000", IF((?count < 10001), "1000 < results ≤ 10000", "10000 or more results") ) ) ) )) AS ?layer ) + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } + } +ORDER BY DESC (?count) diff --git a/scholia/app/templates/wikiproject_publications-per-year.sparql b/scholia/app/templates/wikiproject_publications-per-year.sparql new file mode 100644 index 000000000..fa6513a36 --- /dev/null +++ b/scholia/app/templates/wikiproject_publications-per-year.sparql @@ -0,0 +1,56 @@ +#defaultView:BarChart + +PREFIX target: + +SELECT + (STR(?year_) AS ?year) + (COUNT(?work) AS ?number_of_publications) + + # Work type used to color the bar chart + ?type +WITH { + # Find works with the topic. Also report the year + SELECT + ?work (MIN(?years) AS ?year_) (1 AS ?dummy) (SAMPLE(?article_type_) AS ?article_type) + WHERE { + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + ?work wdt:P577 ?dates . + BIND(YEAR(?dates) AS ?years) . + + ?work wdt:P31 ?article_type_ . + } + GROUP BY ?work +} AS %works +WITH { + SELECT ?year_ WHERE { + # default values = 0 + ?year_item wdt:P31 wd:Q577 . + ?year_item wdt:P585 ?date . + BIND(YEAR(?date) AS ?year_) + } +} AS %default_counts +WITH { + # Find earliest publication year + SELECT (MIN(?year_) AS ?earliest_year) WHERE { + INCLUDE %works + } + GROUP BY ?dummy +} AS %earliest +WHERE { + { + INCLUDE %works + ?article_type rdfs:label ?type . FILTER (LANG(?type) = "en") + } + UNION + { + INCLUDE %default_counts + BIND("_" AS ?type) + } + INCLUDE %earliest + BIND(YEAR(NOW()) AS ?this_year) + FILTER (?year_ >= ?earliest_year && ?year_ <= ?this_year && ?year_ >= YEAR("1900-01-01"^^xsd:dateTime)) +} +GROUP BY ?year_ ?type +ORDER BY ?year diff --git a/scholia/app/templates/wikiproject_recently-published-works.sparql b/scholia/app/templates/wikiproject_recently-published-works.sparql new file mode 100644 index 000000000..d2120f49c --- /dev/null +++ b/scholia/app/templates/wikiproject_recently-published-works.sparql @@ -0,0 +1,34 @@ +PREFIX target: + +SELECT ?date ?work ?workLabel (CONCAT("/work/", SUBSTR(STR(?work), 32)) AS ?workUrl) + ?topicsUrl ?topics +WITH { + SELECT DISTINCT ?work WHERE { + { ?work wdt:P6104 target: .} + union + { ?work wdt:P5008 target: .} + } +} AS %works +WITH { + SELECT (MAX(?dates) as ?datetime) ?work (GROUP_CONCAT(DISTINCT ?topic_label; separator=" // ") AS ?topics) + (CONCAT("../topics/", GROUP_CONCAT(DISTINCT SUBSTR(STR(?topic), 32); separator=",")) AS ?topicsUrl) + WHERE { + INCLUDE %works + ?work wdt:P921 ?topic . + OPTIONAL { ?work wdt:P577 ?dates . } + ?topic rdfs:label ?topic_label . FILTER (lang(?topic_label) = 'en') + } + GROUP BY ?work +} AS %result +WHERE { + INCLUDE %result + + # There is a problem with BC dates + # BIND(xsd:date(?datetime) AS ?date) + BIND(REPLACE(STR(?datetime), 'T.*', '') AS ?date) + + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } +} +GROUP BY ?date ?work ?workLabel ?topicsUrl ?topics +ORDER BY DESC(?date) +LIMIT 500 diff --git a/scholia/app/templates/wikiproject_topics.sparql b/scholia/app/templates/wikiproject_topics.sparql new file mode 100644 index 000000000..c046db33f --- /dev/null +++ b/scholia/app/templates/wikiproject_topics.sparql @@ -0,0 +1,28 @@ +#defaultView:Table + +PREFIX target: + +SELECT ?count (CONCAT("/topics/{{ q }},", SUBSTR(STR(?topic), 32)) AS ?countUrl) + ?topic ?topicLabel (CONCAT("/topic/", SUBSTR(STR(?topic), 32)) AS ?topicUrl) + ?example_work ?example_workLabel (CONCAT("/work/", SUBSTR(STR(?example_work), 32)) AS ?example_workUrl) +WITH { + SELECT (COUNT(?work) AS ?count) ?topic (SAMPLE(?work) AS ?example_work) WHERE { + # Find works for the specific queried topic + VALUES ?p { wdt:P6104 wdt:P5008 } + # Find works for the specific queried topic + SERVICE bd:sample { ?work ?p target: . bd:serviceParam bd:sample.limit 10000 } + + # Find co-occuring topics + ?work wdt:P921 ?topic . + + # Avoid listing the queried topic + FILTER (target: != ?topic) + } + GROUP BY ?topic +} AS %result +WHERE { + # Label the results + INCLUDE %result + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } +} +ORDER BY DESC(?count) diff --git a/scholia/app/templates/wikiproject_venues.sparql b/scholia/app/templates/wikiproject_venues.sparql new file mode 100644 index 000000000..5b082cf7e --- /dev/null +++ b/scholia/app/templates/wikiproject_venues.sparql @@ -0,0 +1,21 @@ +#defaultView:Table + +PREFIX target: + +SELECT ?count ?short_name +?venue ?venueLabel (CONCAT("/venue/", SUBSTR(STR(?venue), 32)) AS ?venueUrl) +WITH { + SELECT (count(?work) as ?count) ?venue (SAMPLE(?short_name_) AS ?short_name) WHERE { + { ?work wdt:P6104 target: . } + union { ?work wdt:P5008 target: . } + ?work wdt:P1433/wdt:P179* ?venue . + OPTIONAL { ?venue wdt:P1813 ?short_name_ . } + } + GROUP BY ?venue +} AS %result +WHERE { + INCLUDE %result + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" . } +} +ORDER BY DESC(?count) +LIMIT 200 diff --git a/scholia/app/views.py b/scholia/app/views.py index 2915dfda3..6dc099424 100644 --- a/scholia/app/views.py +++ b/scholia/app/views.py @@ -2465,6 +2465,24 @@ def show_about(): return render_template('about.html') +@main.route('/wikiproject/' + q_pattern) +def show_wikiproject(q): + """Return rendered HTML page for specific WikiProject. + + Parameters + ---------- + q : str + Wikidata item identifier + + Returns + ------- + html : str + Rendered HTML page for specific WikiProject. + + """ + return render_template('wikiproject.html', q=q) + + @main.route('/favicon.ico') def show_favicon(): """Detect and redirect for the favicon.ico.""" diff --git a/scholia/query.py b/scholia/query.py index 75a84d7fb..20c2e6979 100644 --- a/scholia/query.py +++ b/scholia/query.py @@ -267,7 +267,7 @@ def identifier_to_qs(property, identifier): Notes ----- - The Wikidata Query Service is queries to resolve the given identifier. If + The Wikidata Query Service is queried to resolve the given identifier. If an error happens an empty list is returned. Examples @@ -1271,7 +1271,7 @@ def q_to_class(q): 'Q46855', # hackathon 'Q625994', # conference 'Q2020153', # scientific conference - 'Q40444998', # akademic workshop + 'Q40444998', # academic workshop ]): class_ = 'event' elif set(classes).intersection([ @@ -1292,6 +1292,8 @@ def q_to_class(q): 'Q22325163', # macromolecular complex ]): class_ = 'complex' + elif ('Q16695773' in classes): # wikiproject + class_ = 'wikiproject' else: query = 'select ?class where {{ wd:{q} wdt:P279+ ?class }}'.format( q=escape_string(q))