From ae4e3a0c883b620542af0c72169bb1b488def8cf Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 22 Feb 2023 14:10:41 -0500 Subject: [PATCH] Option to download default stickers and save their cid and url in database --- src/cheogram/AndroidManifest.xml | 1 + .../android/DownloadDefaultStickers.java | 164 ++++++++++++++++++ .../persistance/DatabaseBackend.java | 13 ++ .../services/XmppConnectionService.java | 6 +- .../conversations/ui/SettingsActivity.java | 23 +++ src/main/res/xml/preferences.xml | 3 + 6 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 src/cheogram/java/com/cheogram/android/DownloadDefaultStickers.java diff --git a/src/cheogram/AndroidManifest.xml b/src/cheogram/AndroidManifest.xml index 82d1ab15712a1fdbc7272086c5df29dd6d5af71e..3df380045568a12df77b1c05277f2940e50985eb 100644 --- a/src/cheogram/AndroidManifest.xml +++ b/src/cheogram/AndroidManifest.xml @@ -7,6 +7,7 @@ + { + try { + download(); + } catch (final Exception e) { + Log.d(Config.LOGTAG, "unable to download stickers", e); + } + stopForeground(true); + RUNNING.set(false); + stopSelf(); + }).start(); + return START_STICKY; + } else { + Log.d(Config.LOGTAG, "DownloadDefaultStickers. ignoring start command because already running"); + } + return START_NOT_STICKY; + } + + private void oneSticker(JSONObject sticker) throws Exception { + Response r = http.newCall(new Request.Builder().url(sticker.getString("url")).build()).execute(); + File file = new File(mStickerDir.getAbsolutePath() + "/" + sticker.getString("pack") + "/" + sticker.getString("name") + "." + MimeUtils.guessExtensionFromMimeType(r.headers().get("content-type"))); + file.getParentFile().mkdirs(); + OutputStream os = new FileOutputStream(file); + ByteStreams.copy(r.body().byteStream(), os); + os.close(); + + JSONArray cids = sticker.getJSONArray("cids"); + for (int i = 0; i < cids.length(); i++) { + Cid cid = Cid.decode(cids.getString(i)); + mDatabaseBackend.saveCid(cid, file, sticker.getString("url")); + } + + try { + File copyright = new File(mStickerDir.getAbsolutePath() + "/" + sticker.getString("pack") + "/copyright.txt"); + OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(copyright, true), "utf-8"); + w.write(sticker.getString("pack")); + w.write('/'); + w.write(sticker.getString("name")); + w.write(": "); + w.write(sticker.getString("copyright")); + w.write('\n'); + w.close(); + } catch (final Exception e) { } + } + + private void download() throws Exception { + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext(), "backup"); + mBuilder.setContentTitle("Downloading Default Stickers") + .setSmallIcon(R.drawable.ic_archive_white_24dp) + .setProgress(1, 0, false); + startForeground(NOTIFICATION_ID, mBuilder.build()); + + Response r = http.newCall(new Request.Builder().url("https://stickers.cheogram.com/index.json").build()).execute(); + JSONArray stickers = new JSONArray(r.body().string()); + + final Progress progress = new Progress(mBuilder, 1, 0); + for (int i = 0; i < stickers.length(); i++) { + oneSticker(stickers.getJSONObject(i)); + + final int percentage = i * 100 / stickers.length(); + notificationManager.notify(NOTIFICATION_ID, progress.build(percentage)); + } + } + + private File stickerDir() { + SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + final String dir = p.getString("sticker_directory", "Stickers"); + if (dir.startsWith("content://")) { + Uri uri = Uri.parse(dir); + uri = DocumentsContract.buildDocumentUriUsingTree(uri, DocumentsContract.getTreeDocumentId(uri)); + return new File(FileUtils.getPath(getBaseContext(), uri)); + } else { + return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/" + dir); + } + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private static class Progress { + private final NotificationCompat.Builder builder; + private final int max; + private final int count; + + private Progress(NotificationCompat.Builder builder, int max, int count) { + this.builder = builder; + this.max = max; + this.count = count; + } + + private Notification build(int percentage) { + builder.setProgress(max * 100, count * 100 + percentage, false); + return builder.build(); + } + } +} diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 1ccc6efe1000a687e361934f0b3f55eb62d93624..708e2630432dfc4049d0791f2b80d31d5c4554c1 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -283,6 +283,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("PRAGMA cheogram.user_version = 6"); } + if(cheogramVersion < 7) { + db.execSQL( + "ALTER TABLE cheogram.cids " + + "ADD COLUMN url TEXT" + ); + db.execSQL("PRAGMA cheogram.user_version = 7"); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -776,10 +784,15 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void saveCid(Cid cid, File file) { + saveCid(cid, file, null); + } + + public void saveCid(Cid cid, File file, String url) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("cid", cid.toString()); cv.put("path", file.getAbsolutePath()); + cv.put("url", url); db.insertWithOnConflict("cheogram.cids", null, cv, SQLiteDatabase.CONFLICT_REPLACE); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 7056b4e1a0441e6c3ff62f9a9e91aede9608bba9..974b0c2b484a783df7172cadeafaef9fcd3e8137 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -562,10 +562,14 @@ public class XmppConnectionService extends Service { } public void saveCid(Cid cid, File file) throws BlockedMediaException { + saveCid(cid, file, null); + } + + public void saveCid(Cid cid, File file, String url) throws BlockedMediaException { if (this.databaseBackend.isBlockedMedia(cid)) { throw new BlockedMediaException(); } - this.databaseBackend.saveCid(cid, file); + this.databaseBackend.saveCid(cid, file, url); } public void blockMedia(File f) { diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index daa13ab7c629732d3160ed941f431d6c28fa6823..4e44d167616e3e688dd0537b279da73fed2f30fd 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -25,6 +25,8 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; +import com.cheogram.android.DownloadDefaultStickers; + import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -69,6 +71,7 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference public static final String PREVENT_SCREENSHOTS = "prevent_screenshots"; public static final int REQUEST_CREATE_BACKUP = 0xbf8701; + public static final int REQUEST_DOWNLOAD_STICKERS = 0xbf8702; private SettingsFragment mSettingsFragment; @@ -390,6 +393,17 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference } } + final Preference downloadDefaultStickers = mSettingsFragment.findPreference("download_default_stickers"); + if (downloadDefaultStickers != null) { + downloadDefaultStickers.setOnPreferenceClickListener( + preference -> { + if (hasStoragePermission(REQUEST_DOWNLOAD_STICKERS)) { + downloadStickers(); + } + return true; + }); + } + final Preference clearBlockedMedia = mSettingsFragment.findPreference("clear_blocked_media"); if (clearBlockedMedia != null) { clearBlockedMedia.setOnPreferenceClickListener((p) -> { @@ -587,6 +601,9 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference if (requestCode == REQUEST_CREATE_BACKUP) { createBackup(); } + if (requestCode == REQUEST_DOWNLOAD_STICKERS) { + downloadStickers(); + } } else { Toast.makeText( this, @@ -620,6 +637,12 @@ public class SettingsActivity extends XmppActivity implements OnSharedPreference builder.create().show(); } + private void downloadStickers() { + Intent intent = new Intent(this, DownloadDefaultStickers.class); + ContextCompat.startForegroundService(this, intent); + displayToast("Sticker download started"); + } + private void displayToast(final String msg) { runOnUiThread(() -> Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show()); } diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 2f57ec695c3291292765b35b7c68d3f76c3cba6e..455e55f2a02e0449011ca26a058e16cb288b485a 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -370,6 +370,9 @@ +