├── APKs
└── iHA bot 6.0 alpha 8
│ ├── iHA bot 6.0 alpha 8.apk
│ └── output-metadata.json
├── Android-app
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── .name
│ ├── compiler.xml
│ ├── gradle.xml
│ ├── misc.xml
│ ├── other.xml
│ ├── render.experimental.xml
│ └── vcs.xml
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── fsoft
│ │ │ └── ihabot
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── ic_launcher-playstore.png
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── fsoft
│ │ │ │ └── ihabot
│ │ │ │ ├── ApplicationManager.java
│ │ │ │ ├── BotActivity.java
│ │ │ │ ├── BotService.java
│ │ │ │ ├── Utils
│ │ │ │ ├── Attachment.java
│ │ │ │ ├── Command.java
│ │ │ │ ├── CommandDesc.java
│ │ │ │ ├── CommandModule.java
│ │ │ │ ├── CommandParser.java
│ │ │ │ ├── F.java
│ │ │ │ ├── FileStorage.java
│ │ │ │ └── Triplet.java
│ │ │ │ ├── answer
│ │ │ │ ├── AnswerDatabase.java
│ │ │ │ ├── AnswerElement.java
│ │ │ │ ├── Attachment.java
│ │ │ │ ├── Message.java
│ │ │ │ └── Synonyme.java
│ │ │ │ ├── communucation
│ │ │ │ ├── Account.java
│ │ │ │ ├── AccountBase.java
│ │ │ │ ├── Communicator.java
│ │ │ │ ├── VolleyMultipartRequest.java
│ │ │ │ └── tg
│ │ │ │ │ ├── Chat.java
│ │ │ │ │ ├── Document.java
│ │ │ │ │ ├── File.java
│ │ │ │ │ ├── Message.java
│ │ │ │ │ ├── MessageEntity.java
│ │ │ │ │ ├── MessageProcessor.java
│ │ │ │ │ ├── PhotoSize.java
│ │ │ │ │ ├── Sticker.java
│ │ │ │ │ ├── TgAccount.java
│ │ │ │ │ ├── TgAccountCore.java
│ │ │ │ │ ├── Update.java
│ │ │ │ │ ├── User.java
│ │ │ │ │ └── UserProfilePhotos.java
│ │ │ │ ├── configuration
│ │ │ │ ├── AdminList.java
│ │ │ │ └── MessageHistory.java
│ │ │ │ └── ui
│ │ │ │ ├── TgLoginWindow.java
│ │ │ │ ├── accounts
│ │ │ │ ├── AccountsAdapter.java
│ │ │ │ └── AccountsFragment.java
│ │ │ │ ├── admins
│ │ │ │ ├── AddAdminUsersAdapter.java
│ │ │ │ ├── AdminsAdapter.java
│ │ │ │ └── AdminsFragment.java
│ │ │ │ ├── gallery
│ │ │ │ ├── GalleryFragment.java
│ │ │ │ └── GalleryViewModel.java
│ │ │ │ ├── home
│ │ │ │ ├── HomeFragment.java
│ │ │ │ └── HomeViewModel.java
│ │ │ │ └── slideshow
│ │ │ │ ├── SlideshowFragment.java
│ │ │ │ └── SlideshowViewModel.java
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ ├── bot_noti.png
│ │ │ ├── ic_add_user.xml
│ │ │ ├── ic_cross.xml
│ │ │ ├── ic_exclamation.xml
│ │ │ ├── ic_launcher_foreground.xml
│ │ │ ├── ic_tg_logo.png
│ │ │ ├── iha_bot.png
│ │ │ └── tg_account_placeholder.png
│ │ │ ├── drawable
│ │ │ ├── background_warning.xml
│ │ │ ├── ic_add_tg_account.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── ic_menu_camera.xml
│ │ │ ├── ic_menu_gallery.xml
│ │ │ ├── ic_menu_message.xml
│ │ │ ├── ic_menu_settings.xml
│ │ │ ├── ic_menu_slideshow.xml
│ │ │ ├── ic_menu_user.xml
│ │ │ ├── ic_pause.xml
│ │ │ └── side_nav_bar.xml
│ │ │ ├── layout
│ │ │ ├── activity_bot.xml
│ │ │ ├── app_bar_bot.xml
│ │ │ ├── content_bot.xml
│ │ │ ├── dialog_add_admin.xml
│ │ │ ├── dialog_add_admin_list_item.xml
│ │ │ ├── dialog_add_telegram_account.xml
│ │ │ ├── fragment_accounts_layout.xml
│ │ │ ├── fragment_accounts_list_item.xml
│ │ │ ├── fragment_admins_layout.xml
│ │ │ ├── fragment_admins_list_item.xml
│ │ │ ├── fragment_gallery.xml
│ │ │ ├── fragment_home.xml
│ │ │ ├── fragment_slideshow.xml
│ │ │ └── nav_header_bot.xml
│ │ │ ├── menu
│ │ │ ├── account_popup_menu.xml
│ │ │ ├── activity_main_drawer.xml
│ │ │ ├── admin_popup_menu.xml
│ │ │ └── bot.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── navigation
│ │ │ └── mobile_navigation.xml
│ │ │ ├── raw
│ │ │ ├── answer_database.zip
│ │ │ └── synonyme.txt
│ │ │ ├── values-land
│ │ │ └── dimens.xml
│ │ │ ├── values-night
│ │ │ └── themes.xml
│ │ │ ├── values-w1240dp
│ │ │ └── dimens.xml
│ │ │ ├── values-w600dp
│ │ │ └── dimens.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── fsoft
│ │ └── ihabot
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── Others
└── 2022 Самые популярные слова (парсинг старой базы)
│ ├── Database_frequent_words
│ ├── Database_frequent_words.pde
│ └── data
│ │ ├── answer_database_old_full.txt
│ │ ├── words_frequency.txt
│ │ └── Синонимы (мной вручную дописанные к words_frequency).txt
│ └── Пояснительная бригада.txt
├── Photos
└── Screenshot_20220324_180909.png
├── README.md
└── iHA bot INFO.md
/APKs/iHA bot 6.0 alpha 8/iHA bot 6.0 alpha 8.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/APKs/iHA bot 6.0 alpha 8/iHA bot 6.0 alpha 8.apk
--------------------------------------------------------------------------------
/APKs/iHA bot 6.0 alpha 8/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "com.fsoft.ihabot",
8 | "variantName": "release",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "attributes": [],
14 | "versionCode": 1,
15 | "versionName": "1.0",
16 | "outputFile": "app-release.apk"
17 | }
18 | ],
19 | "elementType": "File"
20 | }
--------------------------------------------------------------------------------
/Android-app/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/Android-app/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/Android-app/.idea/.name:
--------------------------------------------------------------------------------
1 | FP iHA bot
--------------------------------------------------------------------------------
/Android-app/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Android-app/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/Android-app/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Android-app/.idea/other.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Android-app/.idea/render.experimental.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Android-app/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Android-app/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/Android-app/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | }
4 |
5 | android {
6 | compileSdk 33
7 |
8 | defaultConfig {
9 | applicationId "com.fsoft.ihabot"
10 | minSdk 29
11 | targetSdk 33
12 | versionCode 3
13 | versionName "6.1"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | compileOptions {
25 | sourceCompatibility JavaVersion.VERSION_1_8
26 | targetCompatibility JavaVersion.VERSION_1_8
27 | }
28 | buildFeatures {
29 | viewBinding true
30 | }
31 | namespace 'com.fsoft.ihabot'
32 | }
33 |
34 | dependencies {
35 |
36 | implementation 'androidx.appcompat:appcompat:1.4.1'
37 | implementation 'com.google.android.material:material:1.5.0'
38 | implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
39 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
40 | implementation 'com.squareup.picasso:picasso:2.71828'
41 | implementation 'jp.wasabeef:picasso-transformations:2.4.0'
42 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
43 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
44 | implementation 'androidx.navigation:navigation-fragment:2.4.2'
45 | implementation 'androidx.navigation:navigation-ui:2.4.2'
46 | testImplementation 'junit:junit:4.13.2'
47 | androidTestImplementation 'androidx.test.ext:junit:1.1.3'
48 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
49 | implementation 'com.android.volley:volley:1.2.1'
50 | // https://mvnrepository.com/artifact/net.lingala.zip4j/zip4j
51 | implementation 'net.lingala.zip4j:zip4j:2.10.0'
52 |
53 | }
--------------------------------------------------------------------------------
/Android-app/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/Android-app/app/src/androidTest/java/com/fsoft/ihabot/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.fsoft.ihabot", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/BotService.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.app.PendingIntent;
7 | import android.app.Service;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.graphics.Color;
11 | import android.os.IBinder;
12 | import android.util.Log;
13 |
14 | import com.fsoft.ihabot.Utils.F;
15 |
16 | public class BotService extends Service {
17 | static public ApplicationManager applicationManager = null;
18 |
19 | @Override
20 | public IBinder onBind(Intent intent) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public void onCreate() {
26 | super.onCreate();
27 | try {
28 | Intent notificationIntent = new Intent(this, BotActivity.class);
29 |
30 | PendingIntent pendingIntent = PendingIntent.getActivity(
31 | this.getApplicationContext(),
32 | 0,
33 | notificationIntent,
34 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
35 | );
36 |
37 | String channelId = "BotRunning";
38 |
39 | NotificationChannel chan = new NotificationChannel(channelId, getText(R.string.notification_channel_name), NotificationManager.IMPORTANCE_NONE);
40 | chan.setLightColor(Color.BLUE);
41 | chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
42 | NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
43 | manager.createNotificationChannel(chan);
44 |
45 | Notification notification = new Notification.Builder(this, channelId)
46 | .setContentTitle(getText(R.string.notification_title))
47 | .setContentText(getText(R.string.notification_content))
48 | .setSmallIcon(R.drawable.bot_noti)
49 | .setContentIntent(pendingIntent)
50 | .setTicker(getText(R.string.notification_content))
51 | .build();
52 |
53 |
54 | // Notification ID cannot be 0.
55 | int ONGOING_NOTIFICATION_ID = 1;
56 | startForeground(ONGOING_NOTIFICATION_ID, notification);
57 | } catch (Exception e) {
58 | Log.d(F.TAG, "Error starting service: " + e.getMessage());
59 | e.printStackTrace();
60 | }
61 | new Thread(new Runnable() {
62 | @Override
63 | public void run() {
64 | try {
65 | Log.d(F.TAG, "BotService ApplicationManager starting...");
66 | applicationManager = new ApplicationManager(BotService.this);
67 | Log.d(F.TAG, "BotService started");
68 | }
69 | catch (Exception e){
70 | Log.d(F.TAG, "Error starting ApplicationManager: " + e.getMessage());
71 | e.printStackTrace();
72 | }
73 | }
74 | }).start();
75 | }
76 |
77 |
78 | @Override
79 | public void onDestroy() {
80 | Log.d(F.TAG, "BotService stopped");
81 | if (applicationManager != null) {
82 | applicationManager.stop();
83 | }
84 | super.onDestroy();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/Utils/Attachment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.Utils;
2 |
3 | public class Attachment {
4 | }
5 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/Utils/Command.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.Utils;
2 |
3 | import com.fsoft.ihabot.answer.Message;
4 | import com.fsoft.ihabot.communucation.tg.TgAccount;
5 | import com.fsoft.ihabot.configuration.AdminList;
6 |
7 | import java.util.ArrayList;
8 |
9 | /**
10 | * Базовый класс для всех обработчиков команд, общий для всех модулей. Это наследование нужно чтобы хранить их все одном массиве
11 | *
12 | * Формат справки:
13 | * [ описание команды ] (до 50 символов)
14 | * ---| botcmmd hui push
15 | * Created by Dr. Failov on 28.11.2014.
16 | */
17 | public interface Command {
18 |
19 | /**
20 | * На входе и на выходе обьект com.fsoft.ihabot.answer.Message
21 | * Обработка команд происзодит раньше чем обработка базой ответов
22 | * Если по итогу модули прислали ответы на команду - Будут отправлены только сообщения с ответами на команду
23 | * Если модули прислали пустые ответы на команду - ничего не будет отправлено. Базой ответов это сообщение не будет обработано.
24 | * Если модули не прислали ни одного ответа на команду - будет выполнена обработка сообщения как обычного ответа
25 | * @param message сообщение на входе от администратора в неизменном виде
26 | * @param tgAccount Аккаунт телеграм бота, который получил команду. Нужен для обращения в сеть и деланья всякого важного разного командами
27 | * @param admin Какой из админов прислал команду. Мы тут можем проверить есть ли у него права, и т.д.
28 | * @return Список сообщений ответов на команду.
29 | * @throws Exception Мало ли что может случиться при обработке. Команды многое могут делать.
30 | * */
31 | ArrayList processCommand(Message message, TgAccount tgAccount, AdminList.AdminListItem admin) throws Exception; //На вход принимается текст без botcmd
32 |
33 | /**
34 | * Эта команда участвует в формировании справки для админа со списком доступных команд
35 | * @param requester Какой админ запрашивает справку. Не будем выводить ему в справку команд, к которым у него нет доступа.
36 | * @return Список обьектов CommandDesc, где каждый содердит достаточно информации о команде
37 | */
38 | ArrayList getHelp(AdminList.AdminListItem requester);
39 | }
40 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/Utils/CommandDesc.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.Utils;
2 | /**
3 | * Этот класс представляет собой элемент справки
4 | * Created by Dr. Failov on 13.07.2017.
5 | */
6 |
7 | public class CommandDesc {
8 | private String helpText = "";
9 | private String example = "";
10 |
11 | public CommandDesc(String example, String helpText) {
12 | this.helpText = helpText;
13 | this.example = example;
14 | }
15 |
16 | public String getHelpText() {
17 | return helpText;
18 | }
19 |
20 | public void setHelpText(String helpText) {
21 | this.helpText = helpText;
22 | }
23 |
24 | public String getExample() {
25 | return example;
26 | }
27 |
28 | public void setExample(String example) {
29 | this.example = example;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/Utils/CommandModule.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.Utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.fsoft.ihabot.answer.Message;
6 | import com.fsoft.ihabot.communucation.tg.TgAccount;
7 | import com.fsoft.ihabot.configuration.AdminList;
8 |
9 | import java.text.SimpleDateFormat;
10 | import java.util.ArrayList;
11 |
12 | /**
13 | * этот класс будет собирать в себе весь общий функционал необходимый для работы модулей внутри самой программы
14 | * Created by Dr. Failov on 12.02.2017.
15 | */
16 | public class CommandModule implements Command {
17 | protected ArrayList childCommands = new ArrayList<>();
18 |
19 |
20 | public CommandModule() {
21 | }
22 |
23 | protected static String log(String string){
24 | Log.d(F.TAG, string);
25 | return string;
26 | }
27 |
28 | @Override
29 | public ArrayList processCommand(Message message, TgAccount tgAccount, AdminList.AdminListItem admin) throws Exception {
30 | ArrayList results = new ArrayList<>();
31 | for (CommandModule child : childCommands) {
32 | results.addAll(child.processCommand(message, tgAccount, admin));
33 | }
34 | return results;
35 | }
36 | @Override
37 | public ArrayList getHelp(AdminList.AdminListItem requester) {
38 | ArrayList result=new ArrayList<>();
39 | for (CommandModule child : childCommands)
40 | result.addAll(child.getHelp(requester));
41 | return result;
42 | }
43 | public void stop() {
44 | //при закрытии программы останавливает процессы
45 | //НЕ ИСПОЛЬЗОВАТЬ ДЛЯ СОХРАНЕНИЯ!!!!!!!!!!!!!!! Сохранять всё на лету, так надежнее
46 | for (CommandModule child : childCommands)
47 | child.stop();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/Utils/CommandParser.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.Utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.fsoft.ihabot.ApplicationManager;
6 |
7 | /**
8 | * Мегаохуительный класс для разбора команд без регистрации и СМС.
9 | * Created by Dr. Failov on 01.01.2015.
10 | */
11 |
12 | public class CommandParser {
13 | /*
14 | * класс для разбора команд.
15 | * */
16 | public static ApplicationManager applicationManager = null;
17 | private String command = "(empty)";
18 | private String[] words;
19 | private int currentWordCounter = 0;
20 |
21 | public CommandParser(String command){
22 | command = deleteCrap(command);
23 | this.command = command;
24 | words = command.split("\\ ");
25 | if(words.length == 1)
26 | words = command.split("_");
27 | }
28 | private void log(String text){
29 | Log.d(F.TAG, text);
30 | }
31 | private String deleteCrap(String in){
32 | String out = in.replace("botcmd", "");
33 | out = out.replace("/", " ");
34 | out = out.replaceAll(" +", " ");
35 | out = out.trim();
36 | return out;
37 | }
38 | public String tryWord(){
39 | //получить СЛЕДУЮЩЕЕ ПО ПОРЯДКУ НО НЕ МЕНЯТЬ СЧЁТЧИК. Т.е. вызов tryWord не повлияет на результат вызова getWord
40 | int index = currentWordCounter;
41 | return getWord(index);
42 | }
43 | public String getWord(){
44 | //получить СЛЕДУЮЩЕЕ ПО ПОРЯДКУ
45 | int index = currentWordCounter;
46 | currentWordCounter ++;
47 | return getWord(index);
48 | }
49 | public String getWord(int wordNumber){
50 | if(wordNumber >= 0 && wordNumber {
4 |
5 | private final T first;
6 | private final U second;
7 | private final V third;
8 |
9 | public Triplet(T first, U second, V third) {
10 | this.first = first;
11 | this.second = second;
12 | this.third = third;
13 | }
14 |
15 | public T getFirst() { return first; }
16 | public U getSecond() { return second; }
17 | public V getThird() { return third; }
18 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/answer/AnswerElement.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.answer;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import com.fsoft.ihabot.communucation.tg.User;
6 |
7 | import org.json.JSONArray;
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import java.text.ParseException;
12 | import java.util.Locale;
13 |
14 | /* * Какая инфа про ответ должна хранится:
15 | * - ID ответа (id, long. В случае коллизий генерировать новые)
16 | * - Message вопроса (текст вопроса, автор вопроса, дата вопроса)
17 | * - Message ответа (текст ответа, автор ответа, дата ответа)
18 | * */
19 | public class AnswerElement {
20 | private long id = 0; //В случае коллизий генерировать новые)
21 | private Message questionMessage = null;
22 | private Message answerMessage = null;
23 | private int timesUsed = 0; //Количество раз, сколько раз бот использовал этот ответ
24 |
25 | public AnswerElement() {
26 | }
27 | public AnswerElement(JSONObject jsonObject)throws JSONException, ParseException {
28 | fromJson(jsonObject);
29 | }
30 |
31 | public long getId() {
32 | return id;
33 | }
34 |
35 | public Message getQuestionMessage() {
36 | return questionMessage;
37 | }
38 |
39 | public Message getAnswerMessage() {
40 | return answerMessage;
41 | }
42 |
43 | public boolean hasAnswer(){
44 | return answerMessage != null;
45 | }
46 |
47 | public void setId(long id) {
48 | this.id = id;
49 | }
50 |
51 | /**
52 | * Используется для быстрого подбора унимального максимального ID.
53 | * Эта функция задаёт ID на единицу больше того что принят, при условии,
54 | * что принятый ID больше или такой же как текущий.
55 | * @param id ID, больше которого надо сделать ID этого ответа
56 | */
57 | public void setIdBiggerThan(long id) {
58 | if(id >= this.id)
59 | this.id = id+1;
60 | }
61 |
62 | public void setQuestionMessage(Message questionMessage) {
63 | this.questionMessage = questionMessage;
64 | }
65 |
66 | public void setAnswerMessage(Message answerMessage) {
67 | this.answerMessage = answerMessage;
68 | }
69 |
70 | public int getTimesUsed() {
71 | return timesUsed;
72 | }
73 |
74 | public void incrementTimesUsed() {
75 | this.timesUsed++;
76 | }
77 |
78 | public JSONObject toJson() throws JSONException {
79 | JSONObject jsonObject = new JSONObject();
80 | jsonObject.put("id", id);
81 | jsonObject.put("timesUsed", timesUsed);
82 | if(questionMessage != null)
83 | jsonObject.put("questionMessage", questionMessage.toJson());
84 | if(answerMessage != null)
85 | jsonObject.put("answerMessage", answerMessage.toJson());
86 | return jsonObject;
87 | }
88 |
89 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
90 | if(jsonObject.has("id"))
91 | id = jsonObject.getLong("id");
92 | if(jsonObject.has("timesUsed"))
93 | timesUsed = jsonObject.getInt("timesUsed");
94 |
95 | if(jsonObject.has("questionMessage"))
96 | questionMessage = new Message(jsonObject.getJSONObject("questionMessage"));
97 |
98 | if(jsonObject.has("answerMessage"))
99 | answerMessage = new Message(jsonObject.getJSONObject("answerMessage"));
100 | }
101 |
102 | public String toStringWithID() {
103 | if(getQuestionMessage() == null && getAnswerMessage() == null){
104 | return String.format(Locale.US, "ID%d NULL -> NULL", getId());
105 | }
106 | if(getQuestionMessage() == null){
107 | return String.format(Locale.US, "ID%d NULL -> %s",
108 | getId(),
109 | getAnswerMessage().toString().replace("\n", ""));
110 | }
111 | if(getAnswerMessage() == null){
112 | return String.format(Locale.US, "ID%d %s -> NULL",
113 | getId(),
114 | getQuestionMessage().toString().replace("\n", ""));
115 | }
116 | return String.format(Locale.US, "ID%d %s -> %s",
117 | getId(),
118 | getQuestionMessage().toString().replace("\n", ""),
119 | getAnswerMessage().toString().replace("\n", ""));
120 |
121 | }
122 | @NonNull
123 | @Override
124 | public String toString() {
125 | if(getQuestionMessage() == null && getAnswerMessage() == null){
126 | return "NULL -> NULL";
127 | }
128 | if(getQuestionMessage() == null){
129 | return String.format(Locale.US, "NULL -> %s",
130 | getAnswerMessage().toString().replace("\n", ""));
131 | }
132 | if(getAnswerMessage() == null){
133 | return String.format(Locale.US, "%s -> NULL",
134 | getQuestionMessage().toString().replace("\n", ""));
135 | }
136 | return String.format(Locale.US, "%s -> %s",
137 | getQuestionMessage().toString().replace("\n", ""),
138 | getAnswerMessage().toString().replace("\n", ""));
139 |
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/answer/Synonyme.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.answer;
2 |
3 | import android.content.res.Resources;
4 |
5 | import com.fsoft.ihabot.R;
6 | import com.fsoft.ihabot.ApplicationManager;
7 | import com.fsoft.ihabot.Utils.CommandModule;
8 | import com.fsoft.ihabot.Utils.F;
9 |
10 | import java.io.BufferedReader;
11 | import java.io.File;
12 | import java.io.FileReader;
13 | import java.util.ArrayList;
14 | import java.util.Arrays;
15 |
16 | /**
17 | *
18 | * Synonyme database replaces all words to its base synonym
19 | *
20 | * @author Dr. Failov
21 | * date 2022-03-28
22 | */
23 | public class Synonyme extends CommandModule {
24 | private final ApplicationManager applicationManager;
25 | private static final int defaultDatabaseResource = R.raw.synonyme;
26 | private File fileSynonyme = null;
27 | private final ArrayList> synonymeRows = new ArrayList<>();
28 |
29 | public Synonyme(AnswerDatabase answerDatabase) throws Exception {
30 | this.applicationManager = answerDatabase.getApplicationManager();
31 | if(applicationManager == null)
32 | return;
33 | fileSynonyme = new File(answerDatabase.getFolderAnswerDatabase(), "synonyme.txt");
34 | if(!fileSynonyme.isFile()){
35 | log(". Файла синонимов нет. Загрузка файла synonyme.zip из ресурсов...");
36 | loadDefaultDatabase();
37 | }
38 | loadDefaultDatabase(); //todo это для отладки!
39 |
40 | BufferedReader bufferedReader = new BufferedReader(new FileReader(fileSynonyme));
41 | String line;
42 | int lineNumber = 0;
43 |
44 | while ((line = bufferedReader.readLine()) != null) {
45 | lineNumber++;
46 | //- Заменить символы которые часто забивают писать (ё ъ щ)
47 | line = AnswerDatabase.replacePhoneticallySimilarLetters(line);
48 | // - устранить любые символы повторяющиеся несколько раз
49 | line = AnswerDatabase.removeRepeatingSymbols(line);
50 | if (lineNumber % 18 == 0)
51 | log(". Загрузка синонимов (" + lineNumber + " рядов загружено) ...");
52 | try {
53 | ArrayList row = new ArrayList<>(Arrays.asList(line.split(",")));
54 | if(row.size() > 1){
55 | synonymeRows.add(row);
56 | }
57 | else {
58 | log("! Строка " + lineNumber + " в базе синонимов содержит слишком мало синонимов");
59 | }
60 | } catch (Exception e) {
61 | e.printStackTrace();
62 | log("! Ошибка разбора строки " + lineNumber + " как ряда синонимов.\n" + e.getMessage());
63 | }
64 | }
65 | //завешить сессию
66 | bufferedReader.close();
67 | System.gc();
68 | log(". Загрузка синонимов из synonyme.txt прошла без ошибок. Загружено " + synonymeRows.size() + " рядов.");
69 | }
70 |
71 | /*текст на входе:
72 | - привести текст входящего сообшения к нижнему регистру
73 | - убрать обращение бот
74 | - Убрать все символы и знаки, оставить только текст
75 | - Заменить символы которые часто забивают писать (ё ъ щ)
76 | - устранить любые символы повторяющиеся несколько раз
77 | */
78 |
79 | public String replaceSynonyms(String in){
80 | in = " " + in + " ";
81 | for (ArrayList row:synonymeRows){
82 | if(row.size() < 2)
83 | continue;
84 | String baseSynonyme = " " + row.get(0) + " ";
85 | for(int i=1;i login() -> startAccount()
19 | * constructor() -> startAccount()
20 | * Created by Dr. Failov on 22.02.2017.
21 | */
22 | public class Account extends CommandModule implements AccountBase {
23 | private long id = 0L;
24 | private String token = null;
25 | //место для хранения данных этого аккаунта и любого наследованного аккаунта
26 | private FileStorage fileStorage = null;
27 | private String fileName = null;
28 | //это настройка для пользователя чтобы выключить аккаунт
29 | private boolean enabled = true;
30 | //устанавливается true во время запуска аккаунта
31 | private boolean running = false;
32 | //это - что-то наподобие временного комментария описывающего, что с этим аккаунтом происходит.
33 | private String state = "";
34 | //Имя под которым можно отображать этот аккаунт в программе
35 | private String screenName = null;
36 | private Runnable onStateChangedListener = null;
37 |
38 |
39 | public Account(ApplicationManager applicationManager, String fileName) {
40 | super();
41 | this.fileName = fileName;
42 | fileStorage = new FileStorage(fileName, applicationManager);
43 | log(". Создан аккаунт: " + fileName);
44 |
45 | enabled = getFileStorage().getBoolean("enabled", enabled);
46 | id = getFileStorage().getLong("id", id);
47 | token = getFileStorage().getString("token", token);
48 | screenName = getFileStorage().getString("screenName", screenName);
49 |
50 | }
51 | public boolean remove(){
52 | //удалить файл аккаунта
53 | return new File(fileStorage.getFilePath()).delete();
54 | }
55 | public void login(){
56 | //открывает процедуру (пере)логина.
57 | // По итогу задает значение для token
58 | }
59 | public void startAccount(){
60 | //если токен есть, эта функция его проверяет. Если токен валидный,
61 | //эта функция запускает работу во всех службах аккаунта, если isEnabled.
62 | running = true;
63 | log(". Аккаунт " + toString() + " запускается...");
64 | setState("Запускается...");
65 | //token_ok = true; //кажется, это не всегда связано
66 | }
67 | public void stopAccount(){
68 | //эта функция останавливает работу во всех службах аккаунта
69 | running = false;
70 | log(". Аккаунт " + toString() + " остановлен.");
71 | setState("Остановлен.");
72 | // token_ok = false; ////кажется, это не всегда связано
73 | }
74 | protected interface OnTokenValidityCheckedListener{
75 | void onTokenPass();
76 | void onTokenFail();
77 | }
78 | protected void checkTokenValidity(OnTokenValidityCheckedListener listener){
79 | //запускать проверку и вызывать лисенер...
80 | log(". Аккаунт " + toString() + " проверяется...");
81 | setState("Проверяется...");
82 | }
83 | public boolean isMine(String commandTreatment){
84 | //Эта функция должна отвечать за то, чтобы при обращении в команде
85 | // можно было понять что обращение именно к этому аккаунту
86 | //например bcd acc 098309832 enable
87 | try{
88 | return Long.parseLong(commandTreatment.trim()) == id;
89 | }catch (Exception e){
90 | return false;
91 | }
92 | }
93 |
94 | public boolean isEnabled() {
95 | return enabled;
96 | }
97 | public boolean isRunning() {
98 | return running;
99 | }
100 | public String getState() {
101 | return state;
102 | }
103 | public FileStorage getFileStorage() {
104 | return fileStorage;
105 | }
106 | public long getId() {
107 | return id;
108 | }
109 | public String getToken() {
110 | return token;
111 | }
112 | public String getFileName() {
113 | //именно это имя аккаунт получает при создании
114 | //эта функция нужна для того чтобы список аккаунтов можно было сохранить, не только загрузить
115 | return fileName;
116 | }
117 | public String getScreenName() {
118 | return screenName;
119 | }
120 | public void setScreenName(String screenName) {
121 | this.screenName = screenName;
122 | getFileStorage().put("screenName", screenName).commit();
123 | }
124 |
125 | //------------
126 | public void setEnabled(boolean enabled) {
127 | this.enabled = enabled;
128 | getFileStorage().put("enabled", enabled).commit();
129 | if(isRunning() && !isEnabled())
130 | stopAccount();
131 | if(!isRunning() && isEnabled())
132 | startAccount();
133 | }
134 | public String state(String state) {
135 | setState(state);
136 | return state;
137 | }
138 | public void setState(String state) {
139 | String time = new SimpleDateFormat("HH:mm").format(new Date());
140 | this.state = time + " " + state;
141 | if(onStateChangedListener != null) {
142 | try {
143 | onStateChangedListener.run();
144 | }
145 | catch (Exception e){
146 | e.printStackTrace();
147 | }
148 | }
149 | }
150 | public void setId(long id) {
151 | this.id = id;
152 | getFileStorage().put("id", id).commit();
153 | }
154 | public void setToken(String token) {
155 | this.token = token;
156 | getFileStorage().put("token", token).commit();
157 | }
158 | public void setOnStateChangedListener(Runnable onStateChangedListener) {
159 | this.onStateChangedListener = onStateChangedListener;
160 | }
161 |
162 | @NonNull
163 | @Override public String toString() {
164 | return "Аккаунт " + id;
165 | }
166 | @Override public boolean equals(Object o) {
167 | if (this == o) return true;
168 | if (o == null || getClass() != o.getClass()) return false;
169 |
170 | Account account = (Account) o;
171 |
172 | if (getId() != account.getId()) return false;
173 |
174 | return true;
175 | }
176 | @Override public int hashCode() {
177 | return (int) (getId() ^ (getId() >>> 32));
178 | }
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/AccountBase.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation;
2 |
3 | import com.fsoft.ihabot.Utils.FileStorage;
4 |
5 | public interface AccountBase
6 | {
7 | public boolean remove();
8 | public void startAccount();
9 | public void stopAccount();
10 | public boolean isEnabled();
11 | public boolean isRunning();
12 | public String getState();
13 | public FileStorage getFileStorage();
14 | public long getId();
15 | public String getToken();
16 | public String getFileName();
17 | public void setEnabled(boolean enabled);
18 | public String state(String state);
19 | public void setState(String state);
20 | public void setId(long id);
21 | public void setToken(String token);
22 | public String getScreenName();
23 | public void setScreenName(String screenName);
24 | }
25 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/Communicator.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation;
2 |
3 | import com.fsoft.ihabot.ApplicationManager;
4 | import com.fsoft.ihabot.Utils.CommandModule;
5 | import com.fsoft.ihabot.Utils.FileStorage;
6 | import com.fsoft.ihabot.communucation.tg.TgAccount;
7 |
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * class for communication with VK
12 | * Created by Dr. Failov on 05.08.2014.
13 | */
14 | public class Communicator extends CommandModule{
15 | ApplicationManager applicationManager = null;
16 | private final ArrayList tgAccounts = new ArrayList<>();
17 | private FileStorage file = null;
18 | private boolean running = false;
19 |
20 | public Communicator(ApplicationManager applicationManager) {
21 | this.applicationManager = applicationManager;
22 | file = new FileStorage("communicator",applicationManager);
23 |
24 | String[] accountList = file.getStringArray("TGaccounts", new String[0]);
25 | for (String acc:accountList)
26 | tgAccounts.add(new TgAccount(applicationManager, acc));
27 | }
28 | public void startCommunicator(){
29 | log("Запуск коммуникатора...");
30 | running = true;
31 | for(TgAccount tgAccount:tgAccounts) {
32 | if(tgAccount.isEnabled())
33 | tgAccount.startAccount();
34 | }
35 | }
36 | public void stopCommunicator(){
37 | running = false;
38 | for(TgAccount tgAccount:tgAccounts) {
39 | tgAccount.stopAccount();
40 | }
41 | }
42 | public TgAccount getTgAccount(long id){
43 | for (TgAccount account : tgAccounts)
44 | if (account.getId() == id)
45 | return account;
46 | return null;
47 | }
48 | public TgAccount getWorkingTgAccount(){
49 | for (TgAccount account : tgAccounts) {
50 | if (account.isRunning() && account.isEnabled())
51 | return account;
52 | }
53 | return null;
54 | }
55 | public ArrayList getTgAccounts() {
56 | return tgAccounts;
57 | }
58 |
59 | public boolean containsTgAccount(long id){
60 | return getTgAccount(id) != null;
61 | }
62 | public void addAccount(TgAccount tgAccount) throws Exception{
63 | if(tgAccount == null)
64 | throw new Exception("Аккаунт не получен");
65 | if(containsTgAccount(tgAccount.getId())) {
66 | tgAccount.stopAccount();
67 | throw new Exception("Такой аккаунт уже есть");
68 | }
69 | tgAccounts.add(tgAccount);
70 |
71 | String[] accountList = new String[tgAccounts.size()];
72 | for (int i = 0; i < tgAccounts.size(); i++)
73 | accountList[i] = tgAccounts.get(i).getFileName();
74 | file.put("TGaccounts", accountList).commit();
75 | log("Аккаунт " + tgAccount.getId() + " добавлен. Список аккаунтов сохранён.");
76 | }
77 | public void remAccount(TgAccount accountToRemove) throws Exception{
78 | if(accountToRemove == null)
79 | throw new Exception("Функция удаления TG аккаунта вызвана с аргументом null");
80 | if(running)
81 | accountToRemove.stopAccount();
82 | tgAccounts.remove(accountToRemove);
83 |
84 | String[] accountList = new String[tgAccounts.size()];
85 | for (int i = 0; i < tgAccounts.size(); i++)
86 | accountList[i] = tgAccounts.get(i).getFileName();
87 | file.put("TGaccounts", accountList).commit();
88 |
89 | if(accountToRemove.remove())
90 | log("Аккаунт TG " + accountToRemove + " успешно удалён.");
91 | else
92 | throw new Exception("Аккаунт TG " + accountToRemove + " удалён из списка, но его файл удалить не получается.");
93 | }
94 |
95 | @Override
96 | public void stop() {
97 | stopCommunicator();
98 | super.stop();
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/Chat.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | import java.text.ParseException;
7 |
8 | public class Chat {
9 | private long id = 0;
10 | private String type = "";
11 | private String title = "";
12 | private String username = "";
13 | private String first_name = "";
14 | private String last_name = "";
15 | private String description = "";
16 | private boolean all_members_are_administrators = false;
17 |
18 | public Chat() {
19 | }
20 |
21 | public Chat(JSONObject jsonObject) throws JSONException, ParseException {
22 | fromJson(jsonObject);
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | if(title == null || title.isEmpty())
28 | return first_name + " " + last_name;
29 | else
30 | return title;
31 | }
32 | public JSONObject toJson() throws JSONException {
33 | JSONObject jsonObject = new JSONObject();
34 | jsonObject.put("id", id);
35 | jsonObject.put("all_members_are_administrators", all_members_are_administrators);
36 | if(type != null)
37 | jsonObject.put("type", type);
38 | if(title != null)
39 | jsonObject.put("title", title);
40 | if(description != null)
41 | jsonObject.put("description", description);
42 | if(first_name != null)
43 | jsonObject.put("first_name", first_name);
44 | if(last_name != null)
45 | jsonObject.put("last_name", last_name);
46 | if(username != null)
47 | jsonObject.put("username", username);
48 | return jsonObject;
49 | }
50 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
51 | id = jsonObject.getLong("id");
52 | if(jsonObject.has("all_members_are_administrators"))
53 | all_members_are_administrators = jsonObject.getBoolean("all_members_are_administrators");
54 | if(jsonObject.has("first_name"))
55 | first_name = jsonObject.getString("first_name");
56 | if(jsonObject.has("last_name"))
57 | last_name = jsonObject.getString("last_name");
58 | if(jsonObject.has("username"))
59 | username = jsonObject.getString("username");
60 | if(jsonObject.has("description"))
61 | description = jsonObject.getString("description");
62 | if(jsonObject.has("title"))
63 | title = jsonObject.getString("title");
64 | if(jsonObject.has("type"))
65 | type = jsonObject.getString("type");
66 | }
67 |
68 | public long getId() {
69 | return id;
70 | }
71 |
72 | public void setId(long id) {
73 | this.id = id;
74 | }
75 |
76 | public String getType() {
77 | return type;
78 | }
79 |
80 | public void setType(String type) {
81 | this.type = type;
82 | }
83 |
84 | public String getTitle() {
85 | return title;
86 | }
87 |
88 | public void setTitle(String title) {
89 | this.title = title;
90 | }
91 |
92 | public String getUsername() {
93 | return username;
94 | }
95 |
96 | public void setUsername(String username) {
97 | this.username = username;
98 | }
99 |
100 | public String getFirst_name() {
101 | return first_name;
102 | }
103 |
104 | public void setFirst_name(String first_name) {
105 | this.first_name = first_name;
106 | }
107 |
108 | public String getLast_name() {
109 | return last_name;
110 | }
111 |
112 | public void setLast_name(String last_name) {
113 | this.last_name = last_name;
114 | }
115 |
116 | public String getDescription() {
117 | return description;
118 | }
119 |
120 | public void setDescription(String description) {
121 | this.description = description;
122 | }
123 |
124 | public boolean isAll_members_are_administrators() {
125 | return all_members_are_administrators;
126 | }
127 |
128 | public void setAll_members_are_administrators(boolean all_members_are_administrators) {
129 | this.all_members_are_administrators = all_members_are_administrators;
130 | }
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/Document.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import com.fsoft.ihabot.communucation.Account;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.text.ParseException;
9 |
10 | public class Document {
11 | private String file_id = "";
12 | private long file_size = 0;
13 | private String file_name = "";
14 |
15 | public Document() {
16 | }
17 | public Document(String file_id, long file_size, String file_name) {
18 | this.file_id = file_id;
19 | this.file_size = file_size;
20 | this.file_name = file_name;
21 | }
22 | public Document(JSONObject jsonObject) throws JSONException, ParseException {
23 | fromJson(jsonObject);
24 | }
25 |
26 | public JSONObject toJson() throws JSONException {
27 | JSONObject jsonObject = new JSONObject();
28 | if(file_id != null)
29 | jsonObject.put("file_id", file_id);
30 | jsonObject.put("file_size", file_size);
31 | if(file_name != null)
32 | jsonObject.put("file_name", file_name);
33 | return jsonObject;
34 | }
35 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
36 | if(jsonObject.has("file_id"))
37 | file_id = jsonObject.getString("file_id");
38 | if(jsonObject.has("file_size"))
39 | file_size = jsonObject.getLong("file_size");
40 | if(jsonObject.has("file_name"))
41 | file_name = jsonObject.getString("file_name");
42 | }
43 |
44 | public String getFile_id() {
45 | return file_id;
46 | }
47 |
48 | public void setFile_id(String file_id) {
49 | this.file_id = file_id;
50 | }
51 |
52 | public long getFile_size() {
53 | return file_size;
54 | }
55 |
56 | public void setFile_size(long file_size) {
57 | this.file_size = file_size;
58 | }
59 |
60 | public String getFile_name() {
61 | return file_name;
62 | }
63 |
64 | public void setFile_name(String file_name) {
65 | this.file_name = file_name;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/File.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import com.fsoft.ihabot.communucation.Account;
4 |
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.text.ParseException;
9 |
10 | public class File {
11 | private String file_id = "";
12 | private long file_size = 0;
13 | private String file_path = "";
14 |
15 | public File() {
16 | }
17 | public File(String file_id, long file_size, String file_path) {
18 | this.file_id = file_id;
19 | this.file_size = file_size;
20 | this.file_path = file_path;
21 | }
22 | public File(JSONObject jsonObject) throws JSONException, ParseException {
23 | fromJson(jsonObject);
24 | }
25 |
26 | public JSONObject toJson() throws JSONException {
27 | JSONObject jsonObject = new JSONObject();
28 | if(file_id != null)
29 | jsonObject.put("file_id", file_id);
30 | jsonObject.put("file_size", file_size);
31 | if(file_path != null)
32 | jsonObject.put("file_path", file_path);
33 | return jsonObject;
34 | }
35 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
36 | if(jsonObject.has("file_id"))
37 | file_id = jsonObject.getString("file_id");
38 | if(jsonObject.has("file_size"))
39 | file_size = jsonObject.getLong("file_size");
40 | if(jsonObject.has("file_path"))
41 | file_path = jsonObject.getString("file_path");
42 | }
43 |
44 | public String getUrl(Account tgAccount){
45 | //https://api.telegram.org/file/bot/
46 | return "https://api.telegram.org/file/bot" + tgAccount.getId() + ":"+tgAccount.getToken()+"/"+file_path;
47 | }
48 |
49 |
50 | public String getFile_id() {
51 | return file_id;
52 | }
53 |
54 | public void setFile_id(String file_id) {
55 | this.file_id = file_id;
56 | }
57 |
58 | public long getFile_size() {
59 | return file_size;
60 | }
61 |
62 | public void setFile_size(long file_size) {
63 | this.file_size = file_size;
64 | }
65 |
66 | public String getFile_path() {
67 | return file_path;
68 | }
69 |
70 | public void setFile_path(String file_path) {
71 | this.file_path = file_path;
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/MessageEntity.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | import java.text.ParseException;
7 |
8 | /*
9 | https://core.telegram.org/bots/api#messageentity
10 |
11 | drfailov 2018-08-19
12 | * */
13 | public class MessageEntity {
14 | private String type = "";
15 | private int offset = 0;
16 | private int length = 0;
17 | private String url = "";
18 | private User user = null;
19 |
20 | public MessageEntity() {
21 | }
22 | public MessageEntity(String type, int offset, int length, String url, User user) {
23 | this.type = type;
24 | this.offset = offset;
25 | this.length = length;
26 | this.url = url;
27 | this.user = user;
28 | }
29 | public MessageEntity(String type, int offset, int length) {
30 | this.type = type;
31 | this.offset = offset;
32 | this.length = length;
33 | }
34 | public MessageEntity(String type, int offset, int length, User user) {
35 | this.type = type;
36 | this.offset = offset;
37 | this.length = length;
38 | this.user = user;
39 | }
40 | public MessageEntity(JSONObject jsonObject) throws JSONException, ParseException {
41 | fromJson(jsonObject);
42 | }
43 |
44 |
45 | public JSONObject toJson() throws JSONException {
46 | JSONObject jsonObject = new JSONObject();
47 | if(type != null)
48 | jsonObject.put("type", type);
49 | if(offset != 0)
50 | jsonObject.put("offset", offset);
51 | if(length != 0)
52 | jsonObject.put("length", length);
53 | if(url != null)
54 | jsonObject.put("url", url);
55 | if(user != null)
56 | jsonObject.put("user", user.toJson());
57 | return jsonObject;
58 | }
59 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
60 | if(jsonObject.has("type"))
61 | type = jsonObject.getString("type");
62 | if(jsonObject.has("offset"))
63 | offset = jsonObject.getInt("offset");
64 | if(jsonObject.has("length"))
65 | length = jsonObject.getInt("length");
66 | if(jsonObject.has("url"))
67 | url = jsonObject.getString("url");
68 | if(jsonObject.has("user"))
69 | user = new User(jsonObject.getJSONObject("user"));
70 | }
71 |
72 | public String getType() {
73 | return type;
74 | }
75 | public void setType(String type) {
76 | this.type = type;
77 | }
78 | public int getOffset() {
79 | return offset;
80 | }
81 | public void setOffset(int offset) {
82 | this.offset = offset;
83 | }
84 | public int getLength() {
85 | return length;
86 | }
87 | public void setLength(int length) {
88 | this.length = length;
89 | }
90 | public String getUrl() {
91 | return url;
92 | }
93 | public void setUrl(String url) {
94 | this.url = url;
95 | }
96 | public User getUser() {
97 | return user;
98 | }
99 | public void setUser(User user) {
100 | this.user = user;
101 | }
102 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/PhotoSize.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 | import org.json.JSONException;
3 | import org.json.JSONObject;
4 |
5 | import java.text.ParseException;
6 |
7 | public class PhotoSize {
8 | private String file_id = "";
9 | private long file_size = 0;
10 | private int height = 0;
11 | private int width = 0;
12 |
13 | public PhotoSize() {
14 | }
15 |
16 | public PhotoSize(String file_id, long file_size, int height, int width) {
17 | this.file_id = file_id;
18 | this.file_size = file_size;
19 | this.height = height;
20 | this.width = width;
21 | }
22 |
23 | public PhotoSize(JSONObject jsonObject) throws JSONException, ParseException {
24 | fromJson(jsonObject);
25 | }
26 |
27 | public JSONObject toJson() throws JSONException {
28 | JSONObject jsonObject = new JSONObject();
29 | if(file_id != null)
30 | jsonObject.put("file_id", file_id);
31 | jsonObject.put("file_size", file_size);
32 | jsonObject.put("height", height);
33 | jsonObject.put("width", width);
34 | return jsonObject;
35 | }
36 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
37 | if(jsonObject.has("file_id"))
38 | file_id = jsonObject.getString("file_id");
39 | if(jsonObject.has("file_size"))
40 | file_size = jsonObject.getLong("file_size");
41 | if(jsonObject.has("height"))
42 | height = jsonObject.getInt("height");
43 | if(jsonObject.has("width"))
44 | width = jsonObject.getInt("width");
45 | }
46 |
47 | public String getFile_id() {
48 | return file_id;
49 | }
50 |
51 | public void setFile_id(String file_id) {
52 | this.file_id = file_id;
53 | }
54 |
55 | public long getFile_size() {
56 | return file_size;
57 | }
58 |
59 | public void setFile_size(long file_size) {
60 | this.file_size = file_size;
61 | }
62 |
63 | public int getHeight() {
64 | return height;
65 | }
66 |
67 | public void setHeight(int height) {
68 | this.height = height;
69 | }
70 |
71 | public int getWidth() {
72 | return width;
73 | }
74 |
75 | public void setWidth(int width) {
76 | this.width = width;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/Sticker.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | import java.text.ParseException;
7 |
8 | /**
9 | * https://core.telegram.org/bots/api#sticker
10 | * @author Dr. Failov
11 | */
12 | public class Sticker {
13 | private String file_id = "";
14 | private int height = 0;
15 | private int width = 0;
16 | private long file_size = 0;
17 | private boolean is_animated = false;
18 | private boolean is_video = false;
19 |
20 |
21 | public Sticker(String file_id, int height, int width, boolean is_animated, boolean is_video) {
22 | this.file_id = file_id;
23 | this.height = height;
24 | this.width = width;
25 | this.is_animated = is_animated;
26 | this.is_video = is_video;
27 | }
28 | public Sticker(JSONObject jsonObject) throws JSONException, ParseException {
29 | fromJson(jsonObject);
30 | }
31 |
32 | public JSONObject toJson() throws JSONException {
33 | JSONObject jsonObject = new JSONObject();
34 | if(file_id != null)
35 | jsonObject.put("file_id", file_id);
36 | jsonObject.put("height", height);
37 | jsonObject.put("width", width);
38 | jsonObject.put("file_size", file_size);
39 | jsonObject.put("is_animated", is_animated);
40 | jsonObject.put("is_video", is_video);
41 | return jsonObject;
42 | }
43 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
44 | if(jsonObject.has("file_id"))
45 | file_id = jsonObject.getString("file_id");
46 | if(jsonObject.has("height"))
47 | height = jsonObject.getInt("height");
48 | if(jsonObject.has("width"))
49 | width = jsonObject.getInt("width");
50 | if(jsonObject.has("file_size"))
51 | file_size = jsonObject.getLong("file_size");
52 | if(jsonObject.has("is_animated"))
53 | is_animated = jsonObject.getBoolean("is_animated");
54 | if(jsonObject.has("is_video"))
55 | is_video = jsonObject.getBoolean("is_video");
56 | }
57 |
58 | public String getFile_id() {
59 | return file_id;
60 | }
61 |
62 | public void setFile_id(String file_id) {
63 | this.file_id = file_id;
64 | }
65 |
66 | public int getHeight() {
67 | return height;
68 | }
69 |
70 | public void setHeight(int height) {
71 | this.height = height;
72 | }
73 |
74 | public int getWidth() {
75 | return width;
76 | }
77 |
78 | public void setWidth(int width) {
79 | this.width = width;
80 | }
81 |
82 | public boolean isIs_animated() {
83 | return is_animated;
84 | }
85 |
86 | public void setIs_animated(boolean is_animated) {
87 | this.is_animated = is_animated;
88 | }
89 |
90 | public boolean isIs_video() {
91 | return is_video;
92 | }
93 |
94 | public void setIs_video(boolean is_video) {
95 | this.is_video = is_video;
96 | }
97 |
98 | public long getFile_size() {
99 | return file_size;
100 | }
101 |
102 | public void setFile_size(long file_size) {
103 | this.file_size = file_size;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/TgAccount.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import com.fsoft.ihabot.ApplicationManager;
4 | import com.fsoft.ihabot.Utils.F;
5 |
6 | import java.io.DataInputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.net.MalformedURLException;
11 | import java.net.URL;
12 | import java.text.SimpleDateFormat;
13 | import java.util.ArrayList;
14 | import java.util.Calendar;
15 | import java.util.Date;
16 | import java.util.Locale;
17 | import java.util.concurrent.TimeoutException;
18 |
19 | public class TgAccount extends TgAccountCore {
20 | private MessageProcessor messageProcessor = null;
21 |
22 | public TgAccount(ApplicationManager applicationManager, String fileName) {
23 | super(applicationManager, fileName);
24 | messageProcessor = new MessageProcessor(applicationManager, this);
25 | }
26 |
27 | @Override
28 | public void startAccount() {
29 | super.startAccount();
30 | checkTokenValidity(new OnTokenValidityCheckedListener() {
31 | @Override
32 | public void onTokenPass() {
33 | messageProcessor.startModule();
34 | }
35 |
36 | @Override
37 | public void onTokenFail() {
38 |
39 | }
40 | });
41 | }
42 |
43 | @Override
44 | public void stopAccount() {
45 | super.stopAccount();
46 | messageProcessor.stopModule();
47 | }
48 |
49 |
50 | public MessageProcessor getMessageProcessor() {
51 | return messageProcessor;
52 | }
53 | public void sendMessage(long chatId, com.fsoft.ihabot.answer.Message message){
54 | messageProcessor.sendAnswer(chatId, message);
55 | }
56 | /**
57 | * Блокирующая(!) версия функции для скачивания файла из телеграма в локальное хранилище.
58 | * Файл будет сохранен под автоматически выбранным именем во временной папке.
59 | * @param fileId FileID с серверов телеграма
60 | * @return Файл который скачан во временную папку
61 | * @throws Exception работаем с фалами и сетью. Может случиться что угодно.
62 | */
63 | public java.io.File downloadPhotoAttachment(String fileId) throws Exception{
64 | log("Попытка получить ссылку для скачивания файла вложения...");
65 | final ArrayList files = new ArrayList<>();
66 | final ArrayList exceptions = new ArrayList<>();
67 | getFile(new GetFileListener() {
68 | @Override
69 | public void gotFile(File file) {
70 | if(file.getFile_path() == null || file.getFile_path().isEmpty()){
71 | exceptions.add(new Exception("Телеграм не прислал ссылку на файл для скачивания."));
72 | return;
73 | }
74 | String directLink = "https://api.telegram.org/file/bot"+getId()+":"+getToken() + "/" + file.getFile_path();
75 | log("Ссылка на файл получена. Попытка скачать файл: " +directLink);
76 | String fileRes = F.getFileExtension(file.getFile_path());
77 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSS", Locale.US);
78 | String filename = simpleDateFormat.format(new Date());
79 | if(!fileRes.isEmpty())
80 | filename += fileRes;
81 | java.io.File placeToSave = new java.io.File(ApplicationManager.getInstance().getTempFolder(), filename);
82 | log("Скачивать файл будем сюда: " + placeToSave.getAbsolutePath());
83 |
84 | try {
85 | URL u = new URL(directLink);
86 | try(InputStream is = u.openStream()) {
87 | DataInputStream dis = new DataInputStream(is);
88 | byte[] buffer = new byte[1024];
89 | int length;
90 | try(FileOutputStream fos = new FileOutputStream(placeToSave)) {
91 | while ((length = dis.read(buffer)) > 0) {
92 | fos.write(buffer, 0, length);
93 | }
94 | }
95 | }
96 | log("Загрузка файла прошла без ошибок. Загружено " + placeToSave.length() + " байт.");
97 | } catch (MalformedURLException mue) {
98 | exceptions.add(new Exception(log("Ошибка MalformedURLException скачивания файла фото: " + mue)));
99 | mue.printStackTrace();
100 | return;
101 | } catch (IOException ioe) {
102 | exceptions.add(new Exception(log("Ошибка IOException скачивания файла: " + ioe.getLocalizedMessage())));
103 | ioe.printStackTrace();
104 | return;
105 | } catch (SecurityException se) {
106 | exceptions.add(new Exception(log("Ошибка SecurityException скачивания файла: " + se.getLocalizedMessage())));
107 | se.printStackTrace();
108 | return;
109 | }
110 | if(placeToSave.isFile())
111 | files.add(placeToSave);
112 | else
113 | exceptions.add(new Exception(log("Всё вроде прошло норм, но фото не был скачан.")));
114 | }
115 |
116 | @Override
117 | public void error(Throwable error) {
118 |
119 | }
120 | }, fileId);
121 |
122 |
123 | Date started = new Date();
124 | //ждать пока что-то появится либо пока не будет какая-то ошибка, либо таймаут 30 секунд
125 | while (files.isEmpty() && exceptions.isEmpty()){
126 | if(Calendar.getInstance().getTime().getTime() - started.getTime() > 60000) {
127 | throw new TimeoutException("Таймаут, файл не получилось скачать.");
128 | }
129 | }
130 | if(!files.isEmpty()){
131 | log("Был получен файл: " + files.get(0).getName());
132 | return files.get(0);
133 | }
134 | if(!exceptions.isEmpty()) {
135 | log("Была получена ошибка: " + exceptions.get(0));
136 | throw exceptions.get(0);
137 | }
138 | throw new Exception("Во время скачивания файла фотографии ни файл ни ошибка не получены. Это странная ситуация.");
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/Update.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import org.json.JSONException;
4 | import org.json.JSONObject;
5 |
6 | import java.text.ParseException;
7 |
8 | /*
9 | *
10 | * https://core.telegram.org/bots/api#update
11 | *
12 | * Created by Dr. Failov 2018-07-24
13 | * */
14 | public class Update {
15 | private long update_id = 0;
16 | private Message message = null;
17 | private Message edited_message = null;
18 |
19 | public Update(JSONObject jsonObject) throws JSONException, ParseException {
20 | fromJson(jsonObject);
21 | }
22 |
23 | public JSONObject toJson() throws JSONException {
24 | JSONObject jsonObject = new JSONObject();
25 | jsonObject.put("update_id", update_id);
26 | if(message != null)
27 | jsonObject.put("message", message.toJson());
28 | if(edited_message != null)
29 | jsonObject.put("edited_message", edited_message.toJson());
30 | return jsonObject;
31 | }
32 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
33 | update_id = jsonObject.getLong("update_id");
34 | if(jsonObject.has("message"))
35 | message = new Message(jsonObject.getJSONObject("message"));
36 | if(jsonObject.has("edited_message"))
37 | edited_message = new Message(jsonObject.getJSONObject("edited_message"));
38 | }
39 |
40 | public long getUpdate_id() {
41 | return update_id;
42 | }
43 |
44 | public void setUpdate_id(long update_id) {
45 | this.update_id = update_id;
46 | }
47 |
48 | public Message getMessage() {
49 | return message;
50 | }
51 |
52 | public void setMessage(Message message) {
53 | this.message = message;
54 | }
55 |
56 | public Message getEdited_message() {
57 | return edited_message;
58 | }
59 |
60 | public void setEdited_message(Message edited_message) {
61 | this.edited_message = edited_message;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/User.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 | import android.util.Log;
4 |
5 | import androidx.annotation.NonNull;
6 |
7 | import com.fsoft.ihabot.Utils.F;
8 |
9 | import org.json.JSONException;
10 | import org.json.JSONObject;
11 |
12 | import java.text.ParseException;
13 | import java.util.Locale;
14 | import java.util.Objects;
15 |
16 | /*Telegram user according to telegram API*/
17 | public class User {
18 | private long id = 0;
19 | private boolean is_bot = false;
20 | private String first_name = "";
21 | private String last_name = "";
22 | private String username = "";
23 | private String language_code = "";
24 |
25 | public User() {
26 | }
27 |
28 | public User(long id, String username, String first_name, String last_name) {
29 | this.id = id;
30 | this.first_name = first_name;
31 | this.last_name = last_name;
32 | this.username = username;
33 | }
34 |
35 | public User(JSONObject jsonObject) throws JSONException, ParseException {
36 | fromJson(jsonObject);
37 | }
38 |
39 | public User(long id, String username) {
40 | this.id = id;
41 | this.username = username;
42 | }
43 |
44 | public User(long id, boolean is_bot, String first_name, String last_name, String username, String language_code) {
45 | this.id = id;
46 | this.is_bot = is_bot;
47 | this.first_name = first_name;
48 | this.last_name = last_name;
49 | this.username = username;
50 | this.language_code = language_code;
51 | }
52 |
53 | public JSONObject toJson() throws JSONException {
54 | JSONObject jsonObject = new JSONObject();
55 | jsonObject.put("id", id);
56 | jsonObject.put("is_bot", is_bot);
57 | if(first_name != null)
58 | jsonObject.put("first_name", first_name);
59 | if(last_name != null)
60 | jsonObject.put("last_name", last_name);
61 | if(username != null)
62 | jsonObject.put("username", username);
63 | if(language_code != null)
64 | jsonObject.put("language_code", language_code);
65 | return jsonObject;
66 | }
67 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
68 | try {
69 | id = jsonObject.getLong("id");
70 | if (jsonObject.has("username"))
71 | username = jsonObject.getString("username");
72 | if (jsonObject.has("is_bot"))
73 | is_bot = jsonObject.getBoolean("is_bot");
74 | if (jsonObject.has("name")) //for backward compatibiluty with old format of users (before 2022-04)
75 | first_name = jsonObject.getString("name");
76 | if (jsonObject.has("first_name"))
77 | first_name = jsonObject.getString("first_name");
78 | if (jsonObject.has("last_name"))
79 | last_name = jsonObject.getString("last_name");
80 | if (jsonObject.has("language_code"))
81 | language_code = jsonObject.getString("language_code");
82 | }
83 | catch (Exception e){
84 | Log.d("USER ERROR " + e.getMessage(), jsonObject.toString());
85 | throw e;
86 | }
87 | }
88 | public String getName(){
89 | if(last_name.isEmpty() || first_name.isEmpty())
90 | return username;
91 | else
92 | return first_name + " " + last_name;
93 | }
94 |
95 | /**
96 | * вовзарает является ли текстовое описание пользователя его однознозначным представлением базируясь на Username или ID
97 | * @param usernameOrId текст его ID, либо username. Можно с собакой можно без.
98 | * @return да, если описание полностью соотвествует текущему юзеру
99 | */
100 | public boolean isIt(String usernameOrId){
101 | if(usernameOrId == null)
102 | return false;
103 | if(usernameOrId.trim().isEmpty())
104 | return false;
105 | if (F.isDigitsOnly(usernameOrId) && id != 0){
106 | try {
107 | long result = Long.parseLong(usernameOrId);
108 | if(result == 0)
109 | return false;
110 | return id == result;
111 | }
112 | catch (Exception e){
113 | //похуй
114 | }
115 | }
116 | usernameOrId = usernameOrId.replace("@", "").toLowerCase(Locale.ROOT).trim();
117 | if(getUsername() != null)
118 | return getUsername().replace("@", "").toLowerCase(Locale.ROOT).trim().equals(usernameOrId);
119 | return false;
120 | }
121 |
122 | public long getId() {
123 | return id;
124 | }
125 |
126 | public void setId(long id) {
127 | this.id = id;
128 | }
129 |
130 | public boolean isIs_bot() {
131 | return is_bot;
132 | }
133 |
134 | public void setIs_bot(boolean is_bot) {
135 | this.is_bot = is_bot;
136 | }
137 |
138 | public String getFirst_name() {
139 | return first_name;
140 | }
141 |
142 | public void setFirst_name(String first_name) {
143 | this.first_name = first_name;
144 | }
145 |
146 | public String getLast_name() {
147 | return last_name;
148 | }
149 |
150 | public void setLast_name(String last_name) {
151 | this.last_name = last_name;
152 | }
153 |
154 | public String getUsername() {
155 | return username;
156 | }
157 |
158 | public void setUsername(String username) {
159 | this.username = username;
160 | }
161 |
162 | public String getLanguage_code() {
163 | return language_code;
164 | }
165 |
166 | public void setLanguage_code(String language_code) {
167 | this.language_code = language_code;
168 | }
169 |
170 | @Override
171 | public boolean equals(Object o) {
172 | if (this == o) return true;
173 | if (o == null || getClass() != o.getClass()) return false;
174 | User userTg = (User) o;
175 | if(id == userTg.id)
176 | return true;
177 | return username != null && userTg.username != null && userTg.username.equals(username);
178 | }
179 |
180 | @Override
181 | public int hashCode() {
182 | return Objects.hash(id, username);
183 | }
184 |
185 | @NonNull
186 | @Override
187 | public String toString() {
188 | StringBuilder sb = new StringBuilder();
189 | if(!first_name.isEmpty())
190 | sb.append(first_name);
191 | sb.append(" ");
192 | if(!last_name.isEmpty())
193 | sb.append(last_name);
194 | if(!first_name.isEmpty() || !last_name.isEmpty())
195 | sb.append(" (");
196 | if(username != null)
197 | sb.append("@").append(username);
198 | else
199 | sb.append("ID ").append(id).append("
");
200 | if(!first_name.isEmpty() || !last_name.isEmpty())
201 | sb.append(")");
202 | return sb.toString().trim();
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/communucation/tg/UserProfilePhotos.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.communucation.tg;
2 |
3 |
4 | import org.json.JSONArray;
5 | import org.json.JSONException;
6 | import org.json.JSONObject;
7 |
8 | import java.text.ParseException;
9 | import java.util.ArrayList;
10 |
11 | public class UserProfilePhotos {
12 | private int total_count = 0;
13 | private ArrayList> arrayPhotos = new ArrayList<>();
14 |
15 | public UserProfilePhotos() {
16 | }
17 |
18 | public UserProfilePhotos(int total_count, ArrayList> photos) {
19 | this.total_count = total_count;
20 | this.arrayPhotos = photos;
21 | }
22 | public UserProfilePhotos(JSONObject jsonObject) throws JSONException, ParseException {
23 | fromJson(jsonObject);
24 | }
25 |
26 | public JSONObject toJson() throws JSONException {
27 | JSONObject jsonObject = new JSONObject();
28 | jsonObject.put("total_count", total_count);
29 | if(arrayPhotos != null && !arrayPhotos.isEmpty()) {
30 | JSONArray jsonArrayPhotos = new JSONArray();
31 | for (int i = 0; i < arrayPhotos.size(); i++){
32 | JSONArray jsonArrayPhoto = new JSONArray();
33 | ArrayList arrayPhoto = arrayPhotos.get(i);
34 | for (int j = 0; j < arrayPhoto.size(); j++){
35 | jsonArrayPhoto.put(arrayPhoto.get(i).toJson());
36 | }
37 | jsonArrayPhotos.put(jsonArrayPhoto);
38 | }
39 | jsonObject.put("photos", jsonArrayPhotos);
40 | }
41 | return jsonObject;
42 | }
43 | private void fromJson(JSONObject jsonObject)throws JSONException, ParseException {
44 | if(jsonObject.has("total_count"))
45 | total_count = jsonObject.getInt("total_count");
46 | arrayPhotos.clear();
47 | if(jsonObject.has("photos")){
48 | JSONArray jsonArrayPhotos = jsonObject.getJSONArray("photos");
49 | for (int i = 0; i < jsonArrayPhotos.length(); i++) {
50 | JSONArray jsonArrayPhoto = jsonArrayPhotos.getJSONArray(i);
51 | ArrayList arrayPhoto = new ArrayList<>();
52 | for (int j = 0; j < jsonArrayPhoto.length(); j++) {
53 | JSONObject arrayItem = jsonArrayPhoto.getJSONObject(j);
54 | arrayPhoto.add(new PhotoSize(arrayItem));
55 | }
56 | arrayPhotos.add(arrayPhoto);
57 | }
58 | }
59 | }
60 |
61 | public int getTotal_count() {
62 | return total_count;
63 | }
64 |
65 | public void setTotal_count(int total_count) {
66 | this.total_count = total_count;
67 | }
68 |
69 | public ArrayList> getArrayPhotos() {
70 | return arrayPhotos;
71 | }
72 |
73 | public void setArrayPhotos(ArrayList> arrayPhotos) {
74 | this.arrayPhotos = arrayPhotos;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/TgLoginWindow.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui;
2 |
3 |
4 | import android.app.Activity;
5 | import android.app.Dialog;
6 | import android.os.Handler;
7 | import android.view.View;
8 | import android.view.Window;
9 | import android.view.WindowManager;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 | import android.widget.Toast;
13 |
14 | import com.fsoft.ihabot.R;
15 | import com.fsoft.ihabot.ApplicationManager;
16 | import com.fsoft.ihabot.Utils.CommandModule;
17 | import com.fsoft.ihabot.communucation.tg.TgAccount;
18 | import com.fsoft.ihabot.communucation.tg.TgAccountCore;
19 | import com.fsoft.ihabot.communucation.tg.User;
20 |
21 | import java.text.SimpleDateFormat;
22 | import java.util.Date;
23 |
24 | /**
25 | * Это окно должно заниматься процедурой логина в аккаунт.
26 | * В его задачи входит:
27 | * - получить обьект аккаунта который нужно залогинить
28 | * - открыть окно логина и ждать пока пользователь залогинится
29 | * - проверить токен на валидность
30 | * - как только токен получен, закрыться и сообщить об успешном логине
31 | * - самостоятельно задать токен в обьекте vkAccount и сделать Start Account
32 | *
33 | *
34 | * Created by Dr. Failov on 22.07.2018.
35 | */
36 |
37 | public class TgLoginWindow extends CommandModule {
38 | private Handler handler = new Handler();
39 | private TgAccount tgAccount = null;
40 | private Dialog loginDialog = null;
41 | private Activity activity = null;
42 | private OnSuccessfulLoginListener onSuccessfulLoginListener = null;
43 |
44 | private EditText tokenField;
45 | private TextView saveButton;
46 | private View closeButton;
47 |
48 | public TgLoginWindow(Activity activity, OnSuccessfulLoginListener onSuccessfulLoginListener) {
49 | super();
50 | this.activity = activity;
51 | this.tgAccount = new TgAccount(ApplicationManager.getInstance(), "acc" + new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss").format(new Date()) + ".json");
52 | this.onSuccessfulLoginListener = onSuccessfulLoginListener;
53 | showLoginWindow();
54 | }
55 |
56 | private void showLoginWindow(){
57 | if(loginDialog == null) {
58 | handler.post(new Runnable() {
59 | @Override
60 | public void run() {
61 | try {
62 | log("Войди в аккаунт");
63 | loginDialog = new Dialog(activity);
64 | loginDialog.setCancelable(false);
65 | loginDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
66 | loginDialog.setContentView(R.layout.dialog_add_telegram_account);
67 | loginDialog.getWindow().getAttributes().width = WindowManager.LayoutParams.MATCH_PARENT;
68 | tokenField = loginDialog.findViewById(R.id.dialog_add_telegram_account_field_token);
69 | saveButton = loginDialog.findViewById(R.id.dialogAdd_telegram_accountButtonSave);
70 | closeButton = loginDialog.findViewById(R.id.dialogadd_telegram_accountButtonCancel);
71 | if(saveButton != null)
72 | saveButton.setOnClickListener(new View.OnClickListener() {
73 | @Override
74 | public void onClick(View v) {
75 | saveButton();
76 | }
77 | });
78 | if(closeButton != null)
79 | closeButton.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | closeLoginWindow();
83 | //String resultOfDeletion = applicationManager.getCommunicator().remTgAccount(tgAccount);
84 | //Toast.makeText(activity, resultOfDeletion, Toast.LENGTH_SHORT).show();
85 | // if(howToRefresh != null)
86 | // howToRefresh.run();
87 | }
88 | });
89 | loginDialog.show();
90 | } catch (Throwable e) {
91 | e.printStackTrace();
92 | log("! Ошибка показа окна логина: " + e.toString());
93 | }
94 | }
95 | });
96 | }
97 | }
98 | private void closeLoginWindow(){
99 | if(loginDialog != null) {
100 | loginDialog.dismiss();
101 | loginDialog = null;
102 | }
103 | }
104 | private void saveButton() {
105 | //проверить и если валидно сохранить
106 | if(tokenField == null)
107 | return;
108 | String tokenString = tokenField.getText().toString();
109 | String[] parts = tokenString.split(":");
110 | if(parts.length != 2) {
111 | Toast.makeText(activity, "Токен введён неверно.", Toast.LENGTH_SHORT).show();
112 | return;
113 | }
114 | String idString = parts[0];
115 | String token = parts[1];
116 | long id = 0;
117 | try {
118 | id = Long.parseLong(idString);
119 | }
120 | catch (Exception e){
121 | Toast.makeText(activity, "Токен введён неверно: " + e.getMessage(), Toast.LENGTH_SHORT).show();
122 | return;
123 | }
124 | tgAccount.setId(id);
125 | tgAccount.setToken(token);
126 | tgAccount.getMe(new TgAccountCore.GetMeListener() {
127 | @Override
128 | public void gotUser(User user) {
129 | Toast.makeText(activity, "Вход выполнен!", Toast.LENGTH_SHORT).show();
130 | closeLoginWindow();
131 | //tgAccount.startAccount();
132 | if(onSuccessfulLoginListener != null)
133 | onSuccessfulLoginListener.onSuccessfulLogin(tgAccount);
134 | }
135 |
136 | @Override
137 | public void error(Throwable error) {
138 | saveButton.setEnabled(true);
139 | saveButton.setText("Сохранить");
140 | tgAccount.setId(0);
141 | tgAccount.setToken("");
142 | Toast.makeText(activity, "Токен не сработал: " + error.getClass().getName() + " " + error.getMessage(), Toast.LENGTH_SHORT).show();
143 | }
144 | });
145 | saveButton.setEnabled(false);
146 | saveButton.setText("Проверка...");
147 | }
148 |
149 | public interface OnSuccessfulLoginListener{
150 | void onSuccessfulLogin(TgAccount tgAccount);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/accounts/AccountsFragment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.accounts;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.ClipData;
5 | import android.content.ClipboardManager;
6 | import android.content.Context;
7 | import android.content.DialogInterface;
8 | import android.os.Bundle;
9 | import android.view.LayoutInflater;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.AdapterView;
14 | import android.widget.ListView;
15 | import android.widget.PopupMenu;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.fragment.app.Fragment;
19 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
20 |
21 | import com.fsoft.ihabot.R;
22 | import com.fsoft.ihabot.ApplicationManager;
23 | import com.fsoft.ihabot.communucation.tg.TgAccount;
24 | import com.google.android.material.snackbar.Snackbar;
25 |
26 | public class AccountsFragment extends Fragment {
27 | ListView listView;
28 | SwipeRefreshLayout swipeRefreshLayout;
29 |
30 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
31 | View root = inflater.inflate(R.layout.fragment_accounts_layout, container, false);
32 | listView = root.findViewById(R.id.listview_accounts_list);
33 | swipeRefreshLayout = root.findViewById(R.id.swiperefreshlayout_accounts_list);
34 | listView.setAdapter(new AccountsAdapter(getActivity()));
35 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
36 | @Override
37 | public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
38 | try {
39 | final TgAccount tgAccount = ApplicationManager.getInstance().getCommunicator().getTgAccounts().get(i);
40 | if(tgAccount == null)
41 | return;
42 | PopupMenu popupMenu = new PopupMenu(getActivity(), view);
43 | popupMenu.inflate(R.menu.account_popup_menu);
44 | if(tgAccount.isEnabled())
45 | popupMenu.getMenu().findItem(R.id.action_enable_account).setVisible(false);
46 | else
47 | popupMenu.getMenu().findItem(R.id.action_disable_account).setVisible(false);
48 | popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
49 | @Override
50 | public boolean onMenuItemClick(MenuItem item) {
51 | if (item.getItemId() == R.id.action_copy_account_username) {
52 | if(getActivity() != null) {
53 | ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
54 | String text = "@" + tgAccount.getUserName();
55 | clipboardManager.setPrimaryClip(ClipData.newPlainText("username", text));
56 | }
57 | }
58 | if (item.getItemId() == R.id.action_disable_account) {
59 | tgAccount.setEnabled(false);
60 | }
61 | if (item.getItemId() == R.id.action_enable_account) {
62 | tgAccount.setEnabled(true);
63 | }
64 | if (item.getItemId() == R.id.action_delete_account) {
65 | new AlertDialog.Builder(getActivity())
66 | .setTitle("Удаление аккаунта")
67 | .setMessage("Вы действительно хотите удалить аккаунт " + tgAccount.getScreenName() + "?")
68 | .setIcon(android.R.drawable.ic_dialog_alert)
69 | .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
70 | public void onClick(DialogInterface dialog, int whichButton) {
71 | try{
72 | ApplicationManager.getInstance().getCommunicator().remAccount(tgAccount);
73 | Snackbar.make(view, "Аккаунт "+tgAccount.getScreenName()+" успешно удалён", Snackbar.LENGTH_SHORT).show();
74 | }
75 | catch (Exception e){
76 | e.printStackTrace();
77 | Snackbar.make(view, "Ошибка: "+e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
78 | }
79 | }})
80 | .setNegativeButton(android.R.string.no, null).show();
81 | }
82 | return false;
83 | }
84 | });
85 | popupMenu.show();
86 | }
87 | catch (Exception e){
88 | e.printStackTrace();
89 | }
90 | }
91 | });
92 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
93 | @Override
94 | public void onRefresh() {
95 | if(listView != null)
96 | listView.invalidateViews();
97 | if(swipeRefreshLayout != null)
98 | swipeRefreshLayout.setRefreshing(false);
99 | }
100 | });
101 | return root;
102 | }
103 |
104 | @Override
105 | public void onDestroyView() {
106 | super.onDestroyView();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/admins/AddAdminUsersAdapter.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.admins;
2 |
3 | import android.app.Activity;
4 | import android.util.Log;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import com.fsoft.ihabot.ApplicationManager;
12 | import com.fsoft.ihabot.R;
13 | import com.fsoft.ihabot.Utils.F;
14 | import com.fsoft.ihabot.communucation.tg.TgAccount;
15 | import com.fsoft.ihabot.communucation.tg.TgAccountCore;
16 | import com.fsoft.ihabot.communucation.tg.User;
17 | import com.fsoft.ihabot.configuration.AdminList;
18 | import com.squareup.picasso.Picasso;
19 |
20 | import java.util.ArrayList;
21 | import java.util.Locale;
22 | import java.util.Timer;
23 | import java.util.TimerTask;
24 |
25 | import jp.wasabeef.picasso.transformations.CropCircleTransformation;
26 |
27 | public class AddAdminUsersAdapter extends BaseAdapter {
28 | Activity activity = null;
29 | ApplicationManager applicationManager = null;
30 | ArrayList users = null;
31 |
32 |
33 | public AddAdminUsersAdapter(Activity activity) {
34 | this.activity = activity;
35 | applicationManager = ApplicationManager.getInstance();
36 | users = applicationManager.getMessageHistory().getLastUsersList();
37 | //Удалить из списка тех кто уже админ
38 | ArrayList admins = applicationManager.getAdminList().getUserList();
39 | for (AdminList.AdminListItem admin:admins){
40 | users.remove(admin.getUser());
41 | }
42 | }
43 |
44 | @Override
45 | public void notifyDataSetChanged() {
46 | if(applicationManager == null)
47 | applicationManager = ApplicationManager.getInstance();
48 | super.notifyDataSetChanged();
49 | }
50 |
51 | @Override
52 | public void notifyDataSetInvalidated() {
53 | if(applicationManager == null)
54 | applicationManager = ApplicationManager.getInstance();
55 | super.notifyDataSetInvalidated();
56 | }
57 |
58 | @Override
59 | public int getCount() {
60 | return users.size();
61 | }
62 |
63 | @Override
64 | public Object getItem(int i) {
65 | return users.get(i);
66 | }
67 |
68 | @Override
69 | public long getItemId(int i) {
70 | return i;
71 | }
72 |
73 | @Override
74 | public View getView(int position, View convertView, ViewGroup container) {
75 | if (convertView == null) {
76 | convertView = activity.getLayoutInflater().inflate(R.layout.dialog_add_admin_list_item, container, false);
77 | }
78 |
79 | User user = users.get(position);
80 | if(user == null) { //если юзер пустой, надо загрузить по новой, чтобы там не висели подвисшие данные с проглого элемента
81 | return activity.getLayoutInflater().inflate(R.layout.dialog_add_admin_list_item, container, false);
82 | }
83 |
84 | { //NAME
85 | TextView textView = convertView.findViewById(R.id.item_user_textView_name);
86 | if(textView != null) {
87 | textView.setText(user.getName());
88 | }
89 | }
90 | { //USERNAME
91 | TextView textView = convertView.findViewById(R.id.item_user_textView_username);
92 | if(textView != null) {
93 | if(user.getUsername().isEmpty())
94 | textView.setText(String.format(Locale.US, "%d", user.getId()));
95 | else
96 | textView.setText(String.format("@%s", user.getUsername()));
97 | }
98 | }
99 |
100 | TgAccount tgAccount = applicationManager.getCommunicator().getWorkingTgAccount();
101 | if(tgAccount != null){//photo
102 | ImageView imageView = convertView.findViewById(R.id.item_user_imageview_avatar);
103 | if(imageView != null) {
104 | Picasso.get()
105 | .load(R.drawable.tg_account_placeholder)
106 | .transform(new CropCircleTransformation())
107 | .into(imageView);
108 | // {
109 | // tgAccount.getUserPhotoUrl(new TgAccountCore.GetUserPhotoListener() {
110 | // @Override
111 | // public void gotPhoto(String url) {
112 | // imageView.post(new Runnable() {
113 | // @Override
114 | // public void run() {
115 | // Picasso.get()
116 | // .load(url)
117 | // .placeholder(R.drawable.tg_account_placeholder)
118 | // .transform(new CropCircleTransformation())
119 | // .into(imageView);
120 | // }
121 | // });
122 | // }
123 | //
124 | // @Override
125 | // public void noPhoto() {
126 | // imageView.post(new Runnable() {
127 | // @Override
128 | // public void run() {
129 | // Picasso.get()
130 | // .load(R.drawable.tg_account_placeholder)
131 | // .transform(new CropCircleTransformation())
132 | // .into(imageView);
133 | // }
134 | // });
135 | //
136 | // }
137 | //
138 | // @Override
139 | // public void error(Throwable error) {
140 | // imageView.post(new Runnable() {
141 | // @Override
142 | // public void run() {
143 | // Picasso.get()
144 | // .load(R.drawable.tg_account_placeholder)
145 | // .transform(new CropCircleTransformation())
146 | // .into(imageView);
147 | // }
148 | // });
149 | //
150 | // error.printStackTrace();
151 | // }
152 | // }, user.getId());
153 | // }
154 | }
155 | else {
156 | Log.d(F.TAG, "R.id.item_account_imageview_avatar is null =(");
157 | }
158 | }
159 |
160 |
161 | return convertView;
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/admins/AdminsFragment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.admins;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.ClipData;
5 | import android.content.ClipboardManager;
6 | import android.content.Context;
7 | import android.content.DialogInterface;
8 | import android.os.Bundle;
9 | import android.view.LayoutInflater;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.AdapterView;
14 | import android.widget.ListView;
15 | import android.widget.PopupMenu;
16 |
17 | import androidx.annotation.NonNull;
18 | import androidx.fragment.app.Fragment;
19 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
20 |
21 | import com.fsoft.ihabot.ApplicationManager;
22 | import com.fsoft.ihabot.R;
23 | import com.fsoft.ihabot.communucation.tg.TgAccount;
24 | import com.fsoft.ihabot.configuration.AdminList;
25 | import com.fsoft.ihabot.ui.accounts.AccountsAdapter;
26 | import com.google.android.material.snackbar.Snackbar;
27 |
28 | public class AdminsFragment extends Fragment {
29 | ListView listView;
30 | SwipeRefreshLayout swipeRefreshLayout;
31 | AdminsAdapter adminsAdapter;
32 |
33 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
34 | View root = inflater.inflate(R.layout.fragment_admins_layout, container, false);
35 | listView = root.findViewById(R.id.listview_admins_list);
36 | swipeRefreshLayout = root.findViewById(R.id.swiperefreshlayout_admins_list);
37 | adminsAdapter = new AdminsAdapter(getActivity());
38 | listView.setAdapter(adminsAdapter);
39 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
40 | @Override
41 | public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
42 | try {
43 | final AdminList.AdminListItem adminListItem = ApplicationManager.getInstance().getAdminList().getUserList().get(i);
44 | if(adminListItem == null)
45 | return;
46 | PopupMenu popupMenu = new PopupMenu(getActivity(), view);
47 | popupMenu.inflate(R.menu.admin_popup_menu);
48 | popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
49 | @Override
50 | public boolean onMenuItemClick(MenuItem item) {
51 | if (item.getItemId() == R.id.action_copy_account_username) {
52 | if(getActivity() != null) {
53 | ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
54 | String text = "@" + adminListItem.getUser().getUsername();
55 | clipboardManager.setPrimaryClip(ClipData.newPlainText("username", text));
56 | }
57 | }
58 | if (item.getItemId() == R.id.action_remove_rights) {
59 | try {
60 | for (AdminList.AdminListItem.Right right : AdminList.AdminListItem.getGenericRightsList()) {
61 | if (right != null)
62 | adminListItem.setAllowed(right, false);
63 | }
64 | ApplicationManager.getInstance().getAdminList().saveArrayToFile();
65 | adminsAdapter.notifyDataSetInvalidated();
66 | }
67 | catch (Exception e) {
68 | e.printStackTrace();
69 | Snackbar.make(view, "Ошибка: "+e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
70 | }
71 | }
72 | if (item.getItemId() == R.id.action_delete_admin) {
73 | new AlertDialog.Builder(getActivity())
74 | .setTitle("Удаление аккаунта")
75 | .setMessage("Вы действительно хотите удалить администратора " + adminListItem.getUser() + "?")
76 | .setIcon(android.R.drawable.ic_dialog_alert)
77 | .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
78 | public void onClick(DialogInterface dialog, int whichButton) {
79 | try{
80 | ApplicationManager.getInstance().getAdminList().rem(adminListItem);
81 | Snackbar.make(view, "Аккаунт "+adminListItem.getUser()+" успешно удалён", Snackbar.LENGTH_SHORT).show();
82 | adminsAdapter.notifyDataSetInvalidated();
83 | }
84 | catch (Exception e){
85 | e.printStackTrace();
86 | Snackbar.make(view, "Ошибка: "+e.getLocalizedMessage(), Snackbar.LENGTH_SHORT).show();
87 | }
88 | }})
89 | .setNegativeButton(android.R.string.no, null).show();
90 | }
91 | return false;
92 | }
93 | });
94 | popupMenu.show();
95 | }
96 | catch (Exception e){
97 | e.printStackTrace();
98 | }
99 | }
100 | });
101 |
102 | swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
103 | @Override
104 | public void onRefresh() {
105 | if (listView != null)
106 | listView.invalidateViews();
107 | if (swipeRefreshLayout != null)
108 | swipeRefreshLayout.setRefreshing(false);
109 | }
110 | });
111 | return root;
112 | }
113 |
114 | @Override
115 | public void onDestroyView() {
116 | super.onDestroyView();
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/gallery/GalleryFragment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.gallery;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.fragment.app.Fragment;
11 | import androidx.lifecycle.ViewModelProvider;
12 |
13 | import com.fsoft.ihabot.databinding.FragmentGalleryBinding;
14 |
15 | public class GalleryFragment extends Fragment {
16 |
17 | private FragmentGalleryBinding binding;
18 |
19 | public View onCreateView(@NonNull LayoutInflater inflater,
20 | ViewGroup container, Bundle savedInstanceState) {
21 | GalleryViewModel galleryViewModel =
22 | new ViewModelProvider(this).get(GalleryViewModel.class);
23 |
24 | binding = FragmentGalleryBinding.inflate(inflater, container, false);
25 | View root = binding.getRoot();
26 |
27 | final TextView textView = binding.textGallery;
28 | galleryViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
29 | return root;
30 | }
31 |
32 | @Override
33 | public void onDestroyView() {
34 | super.onDestroyView();
35 | binding = null;
36 | }
37 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/gallery/GalleryViewModel.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.gallery;
2 |
3 | import androidx.lifecycle.LiveData;
4 | import androidx.lifecycle.MutableLiveData;
5 | import androidx.lifecycle.ViewModel;
6 |
7 | public class GalleryViewModel extends ViewModel {
8 |
9 | private final MutableLiveData mText;
10 |
11 | public GalleryViewModel() {
12 | mText = new MutableLiveData<>();
13 | mText.setValue("This is gallery fragment");
14 | }
15 |
16 | public LiveData getText() {
17 | return mText;
18 | }
19 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/home/HomeFragment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.home;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.fragment.app.Fragment;
11 | import androidx.lifecycle.ViewModelProvider;
12 |
13 | import com.fsoft.ihabot.databinding.FragmentHomeBinding;
14 |
15 | public class HomeFragment extends Fragment {
16 |
17 | private FragmentHomeBinding binding;
18 |
19 | public View onCreateView(@NonNull LayoutInflater inflater,
20 | ViewGroup container, Bundle savedInstanceState) {
21 | HomeViewModel homeViewModel =
22 | new ViewModelProvider(this).get(HomeViewModel.class);
23 |
24 | binding = FragmentHomeBinding.inflate(inflater, container, false);
25 | View root = binding.getRoot();
26 |
27 | final TextView textView = binding.textHome;
28 | homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
29 | return root;
30 | }
31 |
32 | @Override
33 | public void onDestroyView() {
34 | super.onDestroyView();
35 | binding = null;
36 | }
37 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/home/HomeViewModel.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.home;
2 |
3 | import androidx.lifecycle.LiveData;
4 | import androidx.lifecycle.MutableLiveData;
5 | import androidx.lifecycle.ViewModel;
6 |
7 | public class HomeViewModel extends ViewModel {
8 |
9 | private final MutableLiveData mText;
10 |
11 | public HomeViewModel() {
12 | mText = new MutableLiveData<>();
13 | mText.setValue("This is home fragment");
14 | }
15 |
16 | public LiveData getText() {
17 | return mText;
18 | }
19 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/slideshow/SlideshowFragment.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.slideshow;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.fragment.app.Fragment;
11 | import androidx.lifecycle.ViewModelProvider;
12 |
13 | import com.fsoft.ihabot.databinding.FragmentSlideshowBinding;
14 |
15 | public class SlideshowFragment extends Fragment {
16 |
17 | private FragmentSlideshowBinding binding;
18 |
19 | public View onCreateView(@NonNull LayoutInflater inflater,
20 | ViewGroup container, Bundle savedInstanceState) {
21 | SlideshowViewModel slideshowViewModel =
22 | new ViewModelProvider(this).get(SlideshowViewModel.class);
23 |
24 | binding = FragmentSlideshowBinding.inflate(inflater, container, false);
25 | View root = binding.getRoot();
26 |
27 | final TextView textView = binding.textSlideshow;
28 | slideshowViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
29 | return root;
30 | }
31 |
32 | @Override
33 | public void onDestroyView() {
34 | super.onDestroyView();
35 | binding = null;
36 | }
37 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/java/com/fsoft/ihabot/ui/slideshow/SlideshowViewModel.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot.ui.slideshow;
2 |
3 | import androidx.lifecycle.LiveData;
4 | import androidx.lifecycle.MutableLiveData;
5 | import androidx.lifecycle.ViewModel;
6 |
7 | public class SlideshowViewModel extends ViewModel {
8 |
9 | private final MutableLiveData mText;
10 |
11 | public SlideshowViewModel() {
12 | mText = new MutableLiveData<>();
13 | mText.setValue("This is slideshow fragment");
14 | }
15 |
16 | public LiveData getText() {
17 | return mText;
18 | }
19 | }
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/bot_noti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/drawable-v24/bot_noti.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/ic_add_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/ic_cross.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/ic_exclamation.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/ic_tg_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/drawable-v24/ic_tg_logo.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/iha_bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/drawable-v24/iha_bot.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable-v24/tg_account_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/drawable-v24/tg_account_placeholder.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/background_warning.xml:
--------------------------------------------------------------------------------
1 |
6 |
14 |
15 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_add_tg_account.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_camera.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_gallery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_slideshow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_menu_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/ic_pause.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/activity_bot.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
25 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/app_bar_bot.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/content_bot.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/dialog_add_admin.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
27 |
34 |
41 |
42 |
43 |
48 |
49 |
59 |
60 |
67 |
74 |
75 |
85 |
86 |
93 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/dialog_add_admin_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
29 |
30 |
37 |
38 |
43 |
44 |
51 |
52 |
56 |
57 |
65 |
66 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/dialog_add_telegram_account.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
21 |
28 |
38 |
46 |
47 |
48 |
49 |
50 |
55 |
56 |
63 |
75 |
76 |
84 |
85 |
91 |
105 |
106 |
107 |
108 |
109 |
110 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_accounts_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
16 |
17 |
18 |
19 |
20 |
32 |
33 |
40 |
48 |
49 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_admins_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
35 |
36 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_admins_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
16 |
17 |
22 |
23 |
28 |
29 |
30 |
37 |
38 |
43 |
44 |
51 |
52 |
56 |
57 |
65 |
66 |
75 |
76 |
77 |
78 |
79 |
87 |
88 |
89 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_gallery.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/fragment_slideshow.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/layout/nav_header_bot.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
22 |
23 |
29 |
30 |
35 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/menu/account_popup_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/menu/admin_popup_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/menu/bot.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/navigation/mobile_navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
23 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/raw/answer_database.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/app/src/main/res/raw/answer_database.zip
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/raw/synonyme.txt:
--------------------------------------------------------------------------------
1 | сам,сама,самостоятельно
2 | хочешь,желаешь,будешь,want,хочеш,бажаєш,будеш
3 | рот,рыло,ебало,їбало,face
4 | ебал,трахал,жарил,fuck,їбав
5 | настроение,настрой,mood,муд,настрій
6 | могу,can,можу
7 | рад,счастлив,рада,счастлива,доволен,довольна,хэппи,happy,щасливий,задоволений
8 | учусь,обучаюсь,изучаю,учу,study,вивчаю,вчусь
9 | девушка,девка,баба,женщина,девочка,дівчина,дівка,жінка,дівчинка
10 | чего,чо,чё,чаво,чобля,чёбля,what,че
11 | про,о,об,за,about
12 | пошли,идём,идем,пішли,ходімо
13 | пошел,иди,ди,go,пошёл,пшол,сьеби,съеби,беги,пиздуй,йди,пішов,біжи
14 | плохо,ужасно,нехорошо,печально,bad,хреново,хуево,хуёво,херово,погано,жахливо
15 | сколько,скока,скільки
16 | хочу,хачу,требую,want,желаю,бажаю
17 | нужно,need,потрібно,треба
18 | тему,темку
19 | ты,ти,you
20 | любишь,любиш,love,лав,обожаешь,нравится,подобається
21 | айфон,огрызок,iphone,яфон,гейфон,ифон,яблофон
22 | ipad,айпэд,айпед,айпад,ипад,япад,гейпад
23 | ios,иос,айос,айоэс,аос,гейось
24 | эпл,гейпл,apple,эппл,аппле,апл,эйпл
25 | ipod,айпод,ипод,гейпод,япод
26 | понятно,ясно,яснопонятно,пон,ясн,зрозуміло
27 | привет,превед,прифет,прив,привіт
28 | пидр,гей,пидарас,пидорас,пидорасина,пидрила,пидор,пидрила,пидер,підор
29 | уебок,уебан,уеба,уебище,уёбок,уёбище,уёба,уйобок
30 | тварь,скотина,скот
31 | андроид,андро,ведроид,ведро,педроид,андроїд
32 | говно,гуано,говнище,дно,днище,dniwe,хрень,херня,хуйня,плохой,кал,калл,дерьмо,дерьмище,гівно,
33 | рулит,рулз,лучший,лучшая,топ,лучшее,супер,классный,классная,крутой,ахуенен,охуенен,охуенный,хороший,отличный,шикарен,божественен,кращий,гарний,найкращий
34 | шикарно,отлично,чудесно,круто,весело,хорошо,чудово
35 | знаю,шарю,понимаю,разбираюсь,осознаю
36 | знаешь,шаришь,понимаешь,разбираешься,сечёшь,панимэ,understand
37 | сказать,произнести,донести,написать,сообщить,рассказать,расказать,говорить,писать
38 | скажи,произнеси,донеси,напиши,сообщи,расскажи,раскажи,говори,пиши
39 | говоришь,произносишь,доносишь,пишешь,сообщаешь,рассказываешь,расказываешь,говоришь,пишешь
40 | нет,нит,не,no,ноуп,ноу,неа,ні
41 | самс,самсунг,самса,сосунг,samsung
42 | ладно,лан,окай,пускай
43 | гугл,google,гогле,гуголь
44 | сказал,написал,донёс,сообщил
45 | опять,снова,апять,знову
46 | группа,ihateapple,iha
47 | лохи,лошары
48 | нищеброды,нищеры,дебилы,идиоты,пидоры,пидарасы,пидрилы,дауны,школота,ідіоти
49 | нищеброд,нищер,лох,лошара,тупой,дебил,идиот,даун,чмо,ідіот
50 | ору,ор
51 | ржу,ржач,ржака,смешно
52 | человек,человечек,поц,штрих,жмых,пацан,пацанчик,man,мэн,людина
53 | просто,прост
54 | прости,сори,сорян,sorry,вибач
55 | купи,приобрети,достань,возьми,бери,візьми
56 | купить,приобрести,достать,взять,взяти
57 | кто,хто,who
58 | шлюха,блядь,шкура,проститутка,блять,сука,сучка
59 | найс,молодец,красава,огонь,красавчик
60 | фото,фотка,фотография,фотки,фоточка
61 | нахуй,нах,нахер,вжопу,впизду
62 | скинь,отправь,пришли,кинь,покажи
63 | ничего,ничо,нічого
64 | интересно,интересненько,тиресна,цікаво
65 | много,дофига,дохрена,дохуя,дохера,багато
66 | значит,означает,означає
67 | очень,оч,дуже
68 | дай,отдай
69 | зовут,называюь,зовется
70 | умный,знающий,прошаренный,розумний
71 | спать,отдыхать,відпочивати
72 | ага,да,еп,єп,yes
73 | зачем,зочем,нах,нахуя,нахера,нахрена,навіщо
74 | что,шо,what
75 | спасибо,благодарю,посеба,сэнкс,пасиб,tnx,дякую
76 | нельзя,низя,незя
77 | ночи,ночки,night,ночі
78 | стих,стишок,стихи,стихотворение,вірш,віршик
79 | норм,нормас,збс,нормально,хорошо,норма
80 | член,хуй,хер,пенис,dick,cock
81 | люблю,обожаю,love
82 | любить,обожать
83 | любит,обожает,loves
84 | умеешь,можешь
85 | поговорим,пообщаемся,поспілкуємось
86 | почему,пачиму,хули,why,чому
87 | нексус,никсус,никсас,никсес,nexus
88 | дела,делишки,справи
89 | ос,ось,система,операционка,os
90 | бот,ихабот,vkihabot,ihabot
91 | делать,делаешь
92 | миша,дима,витя,коля,вася,рома,макс,артем,леша,паша,стас,тоша,сережа,илья,серый,сережа,антон,олег,юра,ваня,андрей,леша,петя
93 | дина,оля,аня,вика,настя,катя,женя,алина,юля,поля,марина,маша,оксана,лена,ксюша,ира
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 48dp
3 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values-w1240dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 200dp
3 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values-w600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 48dp
3 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2c3e57
4 | #16292b
5 |
6 | #415b80
7 | #417980
8 |
9 | #75a4e5
10 | #75dae5
11 |
12 | #FF000000
13 | #FF303030
14 | #FFFFFFFF
15 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 8dp
6 | 176dp
7 | 16dp
8 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FP iHA bot
3 | FP iHA bot 6
4 | beta
5 | Выключить бота
6 |
7 | Сообщения
8 | Аккаунты
9 | Администраторы
10 | Бот работает
11 | iHA bot 6.0 beta 1
12 | Бот работает
13 |
--------------------------------------------------------------------------------
/Android-app/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Android-app/app/src/test/java/com/fsoft/ihabot/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.fsoft.ihabot;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/Android-app/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id 'com.android.application' version '8.1.1' apply false
4 | id 'com.android.library' version '8.1.1' apply false
5 | }
6 |
7 | task clean(type: Delete) {
8 | delete rootProject.buildDir
9 | }
--------------------------------------------------------------------------------
/Android-app/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Enables namespacing of each library's R class so that its R class includes only the
19 | # resources declared in the library itself and none from the library's dependencies,
20 | # thereby reducing the size of the R class for that library
21 | android.nonTransitiveRClass=true
22 | android.defaults.buildfeatures.buildconfig=true
23 | android.nonFinalResIds=false
--------------------------------------------------------------------------------
/Android-app/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Android-app/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Android-app/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Mar 21 23:04:45 EET 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/Android-app/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/Android-app/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/Android-app/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "FP iHA bot"
16 | include ':app'
17 |
--------------------------------------------------------------------------------
/Others/2022 Самые популярные слова (парсинг старой базы)/Database_frequent_words/Database_frequent_words.pde:
--------------------------------------------------------------------------------
1 | import java.util.Hashtable;
2 | import java.util.Map;
3 | import java.util.Enumeration;
4 |
5 | JSONObject json;
6 | Hashtable hashtable = new Hashtable();
7 |
8 | void setup() {
9 | println("Start...");
10 | BufferedReader reader;
11 | PrintWriter output;
12 | String line = "";
13 | long counter = 0;
14 |
15 | println("Open IN file...");
16 | reader = createReader("data/answer_database_old_full.txt");
17 |
18 | try {
19 | while(line != null){
20 | line = reader.readLine();
21 | if(line == null || line.isEmpty()){
22 |
23 | println("Finished at ", counter);
24 | break;
25 | }
26 |
27 | counter++;
28 | //println(counter++, jsonIn.toString().replace("\t", "").replace("\n", "").replace(" ", " ").substring(0,110), "...");
29 | JSONObject jsonIn = parseJSONObject(line);
30 | String jsonIn_questionText = jsonIn.getString("questionText");
31 | String jsonIn_answerText = jsonIn.getString("answerText");
32 | JSONObject jsonIn_questionAuthor = jsonIn.getJSONObject("questionAuthor");
33 | long jsonIn_questionAuthor_id = jsonIn_questionAuthor.getLong("id");
34 | JSONObject jsonIn_createdAuthor = jsonIn.getJSONObject("createdAuthor");
35 | long jsonIn_createdAuthor_id = jsonIn_createdAuthor.getLong("id");
36 | String jsonIn_questionDate = jsonIn.getString("questionDate");
37 | String jsonIn_createdDate = jsonIn.getString("createdDate");
38 | long jsonIn_timesUsed = jsonIn.getLong("timesUsed");
39 | JSONArray jsonIn_answerAttachments = jsonIn.getJSONArray("answerAttachments");
40 | ArrayList answerAttachments_types = new ArrayList<>();
41 | ArrayList answerAttachments_files = new ArrayList<>();
42 | for(int i=0; i e = hashtable.keys();
79 | int total = 0;
80 | while (e.hasMoreElements()) {
81 |
82 | // Getting the key of a particular entry
83 | String word = e.nextElement();
84 | int freq = (Integer)hashtable.get(word);
85 | if(freq > 20){
86 | println(freq, word);
87 | output.println(freq + "\t" + word);
88 | total ++;
89 | }
90 | }
91 |
92 |
93 |
94 | output.flush(); // Writes the remaining data to the file
95 | output.close(); // Finishes the file
96 | println("Wrote lines: ", total);
97 | println("Close OUT file...");
98 | exit();
99 | }
100 |
101 | String filterSymbols(String input){
102 | String allowedSymbols = "qwertyuiopasdfghjklzxcvbnm їіёйцукенгшщзхъфывапролджэячсмитьбю 1234567890";
103 | StringBuilder builder = new StringBuilder();
104 | for (int i = 0; i < input.length(); i++) {
105 | char c = input.charAt(i);
106 | if(allowedSymbols.indexOf(c) >= 0)
107 | builder.append(c);
108 | }
109 | return builder.toString();
110 | }
111 |
--------------------------------------------------------------------------------
/Others/2022 Самые популярные слова (парсинг старой базы)/Database_frequent_words/data/words_frequency.txt:
--------------------------------------------------------------------------------
1 | 78 сам
2 | 86 хочешь
3 | 161 ithappens
4 | 32 рот
5 | 27 ебал
6 | 22 настроение
7 | 24 могу
8 | 27 раз
9 | 23 рад
10 | 25 учусь
11 | 26 девушка
12 | 55 чего
13 | 30 понимаешь
14 | 55 про
15 | 23 под
16 | 27 мной
17 | 22 день
18 | 27 пошли
19 | 21 пошел
20 | 35 плохо
21 | 108 сколько
22 | 61 хочу
23 | 33 они
24 | 43 она
25 | 28 тему
26 | 23 you
27 | 106 любишь
28 | 23 понятно
29 | 54 привет
30 | 423 тебя
31 | 369 тебе
32 | 21 пидор
33 | 56 знаю
34 | 45 хорошо
35 | 26 сказать
36 | 147 нет
37 | 36 ладно
38 | 30 нас
39 | 42 сказал
40 | 23 опять
41 | 27 будь
42 | 32 тогда
43 | 83 знаешь
44 | 44 буду
45 | 44 моя
46 | 73 мой
47 | 428 мне
48 | 24 больше
49 | 22 лох
50 | 25 лол
51 | 55 твоя
52 | 28 твою
53 | 51 твой
54 | 34 человек
55 | 21 жизни
56 | 56 просто
57 | 22 прости
58 | 54 тобой
59 | 27 купи
60 | 213 кто
61 | 26 шлюха
62 | 25 этом
63 | 24 смешно
64 | 54 афоризм
65 | 43 куда
66 | 418 как
67 | 22 жопу
68 | 100 давай
69 | 44 фото
70 | 32 нахуй
71 | 41 себя
72 | 34 себе
73 | 22 имя
74 | 72 или
75 | 22 самый
76 | 71 иди
77 | 26 боты
78 | 28 бота
79 | 53 лучше
80 | 73 надо
81 | 345 меня
82 | 113 есть
83 | 53 пока
84 | 32 скинь
85 | 34 ничего
86 | 42 если
87 | 23 интересно
88 | 22 сделай
89 | 28 думаешь
90 | 21 ботов
91 | 24 свою
92 | 28 много
93 | 23 ещё
94 | 46 частушки
95 | 54 еще
96 | 49 кого
97 | 30 его
98 | 39 можешь
99 | 23 стоит
100 | 22 скучно
101 | 39 понял
102 | 31 значит
103 | 38 очень
104 | 27 для
105 | 75 какой
106 | 26 какое
107 | 38 какие
108 | 263 это
109 | 50 дай
110 | 37 какая
111 | 57 сейчас
112 | 65 можно
113 | 40 может
114 | 108 где
115 | 39 блять
116 | 21 чё
117 | 37 чо
118 | 73 че
119 | 23 тя
120 | 1440 ты
121 | 61 то
122 | 27 ти
123 | 32 со
124 | 56 расскажи
125 | 27 всё
126 | 114 все
127 | 116 по
128 | 71 от
129 | 56 он
130 | 27 ок
131 | 193 ну
132 | 40 но
133 | 73 вот
134 | 1060 не
135 | 322 на
136 | 74 мы
137 | 30 зовут
138 | 54 ли
139 | 59 из
140 | 129 за
141 | 100 же
142 | 26 до
143 | 155 да
144 | 110 го
145 | 104 вы
146 | 23 во
147 | 28 вк
148 | 66 бы
149 | 37 вас
150 | 28 вам
151 | 38 только
152 | 31 делать
153 | 23 был
154 | 33 умный
155 | 78 бот
156 | 26 бля
157 | 34 без
158 | 395 баш
159 | 34 тупой
160 | 26 вообще
161 | 46 спать
162 | 23 ага
163 | 69 будешь
164 | 21 бывает
165 | 27 ответ
166 | 36 кинь
167 | 61 скажи
168 | 157 задолбали
169 | 72 зачем
170 | 545 что
171 | 22 чмо
172 | 29 всегда
173 | 116 чем
174 | 48 тоже
175 | 68 сука
176 | 42 спасибо
177 | 22 нельзя
178 | 24 цитата
179 | 28 завтра
180 | 21 ночи
181 | 171 анекдот
182 | 55 нравится
183 | 28 норм
184 | 62 когда
185 | 73 стих
186 | 21 член
187 | 61 хуй
188 | 31 откуда
189 | 31 быть
190 | 21 вопрос
191 | 21 хотел
192 | 34 говоришь
193 | 30 было
194 | 21 говорить
195 | 56 такой
196 | 32 такое
197 | 22 погода
198 | 30 ясно
199 | 35 факт
200 | 36 нужно
201 | 26 говно
202 | 23 писать
203 | 45 люблю
204 | 41 любит
205 | 59 уже
206 | 23 молодец
207 | 32 хули
208 | 62 будет
209 | 23 покажи
210 | 24 будем
211 | 23 время
212 | 33 умеешь
213 | 43 история
214 | 1126 я
215 | 52 тут
216 | 355 у
217 | 305 с
218 | 129 о
219 | 69 к
220 | 261 и
221 | 590 в
222 | 536 а
223 | 47 поговорим
224 | 31 там
225 | 137 так
226 | 139 почему
227 | 25 5
228 | 27 3
229 | 22 2
230 | 92
231 |
--------------------------------------------------------------------------------
/Others/2022 Самые популярные слова (парсинг старой базы)/Database_frequent_words/data/Синонимы (мной вручную дописанные к words_frequency).txt:
--------------------------------------------------------------------------------
1 | сам,сама,самостоятельно
2 | хочешь,желаешь,будешь,want
3 | рот,рыло,ебало
4 | ебал,трахал,fuck
5 | настроение,настрой,mood,муд
6 | могу,can
7 | рад,счастлив,рада,счастлива,доволен,довольна,хэппи,happy
8 | учусь,обучаюсь,изучаю,учу,study
9 | девушка,девка,баба,женщина,девочка
10 | чего,чо,чё,чаво,чобля,чёбля,what,че
11 | про,о,об,за,about
12 | пошли,идём,идем,го,давай
13 | пошел,иди,ди,go,пошёл,пшол,сьеби,съеби,беги,пиздуй
14 | плохо,ужасно,нехорошо,печально,bad,хреново,хуево,хуёво,херово
15 | сколько,скока
16 | хочу,хачу,требую,нужно,need
17 | тему,темку
18 | ты,ти,you
19 | любишь,любиш,love,лав,обожаешь,нравится
20 | айфон,огрызок,iphone,яфон,гейфон,ифон,яблофон
21 | ipad,айпэд,айпед,айпад,ипад,япад,гейпад
22 | ios,иос,айос,айоэс,аос,гейось
23 | эпл,гейпл,apple,эппл,аппле,апл,эйпл
24 | ipod,айпод,ипод,гейпод,япод
25 | понятно,ясно,яснопонятно,пон,ясн
26 | привет,превед,прифет,прив
27 | пидр,гей,пидарас,пидорас,пидорасина,пидрила,пидор
28 | андроид,андро,ведроид,ведро,педроид
29 | говно,гуано,говнище,дно,днище,dniwe,хрень,херня,хуйня,плохой,кал,калл,дерьмо,дерьмище
30 | рулит,рулз,лучший,лучшая,топ,лучшее,супер,классный,классная,крутой,ахуенен,охуенен,охуенный,хороший,отличный,шикарен,божественен
31 | шикарно,отлично,чудесно,круто,весело,хорошо
32 | знаю,шарю,понимаю,разбираюсь,осознаю
33 | знаешь,шаришь,понимаешь,разбираешься,сечёшь,панимэ,understand
34 | сказать,произнести,донести,написать,сообщить,рассказать,расказать,говорить,писать
35 | скажи,произнеси,донеси,напиши,сообщи,расскажи,раскажи,говори,пиши
36 | говоришь,произносишь,доносишь,пишешь,сообщаешь,рассказываешь,расказываешь,говоришь,пишешь
37 | нет,нит,не,no,ноуп,ноу,неа
38 | самс,самсунг,самса,сосунг,samsung
39 | ладно,лан,окай,пускай
40 | гугл,google,гогле,гуголь
41 | сказал,написал,донёс,сообщил
42 | опять,снова,апять
43 | группа,ihateapple,iha
44 | лохи,лошары
45 | нищеброды,нищеры,дебилы,идиоты,пидоры,пидарасы,пидрилы,дауны,школота
46 | нищеброд,нищер,лох,лошара,тупой,дебил,идиот,даун,чмо
47 | лол,ору,ор,ржу,ржач,ржака,lol,смешно
48 | человек,человечек,поц,штрих,жмых,пацан,пацанчик,man,мэн
49 | просто,прост
50 | прости,сори,сорян,sorry
51 | купи,приобрети,достань,возьми,бери
52 | купить,приобрести,достать,взять
53 | кто,хто,who
54 | шлюха,блядь,шкура,проститутка,блять,сука,сучка
55 | найс,молодец,красава,огонь
56 | фото,фотка,фотография,фотки,фоточка
57 | нахуй,нах,нахер,вжопу,впизду
58 | скинь,отправь,пришли,кинь,покажи
59 | ничего,ничо
60 | интересно,интересненько,тиресна
61 | много,дофига,дохрена,дохуя,дохера
62 | значит,означает
63 | очень,оч
64 | дай,отдай
65 | зовут,называюь,зовется
66 | умный,знающий,прошаренный
67 | спать,отдыхать
68 | ага,да,еп,єп,yes
69 | зачем,зочем,нах,нахуя,нахера,нахрена
70 | что,шо,what
71 | спасибо,благодарю,посеба,сэнкс,пасиб,tnx
72 | нельзя,низя,незя
73 | ночи,ночки,night
74 | стих,стишок,стихи,стихотворение
75 | норм,нормас,збс,нормально,хорошо,норма
76 | член,хуй,хер,пенис,dick,cock
77 | люблю,обожаю,love
78 | любить,обожать
79 | любит,обожает,loves
80 | молодец,красава,красавчик
81 | умеешь,можешь,can
82 | поговорим,пообщаемся
83 | почему,пачиму,хули,why
84 | нексус,никсус,никсас,никсес,nexus
85 | дела,делишки,работа,занятие,занимаешься
86 | ос,ось,система,операционка,os
87 | бот,ихабот,vkihabot,ihabot
88 | миша,дима,витя,коля,вася,рома,макс,артем,леша,паша,стас,тоша,сережа,илья,серый,сережа,антон,олег,юра,ваня,андрей,леша,петя
89 | дина,оля,аня,вика,настя,катя,женя,алина,юля,поля,марина,маша,оксана,лена,ксюша,ира
--------------------------------------------------------------------------------
/Others/2022 Самые популярные слова (парсинг старой базы)/Пояснительная бригада.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Others/2022 Самые популярные слова (парсинг старой базы)/Пояснительная бригада.txt
--------------------------------------------------------------------------------
/Photos/Screenshot_20220324_180909.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drfailov/FP_iHA_bot/150903e58adbc05563959e507b6e17abfd2d90ae/Photos/Screenshot_20220324_180909.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # About project FP iHA bot 6
5 | 
6 |
7 |
--------------------------------------------------------------------------------