major database improvements

This commit is contained in:
NudeDude 2018-07-06 18:59:52 +02:00
parent 5fdb7cef74
commit 8ac47c75ed
23 changed files with 315 additions and 288 deletions

22
.idea/compiler.xml generated
View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@ -1,7 +0,0 @@
<component name="CopyrightManager">
<settings default="">
<LanguageOptions name="Kotlin">
<option name="fileTypeOverride" value="1" />
</LanguageOptions>
</settings>
</component>

View File

@ -1,8 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="Sufian">
<words>
<w>retweet</w>
<w>sqlite</w>
</words>
</dictionary>
</component>

3
.idea/gradle.xml generated
View File

@ -3,9 +3,8 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-4.4" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

9
.idea/kotlinc.xml generated
View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JvmCompilerArguments">
<option name="jvmTarget" value="1.8" />
</component>
<component name="KotlinCompilerSettings">
<option name="copyJsLibraryFiles" value="false" />
</component>
</project>

9
.idea/misc.xml generated
View File

@ -5,11 +5,12 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<list size="5">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
@ -24,7 +25,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="9.0" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

9
.idea/modules.xml generated
View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Twidda.iml" filepath="$PROJECT_DIR$/Twidda.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>

1
.idea/vcs.xml generated
View File

@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,33 +1,37 @@
apply plugin: 'com.android.application'
android {
buildToolsVersion '27.0.3'
compileSdkVersion 27
buildToolsVersion '28.0.1'
compileSdkVersion 28
defaultConfig {
applicationId "org.nuclearfog.twidda"
minSdkVersion 22
targetSdkVersion 27
targetSdkVersion 28
versionCode 1
versionName '1.4'
versionName '1.5'
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
debuggable false
minifyEnabled true
//minifyEnabled = true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
//minifyEnabled = true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation files('libs/colorpicker.aar')
implementation files('libs/picasso-2.5.2.jar')
implementation files('libs/twitter4j-core-4.0.6.jar')
implementation files('libs/twitter4j-core-4.0.6-sources.jar')
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation 'com.android.support:cardview-v7:28.0.0-alpha3'
implementation 'com.android.support:design:28.0.0-alpha3'
}
repositories {

View File

@ -23,3 +23,9 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-dontwarn
#-keep class twitter4j.** { *; }
#-keep class com.squareup.picasso.** { *; }

View File

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"

View File

@ -119,8 +119,10 @@ public class ImagePopup extends AsyncTask<String, Void, Boolean> {
}
private void setImage(Bitmap btm, ImageView mImg) {
int height = (int)(btm.getHeight() / (btm.getWidth() / 640.0));
btm = Bitmap.createScaledBitmap( btm,640,height, false);
mImg.setImageBitmap(btm);
if(btm != null) {
int height = (int) (btm.getHeight() / (btm.getWidth() / 640.0));
btm = Bitmap.createScaledBitmap(btm, 640, height, false);
mImg.setImageBitmap(btm);
}
}
}

View File

@ -95,11 +95,11 @@ public class MainPage extends AsyncTask<Integer, Void, Integer> {
if(timelineAdapter.getItemCount() > 0) {
id = timelineAdapter.getItemId(0);
tweets = mTwitter.getHome(page,id);
tweetDb.store(tweets, DatabaseAdapter.HOME,-1L);
tweetDb.storeHomeTimeline(tweets);
tweets.addAll(timelineAdapter.getData());
} else {
tweets = mTwitter.getHome(page,id);
tweetDb.store(tweets, DatabaseAdapter.HOME,-1L);
tweetDb.storeHomeTimeline(tweets);
}
timelineAdapter.setData(tweets);
timelineAdapter.setColor(highlight, font);
@ -109,7 +109,7 @@ public class MainPage extends AsyncTask<Integer, Void, Integer> {
case H_LOAD:
DatabaseAdapter tweetDeck = new DatabaseAdapter(ui.get());
tweets = tweetDeck.load(DatabaseAdapter.HOME, -1L);
tweets = tweetDeck.getHomeTimeline();
timelineAdapter.setData(tweets);
timelineAdapter.setColor(highlight, font);
timelineAdapter.toggleImage(image);
@ -135,11 +135,11 @@ public class MainPage extends AsyncTask<Integer, Void, Integer> {
if(mentionAdapter.getItemCount() != 0) {
id = mentionAdapter.getItemId(0);
mention = mTwitter.getMention(page,id);
tweetDb.store(mention, DatabaseAdapter.MENT,-1L);
tweetDb.storeMentions(mention);
mention.addAll(mentionAdapter.getData());
} else {
mention = mTwitter.getMention(page,id);
tweetDb.store(mention, DatabaseAdapter.MENT,-1L);
tweetDb.storeMentions(mention);
}
mentionAdapter.setData(mention);
mentionAdapter.setColor(highlight, font);
@ -149,7 +149,7 @@ public class MainPage extends AsyncTask<Integer, Void, Integer> {
case M_LOAD:
DatabaseAdapter mentDeck = new DatabaseAdapter(ui.get());
mention = mentDeck.load(DatabaseAdapter.MENT,-1L);
mention = mentDeck.getMentions();
mentionAdapter.setData(mention);
mentionAdapter.setColor(highlight, font);
mentionAdapter.toggleImage(image);

View File

@ -132,13 +132,13 @@ public class ProfileLoader extends AsyncTask<Long,Void,Long> {
if(homeTl.getItemCount() > 0) {
id = homeTl.getItemId(0);
tweets = mTwitter.getUserTweets(userId,args[2],id);
tweetDb.store(tweets, DatabaseAdapter.TWEET, userId);
tweetDb.storeUserTweets(tweets);
tweets.addAll(homeTl.getData());
} else {
tweets = tweetDb.load(DatabaseAdapter.TWEET,userId);
if(tweets.size() < 10) {
tweets = tweetDb.getUserTweets(userId);
if(tweets.size() == 0) {
tweets = mTwitter.getUserTweets(userId,args[2],id);
tweetDb.store(tweets, DatabaseAdapter.TWEET, userId);
tweetDb.storeUserTweets(tweets);
}
}
homeTl.setData(tweets);
@ -153,13 +153,13 @@ public class ProfileLoader extends AsyncTask<Long,Void,Long> {
if(homeFav.getItemCount() > 0) {
id = homeFav.getItemId(0);
favorits = mTwitter.getUserFavs(userId,args[2],id);
tweetDb.store(favorits, DatabaseAdapter.FAVT, userId);
tweetDb.storeUserFavs(favorits,userId);
favorits.addAll(homeFav.getData());
} else {
favorits = tweetDb.load(DatabaseAdapter.FAVT,userId);
if(favorits.size() < 10) {
favorits = tweetDb.getUserFavs(userId);
if(favorits.size() == 0) {
favorits = mTwitter.getUserFavs(userId,args[2],id);
tweetDb.store(favorits, DatabaseAdapter.FAVT, userId);
tweetDb.storeUserFavs(favorits,userId);
}
}
homeFav.setData(favorits);

View File

@ -87,21 +87,20 @@ public class StatusLoader extends AsyncTask<Long, Void, Long> implements View.On
tweetID = data[0];
final long MODE = data[1];
try {
Tweet tweet;
DatabaseAdapter dbAdp = new DatabaseAdapter(ui.get());
if(MODE == LOAD_TWEET || MODE == LOAD_DB) {
Tweet tweet;
if( MODE == LOAD_DB ) {
DatabaseAdapter dbAdp = new DatabaseAdapter(ui.get());
tweet = dbAdp.getStatus(tweetID);
List<Tweet> answers = dbAdp.load(DatabaseAdapter.ANS, tweetID);
List<Tweet> answers = dbAdp.getAnswers(tweetID);
tlAdp.setData(answers);
tlAdp.setColor(highlight, font);
if(tweet == null)
return IGNORE; // NOT FOUND
} else {
tweet = mTwitter.getStatus(tweetID);
DatabaseAdapter dbAdp = new DatabaseAdapter(ui.get());
if(dbAdp.containStatus(tweetID))
dbAdp.storeStatus(tweet);
dbAdp.updateStatus(tweet);
}
if (tweet.embedded != null) {
retweeter = tweet.user.screenname;
@ -135,7 +134,6 @@ public class StatusLoader extends AsyncTask<Long, Void, Long> implements View.On
}
else if(MODE == LOAD_REPLY) {
List<Tweet> answers;
DatabaseAdapter mData = new DatabaseAdapter(ui.get());
if(tlAdp.getItemCount() > 0) {
long sinceId = tlAdp.getItemId(0);
answers = mTwitter.getAnswers(tweetID, sinceId);
@ -145,8 +143,8 @@ public class StatusLoader extends AsyncTask<Long, Void, Long> implements View.On
}
tlAdp.setData(answers);
tlAdp.setColor(highlight, font);
if(mData.containStatus(tweetID))
mData.store(answers,DatabaseAdapter.TWEET,-1L);
if(answers.size() > 0 && dbAdp.containStatus(tweetID))
dbAdp.storeReplies(answers);
}
else if(MODE == DELETE) {
mTwitter.deleteTweet(tweetID);
@ -208,7 +206,7 @@ public class StatusLoader extends AsyncTask<Long, Void, Long> implements View.On
txtAns.setText(ansStr);
if(tweetReplyID > 0) {
String reply = "antwort";
String reply = "antwort ";
if(repliedUsername != null)
reply += '@'+repliedUsername;

View File

@ -38,7 +38,7 @@ import twitter4j.conf.ConfigurationBuilder;
public class TwitterEngine {
private final String TWITTER_CONSUMER_KEY = "0EKRHWYcakpCkl8Lr4OcBFMZb";
private final String TWITTER_CONSUMER_SECRET = "xxx";
private final String TWITTER_CONSUMER_SECRET = "RQrf0uQus5v7IMuYgdlVeBuLw1ApRJhxcAMM8MyUVRh1nKSxnR";
private static TwitterEngine mTwitter;
private static long twitterID = -1L;
@ -145,6 +145,7 @@ public class TwitterEngine {
twitterID = settings.getLong("userID", -1L);
}
/**
* set amount of tweets to be loaded
*/
@ -152,6 +153,7 @@ public class TwitterEngine {
load = settings.getInt("preload", 20);
}
/**
* @return if Twitter4J is registered
*/
@ -168,7 +170,8 @@ public class TwitterEngine {
* @throws TwitterException if access is unavailable
*/
public List<Tweet> getHome(int page, long lastId) throws TwitterException {
return convertStatusList(twitter.getHomeTimeline(new Paging(page,load,lastId)));
List<Status> homeTweets = twitter.getHomeTimeline(new Paging(page,load,lastId));
return convertStatusList(homeTweets);
}
@ -180,7 +183,8 @@ public class TwitterEngine {
* @throws TwitterException if access is unavailable
*/
public List<Tweet> getMention(int page, long id) throws TwitterException {
return convertStatusList(twitter.getMentionsTimeline(new Paging(page,/*load*/5,id)));
List<Status> mentions = twitter.getMentionsTimeline(new Paging(page,/*load*/5,id));
return convertStatusList(mentions);
}
@ -197,7 +201,8 @@ public class TwitterEngine {
q.setCount(load);
q.setSinceId(id);
QueryResult result = twitter.search(q);
return convertStatusList(result.getTweets());
List<Status> results = result.getTweets();
return convertStatusList(results);
}
@ -239,7 +244,7 @@ public class TwitterEngine {
*/
public List<Tweet> getUserTweets(long userId, long page, long id) throws TwitterException {
List<Status> result = twitter.getUserTimeline(userId, new Paging((int)page,load, id));
return convertStatusList(result,true);
return convertStatusList(result);
}
@ -251,7 +256,8 @@ public class TwitterEngine {
* @throws TwitterException if access is unavailable
*/
public List<Tweet> getUserFavs(long userId, long page, long id) throws TwitterException {
return convertStatusList(twitter.getFavorites(userId,new Paging((int)page,load,id)));
List<Status> favorits = twitter.getFavorites(userId,new Paging((int)page,load,id));
return convertStatusList(favorits);
}
@ -506,23 +512,13 @@ public class TwitterEngine {
}
/**
* convert #twitter4j.Status to Tweet List
* @param statuses Twitter4J status List
* @return TwitterStatus
*/
private List<Tweet> convertStatusList(List<Status> statuses) {
return convertStatusList(statuses, false);
}
/**
* convert #twitter4j.Status to Tweet List
* @param statuses Twitter4J status List
* @param profileflag attach tweets to an User
* @return TwitterStatus
*/
private List<Tweet> convertStatusList(List<Status> statuses, boolean profileflag) {
private List<Tweet>convertStatusList(List<Status> statuses) {
List<Tweet> result = new ArrayList<>();
if(statuses.isEmpty())
return result;
@ -532,10 +528,10 @@ public class TwitterEngine {
Status embedded = status.getRetweetedStatus();
if(embedded != null) {
Tweet retweet = getTweet(embedded, null);
Tweet tweet = getTweet(status, retweet, profileflag);
Tweet tweet = getTweet(status, retweet);
result.add(tweet);
} else {
Tweet tweet = getTweet(status, null, profileflag);
Tweet tweet = getTweet(status,null);
result.add(tweet);
}
} catch (Exception err) {
@ -552,22 +548,12 @@ public class TwitterEngine {
* @param retweetedStat embedded Status
* @return Tweet item
*/
private Tweet getTweet(Status status, Tweet retweetedStat) {
return getTweet(status, retweetedStat, false);
}
/**
* @param status twitter4j.Status
* @param retweetedStat embedded Status
* @param profileflag attach tweet to an User
* @return Tweet item
*/
private Tweet getTweet(Status status, Tweet retweetedStat, boolean profileflag) {
private Tweet getTweet(Status status,Tweet retweetedStat){
TwitterUser user = getUser(status.getUser());
return new Tweet(status.getId(),status.getRetweetCount(),status.getFavoriteCount(),user,
status.getText(),status.getCreatedAt().getTime(),status.getInReplyToScreenName(),
getMediaLinks(status),status.getSource(),status.getInReplyToStatusId(),
retweetedStat, status.isRetweeted(), status.isFavorited(),profileflag);
retweetedStat, status.isRetweeted(), status.isFavorited());
}
/**
@ -593,7 +579,6 @@ public class TwitterEngine {
for(MediaEntity media : mediaEntities) {
medialinks[i++] = media.getMediaURLHttps();
}
return medialinks;
}

View File

@ -8,11 +8,12 @@ public class Tweet {
public final long time, replyID;
public final int retweet, favorit;
public final String[] media;
public final boolean retweeted, favorized, profileflag;
public final boolean retweeted, favorized;
public Tweet(long tweetID, int retweet, int favorit, TwitterUser user, String tweet, long time,
String replyName, String[] media, String source, long replyID, Tweet embedded,
boolean retweeted, boolean favorized, boolean profileflag) {
boolean retweeted, boolean favorized) {
this.tweetID = tweetID;
this.user = user;
this.retweet = retweet;
@ -26,6 +27,5 @@ public class Tweet {
this.source = source;
this.retweeted = retweeted;
this.favorized = favorized;
this.profileflag = profileflag;
}
}

View File

@ -22,12 +22,6 @@ public class AppDatabase extends SQLiteOpenHelper
"FOREIGN KEY (userID) REFERENCES user(userID)," +
"FOREIGN KEY (tweetID) REFERENCES tweet(tweetID));";
private static final String timelineTable = "CREATE TABLE IF NOT EXISTS timeline (" +
"tweetID INTEGER UNIQUE, FOREIGN KEY (tweetID) REFERENCES tweet(tweetID) );";
private static final String mentionTable = "CREATE TABLE IF NOT EXISTS mention (" +
"tweetID INTEGER UNIQUE, FOREIGN KEY (tweetID) REFERENCES tweet(tweetID) );";
private static final String trendTable = "CREATE TABLE IF NOT EXISTS trend (" +
"trendpos INTEGER PRIMARY KEY, trendname TEXT, trendlink TEXT);";
@ -45,8 +39,6 @@ public class AppDatabase extends SQLiteOpenHelper
db.execSQL(userTable);
db.execSQL(tweetTable);
db.execSQL(trendTable);
db.execSQL(timelineTable);
db.execSQL(mentionTable);
db.execSQL(favoriteTable);
db.execSQL(errorTable);
}

View File

@ -4,6 +4,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable;
import org.nuclearfog.twidda.backend.listitems.Tweet;
import org.nuclearfog.twidda.backend.listitems.TwitterUser;
@ -11,114 +12,134 @@ import org.nuclearfog.twidda.backend.listitems.TwitterUser;
import java.util.ArrayList;
import java.util.List;
import static android.database.sqlite.SQLiteDatabase.CONFLICT_IGNORE;
import static android.database.sqlite.SQLiteDatabase.CONFLICT_REPLACE;
public class DatabaseAdapter {
public static final int FAVT = 1;
public static final int TWEET = 2;
public static final int HOME = 3;
public static final int MENT = 4;
public static final int ANS = 5;
private AppDatabase dataHelper;
/**
* Public Cunstructor
* @param context Activity Context
*/
public DatabaseAdapter(Context context) {
dataHelper = AppDatabase.getInstance(context);
}
/**
* Nutzer Tweets speichern
* @param stats Tweet Liste
*/
public void storeUserTweets(List<Tweet> stats) {
SQLiteDatabase db = dataHelper.getWritableDatabase();
int statusregister = 1 << 4;
for(int pos = 0; pos < stats.size(); pos++) {
Tweet tweet = stats.get(pos);
storeStatus(tweet,statusregister,db);
}
}
/**
* Store Tweet List
* @param stats List of Tweets
* @param mode store in extra table
* @param id Owner ID of favorite table
* Nutzer Favoriten Speichern
* @param fav Tweet Liste
* @param ownerId User ID
*/
public void store(final List<Tweet> stats, final int mode, final long id) {
new Thread(new Runnable() {
@Override
public void run() {
SQLiteDatabase db = dataHelper.getWritableDatabase();
public void storeUserFavs(List<Tweet> fav, long ownerId){
SQLiteDatabase db = dataHelper.getWritableDatabase();
for(int pos = 0; pos < fav.size(); pos++) {
Tweet tweet = fav.get(pos);
storeStatus(tweet,0,db);
ContentValues favTable = new ContentValues();
favTable.put("tweetID", tweet.tweetID);
favTable.put("userID", ownerId);
db.insertWithOnConflict("favorit",null,favTable,CONFLICT_IGNORE);
}
}
ContentValues home = new ContentValues();
ContentValues fav = new ContentValues();
ContentValues ment = new ContentValues();
/**
* Home Timeline speichern
* @param home Tweet Liste
*/
public void storeHomeTimeline(List<Tweet> home){
SQLiteDatabase db = dataHelper.getWritableDatabase();
int statusregister = 1 << 2;
for(int pos = 0; pos < home.size(); pos++) {
Tweet tweet = home.get(pos);
storeStatus(tweet,statusregister,db);
}
}
for(int pos = 0; pos < stats.size(); pos++) {
Tweet tweet = stats.get(pos);
storeStatus(tweet,db);
/**
* Erwähnungen speichern
* @param mentions Tweet Liste
*/
public void storeMentions(List<Tweet> mentions) {
SQLiteDatabase db = dataHelper.getWritableDatabase();
int statusregister = 1 << 3;
for(int pos = 0; pos < mentions.size(); pos++) {
Tweet tweet = mentions.get(pos);
storeStatus(tweet,statusregister,db);
}
}
if(mode != TWEET) {
if(mode == HOME) {
home.put("tweetID", tweet.tweetID);
db.insertWithOnConflict("timeline",null,home,SQLiteDatabase.CONFLICT_REPLACE);
} else if(mode == FAVT) {
fav.put("tweetID", tweet.tweetID);
fav.put("userID", id);
db.insertWithOnConflict("favorit",null,fav,SQLiteDatabase.CONFLICT_REPLACE);
} else if(mode == MENT) {
ment.put("tweetID", tweet.tweetID);
db.insertWithOnConflict("mention",null,ment,SQLiteDatabase.CONFLICT_REPLACE);
}
}
}
}
}).start();
/**
* Tweet Antworten speicher
* @param replies Tweet Antworten Liste
*/
public void storeReplies(List<Tweet> replies) {
SQLiteDatabase db = dataHelper.getWritableDatabase();
int statusregister = 1 << 5;
for(int pos = 0; pos < replies.size(); pos++) {
Tweet tweet = replies.get(pos);
storeStatus(tweet,statusregister,db);
}
}
/**
* Nutzer speichern
* @param user Nutzer Information
*/
public void storeUser(TwitterUser user) {
storeUser(user, dataHelper.getWritableDatabase());
}
/**
* Load Tweet list from Table
* @param mode select table
* @param id User ID for user tweets and favorites
* @return List of Tweets
* Lade Home Timeline
* @return Tweet Liste
*/
public List<Tweet> load(int mode, long id) {
List<Tweet> tweetList = new ArrayList<>();
public List<Tweet> getHomeTimeline() {
SQLiteDatabase db = dataHelper.getReadableDatabase();
String SQL_GET_HOME="";
int limit = 0;
if(mode == HOME) {
SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN timeline ON timeline.tweetID = tweet.tweetID " +
"INNER JOIN user ON tweet.userID = user.userID ORDER BY tweetID DESC";
}
else if(mode == MENT) {
SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN mention ON mention.tweetID = tweet.tweetID " +
"INNER JOIN user ON tweet.userID = user.userID ORDER BY tweetID DESC";
}
else if(mode == TWEET) {
SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID = user.userID"+
" WHERE user.userID = "+id+" ORDER BY tweetID DESC";
}
else if(mode == FAVT) {
SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN favorit ON favorit.tweetID = tweet.tweetID " +
"INNER JOIN user ON tweet.userID = user.userID " +
"WHERE favorit.userID = "+id+" ORDER BY tweetID DESC";
}
else if(mode == ANS) {
SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID = user.userID"+
" WHERE tweet.replyID = "+id+" ORDER BY tweetID DESC";
}
List<Tweet> tweetList = new ArrayList<>();
String SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID=user.userID " +
"WHERE statusregister&(1<<2)>0 " +
"ORDER BY tweetID DESC";
Cursor cursor = db.rawQuery(SQL_GET_HOME,null);
if(cursor.moveToFirst()) {
if(mode == TWEET) {
do {
Tweet tweet = getStatus(cursor);
if (tweet.profileflag)
tweetList.add(tweet);
} while (cursor.moveToNext());
} else {
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext() && limit++ < 200);
}
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext());
}
cursor.close();
return tweetList;
}
/**
* Erwähnungen laden
* @return Tweet Liste
*/
public List<Tweet> getMentions() {
SQLiteDatabase db = dataHelper.getReadableDatabase();
List<Tweet> tweetList = new ArrayList<>();
String SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID=user.userID " +
"WHERE statusregister&(1<<3)>0 " +
"ORDER BY tweetID DESC";
Cursor cursor = db.rawQuery(SQL_GET_HOME,null);
if(cursor.moveToFirst()) {
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext());
}
cursor.close();
return tweetList;
@ -126,16 +147,91 @@ public class DatabaseAdapter {
/**
* get single Tweet
* @param tweetId ID of tweet
* @return Tweet or null if not found
* Tweet Liste eines Nutzers
* @param userID Nutzer ID
* @return Tweet Liste des Users
*/
public List<Tweet> getUserTweets(long userID) {
SQLiteDatabase db = dataHelper.getReadableDatabase();
List<Tweet> tweetList = new ArrayList<>();
String SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID = user.userID "+
"WHERE statusregister&(1<<4)>0 " +
"AND user.userID ="+userID+" ORDER BY tweetID DESC";
Cursor cursor = db.rawQuery(SQL_GET_HOME,null);
if(cursor.moveToFirst()) {
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext());
}
cursor.close();
return tweetList;
}
/**
* Lade Favorisierte Tweets eines Nutzers
* @param userID Nutzer ID
* @return Favoriten des Nutzers
*/
public List<Tweet> getUserFavs(long userID) {
SQLiteDatabase db = dataHelper.getReadableDatabase();
List<Tweet> tweetList = new ArrayList<>();
String SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID = user.userID " +
"INNER JOIN favorit on tweet.tweetID = favorit.tweetID " +
"WHERE favorit.userID ="+userID + " ORDER BY tweetID DESC";
Cursor cursor = db.rawQuery(SQL_GET_HOME,null);
if(cursor.moveToFirst()) {
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext());
}
cursor.close();
return tweetList;
}
/**
* Lade Antworten
* @param tweetId Tweet ID
* @return Antworten zur Tweet ID
*/
public List<Tweet> getAnswers(long tweetId) {
SQLiteDatabase db = dataHelper.getReadableDatabase();
List<Tweet> tweetList = new ArrayList<>();
String SQL_GET_HOME = "SELECT * FROM tweet " +
"INNER JOIN user ON tweet.userID = user.userID " +
"WHERE tweet.replyID="+tweetId+"AND statusregister&(1<<5)>0 " +
"ORDER BY tweetID DESC";
Cursor cursor = db.rawQuery(SQL_GET_HOME,null);
if(cursor.moveToFirst()) {
do {
Tweet tweet = getStatus(cursor);
tweetList.add(tweet);
} while (cursor.moveToNext());
}
cursor.close();
return tweetList;
}
/**
* Lade Tweet
* @param tweetId Tweet ID
* @return Gefundener Tweet oder NULL falls nicht vorhanden
*/
@Nullable
public Tweet getStatus(long tweetId) {
SQLiteDatabase search = dataHelper.getReadableDatabase();
Tweet result = null;
String query = "SELECT * FROM tweet " +
"INNER JOIN user ON user.userID = tweet.userID " +
"WHERE tweet.tweetID == " + tweetId;
Cursor cursor = search.rawQuery(query,null);
if(cursor.moveToFirst())
result = getStatus(cursor);
@ -143,12 +239,12 @@ public class DatabaseAdapter {
return result;
}
/**
* get single User
* @param userId User ID
* @return User or null if not found
* Lade Nutzer Information
* @param userId Nutzer ID
* @return Nutzer Informationen oder NULL falls nicht vorhanden
*/
@Nullable
public TwitterUser getUser(long userId) {
SQLiteDatabase search = dataHelper.getReadableDatabase();
TwitterUser user = null;
@ -160,37 +256,22 @@ public class DatabaseAdapter {
return user;
}
/**
* Store single Tweet
* @param tweet Tweet to be stored
* Aktualisiere Tweet (nur Retweet & Favorit anzahl)
* @param tweet Tweet
*/
public void storeStatus(final Tweet tweet) {
new Thread(new Runnable() {
@Override
public void run() {
storeStatus(tweet, dataHelper.getWritableDatabase());
}
}).start();
}
/**
* Store single User
* @param user Twitteruser to be stored
*/
public void storeUser(final TwitterUser user) {
new Thread(new Runnable() {
@Override
public void run() {
storeUser(user, dataHelper.getWritableDatabase());
}
}).start();
public void updateStatus(Tweet tweet) {
SQLiteDatabase db = dataHelper.getWritableDatabase();
ContentValues status = new ContentValues();
status.put("retweet", tweet.retweet);
status.put("favorite", tweet.favorit);
db.update("tweet",status,"tweet.tweetID = "+tweet.tweetID,null);
}
/**
* Delete Status
* @param id Status id
* Lösche Tweet
* @param id Tweet ID
*/
public void removeStatus(final long id) {
new Thread(new Runnable() {
@ -202,22 +283,26 @@ public class DatabaseAdapter {
}).start();
}
/**
* Check if Tweet exists in Database
* Suche Tweet in Datenbank
* @param id Tweet ID
* @return true if found
* @return True falls gefunden, ansonsten False
*/
public boolean containStatus(long id) {
SQLiteDatabase db = dataHelper.getReadableDatabase();
String query = "SELECT EXISTS(SELECT tweetID FROM tweet WHERE tweetID="+id+" LIMIT 1);";
Cursor c = db.rawQuery(query,null);
c.moveToFirst();
boolean found = c.getInt(0) == 1;
if(c.moveToFirst()) {
c.close();
return c.getInt(0) == 1;
}
c.close();
return found;
return false;
}
private Tweet getStatus(Cursor cursor) {
int index;
index = cursor.getColumnIndex("time");
@ -244,7 +329,7 @@ public class DatabaseAdapter {
int statusregister = cursor.getInt(index);
boolean favorited = (statusregister & 1) == 1;
boolean retweeted = (statusregister & 2) == 2;
boolean profileflag = (statusregister & 4) == 4;
String[] medias = parseMedia(medialinks);
TwitterUser user = getUser(cursor);
@ -252,7 +337,7 @@ public class DatabaseAdapter {
if(retweetId > 0)
embeddedTweet = getStatus(retweetId);
return new Tweet(tweetId,retweet,favorit,user,tweettext,time,replyname,medias,
source,replyStatusId,embeddedTweet,retweeted,favorited,profileflag);
source,replyStatusId,embeddedTweet,retweeted,favorited);
}
@ -288,47 +373,42 @@ public class DatabaseAdapter {
}
private void storeStatus(Tweet tweet, SQLiteDatabase db) {
private void storeStatus(Tweet tweet, int statusregister, SQLiteDatabase db) {
ContentValues status = new ContentValues();
Tweet rtStat = tweet.embedded;
long rtId = -1;
long rtId = 1L;
if(rtStat != null) {
storeStatus(rtStat, db);
storeStatus(rtStat,0, db);
rtId = rtStat.tweetID;
}
TwitterUser mUser = tweet.user;
storeUser(mUser,db);
status.put("tweetID", tweet.tweetID);
status.put("userID", mUser.userID);
status.put("time", tweet.time);
status.put("tweet", tweet.tweet);
status.put("retweet", tweet.retweet);
status.put("favorite", tweet.favorit);
status.put("retweetID", rtId);
status.put("source", tweet.source);
status.put("replyID", tweet.replyID);
status.put("replyname", tweet.replyName);
status.put("retweet", tweet.retweet);
status.put("favorite", tweet.favorit);
String[] medialinks = tweet.media;
StringBuilder media = new StringBuilder();
for(String link : medialinks) {
media.append(link);
media.append(";");
}
status.put("media",media.toString());
if (tweet.favorized)
statusregister |= 1;
if (tweet.retweeted)
statusregister |= 1 << 1;
int statusregister = 0;
if(tweet.favorized)
statusregister += 1;
if(tweet.retweeted)
statusregister += 2;
if(tweet.profileflag)
statusregister += 4;
status.put("statusregister",statusregister);
db.insertWithOnConflict("tweet",null, status,SQLiteDatabase.CONFLICT_REPLACE);
status.put("statusregister", statusregister);
db.insertWithOnConflict("tweet",null, status, CONFLICT_REPLACE);
}
@ -347,7 +427,7 @@ public class DatabaseAdapter {
userColumn.put("createdAt", user.created);
userColumn.put("following", user.following);
userColumn.put("follower", user.follower);
db.insertWithOnConflict("user",null, userColumn,SQLiteDatabase.CONFLICT_REPLACE);
db.insertWithOnConflict("user",null, userColumn, CONFLICT_REPLACE);
}

View File

@ -1,9 +1,12 @@
package org.nuclearfog.twidda.window;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
@ -135,8 +138,19 @@ public class TweetPopup extends AppCompatActivity implements View.OnClickListene
showClosingMsg();
break;
case R.id.image:
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 0);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int check = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
if(check == PackageManager.PERMISSION_GRANTED) {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 0);
}
else {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
} else {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 0);
}
break;
case R.id.img_preview:
new ImagePopup(this).execute(mediaPath.toArray(new String[mediaPath.size()]));

View File

@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath "com.android.tools.build:gradle:3.1.2"
classpath 'com.android.tools.build:gradle:3.1.3'
}
}

View File

@ -11,6 +11,7 @@
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip