mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +01:00 
			
		
		
		
	Moved single-use code out of Utils over to where it's actually used.
This commit is contained in:
		
							parent
							
								
									388f588301
								
							
						
					
					
						commit
						d0a85dbd82
					
				
					 12 changed files with 184 additions and 217 deletions
				
			
		|  | @ -144,12 +144,6 @@ public class CommonsApplication extends DaggerApplication { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean deviceHasCamera() { | ||||
|         PackageManager pm = getPackageManager(); | ||||
|         return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || | ||||
|                 pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); | ||||
|     } | ||||
| 
 | ||||
|     public void clearApplicationData(Context context) { | ||||
|         File cacheDirectory = context.getCacheDir(); | ||||
|         File applicationDirectory = new File(cacheDirectory.getParent()); | ||||
|  |  | |||
|  | @ -5,7 +5,9 @@ import android.content.res.Resources; | |||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.Locale; | ||||
|  | @ -21,7 +23,7 @@ public class LicenseList { | |||
|     public LicenseList(Activity activity) { | ||||
|         res = activity.getResources(); | ||||
|         XmlPullParser parser = res.getXml(R.xml.wikimedia_licenses); | ||||
|         while (Utils.xmlFastForward(parser, XMLNS_LICENSE, "license")) { | ||||
|         while (xmlFastForward(parser, XMLNS_LICENSE, "license")) { | ||||
|             String id = parser.getAttributeValue(null, "id"); | ||||
|             String template = parser.getAttributeValue(null, "template"); | ||||
|             String url = parser.getAttributeValue(null, "url"); | ||||
|  | @ -76,4 +78,34 @@ public class LicenseList { | |||
|         } | ||||
|         return template; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      */ | ||||
|     private 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; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,26 +1,10 @@ | |||
| package fr.free.nrw.commons; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.os.Build; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.text.Html; | ||||
| import android.text.Spanned; | ||||
| 
 | ||||
| import org.apache.commons.codec.binary.Hex; | ||||
| import org.apache.commons.codec.digest.DigestUtils; | ||||
| import org.w3c.dom.Node; | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| 
 | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.StringWriter; | ||||
| import java.io.UnsupportedEncodingException; | ||||
| import java.math.BigInteger; | ||||
| import java.net.URLEncoder; | ||||
| import java.security.MessageDigest; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.text.ParseException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
|  | @ -29,70 +13,10 @@ import java.util.TimeZone; | |||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
| 
 | ||||
| import javax.xml.transform.Transformer; | ||||
| import javax.xml.transform.TransformerConfigurationException; | ||||
| import javax.xml.transform.TransformerException; | ||||
| import javax.xml.transform.TransformerFactory; | ||||
| import javax.xml.transform.TransformerFactoryConfigurationError; | ||||
| import javax.xml.transform.dom.DOMSource; | ||||
| import javax.xml.transform.stream.StreamResult; | ||||
| 
 | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| 
 | ||||
| public class Utils { | ||||
| 
 | ||||
|     // Get SHA1 of file from input stream | ||||
|     public static String getSHA1(InputStream is) { | ||||
| 
 | ||||
|         MessageDigest digest; | ||||
|         try { | ||||
|             digest = MessageDigest.getInstance("SHA1"); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             Timber.e(e, "Exception while getting Digest"); | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         byte[] buffer = new byte[8192]; | ||||
|         int read; | ||||
|         try { | ||||
|             while ((read = is.read(buffer)) > 0) { | ||||
|                 digest.update(buffer, 0, read); | ||||
|             } | ||||
|             byte[] md5sum = digest.digest(); | ||||
|             BigInteger bigInt = new BigInteger(1, md5sum); | ||||
|             String output = bigInt.toString(16); | ||||
|             // Fill to 40 chars | ||||
|             output = String.format("%40s", output).replace(' ', '0'); | ||||
|             Timber.i("File SHA1: %s", output); | ||||
| 
 | ||||
|             return output; | ||||
|         } catch (IOException e) { | ||||
|             Timber.e(e, "IO Exception"); | ||||
|             return ""; | ||||
|         } finally { | ||||
|             try { | ||||
|                 is.close(); | ||||
|             } catch (IOException e) { | ||||
|                 Timber.e(e, "Exception on closing MD5 input stream"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** Fix Html.fromHtml is deprecated problem | ||||
|      * @param source provided Html string | ||||
|      * @return returned Spanned of appropriate method according to version check | ||||
|      * */ | ||||
|     public static Spanned fromHtml(String source) { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|             return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY); | ||||
|         } else { | ||||
|             //noinspection deprecation | ||||
|             return Html.fromHtml(source); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Strips localization symbols from a string. | ||||
|      * Removes the suffix after "@" and quotes. | ||||
|  | @ -109,49 +33,12 @@ public class Utils { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static Date parseMWDate(String mwDate) { | ||||
|         SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC | ||||
|         try { | ||||
|             return isoFormat.parse(mwDate); | ||||
|         } catch (ParseException e) { | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static String toMWDate(Date date) { | ||||
|         SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC | ||||
|         isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); | ||||
|         return isoFormat.format(date); | ||||
|     } | ||||
| 
 | ||||
|     public static String makeThumbBaseUrl(String filename) { | ||||
|         String name = new PageTitle(filename).getPrefixedText(); | ||||
|         String sha = new String(Hex.encodeHex(DigestUtils.md5(name))); | ||||
|         return String.format("%s/%s/%s/%s", CommonsApplication.IMAGE_URL_BASE, sha.substring(0, 1), sha.substring(0, 2), urlEncode(name)); | ||||
|     } | ||||
| 
 | ||||
|     public static String getStringFromDOM(Node dom) { | ||||
|         Transformer transformer = null; | ||||
|         try { | ||||
|             transformer = TransformerFactory.newInstance().newTransformer(); | ||||
|         } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { | ||||
|             // TODO Auto-generated catch block | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| 
 | ||||
|         StringWriter outputStream = new StringWriter(); | ||||
|         DOMSource domSource = new DOMSource(dom); | ||||
|         StreamResult strResult = new StreamResult(outputStream); | ||||
| 
 | ||||
|         try { | ||||
|             transformer.transform(domSource, strResult); | ||||
|         } catch (TransformerException e) { | ||||
|             // TODO Auto-generated catch block | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return outputStream.toString(); | ||||
|     } | ||||
| 
 | ||||
|     public static String urlEncode(String url) { | ||||
|         try { | ||||
|             return URLEncoder.encode(url, "utf-8"); | ||||
|  | @ -160,39 +47,10 @@ public class Utils { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static long countBytes(InputStream stream) throws IOException { | ||||
|         long count = 0; | ||||
|         BufferedInputStream bis = new BufferedInputStream(stream); | ||||
|         while (bis.read() != -1) { | ||||
|             count++; | ||||
|         } | ||||
|         return count; | ||||
|     } | ||||
| 
 | ||||
|     public static String capitalize(String string) { | ||||
|         return string.substring(0, 1).toUpperCase(Locale.getDefault()) + string.substring(1); | ||||
|     } | ||||
| 
 | ||||
|     public static String licenseTemplateFor(String license) { | ||||
|         switch (license) { | ||||
|             case Prefs.Licenses.CC_BY_3: | ||||
|                 return "{{self|cc-by-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_4: | ||||
|                 return "{{self|cc-by-4.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA_3: | ||||
|                 return "{{self|cc-by-sa-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA_4: | ||||
|                 return "{{self|cc-by-sa-4.0}}"; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return "{{self|cc-zero}}"; | ||||
|             case Prefs.Licenses.CC_BY: | ||||
|                 return "{{self|cc-by-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA: | ||||
|                 return "{{self|cc-by-sa-3.0}}"; | ||||
|         } | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|     } | ||||
| 
 | ||||
|     public static int licenseNameFor(String license) { | ||||
|         switch (license) { | ||||
|             case Prefs.Licenses.CC_BY_3: | ||||
|  | @ -213,51 +71,6 @@ public class Utils { | |||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|     } | ||||
| 
 | ||||
|     public static String licenseUrlFor(String license) { | ||||
|         switch (license) { | ||||
|             case Prefs.Licenses.CC_BY_3: | ||||
|                 return "https://creativecommons.org/licenses/by/3.0/"; | ||||
|             case Prefs.Licenses.CC_BY_4: | ||||
|                 return "https://creativecommons.org/licenses/by/4.0/"; | ||||
|             case Prefs.Licenses.CC_BY_SA_3: | ||||
|                 return "https://creativecommons.org/licenses/by-sa/3.0/"; | ||||
|             case Prefs.Licenses.CC_BY_SA_4: | ||||
|                 return "https://creativecommons.org/licenses/by-sa/4.0/"; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return "https://creativecommons.org/publicdomain/zero/1.0/"; | ||||
|         } | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static String fixExtension(String title, String extension) { | ||||
|         Pattern jpegPattern = Pattern.compile("\\.jpeg$", Pattern.CASE_INSENSITIVE); | ||||
| 
 | ||||
|  | @ -272,8 +85,4 @@ public class Utils { | |||
|         return title; | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isNullOrWhiteSpace(String value) { | ||||
|         return value == null || value.trim().isEmpty(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import android.database.sqlite.SQLiteDatabase; | |||
| import android.net.Uri; | ||||
| import android.os.Parcel; | ||||
| import android.os.RemoteException; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.text.TextUtils; | ||||
| 
 | ||||
| import java.text.SimpleDateFormat; | ||||
|  | @ -16,7 +17,6 @@ import java.util.Locale; | |||
| import fr.free.nrw.commons.BuildConfig; | ||||
| import fr.free.nrw.commons.CommonsApplication; | ||||
| import fr.free.nrw.commons.Media; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| 
 | ||||
| public class Contribution extends Media { | ||||
|  | @ -149,7 +149,7 @@ public class Contribution extends Media { | |||
|         } | ||||
| 
 | ||||
|         buffer.append("== {{int:license-header}} ==\n") | ||||
|                 .append(Utils.licenseTemplateFor(getLicense())).append("\n\n") | ||||
|                 .append(licenseTemplateFor(getLicense())).append("\n\n") | ||||
|                 .append("{{Uploaded from Mobile|platform=Android|version=").append(BuildConfig.VERSION_NAME).append("}}\n") | ||||
|                 .append(getTrackingTemplates()); | ||||
|         return buffer.toString(); | ||||
|  | @ -377,4 +377,25 @@ public class Contribution extends Media { | |||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private String licenseTemplateFor(String license) { | ||||
|         switch (license) { | ||||
|             case Prefs.Licenses.CC_BY_3: | ||||
|                 return "{{self|cc-by-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_4: | ||||
|                 return "{{self|cc-by-4.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA_3: | ||||
|                 return "{{self|cc-by-sa-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA_4: | ||||
|                 return "{{self|cc-by-sa-4.0}}"; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return "{{self|cc-zero}}"; | ||||
|             case Prefs.Licenses.CC_BY: | ||||
|                 return "{{self|cc-by-3.0}}"; | ||||
|             case Prefs.Licenses.CC_BY_SA: | ||||
|                 return "{{self|cc-by-sa-3.0}}"; | ||||
|         } | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -196,11 +196,17 @@ public class ContributionsListFragment extends DaggerFragment { | |||
|         menu.clear(); // See http://stackoverflow.com/a/8495697/17865 | ||||
|         inflater.inflate(R.menu.fragment_contributions_list, menu); | ||||
| 
 | ||||
|         if (!application.deviceHasCamera()) { | ||||
|         if (!deviceHasCamera()) { | ||||
|             menu.findItem(R.id.menu_from_camera).setEnabled(false); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean deviceHasCamera() { | ||||
|         PackageManager pm = getContext().getPackageManager(); | ||||
|         return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || | ||||
|                 pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  |  | |||
|  | @ -13,9 +13,12 @@ import android.os.RemoteException; | |||
| import android.text.TextUtils; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.TimeZone; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| 
 | ||||
|  | @ -130,7 +133,13 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter { | |||
|                 done = true; | ||||
|             } | ||||
|         } | ||||
|         prefs.edit().putString("lastSyncTimestamp", Utils.toMWDate(curTime)).apply(); | ||||
|         prefs.edit().putString("lastSyncTimestamp", toMWDate(curTime)).apply(); | ||||
|         Timber.d("Oh hai, everyone! Look, a kitty!"); | ||||
|     } | ||||
| 
 | ||||
|     private String toMWDate(Date date) { | ||||
|         SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC | ||||
|         isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); | ||||
|         return isoFormat.format(date); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,6 @@ import java.io.IOException; | |||
| import javax.inject.Inject; | ||||
| 
 | ||||
| import fr.free.nrw.commons.CommonsApplication; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.contributions.Contribution; | ||||
| import fr.free.nrw.commons.contributions.ContributionsContentProvider; | ||||
| import fr.free.nrw.commons.mwapi.MediaWikiApi; | ||||
|  | @ -59,7 +58,7 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (Utils.isNullOrWhiteSpace(authCookie)) { | ||||
|         if (isNullOrWhiteSpace(authCookie)) { | ||||
|             Timber.d("Could not authenticate :("); | ||||
|             return; | ||||
|         } | ||||
|  | @ -133,4 +132,8 @@ public class ModificationsSyncAdapter extends AbstractThreadedSyncAdapter { | |||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private boolean isNullOrWhiteSpace(String value) { | ||||
|         return value == null || value.trim().isEmpty(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -25,6 +25,8 @@ import org.mediawiki.api.MWApi; | |||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.text.ParseException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.Date; | ||||
|  | @ -33,7 +35,6 @@ import java.util.Locale; | |||
| 
 | ||||
| import fr.free.nrw.commons.BuildConfig; | ||||
| import fr.free.nrw.commons.PageTitle; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import in.yuvi.http.fluent.Http; | ||||
| import io.reactivex.Observable; | ||||
| import io.reactivex.Single; | ||||
|  | @ -337,7 +338,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { | |||
|             logEvents.add(new LogEventResult.LogEvent( | ||||
|                     image.getString("@pageid"), | ||||
|                     image.getString("@title"), | ||||
|                     Utils.parseMWDate(image.getString("@timestamp"))) | ||||
|                     parseMWDate(image.getString("@timestamp"))) | ||||
|             ); | ||||
|         } | ||||
|         return logEvents; | ||||
|  | @ -399,7 +400,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { | |||
|             String errorCode = result.getString("/api/error/@code"); | ||||
|             return new UploadResult(resultStatus, errorCode); | ||||
|         } else { | ||||
|             Date dateUploaded = Utils.parseMWDate(result.getString("/api/upload/imageinfo/@timestamp")); | ||||
|             Date dateUploaded = parseMWDate(result.getString("/api/upload/imageinfo/@timestamp")); | ||||
|             String canonicalFilename = "File:" + result.getString("/api/upload/@filename").replace("_", " "); // Title vs Filename | ||||
|             String imageUrl = result.getString("/api/upload/imageinfo/@url"); | ||||
|             return new UploadResult(resultStatus, dateUploaded, canonicalFilename, imageUrl); | ||||
|  | @ -425,4 +426,13 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { | |||
|             return Integer.parseInt(uploadCount); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private Date parseMWDate(String mwDate) { | ||||
|         SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC | ||||
|         try { | ||||
|             return isoFormat.parse(mwDate); | ||||
|         } catch (ParseException e) { | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,12 +1,13 @@ | |||
| package fr.free.nrw.commons.ui.widget; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.os.Build; | ||||
| import android.support.v7.widget.AppCompatTextView; | ||||
| import android.text.Html; | ||||
| import android.text.Spanned; | ||||
| import android.text.method.LinkMovementMethod; | ||||
| import android.util.AttributeSet; | ||||
| 
 | ||||
| import fr.free.nrw.commons.Utils; | ||||
| 
 | ||||
| /** | ||||
|  * An {@link AppCompatTextView} which formats the text to HTML displayable text and makes any | ||||
|  * links clickable. | ||||
|  | @ -17,10 +18,25 @@ public class HtmlTextView extends AppCompatTextView { | |||
|         super(context, attrs); | ||||
| 
 | ||||
|         setMovementMethod(LinkMovementMethod.getInstance()); | ||||
|         setText(Utils.fromHtml(getText().toString())); | ||||
|         setText(fromHtml(getText().toString())); | ||||
|     } | ||||
| 
 | ||||
|     public void setHtmlText(String newText) { | ||||
|         setText(Utils.fromHtml(newText)); | ||||
|         setText(fromHtml(newText)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Fix Html.fromHtml is deprecated problem | ||||
|      * | ||||
|      * @param source provided Html string | ||||
|      * @return returned Spanned of appropriate method according to version check | ||||
|      */ | ||||
|     private static Spanned fromHtml(String source) { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||||
|             return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY); | ||||
|         } else { | ||||
|             //noinspection deprecation | ||||
|             return Html.fromHtml(source); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -27,6 +27,9 @@ import com.facebook.drawee.view.SimpleDraweeView; | |||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.math.BigInteger; | ||||
| import java.security.MessageDigest; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| 
 | ||||
|  | @ -35,7 +38,6 @@ import javax.inject.Inject; | |||
| import butterknife.ButterKnife; | ||||
| import fr.free.nrw.commons.CommonsApplication; | ||||
| import fr.free.nrw.commons.R; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.auth.AuthenticatedActivity; | ||||
| import fr.free.nrw.commons.caching.CacheController; | ||||
| import fr.free.nrw.commons.category.CategorizationFragment; | ||||
|  | @ -380,7 +382,7 @@ public  class       ShareActivity | |||
|                 try { | ||||
|                     InputStream inputStream = getContentResolver().openInputStream(mediaUri); | ||||
|                     Timber.d("Input stream created from %s", mediaUri.toString()); | ||||
|                     String fileSHA1 = Utils.getSHA1(inputStream); | ||||
|                     String fileSHA1 = getSHA1(inputStream); | ||||
|                     Timber.d("File SHA1 is: %s", fileSHA1); | ||||
| 
 | ||||
|                     ExistingFileAsync fileAsyncTask = | ||||
|  | @ -536,4 +538,41 @@ public  class       ShareActivity | |||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
| 
 | ||||
|     // Get SHA1 of file from input stream | ||||
|     private String getSHA1(InputStream is) { | ||||
| 
 | ||||
|         MessageDigest digest; | ||||
|         try { | ||||
|             digest = MessageDigest.getInstance("SHA1"); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             Timber.e(e, "Exception while getting Digest"); | ||||
|             return ""; | ||||
|         } | ||||
| 
 | ||||
|         byte[] buffer = new byte[8192]; | ||||
|         int read; | ||||
|         try { | ||||
|             while ((read = is.read(buffer)) > 0) { | ||||
|                 digest.update(buffer, 0, read); | ||||
|             } | ||||
|             byte[] md5sum = digest.digest(); | ||||
|             BigInteger bigInt = new BigInteger(1, md5sum); | ||||
|             String output = bigInt.toString(16); | ||||
|             // Fill to 40 chars | ||||
|             output = String.format("%40s", output).replace(' ', '0'); | ||||
|             Timber.i("File SHA1: %s", output); | ||||
| 
 | ||||
|             return output; | ||||
|         } catch (IOException e) { | ||||
|             Timber.e(e, "IO Exception"); | ||||
|             return ""; | ||||
|         } finally { | ||||
|             try { | ||||
|                 is.close(); | ||||
|             } catch (IOException e) { | ||||
|                 Timber.e(e, "Exception on closing MD5 input stream"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import android.graphics.Color; | |||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.support.v4.app.Fragment; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.v7.app.AlertDialog; | ||||
| import android.text.Editable; | ||||
| import android.text.TextWatcher; | ||||
|  | @ -184,7 +184,7 @@ public class SingleUploadFragment extends DaggerFragment { | |||
|         if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) { | ||||
|             Intent intent = new Intent(); | ||||
|             intent.setAction(Intent.ACTION_VIEW); | ||||
|             intent.setData(Uri.parse(Utils.licenseUrlFor(license))); | ||||
|             intent.setData(Uri.parse(licenseUrlFor(license))); | ||||
|             startActivity(intent); | ||||
|             return true; | ||||
|         } else { | ||||
|  | @ -280,6 +280,23 @@ public class SingleUploadFragment extends DaggerFragment { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private String licenseUrlFor(String license) { | ||||
|         switch (license) { | ||||
|             case Prefs.Licenses.CC_BY_3: | ||||
|                 return "https://creativecommons.org/licenses/by/3.0/"; | ||||
|             case Prefs.Licenses.CC_BY_4: | ||||
|                 return "https://creativecommons.org/licenses/by/4.0/"; | ||||
|             case Prefs.Licenses.CC_BY_SA_3: | ||||
|                 return "https://creativecommons.org/licenses/by-sa/3.0/"; | ||||
|             case Prefs.Licenses.CC_BY_SA_4: | ||||
|                 return "https://creativecommons.org/licenses/by-sa/4.0/"; | ||||
|             case Prefs.Licenses.CC0: | ||||
|                 return "https://creativecommons.org/publicdomain/zero/1.0/"; | ||||
|         } | ||||
|         throw new RuntimeException("Unrecognized license value: " + license); | ||||
|     } | ||||
| 
 | ||||
|     private class TitleTextWatcher implements TextWatcher { | ||||
|         @Override | ||||
|         public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } | ||||
|  |  | |||
|  | @ -13,13 +13,14 @@ import android.preference.PreferenceManager; | |||
| import android.provider.MediaStore; | ||||
| import android.text.TextUtils; | ||||
| 
 | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.Date; | ||||
| import java.util.concurrent.Executors; | ||||
| 
 | ||||
| import fr.free.nrw.commons.CommonsApplication; | ||||
| import fr.free.nrw.commons.HandlerService; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.contributions.Contribution; | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| import timber.log.Timber; | ||||
|  | @ -109,7 +110,7 @@ public class UploadController { | |||
|                                 .getLength(); | ||||
|                         if(length == -1) { | ||||
|                             // Let us find out the long way! | ||||
|                             length = Utils.countBytes(application.getContentResolver() | ||||
|                             length = countBytes(application.getContentResolver() | ||||
|                                     .openInputStream(contribution.getLocalUri())); | ||||
|                         } | ||||
|                         contribution.setDataLength(length); | ||||
|  | @ -165,4 +166,14 @@ public class UploadController { | |||
|             } | ||||
|         }.executeOnExecutor(Executors.newFixedThreadPool(1)); // TODO remove this by using a sensible thread handling strategy | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private long countBytes(InputStream stream) throws IOException { | ||||
|         long count = 0; | ||||
|         BufferedInputStream bis = new BufferedInputStream(stream); | ||||
|         while (bis.read() != -1) { | ||||
|             count++; | ||||
|         } | ||||
|         return count; | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Paul Hawke
						Paul Hawke