├── libs
└── WaitCursor.dll
├── database
└── DbTesOnline.db
├── src
├── nuget.config
├── OnlineTestWABot.Model
│ ├── packages.config
│ ├── Entity
│ │ ├── HasilTes.cs
│ │ ├── User.cs
│ │ ├── BankSoal.cs
│ │ ├── Chat.cs
│ │ ├── Sesi.cs
│ │ └── HistoriTes.cs
│ ├── Repository
│ │ ├── IBaseRepository.cs
│ │ ├── ChatRepository.cs
│ │ ├── UserRepository.cs
│ │ ├── SesiRepository.cs
│ │ ├── HistoriTesRepository.cs
│ │ └── BankSoalRepository.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Context
│ │ └── DbContext.cs
│ └── OnlineTestWABot.Model.csproj
├── OnlineTestWABot.WinApp
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── Controller
│ │ ├── IBaseController.cs
│ │ ├── ChatController.cs
│ │ ├── UserController.cs
│ │ ├── SesiController.cs
│ │ ├── BankSoalController.cs
│ │ └── HistoriTesController.cs
│ ├── App.config
│ ├── packages.config
│ ├── Program.cs
│ ├── FrmStartUp.cs
│ ├── FrmStartUp.Designer.cs
│ ├── FrmMain.Designer.cs
│ ├── FrmMain.resx
│ ├── FrmStartUp.resx
│ ├── OnlineTestWABot.WinApp.csproj
│ ├── FrmMain.cs
│ └── PerintahBot.cs
└── OnlineTestWABot.sln
├── README.md
└── .gitignore
/libs/WaitCursor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/k4m4r82/OnlineTestWABot/HEAD/libs/WaitCursor.dll
--------------------------------------------------------------------------------
/database/DbTesOnline.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/k4m4r82/OnlineTestWABot/HEAD/database/DbTesOnline.db
--------------------------------------------------------------------------------
/src/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/IBaseController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace OnlineTestWABot.Controller
7 | {
8 | public interface IBaseController
9 | where T : class
10 | {
11 | int Save(T obj);
12 | int Update(T obj);
13 | int Delete(T obj);
14 |
15 | IList GetAll();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/HasilTes.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | namespace OnlineTestWABot.Model.Entity
20 | {
21 | public class HasilTes
22 | {
23 | public int benar { get; set; }
24 | public int salah { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/IBaseRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | namespace OnlineTestWABot.Model.Repository
25 | {
26 | public interface IBaseRepository
27 | where T : class
28 | {
29 | int Save(T obj);
30 | int Update(T obj);
31 | int Delete(T obj);
32 | IList GetAll();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OnlineTestWABot.WinApp.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/User.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper.Contrib.Extensions;
25 |
26 | namespace OnlineTestWABot.Model.Entity
27 | {
28 | [Table("user")]
29 | public class User
30 | {
31 | public User()
32 | {
33 | registered = DateTime.Now;
34 | }
35 |
36 | [ExplicitKey]
37 | public string user_id { get; set; }
38 | public DateTime registered { get; set; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Program.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Windows.Forms;
23 |
24 | namespace OnlineTestWABot.WinApp
25 | {
26 | static class Program
27 | {
28 | ///
29 | /// The main entry point for the application.
30 | ///
31 | [STAThread]
32 | static void Main()
33 | {
34 | Application.EnableVisualStyles();
35 | Application.SetCompatibleTextRenderingDefault(false);
36 | Application.Run(new FrmMain());
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/BankSoal.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper.Contrib.Extensions;
25 |
26 | namespace OnlineTestWABot.Model.Entity
27 | {
28 | [Table("bank_soal")]
29 | public class BankSoal
30 | {
31 | [Key]
32 | public int bank_soal_id { get; set; }
33 | public string soal { get; set; }
34 | public string jawaban { get; set; }
35 | public string analisa { get; set; }
36 |
37 | [Write(false)]
38 | public int nomor_soal { get; set; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/Chat.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper.Contrib.Extensions;
25 |
26 | namespace OnlineTestWABot.Model.Entity
27 | {
28 | [Table("chat")]
29 | public class Chat
30 | {
31 | public Chat()
32 | {
33 | tanggal = DateTime.Now;
34 | }
35 |
36 | [Key]
37 | public int chat_id { get; set; }
38 | public string user_id { get; set; }
39 | public DateTime tanggal { get; set; }
40 | public string text { get; set; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/Sesi.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper.Contrib.Extensions;
25 |
26 | namespace OnlineTestWABot.Model.Entity
27 | {
28 | [Table("sesi")]
29 | public class Sesi
30 | {
31 | public Sesi()
32 | {
33 | tanggal = DateTime.Now;
34 | }
35 |
36 | [Key]
37 | public int sesi_id { get; set; }
38 | public string user_id { get; set; }
39 | public DateTime tanggal { get; set; }
40 | public bool is_timeout { get; set; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WhatsApp Bot - Online Test
2 |
3 | Ini adalah contoh aplikasi WhatsApp Bot dengan tema **Tes Online Bahasa Inggris**. Project ini dibuat menggunakan bahasa C# dan menggunakan library [WhatsApp NET Client](http://wa-net.coding4ever.net/) untuk mempermudah komunikasi ke aplikasi WhatsApp web.
4 |
5 | ## Library Pendukung
6 |
7 | * [Dapper](https://www.nuget.org/packages/Dapper/)
8 | * [Dapper.Contrib](https://www.nuget.org/packages/Dapper.Contrib/)
9 | * [System.Data.SQLite.Core](https://www.nuget.org/packages/System.Data.SQLite.Core/)
10 | * [WhatsApp NET Client](https://www.nuget.org/packages/WhatsAppNETAPI)
11 |
12 | ## Persyaratan Sistem
13 |
14 | * Windows 8, 10 dan windows versi terbaru
15 | * .NET Framework 4.5 dan .NET versi terbaru
16 | * Node.js versi 14.16.x atau versi terbaru
17 | * Software git (version control)
18 |
19 | ## Instalasi
20 |
21 | * Buka project WhatsApp Bot, kemudian klik kanan solution `OnlineTestWABot` -> `Rebuild Solution`. Langkah ini akan merestore library-library [Nuget](https://www.nuget.org/) yang digunakan project ini.
22 | * Copykan folder **database** ke folder **bin\Debug** atau **bin\Release**.
23 | * Setelah itu Anda bisa langsung menjalankan project dengan menekan tombol F5, kemudian mengeset lokasi direktori `WhatsAppNETAPINodeJs` dan menekan tombol `Start` untuk mengaktifkan bot.
24 |
25 | Untuk mendapatkan direktori `WhatsAppNETAPINodeJs`, langkah-langkahnya bisa Anda baca di [sini](http://wa-net.coding4ever.net/).
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("OnlineTestWABot.Model")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("OnlineTestWABot.Model")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("366516e0-144a-4df6-bf1a-3c9d00afe378")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("OnlineTestWABot.WinApp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("OnlineTestWABot.WinApp")]
13 | [assembly: AssemblyCopyright("Copyright © 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("e249ad9c-36c7-4573-a623-7ce13f075702")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.1.0.0")]
36 | [assembly: AssemblyFileVersion("1.1.0")]
37 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Entity/HistoriTes.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper.Contrib.Extensions;
25 |
26 | namespace OnlineTestWABot.Model.Entity
27 | {
28 | [Table("histori_tes")]
29 | public class HistoriTes
30 | {
31 | [Key]
32 | public int histori_tes_id { get; set; }
33 | public string user_id { get; set; }
34 | public int sesi_id { get; set; }
35 | public DateTime tanggal { get; set; }
36 | public int bank_soal_id { get; set; }
37 |
38 | [Write(false)]
39 | public BankSoal BankSoal { get; set; }
40 | public string jawaban { get; set; }
41 | public bool hasil_jawaban { get; set; }
42 | public bool batal { get; set; }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.40629.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{89EEC89A-0EBA-4AB3-A696-B5E87A5906E3}"
7 | ProjectSection(SolutionItems) = preProject
8 | nuget.config = nuget.config
9 | EndProjectSection
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnlineTestWABot.Model", "OnlineTestWABot.Model\OnlineTestWABot.Model.csproj", "{9C1541D1-E24D-4D48-80A0-72DBD6632E38}"
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OnlineTestWABot.WinApp", "OnlineTestWABot.WinApp\OnlineTestWABot.WinApp.csproj", "{74A83EF2-0A5C-429B-82F7-911510944921}"
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {9C1541D1-E24D-4D48-80A0-72DBD6632E38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {9C1541D1-E24D-4D48-80A0-72DBD6632E38}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {9C1541D1-E24D-4D48-80A0-72DBD6632E38}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {9C1541D1-E24D-4D48-80A0-72DBD6632E38}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {74A83EF2-0A5C-429B-82F7-911510944921}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {74A83EF2-0A5C-429B-82F7-911510944921}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {74A83EF2-0A5C-429B-82F7-911510944921}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {74A83EF2-0A5C-429B-82F7-911510944921}.Release|Any CPU.Build.0 = Release|Any CPU
29 | EndGlobalSection
30 | GlobalSection(SolutionProperties) = preSolution
31 | HideSolutionNode = FALSE
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/ChatController.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using OnlineTestWABot.Model.Entity;
25 | using OnlineTestWABot.Model.Repository;
26 | using OnlineTestWABot.Model.Context;
27 |
28 | namespace OnlineTestWABot.Controller
29 | {
30 | public interface IChatController : IBaseController
31 | {
32 |
33 | }
34 |
35 | public class ChatController : IChatController
36 | {
37 | private IChatRepository _repository;
38 |
39 | public int Save(Chat obj)
40 | {
41 | var result = 0;
42 |
43 | using (IDbContext context = new DbContext())
44 | {
45 | _repository = new ChatRepository(context);
46 | result = _repository.Save(obj);
47 | }
48 |
49 | return result;
50 | }
51 |
52 | public int Update(Chat obj)
53 | {
54 | throw new NotImplementedException();
55 | }
56 |
57 | public int Delete(Chat obj)
58 | {
59 | throw new NotImplementedException();
60 | }
61 |
62 | public IList GetAll()
63 | {
64 | throw new NotImplementedException();
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/UserController.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using OnlineTestWABot.Model.Entity;
25 | using OnlineTestWABot.Model.Repository;
26 | using OnlineTestWABot.Model.Context;
27 |
28 | namespace OnlineTestWABot.Controller
29 | {
30 | public interface IUserController : IBaseController
31 | {
32 |
33 | }
34 |
35 | public class UserController : IUserController
36 | {
37 | private IUserRepository _repository;
38 |
39 | public int Save(User obj)
40 | {
41 | var result = 0;
42 |
43 | using (IDbContext context = new DbContext())
44 | {
45 | _repository = new UserRepository(context);
46 | result = _repository.Save(obj);
47 | }
48 |
49 | return result;
50 | }
51 |
52 | public int Update(User obj)
53 | {
54 | throw new NotImplementedException();
55 | }
56 |
57 | public int Delete(User obj)
58 | {
59 | throw new NotImplementedException();
60 | }
61 |
62 | public IList GetAll()
63 | {
64 | throw new NotImplementedException();
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/ChatRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper;
25 | using Dapper.Contrib.Extensions;
26 | using OnlineTestWABot.Model.Entity;
27 | using OnlineTestWABot.Model.Context;
28 |
29 | namespace OnlineTestWABot.Model.Repository
30 | {
31 | public interface IChatRepository : IBaseRepository
32 | {
33 |
34 | }
35 |
36 | public class ChatRepository : IChatRepository
37 | {
38 | private readonly IDbContext _context;
39 |
40 | public ChatRepository(IDbContext context)
41 | {
42 | _context = context;
43 | }
44 |
45 | public int Save(Chat obj)
46 | {
47 | var result = 0;
48 |
49 | try
50 | {
51 | _context.Db.Insert(obj);
52 | result = 1;
53 | }
54 | catch (Exception ex)
55 | {
56 | //_log.Error("Error:", ex);
57 | }
58 |
59 | return result;
60 | }
61 |
62 | public int Update(Chat obj)
63 | {
64 | throw new NotImplementedException();
65 | }
66 |
67 | public int Delete(Chat obj)
68 | {
69 | throw new NotImplementedException();
70 | }
71 |
72 | public IList GetAll()
73 | {
74 | throw new NotImplementedException();
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/UserRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper;
25 | using Dapper.Contrib.Extensions;
26 | using OnlineTestWABot.Model.Entity;
27 | using OnlineTestWABot.Model.Context;
28 |
29 | namespace OnlineTestWABot.Model.Repository
30 | {
31 | public interface IUserRepository : IBaseRepository
32 | {
33 |
34 | }
35 |
36 | public class UserRepository : IUserRepository
37 | {
38 | private readonly IDbContext _context;
39 |
40 | public UserRepository(IDbContext context)
41 | {
42 | _context = context;
43 | }
44 |
45 | public int Save(User obj)
46 | {
47 | var result = 0;
48 |
49 | try
50 | {
51 | var existUser = _context.Db.Get(obj.user_id);
52 |
53 | if (existUser == null)
54 | {
55 | _context.Db.Insert(obj);
56 | result = 1;
57 | }
58 | }
59 | catch (Exception ex)
60 | {
61 | //_log.Error("Error:", ex);
62 | }
63 |
64 | return result;
65 | }
66 |
67 | public int Update(User obj)
68 | {
69 | throw new NotImplementedException();
70 | }
71 |
72 | public int Delete(User obj)
73 | {
74 | throw new NotImplementedException();
75 | }
76 |
77 | public IList GetAll()
78 | {
79 | throw new NotImplementedException();
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/SesiController.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using OnlineTestWABot.Model.Entity;
25 | using OnlineTestWABot.Model.Repository;
26 | using OnlineTestWABot.Model.Context;
27 |
28 | namespace OnlineTestWABot.Controller
29 | {
30 | public interface ISesiController : IBaseController
31 | {
32 | Sesi GetLastSession(string userId);
33 | }
34 |
35 | public class SesiController : ISesiController
36 | {
37 | private ISesiRepository _repository;
38 |
39 | public Sesi GetLastSession(string userId)
40 | {
41 | Sesi obj = null;
42 |
43 | using (IDbContext context = new DbContext())
44 | {
45 | _repository = new SesiRepository(context);
46 | obj = _repository.GetLastSession(userId);
47 | }
48 |
49 | return obj;
50 | }
51 |
52 | public int Save(Sesi obj)
53 | {
54 | var result = 0;
55 |
56 | using (IDbContext context = new DbContext())
57 | {
58 | _repository = new SesiRepository(context);
59 | result = _repository.Save(obj);
60 | }
61 |
62 | return result;
63 | }
64 |
65 | public int Update(Sesi obj)
66 | {
67 | var result = 0;
68 |
69 | using (IDbContext context = new DbContext())
70 | {
71 | _repository = new SesiRepository(context);
72 | result = _repository.Update(obj);
73 | }
74 |
75 | return result;
76 | }
77 |
78 | public int Delete(Sesi obj)
79 | {
80 | throw new NotImplementedException();
81 | }
82 |
83 | public IList GetAll()
84 | {
85 | throw new NotImplementedException();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/BankSoalController.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using OnlineTestWABot.Model.Entity;
25 | using OnlineTestWABot.Model.Repository;
26 | using OnlineTestWABot.Model.Context;
27 |
28 | namespace OnlineTestWABot.Controller
29 | {
30 | public interface IBankSoalController
31 | {
32 | BankSoal GetById(int soalId);
33 | BankSoal GetNewSoal(int sesiId);
34 | HistoriTes GetLastSoal(int sesiId, bool cekJawaban = true, int incrementSoalNumber = 1);
35 | }
36 |
37 | public class BankSoalController : IBankSoalController
38 | {
39 | private IBankSoalRepository _repository;
40 |
41 | public BankSoal GetById(int soalId)
42 | {
43 | BankSoal obj = null;
44 |
45 | using (IDbContext context = new DbContext())
46 | {
47 | _repository = new BankSoalRepository(context);
48 | obj = _repository.GetById(soalId);
49 | }
50 |
51 | return obj;
52 | }
53 |
54 | public BankSoal GetNewSoal(int sesiId)
55 | {
56 | BankSoal obj = null;
57 |
58 | using (IDbContext context = new DbContext())
59 | {
60 | _repository = new BankSoalRepository(context);
61 | obj = _repository.GetNewSoal(sesiId);
62 | }
63 |
64 | return obj;
65 | }
66 |
67 | public HistoriTes GetLastSoal(int sesiId, bool cekJawaban = true, int incrementSoalNumber = 1)
68 | {
69 | HistoriTes obj = null;
70 |
71 | using (IDbContext context = new DbContext())
72 | {
73 | _repository = new BankSoalRepository(context);
74 | obj = _repository.GetLastSoal(sesiId, cekJawaban, incrementSoalNumber);
75 | }
76 |
77 | return obj;
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Context/DbContext.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Data;
22 | using System.Data.Common;
23 | using System.IO;
24 | using System.Linq;
25 | using System.Text;
26 |
27 | namespace OnlineTestWABot.Model.Context
28 | {
29 | public interface IDbContext : IDisposable
30 | {
31 | IDbConnection Db { get; }
32 | }
33 |
34 | public class DbContext : IDbContext
35 | {
36 | private IDbConnection _db;
37 |
38 | private readonly string _providerName;
39 | private readonly string _connectionString;
40 |
41 | public DbContext()
42 | {
43 | var dbName = Directory.GetCurrentDirectory() + @"\database\DbTesOnline.db";
44 |
45 | _providerName = "System.Data.SQLite";
46 | _connectionString = "Data Source=" + dbName;
47 | }
48 |
49 | private IDbConnection GetOpenConnection(string providerName, string connectionString)
50 | {
51 | DbConnection conn = null;
52 |
53 | try
54 | {
55 | var provider = DbProviderFactories.GetFactory(providerName);
56 | conn = provider.CreateConnection();
57 | conn.ConnectionString = connectionString;
58 | conn.Open();
59 | }
60 | catch { }
61 |
62 | return conn;
63 | }
64 |
65 | public IDbConnection Db
66 | {
67 | get { return _db ?? (_db = GetOpenConnection(_providerName, _connectionString)); }
68 | }
69 |
70 | public void Dispose()
71 | {
72 | if (_db != null)
73 | {
74 | try
75 | {
76 | if (_db.State != ConnectionState.Closed)
77 | _db.Close();
78 | }
79 | finally
80 | {
81 | _db.Dispose();
82 | }
83 | }
84 |
85 | GC.SuppressFinalize(this);
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmStartUp.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System.IO;
20 | using System.Drawing;
21 | using System.Windows.Forms;
22 |
23 | namespace OnlineTestWABot.WinApp
24 | {
25 | public partial class FrmStartUp : Form
26 | {
27 | public FrmStartUp()
28 | {
29 | InitializeComponent();
30 | }
31 |
32 | public void OnScanMeHandler(string qrcodePath, string sessionId)
33 | {
34 | try
35 | {
36 | if (File.Exists(qrcodePath))
37 | {
38 | Image qrCode = null;
39 |
40 | // https://stackoverflow.com/questions/13625637/c-sharp-image-from-file-close-connection
41 | using (var originalImage = new Bitmap(qrcodePath))
42 | {
43 | qrCode = new Bitmap(originalImage);
44 | }
45 |
46 | // update UI dari thread yang berbeda
47 | picQRCode.Invoke(new MethodInvoker(() =>
48 | {
49 | picQRCode.Visible = true;
50 | picQRCode.Image = qrCode;
51 | }));
52 | }
53 | }
54 | catch
55 | {
56 |
57 | }
58 | }
59 |
60 | public void OnStartupHandler(string message, string sessionId)
61 | {
62 | if (message.IndexOf("Ready") >= 0 || message.IndexOf("Failure") >= 0
63 | || message.IndexOf("Timeout") >= 0 || message.IndexOf("ERR_NAME") >= 0)
64 | {
65 | if (this.IsHandleCreated)
66 | this.Invoke(new MethodInvoker(() => this.Close()));
67 | }
68 | else
69 | {
70 | // update UI dari thread yang berbeda
71 | lstLog.Invoke(new MethodInvoker(() =>
72 | {
73 | lstLog.Items.Add(message);
74 | lstLog.SelectedIndex = lstLog.Items.Count - 1;
75 | }
76 | ));
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OnlineTestWABot.WinApp.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OnlineTestWABot.WinApp.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/SesiRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper;
25 | using Dapper.Contrib.Extensions;
26 | using OnlineTestWABot.Model.Entity;
27 | using OnlineTestWABot.Model.Context;
28 |
29 | namespace OnlineTestWABot.Model.Repository
30 | {
31 | public interface ISesiRepository : IBaseRepository
32 | {
33 | Sesi GetLastSession(string userId);
34 | }
35 |
36 | public class SesiRepository : ISesiRepository
37 | {
38 | private readonly IDbContext _context;
39 |
40 | public SesiRepository(IDbContext context)
41 | {
42 | _context = context;
43 | }
44 |
45 | public Sesi GetLastSession(string userId)
46 | {
47 | Sesi obj = null;
48 |
49 | try
50 | {
51 | var sql = @"select * from sesi
52 | where user_id = @userId and is_timeout = 0
53 | order by sesi_id desc
54 | limit 1";
55 | obj = _context.Db.QuerySingleOrDefault(sql, new { userId });
56 | }
57 | catch (Exception ex)
58 | {
59 | //_log.Error("Error:", ex);
60 | }
61 |
62 | return obj;
63 | }
64 |
65 | public int Save(Sesi obj)
66 | {
67 | var result = 0;
68 |
69 | try
70 | {
71 | _context.Db.Insert(obj);
72 | result = 1;
73 | }
74 | catch (Exception ex)
75 | {
76 | //_log.Error("Error:", ex);
77 | }
78 |
79 | return result;
80 | }
81 |
82 | public int Update(Sesi obj)
83 | {
84 | var result = 0;
85 |
86 | try
87 | {
88 | result = _context.Db.Update(obj) ? 1 : 0;
89 | }
90 | catch (Exception ex)
91 | {
92 | //_log.Error("Error:", ex);
93 | }
94 |
95 | return result;
96 | }
97 |
98 | public int Delete(Sesi obj)
99 | {
100 | throw new NotImplementedException();
101 | }
102 |
103 | public IList GetAll()
104 | {
105 | throw new NotImplementedException();
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Controller/HistoriTesController.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using OnlineTestWABot.Model.Entity;
25 | using OnlineTestWABot.Model.Repository;
26 | using OnlineTestWABot.Model.Context;
27 |
28 | namespace OnlineTestWABot.Controller
29 | {
30 | public interface IHistoriTesController : IBaseController
31 | {
32 | int GetSoalNumber(int sesiId, int incrementSoalNumber = 1);
33 | HasilTes GetHasilTes(int sesiId);
34 | }
35 |
36 | public class HistoriTesController : IHistoriTesController
37 | {
38 | private IHistoriTesRepository _repository;
39 |
40 | public int GetSoalNumber(int sesiId, int incrementSoalNumber = 1)
41 | {
42 | var result = 0;
43 |
44 | using (IDbContext context = new DbContext())
45 | {
46 | _repository = new HistoriTesRepository(context);
47 | result = _repository.GetSoalNumber(sesiId, incrementSoalNumber);
48 | }
49 |
50 | return result;
51 | }
52 |
53 | public HasilTes GetHasilTes(int sesiId)
54 | {
55 | HasilTes obj = null;
56 |
57 | using (IDbContext context = new DbContext())
58 | {
59 | _repository = new HistoriTesRepository(context);
60 | obj = _repository.GetHasilTes(sesiId);
61 | }
62 |
63 | return obj;
64 | }
65 |
66 | public int Save(HistoriTes obj)
67 | {
68 | var result = 0;
69 |
70 | using (IDbContext context = new DbContext())
71 | {
72 | _repository = new HistoriTesRepository(context);
73 | result = _repository.Save(obj);
74 | }
75 |
76 | return result;
77 | }
78 |
79 | public int Update(HistoriTes obj)
80 | {
81 | var result = 0;
82 |
83 | using (IDbContext context = new DbContext())
84 | {
85 | _repository = new HistoriTesRepository(context);
86 | result = _repository.Update(obj);
87 | }
88 |
89 | return result;
90 | }
91 |
92 | public int Delete(HistoriTes obj)
93 | {
94 | throw new NotImplementedException();
95 | }
96 |
97 | public IList GetAll()
98 | {
99 | throw new NotImplementedException();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/OnlineTestWABot.Model.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {9C1541D1-E24D-4D48-80A0-72DBD6632E38}
8 | Library
9 | Properties
10 | OnlineTestWABot.Model
11 | OnlineTestWABot.Model
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | false
34 |
35 |
36 |
37 | ..\..\libs\Dapper.1.50.2\lib\net45\Dapper.dll
38 |
39 |
40 | ..\..\libs\Dapper.Contrib.1.50.0\lib\net45\Dapper.Contrib.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/HistoriTesRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper;
25 | using Dapper.Contrib.Extensions;
26 | using OnlineTestWABot.Model.Entity;
27 | using OnlineTestWABot.Model.Context;
28 |
29 | namespace OnlineTestWABot.Model.Repository
30 | {
31 | public interface IHistoriTesRepository : IBaseRepository
32 | {
33 | int GetSoalNumber(int sesiId, int incrementSoalNumber = 1);
34 | HasilTes GetHasilTes(int sesiId);
35 | }
36 |
37 | public class HistoriTesRepository : IHistoriTesRepository
38 | {
39 | private readonly IDbContext _context;
40 |
41 | public HistoriTesRepository(IDbContext context)
42 | {
43 | _context = context;
44 | }
45 |
46 | public int GetSoalNumber(int sesiId, int incrementSoalNumber = 1)
47 | {
48 | var result = 0;
49 |
50 | try
51 | {
52 | var sql = @"select count(*) + @increment
53 | from histori_tes
54 | where sesi_id = @sesiId";
55 |
56 | result = _context.Db.QuerySingleOrDefault(sql, new { sesiId, increment = incrementSoalNumber });
57 | }
58 | catch (Exception ex)
59 | {
60 | //_log.Error("Error:", ex);
61 | }
62 |
63 | return result;
64 | }
65 |
66 | public HasilTes GetHasilTes(int sesiId)
67 | {
68 | HasilTes obj = null;
69 |
70 | try
71 | {
72 | var sql = @"select
73 | count(case hasil_jawaban when 1 then hasil_jawaban end) as benar,
74 | count(case hasil_jawaban when 0 then hasil_jawaban end) as salah
75 | from histori_tes
76 | where sesi_id = @sesiId and batal = 0 and jawaban is not null";
77 |
78 | obj = _context.Db.QuerySingleOrDefault(sql, new { sesiId });
79 |
80 | }
81 | catch (Exception ex)
82 | {
83 | //_log.Error("Error:", ex);
84 | }
85 |
86 | return obj;
87 | }
88 |
89 | public int Save(HistoriTes obj)
90 | {
91 | var result = 0;
92 |
93 | try
94 | {
95 | _context.Db.Insert(obj);
96 | result = 1;
97 | }
98 | catch (Exception ex)
99 | {
100 | //_log.Error("Error:", ex);
101 | }
102 |
103 | return result;
104 | }
105 |
106 | public int Update(HistoriTes obj)
107 | {
108 | var result = 0;
109 |
110 | try
111 | {
112 | result = _context.Db.Update(obj) ? 1 : 0;
113 | }
114 | catch (Exception ex)
115 | {
116 | //_log.Error("Error:", ex);
117 | }
118 |
119 | return result;
120 | }
121 |
122 | public int Delete(HistoriTes obj)
123 | {
124 | throw new NotImplementedException();
125 | }
126 |
127 | public IList GetAll()
128 | {
129 | throw new NotImplementedException();
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.Model/Repository/BankSoalRepository.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.Linq;
22 | using System.Text;
23 |
24 | using Dapper;
25 | using Dapper.Contrib.Extensions;
26 | using OnlineTestWABot.Model.Entity;
27 | using OnlineTestWABot.Model.Context;
28 |
29 | namespace OnlineTestWABot.Model.Repository
30 | {
31 | public interface IBankSoalRepository
32 | {
33 | BankSoal GetById(int soalId);
34 | BankSoal GetNewSoal(int sesiId);
35 | HistoriTes GetLastSoal(int sesiId, bool cekJawaban = true, int incrementSoalNumber = 1);
36 | }
37 |
38 | public class BankSoalRepository : IBankSoalRepository
39 | {
40 | private readonly IDbContext _context;
41 |
42 | public BankSoalRepository(IDbContext context)
43 | {
44 | _context = context;
45 | }
46 |
47 | public BankSoal GetById(int soalId)
48 | {
49 | BankSoal obj = null;
50 |
51 | try
52 | {
53 | obj = _context.Db.Get(soalId);
54 | }
55 | catch (Exception ex)
56 | {
57 | //_log.Error("Error:", ex);
58 | }
59 |
60 | return obj;
61 | }
62 |
63 | public BankSoal GetNewSoal(int sesiId)
64 | {
65 | BankSoal obj = null;
66 |
67 | try
68 | {
69 | var random = new Random();
70 |
71 | var sql = @"select bank_soal_id from bank_soal
72 | where bank_soal_id not in (select bank_soal_id from histori_tes where sesi_id = @sesiId)";
73 | var soalId = _context.Db.Query(sql, new { sesiId })
74 | .OrderBy(f => random.Next()).Take(1)
75 | .FirstOrDefault();
76 |
77 | obj = GetById(soalId);
78 |
79 | if (obj != null)
80 | {
81 | IHistoriTesRepository repo = new HistoriTesRepository(_context);
82 | obj.nomor_soal = repo.GetSoalNumber(sesiId);
83 | }
84 | }
85 | catch (Exception ex)
86 | {
87 | //_log.Error("Error:", ex);
88 | }
89 |
90 | return obj;
91 | }
92 |
93 | public HistoriTes GetLastSoal(int sesiId, bool cekJawaban = true, int incrementSoalNumber = 1)
94 | {
95 | HistoriTes obj = null;
96 |
97 | try
98 | {
99 | var sql = @"select histori_tes.histori_tes_id, histori_tes.user_id, histori_tes.sesi_id, histori_tes.tanggal, histori_tes.jawaban,
100 | histori_tes.hasil_jawaban, histori_tes.batal,
101 | bank_soal.bank_soal_id, bank_soal.soal, bank_soal.jawaban, bank_soal.analisa
102 | from histori_tes inner join bank_soal on bank_soal.bank_soal_id = histori_tes.bank_soal_id
103 | {WHERE}
104 | order by histori_tes.histori_tes_id desc
105 | limit 1";
106 |
107 | if (cekJawaban)
108 | sql = sql.Replace("{WHERE}", "where histori_tes.sesi_id = @sesiId and histori_tes.batal = 0 and histori_tes.jawaban is null");
109 | else
110 | sql = sql.Replace("{WHERE}", "where histori_tes.sesi_id = @sesiId and histori_tes.batal = 0");
111 |
112 | obj = _context.Db.Query(sql, (histori, soal) =>
113 | {
114 | histori.bank_soal_id = soal.bank_soal_id;
115 | histori.BankSoal = soal;
116 |
117 | return histori;
118 | }, new { sesiId }, splitOn: "bank_soal_id").SingleOrDefault();
119 |
120 | if (obj != null)
121 | {
122 | IHistoriTesRepository repo = new HistoriTesRepository(_context);
123 | obj.BankSoal.nomor_soal = repo.GetSoalNumber(sesiId, incrementSoalNumber);
124 | }
125 | }
126 | catch (Exception ex)
127 | {
128 | //_log.Error("Error:", ex);
129 | }
130 |
131 | return obj;
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmStartUp.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace OnlineTestWABot.WinApp
2 | {
3 | partial class FrmStartUp
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
32 | this.lstLog = new System.Windows.Forms.ListBox();
33 | this.picQRCode = new System.Windows.Forms.PictureBox();
34 | this.tableLayoutPanel1.SuspendLayout();
35 | ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).BeginInit();
36 | this.SuspendLayout();
37 | //
38 | // tableLayoutPanel1
39 | //
40 | this.tableLayoutPanel1.ColumnCount = 2;
41 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
42 | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
43 | this.tableLayoutPanel1.Controls.Add(this.lstLog, 0, 0);
44 | this.tableLayoutPanel1.Controls.Add(this.picQRCode, 1, 0);
45 | this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
46 | this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
47 | this.tableLayoutPanel1.Name = "tableLayoutPanel1";
48 | this.tableLayoutPanel1.RowCount = 1;
49 | this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
50 | this.tableLayoutPanel1.Size = new System.Drawing.Size(563, 305);
51 | this.tableLayoutPanel1.TabIndex = 0;
52 | //
53 | // lstLog
54 | //
55 | this.lstLog.Dock = System.Windows.Forms.DockStyle.Fill;
56 | this.lstLog.FormattingEnabled = true;
57 | this.lstLog.Items.AddRange(new object[] {
58 | "- Wait ..."});
59 | this.lstLog.Location = new System.Drawing.Point(10, 10);
60 | this.lstLog.Margin = new System.Windows.Forms.Padding(10);
61 | this.lstLog.Name = "lstLog";
62 | this.lstLog.Size = new System.Drawing.Size(236, 285);
63 | this.lstLog.TabIndex = 0;
64 | //
65 | // picQRCode
66 | //
67 | this.picQRCode.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
68 | this.picQRCode.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
69 | this.picQRCode.Dock = System.Windows.Forms.DockStyle.Fill;
70 | this.picQRCode.Location = new System.Drawing.Point(266, 10);
71 | this.picQRCode.Margin = new System.Windows.Forms.Padding(10);
72 | this.picQRCode.Name = "picQRCode";
73 | this.picQRCode.Size = new System.Drawing.Size(287, 285);
74 | this.picQRCode.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
75 | this.picQRCode.TabIndex = 1;
76 | this.picQRCode.TabStop = false;
77 | this.picQRCode.Visible = false;
78 | //
79 | // FrmStartUp
80 | //
81 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
82 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
83 | this.BackColor = System.Drawing.Color.White;
84 | this.ClientSize = new System.Drawing.Size(563, 305);
85 | this.Controls.Add(this.tableLayoutPanel1);
86 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
87 | this.MaximizeBox = false;
88 | this.MinimizeBox = false;
89 | this.Name = "FrmStartUp";
90 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
91 | this.Text = "StartUp";
92 | this.tableLayoutPanel1.ResumeLayout(false);
93 | this.tableLayoutPanel1.PerformLayout();
94 | ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).EndInit();
95 | this.ResumeLayout(false);
96 |
97 | }
98 |
99 | #endregion
100 |
101 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
102 | private System.Windows.Forms.ListBox lstLog;
103 | private System.Windows.Forms.PictureBox picQRCode;
104 | }
105 | }
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmMain.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace OnlineTestWABot.WinApp
2 | {
3 | partial class FrmMain
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.btnStart = new System.Windows.Forms.Button();
32 | this.btnStop = new System.Windows.Forms.Button();
33 | this.txtLokasiWhatsAppNETAPINodeJs = new System.Windows.Forms.TextBox();
34 | this.label4 = new System.Windows.Forms.Label();
35 | this.btnLokasiWAAutomateNodejs = new System.Windows.Forms.Button();
36 | this.SuspendLayout();
37 | //
38 | // btnStart
39 | //
40 | this.btnStart.Location = new System.Drawing.Point(347, 51);
41 | this.btnStart.Name = "btnStart";
42 | this.btnStart.Size = new System.Drawing.Size(75, 23);
43 | this.btnStart.TabIndex = 0;
44 | this.btnStart.Text = "Start";
45 | this.btnStart.UseVisualStyleBackColor = true;
46 | this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
47 | //
48 | // btnStop
49 | //
50 | this.btnStop.Enabled = false;
51 | this.btnStop.Location = new System.Drawing.Point(428, 52);
52 | this.btnStop.Name = "btnStop";
53 | this.btnStop.Size = new System.Drawing.Size(75, 23);
54 | this.btnStop.TabIndex = 1;
55 | this.btnStop.Text = "Stop";
56 | this.btnStop.UseVisualStyleBackColor = true;
57 | this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
58 | //
59 | // txtLokasiWhatsAppNETAPINodeJs
60 | //
61 | this.txtLokasiWhatsAppNETAPINodeJs.Location = new System.Drawing.Point(15, 25);
62 | this.txtLokasiWhatsAppNETAPINodeJs.Name = "txtLokasiWhatsAppNETAPINodeJs";
63 | this.txtLokasiWhatsAppNETAPINodeJs.ReadOnly = true;
64 | this.txtLokasiWhatsAppNETAPINodeJs.Size = new System.Drawing.Size(448, 20);
65 | this.txtLokasiWhatsAppNETAPINodeJs.TabIndex = 3;
66 | //
67 | // label4
68 | //
69 | this.label4.AutoSize = true;
70 | this.label4.Location = new System.Drawing.Point(12, 9);
71 | this.label4.Name = "label4";
72 | this.label4.Size = new System.Drawing.Size(175, 13);
73 | this.label4.TabIndex = 4;
74 | this.label4.Text = "Lokasi WhatsApp NET API NodeJs";
75 | this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
76 | //
77 | // btnLokasiWAAutomateNodejs
78 | //
79 | this.btnLokasiWAAutomateNodejs.Location = new System.Drawing.Point(469, 23);
80 | this.btnLokasiWAAutomateNodejs.Name = "btnLokasiWAAutomateNodejs";
81 | this.btnLokasiWAAutomateNodejs.Size = new System.Drawing.Size(34, 23);
82 | this.btnLokasiWAAutomateNodejs.TabIndex = 5;
83 | this.btnLokasiWAAutomateNodejs.Text = "...";
84 | this.btnLokasiWAAutomateNodejs.UseVisualStyleBackColor = true;
85 | this.btnLokasiWAAutomateNodejs.Click += new System.EventHandler(this.btnLokasiWAAutomateNodejs_Click);
86 | //
87 | // FrmMain
88 | //
89 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
90 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
91 | this.ClientSize = new System.Drawing.Size(510, 83);
92 | this.Controls.Add(this.btnLokasiWAAutomateNodejs);
93 | this.Controls.Add(this.label4);
94 | this.Controls.Add(this.txtLokasiWhatsAppNETAPINodeJs);
95 | this.Controls.Add(this.btnStop);
96 | this.Controls.Add(this.btnStart);
97 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
98 | this.MaximizeBox = false;
99 | this.Name = "FrmMain";
100 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
101 | this.Text = "Online Test WA Bot";
102 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmMain_FormClosing);
103 | this.ResumeLayout(false);
104 | this.PerformLayout();
105 |
106 | }
107 |
108 | #endregion
109 |
110 | private System.Windows.Forms.Button btnStart;
111 | private System.Windows.Forms.Button btnStop;
112 | private System.Windows.Forms.TextBox txtLokasiWhatsAppNETAPINodeJs;
113 | private System.Windows.Forms.Label label4;
114 | private System.Windows.Forms.Button btnLokasiWAAutomateNodejs;
115 | }
116 | }
117 |
118 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmMain.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmStartUp.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/OnlineTestWABot.WinApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {74A83EF2-0A5C-429B-82F7-911510944921}
8 | WinExe
9 | Properties
10 | OnlineTestWABot.WinApp
11 | OnlineTestWABot.WinApp
12 | v4.5
13 | 512
14 |
15 |
16 |
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 | false
28 |
29 |
30 | AnyCPU
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 | false
38 |
39 |
40 |
41 | False
42 | ..\..\libs\WhatsAppNETAPI.3.0.0\lib\net45\JamesWright.SimpleHttp.dll
43 | True
44 |
45 |
46 | ..\..\libs\Microsoft.AspNet.SignalR.Client.2.4.2\lib\net45\Microsoft.AspNet.SignalR.Client.dll
47 |
48 |
49 | ..\..\libs\Microsoft.AspNet.SignalR.Core.2.4.2\lib\net45\Microsoft.AspNet.SignalR.Core.dll
50 |
51 |
52 | ..\..\libs\Microsoft.Owin.4.2.0\lib\net45\Microsoft.Owin.dll
53 |
54 |
55 | ..\..\libs\Microsoft.Owin.Cors.4.2.0\lib\net45\Microsoft.Owin.Cors.dll
56 |
57 |
58 | ..\..\libs\Microsoft.Owin.Diagnostics.2.1.0\lib\net40\Microsoft.Owin.Diagnostics.dll
59 |
60 |
61 | ..\..\libs\Microsoft.Owin.Host.HttpListener.2.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll
62 |
63 |
64 | ..\..\libs\Microsoft.Owin.Hosting.4.2.0\lib\net45\Microsoft.Owin.Hosting.dll
65 |
66 |
67 | ..\..\libs\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll
68 |
69 |
70 | ..\..\libs\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
71 |
72 |
73 | ..\..\libs\Owin.1.0\lib\net40\Owin.dll
74 |
75 |
76 |
77 |
78 | ..\..\libs\System.Data.SQLite.Core.1.0.108.0\lib\net45\System.Data.SQLite.dll
79 |
80 |
81 |
82 |
83 |
84 | ..\..\libs\Microsoft.AspNet.Cors.5.0.0\lib\net45\System.Web.Cors.dll
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | ..\..\libs\WaitCursor.dll
96 |
97 |
98 | False
99 | ..\..\libs\WhatsAppNETAPI.3.0.0\lib\net45\WhatsAppNETAPI.dll
100 | True
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | Form
112 |
113 |
114 | FrmMain.cs
115 |
116 |
117 | Form
118 |
119 |
120 | FrmStartUp.cs
121 |
122 |
123 |
124 |
125 |
126 | FrmMain.cs
127 |
128 |
129 | FrmStartUp.cs
130 |
131 |
132 | ResXFileCodeGenerator
133 | Resources.Designer.cs
134 | Designer
135 |
136 |
137 | True
138 | Resources.resx
139 | True
140 |
141 |
142 |
143 |
144 | SettingsSingleFileGenerator
145 | Settings.Designer.cs
146 |
147 |
148 | True
149 | Settings.settings
150 | True
151 |
152 |
153 |
154 |
155 | {9c1541d1-e24d-4d48-80a0-72dbd6632e38}
156 | OnlineTestWABot.Model
157 |
158 |
159 |
160 |
161 |
162 |
163 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
164 |
165 |
166 |
167 |
174 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/visualstudio,csharp
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio,csharp
3 |
4 | ### Csharp ###
5 | ## Ignore Visual Studio temporary files, build results, and
6 | ## files generated by popular Visual Studio add-ons.
7 | ##
8 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
9 |
10 | # User-specific files
11 | *.rsuser
12 | *.suo
13 | *.user
14 | *.userosscache
15 | *.sln.docstates
16 |
17 | # User-specific files (MonoDevelop/Xamarin Studio)
18 | *.userprefs
19 |
20 | # User-specific directories
21 | libs/
22 |
23 | # Mono auto generated files
24 | mono_crash.*
25 |
26 | # Build results
27 | [Dd]ebug/
28 | [Dd]ebugPublic/
29 | [Rr]elease/
30 | [Rr]eleases/
31 | x64/
32 | x86/
33 | [Aa][Rr][Mm]/
34 | [Aa][Rr][Mm]64/
35 | bld/
36 | [Bb]in/
37 | [Oo]bj/
38 | [Ll]og/
39 | [Ll]ogs/
40 |
41 | # Visual Studio 2015/2017 cache/options directory
42 | .vs/
43 | # Uncomment if you have tasks that create the project's static files in wwwroot
44 | #wwwroot/
45 |
46 | # Visual Studio 2017 auto generated files
47 | Generated\ Files/
48 |
49 | # MSTest test Results
50 | [Tt]est[Rr]esult*/
51 | [Bb]uild[Ll]og.*
52 |
53 | # NUnit
54 | *.VisualState.xml
55 | TestResult.xml
56 | nunit-*.xml
57 |
58 | # Build Results of an ATL Project
59 | [Dd]ebugPS/
60 | [Rr]eleasePS/
61 | dlldata.c
62 |
63 | # Benchmark Results
64 | BenchmarkDotNet.Artifacts/
65 |
66 | # .NET Core
67 | project.lock.json
68 | project.fragment.lock.json
69 | artifacts/
70 |
71 | # StyleCop
72 | StyleCopReport.xml
73 |
74 | # Files built by Visual Studio
75 | *_i.c
76 | *_p.c
77 | *_h.h
78 | *.ilk
79 | *.meta
80 | *.obj
81 | *.iobj
82 | *.pch
83 | *.pdb
84 | *.ipdb
85 | *.pgc
86 | *.pgd
87 | *.rsp
88 | *.sbr
89 | *.tlb
90 | *.tli
91 | *.tlh
92 | *.tmp
93 | *.tmp_proj
94 | *_wpftmp.csproj
95 | *.log
96 | *.vspscc
97 | *.vssscc
98 | .builds
99 | *.pidb
100 | *.svclog
101 | *.scc
102 |
103 | # Chutzpah Test files
104 | _Chutzpah*
105 |
106 | # Visual C++ cache files
107 | ipch/
108 | *.aps
109 | *.ncb
110 | *.opendb
111 | *.opensdf
112 | *.sdf
113 | *.cachefile
114 | *.VC.db
115 | *.VC.VC.opendb
116 |
117 | # Visual Studio profiler
118 | *.psess
119 | *.vsp
120 | *.vspx
121 | *.sap
122 |
123 | # Visual Studio Trace Files
124 | *.e2e
125 |
126 | # TFS 2012 Local Workspace
127 | $tf/
128 |
129 | # Guidance Automation Toolkit
130 | *.gpState
131 |
132 | # ReSharper is a .NET coding add-in
133 | _ReSharper*/
134 | *.[Rr]e[Ss]harper
135 | *.DotSettings.user
136 |
137 | # TeamCity is a build add-in
138 | _TeamCity*
139 |
140 | # DotCover is a Code Coverage Tool
141 | *.dotCover
142 |
143 | # AxoCover is a Code Coverage Tool
144 | .axoCover/*
145 | !.axoCover/settings.json
146 |
147 | # Coverlet is a free, cross platform Code Coverage Tool
148 | coverage*[.json, .xml, .info]
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | ### VisualStudio ###
363 |
364 | # User-specific files
365 |
366 | # User-specific files (MonoDevelop/Xamarin Studio)
367 |
368 | # Mono auto generated files
369 |
370 | # Build results
371 |
372 | # Visual Studio 2015/2017 cache/options directory
373 | # Uncomment if you have tasks that create the project's static files in wwwroot
374 |
375 | # Visual Studio 2017 auto generated files
376 |
377 | # MSTest test Results
378 |
379 | # NUnit
380 |
381 | # Build Results of an ATL Project
382 |
383 | # Benchmark Results
384 |
385 | # .NET Core
386 |
387 | # StyleCop
388 |
389 | # Files built by Visual Studio
390 |
391 | # Chutzpah Test files
392 |
393 | # Visual C++ cache files
394 |
395 | # Visual Studio profiler
396 |
397 | # Visual Studio Trace Files
398 |
399 | # TFS 2012 Local Workspace
400 |
401 | # Guidance Automation Toolkit
402 |
403 | # ReSharper is a .NET coding add-in
404 |
405 | # TeamCity is a build add-in
406 |
407 | # DotCover is a Code Coverage Tool
408 |
409 | # AxoCover is a Code Coverage Tool
410 |
411 | # Coverlet is a free, cross platform Code Coverage Tool
412 |
413 | # Visual Studio code coverage results
414 |
415 | # NCrunch
416 |
417 | # MightyMoose
418 |
419 | # Web workbench (sass)
420 |
421 | # Installshield output folder
422 |
423 | # DocProject is a documentation generator add-in
424 |
425 | # Click-Once directory
426 |
427 | # Publish Web Output
428 | # Note: Comment the next line if you want to checkin your web deploy settings,
429 | # but database connection strings (with potential passwords) will be unencrypted
430 |
431 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
432 | # checkin your Azure Web App publish settings, but sensitive information contained
433 | # in these scripts will be unencrypted
434 |
435 | # NuGet Packages
436 | # NuGet Symbol Packages
437 | # The packages folder can be ignored because of Package Restore
438 | # except build/, which is used as an MSBuild target.
439 | # Uncomment if necessary however generally it will be regenerated when needed
440 | # NuGet v3's project.json files produces more ignorable files
441 |
442 | # Microsoft Azure Build Output
443 |
444 | # Microsoft Azure Emulator
445 |
446 | # Windows Store app package directories and files
447 |
448 | # Visual Studio cache files
449 | # files ending in .cache can be ignored
450 | # but keep track of directories ending in .cache
451 |
452 | # Others
453 |
454 | # Including strong name files can present a security risk
455 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
456 |
457 | # Since there are multiple workflows, uncomment next line to ignore bower_components
458 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
459 |
460 | # RIA/Silverlight projects
461 |
462 | # Backup & report files from converting an old project file
463 | # to a newer Visual Studio version. Backup files are not needed,
464 | # because we have git ;-)
465 |
466 | # SQL Server files
467 |
468 | # Business Intelligence projects
469 |
470 | # Microsoft Fakes
471 |
472 | # GhostDoc plugin setting file
473 |
474 | # Node.js Tools for Visual Studio
475 |
476 | # Visual Studio 6 build log
477 |
478 | # Visual Studio 6 workspace options file
479 |
480 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
481 |
482 | # Visual Studio LightSwitch build output
483 |
484 | # Paket dependency manager
485 |
486 | # FAKE - F# Make
487 |
488 | # CodeRush personal settings
489 |
490 | # Python Tools for Visual Studio (PTVS)
491 |
492 | # Cake - Uncomment if you are using it
493 | # tools/**
494 | # !tools/packages.config
495 |
496 | # Tabs Studio
497 |
498 | # Telerik's JustMock configuration file
499 |
500 | # BizTalk build output
501 |
502 | # OpenCover UI analysis results
503 |
504 | # Azure Stream Analytics local run output
505 |
506 | # MSBuild Binary and Structured Log
507 |
508 | # NVidia Nsight GPU debugger configuration file
509 |
510 | # MFractors (Xamarin productivity tool) working folder
511 |
512 | # Local History for Visual Studio
513 |
514 | # BeatPulse healthcheck temp database
515 |
516 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
517 |
518 | # Ionide (cross platform F# VS Code tools) working folder
519 |
520 | # End of https://www.toptal.com/developers/gitignore/api/visualstudio,csharp
521 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/FrmMain.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.ComponentModel;
22 | using System.Data;
23 | using System.Drawing;
24 | using System.Linq;
25 | using System.Text;
26 | using System.Windows.Forms;
27 |
28 | using WhatsAppNETAPI;
29 | using ConceptCave.WaitCursor;
30 |
31 | using OnlineTestWABot.Model.Entity;
32 | using OnlineTestWABot.Controller;
33 | using System.Threading;
34 | using System.Diagnostics;
35 |
36 | namespace OnlineTestWABot.WinApp
37 | {
38 | public partial class FrmMain : Form
39 | {
40 | private const string ABOUT = "*WhatsApp Bot - Online Test {0}*\r\n" +
41 | "By *{1}*\r\n" +
42 | "Email : {2}\r\n" +
43 | "Blog : {3}";
44 |
45 | private const string BANTUAN = "*WhatsApp Bot - Online Test {0}*\r\n" +
46 | "By *{1}*\r\n" +
47 | "Email : {2}\r\n" +
48 | "Blog : {3}\r\n\r\n" +
49 |
50 | "Anda akan mendapatkan *40 SOAL* dengan model pilihan ganda.\r\n\r\n" +
51 |
52 | "Daftar keyword yang tersedia :\r\n\r\n" +
53 | "\U00002705 *about* - informasi program\r\n" +
54 | "\U00002705 *bantuan* - untuk menampilkan perintah yang tersedia\r\n" +
55 | "\U00002705 *mulai* - untuk memulai tes bahasa inggris\r\n" +
56 | "\U00002705 *soal* - untuk mendapatkan soal tes bahasa inggris\r\n" +
57 | "\U00002705 *soalterakhir* - informasi soal terakhir\r\n" +
58 | "\U00002705 *jawab jawaban* - untuk menjawab soal. contoh *jawab A*\r\n" +
59 | "\U00002705 *batal* - untuk mengabaikan soal terakhir/enggak sanggup jawab \U0001F61C\r\n" +
60 | "\U00002705 *selesai* - untuk mengakhiri tes bahasa Inggris";
61 |
62 | private const string PERINTAH_SALAH = "Maaf perintah *{0}* tidak dikenal, ketik *bantuan* untuk informasi lebih lanjut.";
63 | private const string AUTHOR = "Kamarudin";
64 | private const string EMAIL = "rudi.krsoftware@gmail.com";
65 | private const string URL = "http://coding4ever.net/";
66 |
67 | private string _currentVersion = string.Empty;
68 | private IWhatsAppNETAPI _wa; // deklarasi objek WhatsApp NET Client
69 |
70 | public FrmMain()
71 | {
72 | InitializeComponent();
73 | _wa = new WhatsAppNETAPI.WhatsAppNETAPI();
74 |
75 | _currentVersion = string.Format("v{0}", GetCurrentVersion());
76 | this.Text = string.Format("WhatsApp Bot - Online Test {0}", _currentVersion);
77 | }
78 |
79 | private string GetCurrentVersion()
80 | {
81 | var fvi = FileVersionInfo.GetVersionInfo(Application.ExecutablePath);
82 | var version = fvi.ProductMajorPart + "." + fvi.ProductMinorPart + "." + fvi.ProductBuildPart;
83 |
84 | return version;
85 | }
86 |
87 | private void AutoReplay(User user, Chat chat, ref string msgToReplay)
88 | {
89 | if (chat.text.Length > 0)
90 | {
91 | var splitPesan = chat.text.Split(' ');
92 | var keyword = splitPesan[0];
93 | var param = string.Empty;
94 |
95 | if (splitPesan.Count() > 1) param = splitPesan[1];
96 |
97 | SaveUser(user);
98 | SaveChat(chat);
99 |
100 | var perintahBot = new PerintahBot();
101 |
102 | switch (keyword.ToLower())
103 | {
104 | case "about":
105 | msgToReplay = string.Format(ABOUT, _currentVersion, AUTHOR, EMAIL, URL);
106 | break;
107 |
108 | case "bantuan":
109 | msgToReplay = string.Format(BANTUAN, _currentVersion, AUTHOR, EMAIL, URL);
110 | break;
111 |
112 | case "mulai":
113 | perintahBot.Mulai(user.user_id, ref msgToReplay);
114 | break;
115 |
116 | case "soal":
117 | perintahBot.Soal(user.user_id, ref msgToReplay);
118 | break;
119 |
120 | case "soalterakhir":
121 | perintahBot.SoalTerakhir(user.user_id, ref msgToReplay);
122 | break;
123 |
124 | case "jawab":
125 | perintahBot.Jawab(user.user_id, param, ref msgToReplay);
126 | break;
127 |
128 | case "batal":
129 | perintahBot.Batal(user.user_id, ref msgToReplay);
130 | break;
131 |
132 | case "selesai":
133 | perintahBot.Selesai(user.user_id, ref msgToReplay);
134 | break;
135 |
136 | default:
137 | msgToReplay = string.Format(PERINTAH_SALAH, keyword.ToLower());
138 | break;
139 | }
140 |
141 | Console.WriteLine("msgToReplay: {0}", msgToReplay);
142 | }
143 | }
144 |
145 | private void SaveChat(Chat obj)
146 | {
147 | IChatController controller = new ChatController();
148 | var result = controller.Save(obj);
149 | }
150 |
151 | private void SaveUser(User obj)
152 | {
153 | IUserController controller = new UserController();
154 | var result = controller.Save(obj);
155 | }
156 |
157 | private void btnStart_Click(object sender, EventArgs e)
158 | {
159 | if (string.IsNullOrEmpty(txtLokasiWhatsAppNETAPINodeJs.Text))
160 | {
161 | MessageBox.Show("Maaf, lokasi folder 'WhatsApp NET API NodeJs' belum di set", "Peringatan",
162 | MessageBoxButtons.OK, MessageBoxIcon.Information);
163 |
164 | txtLokasiWhatsAppNETAPINodeJs.Focus();
165 | return;
166 | }
167 |
168 | _wa.WaNetApiNodeJsPath = txtLokasiWhatsAppNETAPINodeJs.Text;
169 |
170 | if (!_wa.IsWaNetApiNodeJsPathExists)
171 | {
172 | MessageBox.Show("Maaf, lokasi folder 'WhatsApp NET API NodeJs' tidak ditemukan !!!", "Peringatan",
173 | MessageBoxButtons.OK, MessageBoxIcon.Information);
174 |
175 | txtLokasiWhatsAppNETAPINodeJs.Focus();
176 | return;
177 | }
178 |
179 | Connect();
180 | }
181 |
182 | private void Connect()
183 | {
184 | this.UseWaitCursor = true;
185 |
186 | // subscribe event
187 | _wa.OnStartup += OnStartupHandler;
188 | _wa.OnReceiveMessage += OnReceiveMessageHandler;
189 | _wa.OnClientConnected += OnClientConnectedHandler;
190 |
191 | _wa.Connect();
192 |
193 | using (var frm = new FrmStartUp())
194 | {
195 | // subscribe event
196 | _wa.OnStartup += frm.OnStartupHandler;
197 | _wa.OnScanMe += frm.OnScanMeHandler;
198 |
199 | frm.UseWaitCursor = true;
200 | frm.ShowDialog();
201 |
202 | // unsubscribe event
203 | _wa.OnStartup -= frm.OnStartupHandler;
204 | _wa.OnScanMe -= frm.OnScanMeHandler;
205 | }
206 | }
207 |
208 | private void btnStop_Click(object sender, EventArgs e)
209 | {
210 | Disconnect();
211 | }
212 |
213 | private void Disconnect()
214 | {
215 | btnStart.Enabled = true;
216 | btnStop.Enabled = false;
217 |
218 | using (new StCursor(Cursors.WaitCursor, new TimeSpan(0, 0, 0, 0)))
219 | {
220 | // unsubscribe event
221 | _wa.OnStartup -= OnStartupHandler;
222 | _wa.OnReceiveMessage -= OnReceiveMessageHandler;
223 | _wa.OnClientConnected -= OnClientConnectedHandler;
224 |
225 | _wa.Disconnect();
226 | }
227 | }
228 |
229 | private void btnLokasiWAAutomateNodejs_Click(object sender, EventArgs e)
230 | {
231 | var folderName = ShowDialogOpenFolder();
232 |
233 | if (!string.IsNullOrEmpty(folderName)) txtLokasiWhatsAppNETAPINodeJs.Text = folderName;
234 | }
235 |
236 | private string ShowDialogOpenFolder()
237 | {
238 | var folderName = string.Empty;
239 |
240 | using (var dlgOpen = new FolderBrowserDialog())
241 | {
242 | var result = dlgOpen.ShowDialog();
243 |
244 | if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(dlgOpen.SelectedPath))
245 | {
246 | folderName = dlgOpen.SelectedPath;
247 | }
248 | }
249 |
250 | return folderName;
251 | }
252 |
253 | private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
254 | {
255 | Disconnect();
256 | }
257 |
258 | # region event handler
259 |
260 | private void OnStartupHandler(string message, string sessionId)
261 | {
262 | // koneksi ke WA berhasil
263 | if (message.IndexOf("Ready") >= 0)
264 | {
265 | btnStart.Invoke(new MethodInvoker(() => btnStart.Enabled = false));
266 | btnStop.Invoke(new MethodInvoker(() => btnStop.Enabled = true));
267 |
268 | this.UseWaitCursor = false;
269 | }
270 |
271 | // koneksi ke WA GAGAL, bisa dicoba lagi
272 | if (message.IndexOf("Failure") >= 0 || message.IndexOf("Timeout") >= 0
273 | || message.IndexOf("ERR_NAME") >= 0)
274 | {
275 | // unsubscribe event
276 | _wa.OnStartup -= OnStartupHandler;
277 | _wa.OnReceiveMessage -= OnReceiveMessageHandler;
278 | _wa.OnClientConnected -= OnClientConnectedHandler;
279 |
280 | _wa.Disconnect();
281 |
282 | this.UseWaitCursor = false;
283 |
284 | var msg = string.Format("{0}\n\nKoneksi ke WA gagal, silahkan cek koneksi internet Anda", message);
285 | MessageBox.Show(msg, "Peringatan", MessageBoxButtons.OK, MessageBoxIcon.Warning);
286 | }
287 | }
288 |
289 | private void OnReceiveMessageHandler(WhatsAppNETAPI.Message message, string sessionId)
290 | {
291 | var user = new User
292 | {
293 | user_id = message.from
294 | };
295 |
296 | var chat = new Chat
297 | {
298 | user_id = message.from,
299 | text = message.content
300 | };
301 |
302 | var msgToReplay = string.Empty;
303 | AutoReplay(user, chat, ref msgToReplay);
304 |
305 | _wa.ReplyMessage(new ReplyMsgArgs(message.from, msgToReplay, message.id));
306 | }
307 |
308 | private void OnClientConnectedHandler(string sessionId)
309 | {
310 | System.Diagnostics.Debug.Print("ClientConnected on {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);
311 | }
312 |
313 | #endregion
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/src/OnlineTestWABot.WinApp/PerintahBot.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2020 Kamarudin (http://coding4ever.net/)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | *
16 | * The latest version of this file can be found at https://github.com/k4m4r82/OnlineTestWABot
17 | */
18 |
19 | using System;
20 | using System.Collections.Generic;
21 | using System.ComponentModel;
22 | using System.Data;
23 | using System.Drawing;
24 | using System.Linq;
25 | using System.Text;
26 | using System.Windows.Forms;
27 |
28 | using OnlineTestWABot.Model.Entity;
29 | using OnlineTestWABot.Controller;
30 |
31 | namespace OnlineTestWABot.WinApp
32 | {
33 | public class PerintahBot
34 | {
35 | private const string SESSION_TIMEOUT = @"Maaf sesi tes bahasa Inggris Anda sudah selesai/belum dibuat, ketik *mulai* untuk memulai tes.";
36 | private const string SESSION_NOT_TIMEOUT = @"Sesi Anda belum habis, silahkan melanjutkan menjawab soal atau *selesai* untuk melihat hasil tes.";
37 | private const string SOAL_SUDAH_DIJAWAB = @"Maaf soal terakhir tidak ditemukan/sudah dijawab, ketik *soal* untuk mendapatkan soal baru atau *selesai* untuk melihat hasil tes.";
38 | private const string SESSION_OK = @"Selamat !!! sesi tes bahasa Inggris Anda sudah dibuat, ketik *soal* untuk memulai tes.";
39 | private const string TES_SELESAI = @"Selamat !!! Anda sudah menyelesaikan semua soal, ketik *selesai* untuk mengakhiri tes.";
40 |
41 | private const string HASIL_TES = "\U0001F3C1 Hasil tes Anda \U0001F3C1\r\n\r\n" +
42 | "\U00002705 *Benar* = {0}\r\n" +
43 | "\U0000274C *Salah* = {1}\r\n" +
44 | "\U0001F4DC *Nilai* = {2}\r\n\r\n" +
45 | "ooO Terima kasih \U0001F64F Ooo";
46 |
47 | public void Mulai(string userId, ref string msgToReplay)
48 | {
49 | var lastSession = GetLastSession(userId);
50 |
51 | if (lastSession == null)
52 | {
53 | lastSession = SaveSession(userId);
54 | msgToReplay = SESSION_OK;
55 | }
56 | else
57 | {
58 | var sekarang = DateTime.Now;
59 | var ts = sekarang.Subtract(lastSession.tanggal);
60 |
61 | if (ts.Minutes >= 30) // ession time out max 30 menit
62 | {
63 | lastSession = SaveSession(userId);
64 | msgToReplay = SESSION_OK;
65 | }
66 | else
67 | {
68 | msgToReplay = SESSION_NOT_TIMEOUT;
69 | }
70 | }
71 | }
72 |
73 | public void Soal(string userId, ref string msgToReplay)
74 | {
75 | var lastSession = GetLastSession(userId);
76 |
77 | if (lastSession == null)
78 | {
79 | msgToReplay = SESSION_TIMEOUT;
80 | }
81 | else
82 | {
83 | // cek soal terakhir sudah dijawab atau belum
84 | var lastSoal = GetLastSoal(lastSession.sesi_id);
85 |
86 | if (lastSoal != null && string.IsNullOrEmpty(lastSoal.jawaban))
87 | {
88 | msgToReplay = @"Maaf soal terakhir belum dijawab, ketik *soalterakhir* untuk melihat soal terakhir.";
89 | }
90 | else
91 | {
92 | var newSoal = GetNewSoal(lastSession.sesi_id);
93 | if (newSoal == null)
94 | {
95 | msgToReplay = TES_SELESAI;
96 | }
97 | else
98 | {
99 | msgToReplay = newSoal.soal + "\r\n\r\n" +
100 | "Ketik: *jawab jawaban* untuk menjawab. Contoh: *jawab a*";
101 |
102 | msgToReplay = msgToReplay.Replace("[A]", "*[A]*");
103 | msgToReplay = msgToReplay.Replace("[B]", "*[B]*");
104 | msgToReplay = msgToReplay.Replace("[C]", "*[C]*");
105 | msgToReplay = msgToReplay.Replace("[D]", "*[D]*");
106 | msgToReplay = msgToReplay.Replace("[E]", "*[E]*");
107 | msgToReplay = msgToReplay.Replace("BACAAN", "*BACAAN*");
108 | msgToReplay = msgToReplay.Replace("PERTANYAAN", "*PERTANYAAN*");
109 |
110 | msgToReplay = string.Format("*Soal Nomor {0}*", newSoal.nomor_soal) + ":\r\n\r\n" +
111 | msgToReplay;
112 |
113 | var histori = new HistoriTes
114 | {
115 | user_id = userId,
116 | sesi_id = lastSession.sesi_id,
117 | tanggal = DateTime.Now,
118 | bank_soal_id = newSoal.bank_soal_id
119 | };
120 |
121 | SaveHistoriTes(histori);
122 | }
123 | }
124 | }
125 | }
126 |
127 | public void SoalTerakhir(string userId, ref string msgToReplay)
128 | {
129 | var lastSession = GetLastSession(userId);
130 |
131 | if (lastSession == null)
132 | {
133 | msgToReplay = SESSION_TIMEOUT;
134 | }
135 | else
136 | {
137 | var lastSoal = GetLastSoal(lastSession.sesi_id, false, 0);
138 | if (lastSoal != null)
139 | {
140 | msgToReplay = lastSoal.BankSoal.soal + "\r\n\r\n" +
141 | "Ketik: *jawab jawaban* untuk menjawab. Contoh: *jawab a*";
142 |
143 | msgToReplay = msgToReplay.Replace("[A]", "*[A]*");
144 | msgToReplay = msgToReplay.Replace("[B]", "*[B]*");
145 | msgToReplay = msgToReplay.Replace("[C]", "*[C]*");
146 | msgToReplay = msgToReplay.Replace("[D]", "*[D]*");
147 | msgToReplay = msgToReplay.Replace("[E]", "*[E]*");
148 |
149 | msgToReplay = string.Format("*Soal Nomor {0}*", lastSoal.BankSoal.nomor_soal) + ":\r\n\r\n" +
150 | msgToReplay;
151 | }
152 | else
153 | {
154 | msgToReplay = @"Maaf soal terakhir tidak ditemukan, ketik *soal* untuk mendapatkan soal baru atau *selesai* untuk melihat hasil tes.";
155 | }
156 | }
157 | }
158 |
159 | public void Jawab(string userId, string param, ref string msgToReplay)
160 | {
161 | var lastSession = GetLastSession(userId);
162 |
163 | if (lastSession == null)
164 | {
165 | msgToReplay = SESSION_TIMEOUT;
166 | }
167 | else
168 | {
169 | if (string.IsNullOrEmpty(param))
170 | {
171 | msgToReplay = @"Maaf jawaban kosong, ketik *jawab jawaban* untuk menjawab soal. Contoh: /jawab a";
172 | }
173 | else
174 | {
175 | var lastSoal = GetLastSoal(lastSession.sesi_id);
176 | if (lastSoal != null)
177 | {
178 | lastSoal.jawaban = param.ToUpper();
179 | lastSoal.hasil_jawaban = param.ToUpper() == lastSoal.BankSoal.jawaban.ToUpper();
180 |
181 | if (lastSoal.hasil_jawaban)
182 | {
183 | msgToReplay = "Jawaban Anda benar \U0001F44D";
184 | }
185 | else
186 | {
187 | msgToReplay = string.Format("Jawaban Anda salah \U0001F61C jawaban yang benar: *{0}*", lastSoal.BankSoal.jawaban);
188 | }
189 |
190 | UpdateHistoriTes(lastSoal);
191 |
192 | msgToReplay = msgToReplay + string.Format("\r\n\r\nAnalisa/Keterangan:\r\n{0}\r\n\r\nKetik *soal* untuk mendapatkan soal baru atau *selesai* untuk melihat hasil tes.", lastSoal.BankSoal.analisa);
193 | }
194 | else
195 | {
196 | msgToReplay = SOAL_SUDAH_DIJAWAB;
197 | }
198 | }
199 | }
200 | }
201 |
202 | public void Batal(string userId, ref string msgToReplay)
203 | {
204 | var lastSession = GetLastSession(userId);
205 |
206 | if (lastSession == null)
207 | {
208 | msgToReplay = SESSION_TIMEOUT;
209 | }
210 | else
211 | {
212 | var lastSoal = GetLastSoal(lastSession.sesi_id);
213 |
214 | if (lastSoal != null)
215 | {
216 | lastSoal.batal = true;
217 | UpdateHistoriTes(lastSoal);
218 |
219 | msgToReplay = "Soal terakhir sudah dibatalkan, ketik *soal* untuk mendapatkan soal baru atau *selesai* untuk melihat hasil tes.\r\n\r\n";
220 | }
221 | else
222 | {
223 | msgToReplay = SOAL_SUDAH_DIJAWAB;
224 | }
225 | }
226 | }
227 |
228 | public void Selesai(string userId, ref string msgToReplay)
229 | {
230 | var lastSession = GetLastSession(userId);
231 |
232 | if (lastSession == null)
233 | {
234 | msgToReplay = SESSION_TIMEOUT;
235 | }
236 | else
237 | {
238 | var hasilTes = GetHasilTes(lastSession.sesi_id);
239 | var nilai = hasilTes.benar * 2.5;
240 |
241 | msgToReplay = string.Format(HASIL_TES, hasilTes.benar, hasilTes.salah, nilai);
242 |
243 | lastSession.is_timeout = true;
244 | SetTimeout(lastSession);
245 | }
246 | }
247 |
248 | private void SaveHistoriTes(HistoriTes obj)
249 | {
250 | IHistoriTesController controller = new HistoriTesController();
251 | var result = controller.Save(obj);
252 | }
253 |
254 | private void UpdateHistoriTes(HistoriTes obj)
255 | {
256 | IHistoriTesController controller = new HistoriTesController();
257 | var result = controller.Update(obj);
258 | }
259 |
260 | private BankSoal GetNewSoal(int sesiId)
261 | {
262 | IBankSoalController controller = new BankSoalController();
263 | var obj = controller.GetNewSoal(sesiId);
264 |
265 | return obj;
266 | }
267 |
268 | private HasilTes GetHasilTes(int sesiId)
269 | {
270 | IHistoriTesController controller = new HistoriTesController();
271 | var obj = controller.GetHasilTes(sesiId);
272 |
273 | return obj;
274 | }
275 |
276 | private HistoriTes GetLastSoal(int sesiId, bool cekJawaban = true, int incrementSoalNumber = 1)
277 | {
278 | IBankSoalController controller = new BankSoalController();
279 | var obj = controller.GetLastSoal(sesiId, cekJawaban, incrementSoalNumber);
280 |
281 | return obj;
282 | }
283 |
284 | private void SetTimeout(Sesi obj)
285 | {
286 | ISesiController controller = new SesiController();
287 | var result = controller.Update(obj);
288 | }
289 |
290 | private Sesi GetLastSession(string userId)
291 | {
292 | ISesiController controller = new SesiController();
293 | var obj = controller.GetLastSession(userId);
294 |
295 | return obj;
296 | }
297 |
298 | private Sesi SaveSession(string userId)
299 | {
300 | var obj = new Sesi
301 | {
302 | user_id = userId
303 | };
304 |
305 | ISesiController controller = new SesiController();
306 | var result = controller.Save(obj);
307 |
308 | return obj;
309 | }
310 | }
311 | }
312 |
--------------------------------------------------------------------------------