diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/CamelTag.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/CamelTag.java new file mode 100644 index 000000000..f55e3b619 --- /dev/null +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/app/CamelTag.java @@ -0,0 +1,116 @@ +package app.fedilab.android.mastodon.client.entities.app; +/* Copyright 2023 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; +import java.util.List; + +import app.fedilab.android.mastodon.exception.DBException; +import app.fedilab.android.sqlite.Sqlite; + +public class CamelTag { + + private final SQLiteDatabase db; + @SerializedName("name") + public String name; + + public CamelTag(Context context) { + this.db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + } + + /** + * Insert or update a status + * + * @param name {@link String} + * @return long - -1 if exists or id + * @throws DBException exception with database + */ + public synchronized long insert(String name) throws DBException { + if (db == null) { + throw new DBException("db is null. Wrong initialization."); + } + boolean exists = tagExists(name); + if (!exists) { + ContentValues values = new ContentValues(); + values.put(Sqlite.COL_TAG, name); + try { + return db.insertOrThrow(Sqlite.TABLE_CACHE_TAGS, null, values); + } catch (Exception e) { + e.printStackTrace(); + return -1; + } + } + return -1; + } + + /** + * Returns tags List of {@String} containing "search" + * + * @param search - String the word to search + * @return List + */ + public List getBy(String search) { + Cursor c = db.query(Sqlite.TABLE_CACHE_TAGS, null, Sqlite.COL_TAG + " LIKE \"%" + search + "%\"", null, null, null, null, null); + return cursorToTag(c); + } + + private boolean tagExists(String name) throws DBException { + Cursor c = db.query(Sqlite.TABLE_CACHE_TAGS, null, Sqlite.COL_TAG + " = \"" + name + "\"", null, null, null, null, null); + boolean isPresent = (c != null && c.getCount() > 0); + assert c != null; + c.close(); + return isPresent; + } + + public void removeAll() { + db.delete(Sqlite.TABLE_CACHE_TAGS, null, null); + } + + public void removeTag(String tag) { + db.delete(Sqlite.TABLE_CACHE_TAGS, Sqlite.COL_TAG + " = ?", new String[]{tag}); + } + + public void update(String oldTag, String newTag) { + ContentValues values = new ContentValues(); + values.put(Sqlite.COL_TAG, newTag); + try { + db.update(Sqlite.TABLE_CACHE_TAGS, values, Sqlite.COL_TAG + " = ?", new String[]{oldTag}); + } catch (Exception ignored) { + } + } + + private List cursorToTag(Cursor c) { + //No element found + if (c.getCount() == 0) { + c.close(); + return null; + } + List tags = new ArrayList<>(); + while (c.moveToNext()) { + tags.add(c.getString(c.getColumnIndexOrThrow(Sqlite.COL_TAG))); + } + //Close the cursor + c.close(); + //Tag list is returned + return tags; + } +} diff --git a/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java b/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java index d010d1b48..357565e2a 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java +++ b/app/src/main/java/app/fedilab/android/mastodon/jobs/ComposeWorker.java @@ -47,6 +47,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; @@ -57,6 +58,7 @@ import app.fedilab.android.mastodon.client.entities.api.ScheduledStatus; import app.fedilab.android.mastodon.client.entities.api.Status; import app.fedilab.android.mastodon.client.entities.app.Account; import app.fedilab.android.mastodon.client.entities.app.BaseAccount; +import app.fedilab.android.mastodon.client.entities.app.CamelTag; import app.fedilab.android.mastodon.client.entities.app.PostState; import app.fedilab.android.mastodon.client.entities.app.StatusDraft; import app.fedilab.android.mastodon.exception.DBException; @@ -232,6 +234,25 @@ public class ComposeWorker extends Worker { if (statuses.get(i).local_only) { statuses.get(i).text += " \uD83D\uDC41"; } + if (statuses.get(i).text != null && statuses.get(i).text.length() > 0) { + Matcher matcher = Helper.hashtagPattern.matcher(statuses.get(i).text); + while (matcher.find()) { + int matchStart = matcher.start(1); + int matchEnd = matcher.end(); + //Get cached tags + if (matchStart >= 0 && matchEnd < statuses.get(i).text.length()) { + String tag = statuses.get(i).text.substring(matchStart, matchEnd); + tag = tag.replace("#", ""); + if (tag.length() > 0) { + try { + new CamelTag(context).insert(tag); + } catch (DBException e) { + throw new RuntimeException(e); + } + } + } + } + } if (dataPost.scheduledDate == null) { if (dataPost.statusEditId == null) { diff --git a/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java b/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java index 4c158990f..7dfa40545 100644 --- a/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java +++ b/app/src/main/java/app/fedilab/android/sqlite/Sqlite.java @@ -23,7 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper; public class Sqlite extends SQLiteOpenHelper { - public static final int DB_VERSION = 9; + public static final int DB_VERSION = 10; public static final String DB_NAME = "fedilab_db"; //Table of owned accounts @@ -94,13 +94,16 @@ public class Sqlite extends SQLiteOpenHelper { public static final String COL_USER_INSTANCE = "USER_INSTANCE"; //Home fetch logs - public static final String TABLE_HOME_FETCH_LOGS = "TABLE_HOME_FETCH_LOGS"; + public static final String TABLE_HOME_FETCH_LOGS = "HOME_FETCH_LOGS"; public static final String COL_INSERTED = "INSERTED"; public static final String COL_UPDATED = "UPDATED"; public static final String COL_FAILED = "FAILED"; public static final String COL_FREQUENCY = "FREQUENCY"; public static final String COL_FETCHED_COUNT = "FETCHED_COUNT"; + public static final String TABLE_CACHE_TAGS = "CACHE_TAGS"; + public static final String COL_TAG = "TAG"; + private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " (" + COL_USER_ID + " TEXT NOT NULL, " @@ -211,6 +214,10 @@ public class Sqlite extends SQLiteOpenHelper { + COL_ABOUT + " TEXT NOT NULL, " + COL_USER_INSTANCE + " TEXT NOT NULL)"; + private final String CREATE_TABLE_CACHE_TAGS = "CREATE TABLE " + + TABLE_CACHE_TAGS + "(" + + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + COL_TAG + " TEXT NOT NULL)"; public static SQLiteDatabase db; private static Sqlite sInstance; @@ -243,6 +250,7 @@ public class Sqlite extends SQLiteOpenHelper { db.execSQL(CREATE_DOMAINS_TRACKING); db.execSQL(CREATE_TABLE_MUTED); db.execSQL(CREATE_TABLE_STORED_INSTANCES); + db.execSQL(CREATE_TABLE_CACHE_TAGS); } @Override @@ -271,6 +279,8 @@ public class Sqlite extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_MUTED); case 8: db.execSQL(CREATE_TABLE_STORED_INSTANCES); + case 9: + db.execSQL(CREATE_TABLE_CACHE_TAGS); default: break; }