mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Extract and show license key
List of available licenses is pre-extracted from UploadWizard
MediaWiki extension. This should eventually be switched to use
some live query to the site configuration.
The license display is more or less localizable, for known templates.
Unrecognized templates specified as parameters to {{self}} will be
recognized (unlocalized) but others may not be.
Change-Id: I9df5fe807798a191a3bb0a45464760c75f19e366
This commit is contained in:
parent
dde64dc4d2
commit
4c45c88ade
11 changed files with 440 additions and 4 deletions
|
|
@ -31,6 +31,14 @@
|
|||
android:text="Description of the media goes here. This can potentially be fairly long, and will need to wrap across multiple lines. We hope it looks nice though."
|
||||
android:id="@+id/mediaDetailDesc"
|
||||
android:layout_gravity="left|start"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="License link"
|
||||
android:id="@+id/mediaDetailLicense"
|
||||
android:layout_gravity="left|start"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp" /> <!-- 18sp == MediumText -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -93,9 +93,42 @@
|
|||
<string name="menu_download">Download</string>
|
||||
<string name="preference_license">License</string>
|
||||
|
||||
<!-- These three are semi-legacy entries, and should be changed in future -->
|
||||
<string name="license_name_cc_by_sa">CC\u00A0Attribution-ShareAlike\u00A03.0</string>
|
||||
<string name="license_name_cc_by">CC\u00A0Attribution\u00A03.0</string>
|
||||
<string name="license_name_cc0">CC0</string>
|
||||
|
||||
<!-- Licenses from the default UploadWizard selection list -->
|
||||
<string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string>
|
||||
<string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (Austria)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_de">CC BY-SA 3.0 (Germany)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ee">CC BY-SA 3.0 (Estonia)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_es">CC BY-SA 3.0 (Spain)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_hr">CC BY-SA 3.0 (Croatia)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_lu">CC BY-SA 3.0 (Luxembourg)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_nl">CC BY-SA 3.0 (Netherlands)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_no">CC BY-SA 3.0 (Norway)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_pl">CC BY-SA 3.0 (Poland)</string>
|
||||
<string name="license_name_cc_by_sa_3_0_ro">CC BY-SA 3.0 (Romania)</string>
|
||||
<string name="license_name_cc_by_3_0">CC BY 3.0</string>
|
||||
<string name="license_name_cc_zero">CC Zero</string>
|
||||
<string name="license_name_own_pd">own-pd</string>
|
||||
<string name="license_name_cc_by_sa_2_5">CC BY-SA 2.5</string>
|
||||
<string name="license_name_cc_by_2_5">CC BY 2.5</string>
|
||||
<string name="license_name_cc_by_sa_2_0">CC BY-SA 2.0</string>
|
||||
<string name="license_name_cc_by_2_0">CC BY-SA 2.0</string>
|
||||
<string name="license_name_cc_2_0">CC BY 2.0</string>
|
||||
<string name="license_name_fal">Free Art License</string>
|
||||
<string name="license_name_pd_old_100">Public domain (author died over 100 years ago)</string>
|
||||
<string name="license_name_pd_old">Public domain (copyright expired)</string>
|
||||
<string name="license_name_pd_art">Public domain (art)</string>
|
||||
<string name="license_name_pd_us">Public domain (US)</string>
|
||||
<string name="license_name_pd_usgov">Public domain (US government)</string>
|
||||
<string name="license_name_pd_usgov_nasa">Public domain (NASA)</string>
|
||||
<string name="license_name_pd_ineligible">Public domain (ineligible for copyright)</string>
|
||||
<string name="license_name_attribution">Attribution</string>
|
||||
<string name="license_name_gfdl">GNU Free Documentation License</string>
|
||||
|
||||
<string name="welcome_wikipedia_text">Contribute your images. Help Wikipedia articles come to life!</string>
|
||||
<string name="welcome_wikipedia_subtext">Images on Wikipedia come from Wikimedia Commons.</string>
|
||||
<string name="welcome_copyright_text">Your images help educate people around the world.</string>
|
||||
|
|
|
|||
31
commons/res/xml/wikimedia_licenses.xml
Normal file
31
commons/res/xml/wikimedia_licenses.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<licenses xmlns="https://www.mediawiki.org/wiki/Extension:UploadWizard/xmlns/licenses">
|
||||
<license id="cc-by-sa-3.0" template="cc-by-sa-3.0" url="https://creativecommons.org/licenses/by-sa/3.0/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-at" template="cc-by-sa-3.0-at" url="https://creativecommons.org/licenses/by-sa/3.0/at/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-de" template="cc-by-sa-3.0-de" url="https://creativecommons.org/licenses/by-sa/3.0/de/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-ee" template="cc-by-sa-3.0-ee" url="https://creativecommons.org/licenses/by-sa/3.0/ee/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-es" template="cc-by-sa-3.0-es" url="https://creativecommons.org/licenses/by-sa/3.0/es/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-hr" template="cc-by-sa-3.0-hr" url="https://creativecommons.org/licenses/by-sa/3.0/hr/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-lu" template="cc-by-sa-3.0-lu" url="https://creativecommons.org/licenses/by-sa/3.0/lu/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-nl" template="cc-by-sa-3.0-nl" url="https://creativecommons.org/licenses/by-sa/3.0/nl/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-no" template="cc-by-sa-3.0-no" url="https://creativecommons.org/licenses/by-sa/3.0/no/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-pl" template="cc-by-sa-3.0-pl" url="https://creativecommons.org/licenses/by-sa/3.0/pl/deed.$lang"/>
|
||||
<license id="cc-by-sa-3.0-ro" template="cc-by-sa-3.0-ro" url="https://creativecommons.org/licenses/by-sa/3.0/ro/deed.$lang"/>
|
||||
<license id="cc-by-3.0" template="cc-by-3.0" url="https://creativecommons.org/licenses/by/3.0/deed.$lang"/>
|
||||
<license id="cc-zero" template="cc-zero" url="https://creativecommons.org/publicdomain/zero/1.0/deed.$lang"/>
|
||||
<license id="own-pd" template="cc-zero"/>
|
||||
<license id="cc-by-sa-2.5" template="cc-by-sa-2.5" url="https://creativecommons.org/licenses/by-sa/2.5/deed.$lang"/>
|
||||
<license id="cc-by-2.5" template="cc-by-2.5" url="https://creativecommons.org/licenses/by/2.5/deed.$lang"/>
|
||||
<license id="cc-by-sa-2.0" template="cc-by-sa-2.0" url="https://creativecommons.org/licenses/by-sa/2.0/deed.$lang"/>
|
||||
<license id="cc-by-2.0" template="cc-by-2.0" url="https://creativecommons.org/licenses/by/2.0/deed.$lang"/>
|
||||
<license id="fal" template="FAL"/>
|
||||
<license id="pd-old-100" template="PD-old-100"/>
|
||||
<license id="pd-old" template="PD-old"/>
|
||||
<license id="pd-art" template="PD-Art"/>
|
||||
<license id="pd-us" template="PD-US"/>
|
||||
<license id="pd-usgov" template="PD-USGov"/>
|
||||
<license id="pd-usgov-nasa" template="PD-USGov-NASA"/>
|
||||
<license id="pd-ineligible" template="pd-ineligible"/>
|
||||
<license id="attribution" template="attribution"/>
|
||||
<license id="gfdl" template="GFDL"/>
|
||||
</licenses>
|
||||
46
commons/src/main/java/org/wikimedia/commons/License.java
Normal file
46
commons/src/main/java/org/wikimedia/commons/License.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package org.wikimedia.commons;
|
||||
|
||||
public class License {
|
||||
String key;
|
||||
String template;
|
||||
String url;
|
||||
String name;
|
||||
|
||||
public License(String key, String template, String url, String name) {
|
||||
if (key == null) {
|
||||
throw new RuntimeException("License.key must not be null");
|
||||
}
|
||||
if (template == null) {
|
||||
throw new RuntimeException("License.template must not be null");
|
||||
}
|
||||
this.key = key;
|
||||
this.template = template;
|
||||
this.url = url;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
// hack
|
||||
return getKey();
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public String getUrl(String language) {
|
||||
if (url == null) {
|
||||
return null;
|
||||
} else {
|
||||
return url.replace("$lang", language);
|
||||
}
|
||||
}
|
||||
}
|
||||
75
commons/src/main/java/org/wikimedia/commons/LicenseList.java
Normal file
75
commons/src/main/java/org/wikimedia/commons/LicenseList.java
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
package org.wikimedia.commons;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class LicenseList {
|
||||
Map<String, License> licenses = new HashMap<String, License>();
|
||||
Resources res;
|
||||
|
||||
private static String XMLNS_LICENSE = "https://www.mediawiki.org/wiki/Extension:UploadWizard/xmlns/licenses";
|
||||
|
||||
public LicenseList(Activity activity) {
|
||||
res = activity.getResources();
|
||||
XmlPullParser parser = res.getXml(R.xml.wikimedia_licenses);
|
||||
while (Utils.xmlFastForward(parser, XMLNS_LICENSE, "license")) {
|
||||
String id = parser.getAttributeValue(null, "id");
|
||||
String template = parser.getAttributeValue(null, "template");
|
||||
String url = parser.getAttributeValue(null, "url");
|
||||
String name = nameForTemplate(template);
|
||||
License license = new License(id, template, url, name);
|
||||
licenses.put(id, license);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Set<String> keySet() {
|
||||
return licenses.keySet();
|
||||
}
|
||||
|
||||
public Collection<License> values() {
|
||||
return licenses.values();
|
||||
}
|
||||
|
||||
public License get(String key) {
|
||||
return licenses.get(key);
|
||||
}
|
||||
|
||||
public License licenseForTemplate(String template) {
|
||||
String ucTemplate = Utils.capitalize(template);
|
||||
for (License license : values()) {
|
||||
if (ucTemplate.equals(Utils.capitalize(license.getTemplate()))) {
|
||||
return license;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String nameIdForTemplate(String template) {
|
||||
// hack :D
|
||||
// cc-by-sa-3.0 -> cc_by_sa_3_0
|
||||
return "license_name_" + template.toLowerCase().replace("-", "_").replace(".", "_");
|
||||
}
|
||||
|
||||
private int stringIdByName(String stringId) {
|
||||
return res.getIdentifier("org.wikimedia.commons:string/" + stringId, null, null);
|
||||
}
|
||||
|
||||
public String nameForTemplate(String template) {
|
||||
Log.d("Commons", "LicenseList.nameForTemplate: template: " + template);
|
||||
String stringId = nameIdForTemplate(template);
|
||||
Log.d("Commons", "LicenseList.nameForTemplate: stringId: " + stringId);
|
||||
int nameId = stringIdByName(stringId);
|
||||
Log.d("Commons", "LicenseList.nameForTemplate: nameId: " + nameId);
|
||||
String name = res.getString(nameId);
|
||||
Log.d("Commons", "LicenseList.nameForTemplate: name: " + name);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -33,16 +33,19 @@ public class MediaDataExtractor {
|
|||
private Map<String, String> descriptions;
|
||||
private String author;
|
||||
private Date date;
|
||||
private String license;
|
||||
private LicenseList licenseList;
|
||||
|
||||
/**
|
||||
* @param filename of the target media object, should include 'File:' prefix
|
||||
*/
|
||||
public MediaDataExtractor(String filename) {
|
||||
public MediaDataExtractor(String filename, LicenseList licenseList) {
|
||||
this.filename = filename;
|
||||
categories = new ArrayList<String>();
|
||||
descriptions = new HashMap<String, String>();
|
||||
fetched = false;
|
||||
processed = false;
|
||||
this.licenseList = licenseList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,7 +117,41 @@ public class MediaDataExtractor {
|
|||
descriptions = getMultilingualText(descriptionNode);
|
||||
|
||||
Node authorNode = findTemplateParameter(templateNode, "author");
|
||||
author = Utils.getStringFromDOM(authorNode);
|
||||
author = getFlatText(authorNode);
|
||||
}
|
||||
|
||||
/*
|
||||
Pull up the license data list...
|
||||
look for the templates in two ways:
|
||||
* look for 'self' template and check its first parameter
|
||||
* if none, look for any of the known templates
|
||||
*/
|
||||
Log.d("Commons", "MediaDataExtractor searching for license");
|
||||
Node selfLicenseNode = findTemplate(doc.getDocumentElement(), "self");
|
||||
if (selfLicenseNode != null) {
|
||||
Node firstNode = findTemplateParameter(selfLicenseNode, 1);
|
||||
String licenseTemplate = getFlatText(firstNode);
|
||||
License license = licenseList.licenseForTemplate(licenseTemplate);
|
||||
if (license == null) {
|
||||
Log.d("Commons", "MediaDataExtractor found no matching license for self parameter: " + licenseTemplate + "; faking it");
|
||||
this.license = licenseTemplate; // hack hack! For non-selectable licenses that are still in the system.
|
||||
} else {
|
||||
// fixme: record the self-ness in here too... sigh
|
||||
// all this needs better server-side metadata
|
||||
this.license = license.getKey();
|
||||
Log.d("Commons", "MediaDataExtractor found self-license " + this.license);
|
||||
}
|
||||
} else {
|
||||
for (License license : licenseList.values()) {
|
||||
String templateName = license.getTemplate();
|
||||
Node template = findTemplate(doc.getDocumentElement(), templateName);
|
||||
if (template != null) {
|
||||
// Found!
|
||||
this.license = license.getKey();
|
||||
Log.d("Commons", "MediaDataExtractor found non-self license " + this.license);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +238,10 @@ public class MediaDataExtractor {
|
|||
throw new IOException("No matching template parameter node found.");
|
||||
}
|
||||
|
||||
private String getFlatText(Node parentNode) throws IOException {
|
||||
return parentNode.getTextContent();
|
||||
}
|
||||
|
||||
// Extract a dictionary of multilingual texts from a subset of the parse tree.
|
||||
// Texts are wrapped in things like {{en|foo} or {{en|1=foo bar}}.
|
||||
// Text outside those wrappers is stuffed into a 'default' faux language key if present.
|
||||
|
|
@ -246,6 +287,9 @@ public class MediaDataExtractor {
|
|||
|
||||
media.setCategories(categories);
|
||||
media.setDescriptions(descriptions);
|
||||
if (license != null) {
|
||||
media.setLicense(license);
|
||||
}
|
||||
|
||||
// add author, date, etc fields
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import org.apache.commons.codec.binary.Hex;
|
|||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.codec.net.URLCodec;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import javax.xml.transform.*;
|
||||
import java.io.*;
|
||||
|
|
@ -194,4 +196,33 @@ public class Utils {
|
|||
String uriStr = CommonsApplication.HOME_URL + urlEncode(underscored);
|
||||
return Uri.parse(uriStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast-forward an XmlPullParser to the next instance of the given element
|
||||
* in the input stream (namespaced).
|
||||
*
|
||||
* @param parser
|
||||
* @param namespace
|
||||
* @param element
|
||||
* @return true on match, false on failure
|
||||
*/
|
||||
public static boolean xmlFastForward(XmlPullParser parser, String namespace, String element) {
|
||||
try {
|
||||
while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
||||
if (parser.getEventType() == XmlPullParser.START_TAG &&
|
||||
parser.getNamespace().equals(namespace) &&
|
||||
parser.getName().equals(element)) {
|
||||
// We found it!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
|
||||
private TextView title;
|
||||
private TextView desc;
|
||||
private TextView license;
|
||||
private ListView listView;
|
||||
private ArrayList<String> categoryNames;
|
||||
private boolean categoriesLoaded = false;
|
||||
|
|
@ -133,6 +134,7 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
spacer = (MediaDetailSpacer) detailView.findViewById(R.id.mediaDetailSpacer);
|
||||
title = (TextView) detailView.findViewById(R.id.mediaDetailTitle);
|
||||
desc = (TextView) detailView.findViewById(R.id.mediaDetailDesc);
|
||||
license = (TextView) detailView.findViewById(R.id.mediaDetailLicense);
|
||||
|
||||
// Enable or disable editing on the title
|
||||
/*
|
||||
|
|
@ -160,10 +162,12 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
// FIXME: cache this data
|
||||
detailFetchTask = new AsyncTask<Void, Void, Boolean>() {
|
||||
private MediaDataExtractor extractor;
|
||||
private LicenseList licenseList;
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
extractor = new MediaDataExtractor(media.getFilename());
|
||||
licenseList = new LicenseList(getActivity());
|
||||
extractor = new MediaDataExtractor(media.getFilename(), licenseList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -187,6 +191,16 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
// Fill some fields
|
||||
desc.setText(media.getDescription("en"));
|
||||
|
||||
String licenseKey = media.getLicense();
|
||||
License licenseObj = licenseList.get(licenseKey);
|
||||
if (licenseObj == null) {
|
||||
license.setText(licenseKey);
|
||||
} else {
|
||||
license.setText(licenseObj.getName());
|
||||
}
|
||||
Log.d("Commons", "Media license is: " + media.getLicense());
|
||||
|
||||
|
||||
categoryNames.removeAll(categoryNames);
|
||||
categoryNames.addAll(media.getCategories());
|
||||
|
||||
|
|
@ -231,7 +245,8 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
}
|
||||
|
||||
title.setText(media.getDisplayTitle());
|
||||
desc.setText("");
|
||||
desc.setText(""); // fill in from network...
|
||||
license.setText(""); // fill in from network...
|
||||
|
||||
/*
|
||||
title.addTextChangedListener(new TextWatcher() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue