Time Table Fixed
This commit is contained in:
Binary file not shown.
@@ -943,3 +943,339 @@ org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (
|
|||||||
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:480)
|
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:480)
|
||||||
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:57)
|
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:57)
|
||||||
at java.base/java.lang.Thread.run(Thread.java:1447)
|
at java.base/java.lang.Thread.run(Thread.java:1447)
|
||||||
|
2026-08-20 04:52:46.342121Z database: flush
|
||||||
|
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]" [50000-240]
|
||||||
|
at org.h2.message.DbException.get(DbException.java:212)
|
||||||
|
at org.h2.message.DbException.convert(DbException.java:407)
|
||||||
|
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:122)
|
||||||
|
at org.h2.mvstore.MVStore.handleException(MVStore.java:1675)
|
||||||
|
at org.h2.mvstore.MVStore.panic(MVStore.java:502)
|
||||||
|
at org.h2.mvstore.MVStore.<init>(MVStore.java:296)
|
||||||
|
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2164)
|
||||||
|
at org.h2.mvstore.db.Store.<init>(Store.java:133)
|
||||||
|
at org.h2.engine.Database.<init>(Database.java:328)
|
||||||
|
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||||
|
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||||
|
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||||
|
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:350)
|
||||||
|
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:124)
|
||||||
|
at org.h2.Driver.connect(Driver.java:59)
|
||||||
|
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:144)
|
||||||
|
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:373)
|
||||||
|
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:210)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:488)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:576)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:97)
|
||||||
|
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:111)
|
||||||
|
at org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider.getConnection(DataSourceConnectionProvider.java:149)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:508)
|
||||||
|
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:48)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:366)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironment(JdbcEnvironmentInitiator.java:143)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:120)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:80)
|
||||||
|
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:133)
|
||||||
|
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:260)
|
||||||
|
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:235)
|
||||||
|
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:212)
|
||||||
|
at org.hibernate.boot.model.relational.Database.<init>(Database.java:44)
|
||||||
|
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:251)
|
||||||
|
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:203)
|
||||||
|
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:180)
|
||||||
|
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1388)
|
||||||
|
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.populateSessionFactoryBuilder(EntityManagerFactoryBuilderImpl.java:1468)
|
||||||
|
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1450)
|
||||||
|
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:93)
|
||||||
|
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:443)
|
||||||
|
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:436)
|
||||||
|
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:411)
|
||||||
|
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:419)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1862)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1811)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:603)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:525)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:333)
|
||||||
|
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:371)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:331)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:201)
|
||||||
|
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:977)
|
||||||
|
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:621)
|
||||||
|
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:756)
|
||||||
|
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:445)
|
||||||
|
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$2(SpringBootContextLoader.java:155)
|
||||||
|
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||||
|
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||||
|
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1465)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:600)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:155)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:114)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:247)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.lambda$loadContext$0(DefaultCacheAwareContextLoaderDelegate.java:167)
|
||||||
|
at org.springframework.test.context.cache.DefaultContextCache.put(DefaultContextCache.java:214)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:160)
|
||||||
|
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:128)
|
||||||
|
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:200)
|
||||||
|
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:139)
|
||||||
|
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
|
||||||
|
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:242)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$1(ClassBasedTestDescriptor.java:423)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:428)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$0(ClassBasedTestDescriptor.java:422)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||||
|
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:422)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$0(ClassBasedTestDescriptor.java:334)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:333)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$1(ClassBasedTestDescriptor.java:322)
|
||||||
|
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$0(ClassBasedTestDescriptor.java:321)
|
||||||
|
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:27)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:127)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:126)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:70)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$0(NodeTestTask.java:144)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:144)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:110)
|
||||||
|
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:42)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$2(NodeTestTask.java:180)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$1(NodeTestTask.java:166)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:138)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$0(NodeTestTask.java:164)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:163)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:116)
|
||||||
|
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:42)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$2(NodeTestTask.java:180)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$1(NodeTestTask.java:166)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:138)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$0(NodeTestTask.java:164)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:163)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:116)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:36)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:52)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:58)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.executeEngine(EngineExecutionOrchestrator.java:246)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.failOrExecuteEngine(EngineExecutionOrchestrator.java:218)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:179)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:66)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:157)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:65)
|
||||||
|
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:125)
|
||||||
|
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
|
||||||
|
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:58)
|
||||||
|
at org.junit.platform.launcher.core.InterceptingLauncher.lambda$execute$2(InterceptingLauncher.java:57)
|
||||||
|
at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
|
||||||
|
at org.junit.platform.launcher.core.InterceptingLauncher.execute(InterceptingLauncher.java:56)
|
||||||
|
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:58)
|
||||||
|
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
|
||||||
|
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
|
||||||
|
at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:125)
|
||||||
|
at org.apache.maven.surefire.junitplatform.LauncherAdapter.executeWithCancellationToken(LauncherAdapter.java:68)
|
||||||
|
at org.apache.maven.surefire.junitplatform.LauncherAdapter.execute(LauncherAdapter.java:54)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:203)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:168)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:136)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||||
|
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]" [50000-240]
|
||||||
|
at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
|
||||||
|
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
|
||||||
|
... 153 more
|
||||||
|
Caused by: org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]
|
||||||
|
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996)
|
||||||
|
at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143)
|
||||||
|
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117)
|
||||||
|
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81)
|
||||||
|
at org.h2.mvstore.MVStore.<init>(MVStore.java:291)
|
||||||
|
... 147 more
|
||||||
|
2026-08-20 04:52:47.925225Z database: flush
|
||||||
|
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]" [50000-240]
|
||||||
|
at org.h2.message.DbException.get(DbException.java:212)
|
||||||
|
at org.h2.message.DbException.convert(DbException.java:407)
|
||||||
|
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:122)
|
||||||
|
at org.h2.mvstore.MVStore.handleException(MVStore.java:1675)
|
||||||
|
at org.h2.mvstore.MVStore.panic(MVStore.java:502)
|
||||||
|
at org.h2.mvstore.MVStore.<init>(MVStore.java:296)
|
||||||
|
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2164)
|
||||||
|
at org.h2.mvstore.db.Store.<init>(Store.java:133)
|
||||||
|
at org.h2.engine.Database.<init>(Database.java:328)
|
||||||
|
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||||
|
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||||
|
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||||
|
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:350)
|
||||||
|
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:124)
|
||||||
|
at org.h2.Driver.connect(Driver.java:59)
|
||||||
|
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:144)
|
||||||
|
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:373)
|
||||||
|
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:210)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:488)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:576)
|
||||||
|
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:97)
|
||||||
|
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:111)
|
||||||
|
at org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider.getConnection(DataSourceConnectionProvider.java:149)
|
||||||
|
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:508)
|
||||||
|
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
|
||||||
|
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:37)
|
||||||
|
at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:61)
|
||||||
|
at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:41)
|
||||||
|
at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:36)
|
||||||
|
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:73)
|
||||||
|
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:63)
|
||||||
|
at org.hibernate.tool.schema.extract.internal.CachingDatabaseInformationImpl.<init>(CachingDatabaseInformationImpl.java:43)
|
||||||
|
at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.buildDatabaseInformation(GroupedSchemaMigratorImpl.java:112)
|
||||||
|
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:83)
|
||||||
|
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:269)
|
||||||
|
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$1(SchemaManagementToolCoordinator.java:101)
|
||||||
|
at java.base/java.util.HashMap.forEach(HashMap.java:1429)
|
||||||
|
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:100)
|
||||||
|
at org.hibernate.boot.internal.SessionFactoryObserverForSchemaExport.sessionFactoryCreated(SessionFactoryObserverForSchemaExport.java:35)
|
||||||
|
at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:33)
|
||||||
|
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:327)
|
||||||
|
at org.hibernate.internal.SessionFactoryRegistry.instantiateSessionFactory(SessionFactoryRegistry.java:64)
|
||||||
|
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:458)
|
||||||
|
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1452)
|
||||||
|
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:93)
|
||||||
|
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:443)
|
||||||
|
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:436)
|
||||||
|
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:411)
|
||||||
|
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:419)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1862)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1811)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:603)
|
||||||
|
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:525)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:333)
|
||||||
|
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:371)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:331)
|
||||||
|
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:201)
|
||||||
|
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:977)
|
||||||
|
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:621)
|
||||||
|
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:756)
|
||||||
|
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:445)
|
||||||
|
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$2(SpringBootContextLoader.java:155)
|
||||||
|
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||||
|
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||||
|
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1465)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:600)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:155)
|
||||||
|
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:114)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:247)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.lambda$loadContext$0(DefaultCacheAwareContextLoaderDelegate.java:167)
|
||||||
|
at org.springframework.test.context.cache.DefaultContextCache.put(DefaultContextCache.java:214)
|
||||||
|
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:160)
|
||||||
|
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:128)
|
||||||
|
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:200)
|
||||||
|
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:139)
|
||||||
|
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
|
||||||
|
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:242)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$1(ClassBasedTestDescriptor.java:423)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:428)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$0(ClassBasedTestDescriptor.java:422)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||||
|
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
|
||||||
|
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
|
||||||
|
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
|
||||||
|
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:422)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$0(ClassBasedTestDescriptor.java:334)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:333)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$1(ClassBasedTestDescriptor.java:322)
|
||||||
|
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||||
|
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$0(ClassBasedTestDescriptor.java:321)
|
||||||
|
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:27)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:127)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:126)
|
||||||
|
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:70)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$0(NodeTestTask.java:144)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:144)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:110)
|
||||||
|
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:42)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$2(NodeTestTask.java:180)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$1(NodeTestTask.java:166)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:138)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$0(NodeTestTask.java:164)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:163)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:116)
|
||||||
|
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:42)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$2(NodeTestTask.java:180)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$1(NodeTestTask.java:166)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:138)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$0(NodeTestTask.java:164)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:74)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:163)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:116)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:36)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:52)
|
||||||
|
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:58)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.executeEngine(EngineExecutionOrchestrator.java:246)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.failOrExecuteEngine(EngineExecutionOrchestrator.java:218)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:179)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:66)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:157)
|
||||||
|
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:65)
|
||||||
|
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:125)
|
||||||
|
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
|
||||||
|
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:58)
|
||||||
|
at org.junit.platform.launcher.core.InterceptingLauncher.lambda$execute$2(InterceptingLauncher.java:57)
|
||||||
|
at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
|
||||||
|
at org.junit.platform.launcher.core.InterceptingLauncher.execute(InterceptingLauncher.java:56)
|
||||||
|
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:58)
|
||||||
|
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
|
||||||
|
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
|
||||||
|
at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:125)
|
||||||
|
at org.apache.maven.surefire.junitplatform.LauncherAdapter.executeWithCancellationToken(LauncherAdapter.java:68)
|
||||||
|
at org.apache.maven.surefire.junitplatform.LauncherAdapter.execute(LauncherAdapter.java:54)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:203)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:168)
|
||||||
|
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:136)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||||
|
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||||
|
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]" [50000-240]
|
||||||
|
at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
|
||||||
|
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
|
||||||
|
... 157 more
|
||||||
|
Caused by: org.h2.mvstore.MVStoreException: The file is locked: /opt/projects/RITz-whatsapp-bot/db/whatsappbot.mv.db [2.4.240/7]
|
||||||
|
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996)
|
||||||
|
at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143)
|
||||||
|
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117)
|
||||||
|
at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81)
|
||||||
|
at org.h2.mvstore.MVStore.<init>(MVStore.java:291)
|
||||||
|
... 151 more
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public class StudentMenuHandler {
|
|||||||
weeklyBtn.put("id", "student_weekly_timetable");
|
weeklyBtn.put("id", "student_weekly_timetable");
|
||||||
weeklyBtn.put("title", "Weekly Timetable");
|
weeklyBtn.put("title", "Weekly Timetable");
|
||||||
buttons.add(weeklyBtn);
|
buttons.add(weeklyBtn);
|
||||||
|
System.out.println("FINAL TODAY TIMETABLE MESSAGE:\n" + todaySchedule);
|
||||||
|
|
||||||
Map<String, Object> buttonMessage = WhatsAppMessageBuilder.buildButtonMessage(todaySchedule, buttons);
|
Map<String, Object> buttonMessage = WhatsAppMessageBuilder.buildButtonMessage(todaySchedule, buttons);
|
||||||
messageService.sendInteractiveMessage(phoneNumber, buttonMessage);
|
messageService.sendInteractiveMessage(phoneNumber, buttonMessage);
|
||||||
|
|||||||
@@ -95,74 +95,136 @@ public class MessageFormatter {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String formatTimetable(String rawJson) {
|
private static class TimetableEntry {
|
||||||
|
String subjectName;
|
||||||
|
String subjectCode;
|
||||||
|
String staffName;
|
||||||
|
String staffCode;
|
||||||
|
|
||||||
|
public TimetableEntry(String subjectName, String subjectCode, String staffName, String staffCode) {
|
||||||
|
this.subjectName = subjectName != null ? subjectName.trim() : "";
|
||||||
|
this.subjectCode = subjectCode != null ? subjectCode.trim() : "";
|
||||||
|
this.staffName = staffName != null ? staffName.trim() : "";
|
||||||
|
this.staffCode = staffCode != null ? staffCode.trim() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return !subjectName.isEmpty() && !subjectCode.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUniqueKey() {
|
||||||
|
return subjectName + "||" + subjectCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatTodayTimetable(String rawJson) {
|
||||||
|
String day = java.time.LocalDate.now()
|
||||||
|
.getDayOfWeek()
|
||||||
|
.getDisplayName(java.time.format.TextStyle.FULL, java.util.Locale.ENGLISH)
|
||||||
|
.toLowerCase(java.util.Locale.ROOT);
|
||||||
|
return formatTodayTimetableForDay(rawJson, day);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatTodayTimetableForDay(String rawJson, String day) {
|
||||||
if (rawJson == null) return "❌ Failed to retrieve timetable data.";
|
if (rawJson == null) return "❌ Failed to retrieve timetable data.";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JsonNode root = mapper.readTree(rawJson);
|
JsonNode root = mapper.readTree(rawJson);
|
||||||
|
if (!root.has("data") || !root.get("data").isObject() || !root.get("data").has("schedule")) {
|
||||||
|
return "❌ Timetable details not available in this format.";
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode schedule = root.get("data").get("schedule");
|
||||||
|
|
||||||
|
System.out.println("TIMETABLE DEBUG");
|
||||||
|
System.out.println("Current day: " + day.toUpperCase());
|
||||||
|
System.out.println("Normalized day: " + day);
|
||||||
|
boolean hasSchedule = schedule.has(day);
|
||||||
|
System.out.println("Schedule found: " + hasSchedule);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("\ud83d\uddd3\ufe0f *Today's Classes*\n\n");
|
sb.append("📅 *Today's Classes*\n");
|
||||||
|
sb.append("━━━━━━━━━━━━━━\n\n");
|
||||||
|
|
||||||
boolean validFormat = false;
|
if (hasSchedule) {
|
||||||
boolean hasClassesToday = false;
|
JsonNode daySchedule = schedule.get(day);
|
||||||
|
|
||||||
if (root.has("data") && root.get("data").isObject() && root.get("data").has("schedule")) {
|
int maxPeriod = 7;
|
||||||
validFormat = true;
|
java.util.Iterator<String> fieldNames = daySchedule.fieldNames();
|
||||||
JsonNode schedule = root.get("data").get("schedule");
|
java.util.List<String> foundPeriods = new java.util.ArrayList<>();
|
||||||
|
while (fieldNames.hasNext()) {
|
||||||
|
String fName = fieldNames.next();
|
||||||
|
foundPeriods.add(fName);
|
||||||
|
try {
|
||||||
|
int p = Integer.parseInt(fName);
|
||||||
|
if (p > maxPeriod) {
|
||||||
|
maxPeriod = p;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
|
System.out.println("Periods found: [" + String.join(", ", foundPeriods) + "]");
|
||||||
|
|
||||||
String today = java.time.LocalDate.now().getDayOfWeek().toString().toLowerCase();
|
for (int period = 1; period <= maxPeriod; period++) {
|
||||||
|
String periodKey = String.valueOf(period);
|
||||||
|
sb.append(getNumberEmoji(period)).append(" ");
|
||||||
|
|
||||||
if (schedule.has(today)) {
|
if (daySchedule.has(periodKey)) {
|
||||||
JsonNode todaySchedule = schedule.get(today);
|
JsonNode periodNode = daySchedule.get(periodKey);
|
||||||
|
java.util.List<TimetableEntry> entries = new java.util.ArrayList<>();
|
||||||
|
|
||||||
if (todaySchedule.isObject() && todaySchedule.size() > 0) {
|
if (periodNode.isArray()) {
|
||||||
java.util.Iterator<java.util.Map.Entry<String, JsonNode>> fields = todaySchedule.fields();
|
for (JsonNode node : periodNode) {
|
||||||
while (fields.hasNext()) {
|
String sName = node.has("subjectName") ? node.get("subjectName").asText() : "";
|
||||||
java.util.Map.Entry<String, JsonNode> field = fields.next();
|
String sCode = node.has("subjectCode") ? node.get("subjectCode").asText() : "";
|
||||||
String timeOrPeriod = field.getKey();
|
String stName = node.has("staffName") ? node.get("staffName").asText() : "";
|
||||||
JsonNode details = field.getValue();
|
String stCode = node.has("staffCode") ? node.get("staffCode").asText() : "";
|
||||||
|
entries.add(new TimetableEntry(sName, sCode, stName, stCode));
|
||||||
if (details.isObject()) {
|
|
||||||
String course = details.has("course_name") ? details.get("course_name").asText() :
|
|
||||||
(details.has("name") ? details.get("name").asText() : "Unknown");
|
|
||||||
String room = details.has("room") ? details.get("room").asText() : "";
|
|
||||||
|
|
||||||
sb.append("*").append(timeOrPeriod).append(":* ").append(course);
|
|
||||||
if (!room.isEmpty()) sb.append(" (Room ").append(room).append(")");
|
|
||||||
sb.append("\n");
|
|
||||||
} else {
|
|
||||||
sb.append("*").append(timeOrPeriod).append(":* ").append(details.asText()).append("\n");
|
|
||||||
}
|
}
|
||||||
hasClassesToday = true;
|
|
||||||
}
|
}
|
||||||
} else if (todaySchedule.isArray() && todaySchedule.size() > 0) {
|
|
||||||
for (JsonNode details : todaySchedule) {
|
|
||||||
String time = details.has("time") ? details.get("time").asText() : "TBA";
|
|
||||||
String course = details.has("course_name") ? details.get("course_name").asText() : "Unknown";
|
|
||||||
String room = details.has("room") ? details.get("room").asText() : "";
|
|
||||||
|
|
||||||
sb.append("*").append(time).append(":* ").append(course);
|
System.out.println("Period " + period + " entries: " + entries.size());
|
||||||
if (!room.isEmpty()) sb.append(" (Room ").append(room).append(")");
|
if (!entries.isEmpty()) {
|
||||||
sb.append("\n");
|
TimetableEntry first = entries.get(0);
|
||||||
hasClassesToday = true;
|
System.out.println("Period " + period + " first subjectName: " + first.subjectName);
|
||||||
|
System.out.println("Period " + period + " first subjectCode: " + first.subjectCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
java.util.Map<String, TimetableEntry> uniqueMap = new java.util.LinkedHashMap<>();
|
||||||
|
for (TimetableEntry entry : entries) {
|
||||||
|
if (entry.isValid()) {
|
||||||
|
uniqueMap.putIfAbsent(entry.getUniqueKey(), entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uniqueMap.isEmpty()) {
|
||||||
|
java.util.List<String> formattedSubjects = new java.util.ArrayList<>();
|
||||||
|
for (TimetableEntry entry : uniqueMap.values()) {
|
||||||
|
formattedSubjects.add("*" + entry.subjectName + "*\n `" + entry.subjectCode + "`");
|
||||||
|
}
|
||||||
|
sb.append(String.join(" / ", formattedSubjects)).append("\n\n");
|
||||||
|
} else {
|
||||||
|
sb.append("*Free Period*\n\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sb.append("*Free Period*\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sb.append("No classes scheduled for today.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validFormat && !hasClassesToday) {
|
sb.append("━━━━━━━━━━━━━━");
|
||||||
sb.append("No classes scheduled for today.\n");
|
|
||||||
} else if (!validFormat) {
|
|
||||||
sb.append("Details not available in this format.\n");
|
|
||||||
sb.append("\n\n*DEBUG RAW JSON:*\n").append(rawJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return "⚠️ Error formatting timetable data.\nRAW JSON: " + rawJson;
|
System.err.println("Error formatting today's timetable: " + e.getMessage());
|
||||||
|
return "⚠️ Error formatting timetable data.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatTimetable(String rawJson) {
|
||||||
|
return formatTodayTimetable(rawJson);
|
||||||
|
}
|
||||||
|
|
||||||
public static String formatResults(String rawJson, int semester) {
|
public static String formatResults(String rawJson, int semester) {
|
||||||
if (rawJson == null) return "❌ Failed to retrieve semester results.";
|
if (rawJson == null) return "❌ Failed to retrieve semester results.";
|
||||||
|
|
||||||
@@ -444,76 +506,105 @@ public class MessageFormatter {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getNumberEmoji(int num) {
|
||||||
|
switch (num) {
|
||||||
|
case 1: return "1️⃣";
|
||||||
|
case 2: return "2️⃣";
|
||||||
|
case 3: return "3️⃣";
|
||||||
|
case 4: return "4️⃣";
|
||||||
|
case 5: return "5️⃣";
|
||||||
|
case 6: return "6️⃣";
|
||||||
|
case 7: return "7️⃣";
|
||||||
|
case 8: return "8️⃣";
|
||||||
|
case 9: return "9️⃣";
|
||||||
|
default: return num + "️⃣";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String formatWeeklyTimetable(String rawJson) {
|
public static String formatWeeklyTimetable(String rawJson) {
|
||||||
if (rawJson == null) return "❌ Failed to retrieve weekly timetable data.";
|
if (rawJson == null) return "❌ Failed to retrieve weekly timetable data.";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JsonNode root = mapper.readTree(rawJson);
|
JsonNode root = mapper.readTree(rawJson);
|
||||||
|
|
||||||
if (!root.has("data") || !root.get("data").isObject() || !root.get("data").has("schedule")) {
|
if (!root.has("data") || !root.get("data").isObject() || !root.get("data").has("schedule")) {
|
||||||
return "❌ Weekly timetable details not available in the response.";
|
return "❌ Weekly timetable details not available in the response.";
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode schedule = root.get("data").get("schedule");
|
JsonNode schedule = root.get("data").get("schedule");
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("📅 *Weekly Class Timetable*\n\n");
|
sb.append("📚 WEEKLY TIMETABLE\n\n");
|
||||||
sb.append("```\n");
|
|
||||||
sb.append(String.format("%-3s | %-11s | %s\n", "Day", "Time/Period", "Subject (Room)"));
|
|
||||||
sb.append("----+-------------+------------------------\n");
|
|
||||||
|
|
||||||
String[] days = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
|
String[] days = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
|
||||||
String[] dayAbbrevs = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
String[] dayLabels = {"MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
||||||
boolean hasAnyClasses = false;
|
boolean hasAnyClasses = false;
|
||||||
|
|
||||||
for (int i = 0; i < days.length; i++) {
|
for (int i = 0; i < days.length; i++) {
|
||||||
String day = days[i];
|
String day = days[i];
|
||||||
String abbrev = dayAbbrevs[i];
|
String label = dayLabels[i];
|
||||||
|
|
||||||
if (schedule.has(day)) {
|
if (schedule.has(day)) {
|
||||||
JsonNode daySchedule = schedule.get(day);
|
JsonNode daySchedule = schedule.get(day);
|
||||||
|
|
||||||
if (daySchedule.isObject() && daySchedule.size() > 0) {
|
sb.append(label).append("\n");
|
||||||
java.util.Iterator<java.util.Map.Entry<String, JsonNode>> fields = daySchedule.fields();
|
|
||||||
while (fields.hasNext()) {
|
|
||||||
java.util.Map.Entry<String, JsonNode> field = fields.next();
|
|
||||||
String timeOrPeriod = field.getKey();
|
|
||||||
JsonNode details = field.getValue();
|
|
||||||
|
|
||||||
String course = "";
|
int maxPeriod = 7;
|
||||||
String room = "";
|
java.util.Iterator<String> fieldNames = daySchedule.fieldNames();
|
||||||
if (details.isObject()) {
|
while (fieldNames.hasNext()) {
|
||||||
course = details.has("course_name") ? details.get("course_name").asText() :
|
try {
|
||||||
(details.has("name") ? details.get("name").asText() : "Unknown");
|
int p = Integer.parseInt(fieldNames.next());
|
||||||
room = details.has("room") ? details.get("room").asText() : "";
|
if (p > maxPeriod) {
|
||||||
} else {
|
maxPeriod = p;
|
||||||
course = details.asText();
|
}
|
||||||
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int period = 1; period <= maxPeriod; period++) {
|
||||||
|
String periodKey = String.valueOf(period);
|
||||||
|
sb.append(getNumberEmoji(period)).append(" ");
|
||||||
|
|
||||||
|
if (daySchedule.has(periodKey)) {
|
||||||
|
JsonNode details = daySchedule.get(periodKey);
|
||||||
|
java.util.Set<String> subjects = new java.util.LinkedHashSet<>();
|
||||||
|
|
||||||
|
if (details.isArray()) {
|
||||||
|
for (JsonNode entry : details) {
|
||||||
|
String name = entry.has("subjectName") ? entry.get("subjectName").asText() : "";
|
||||||
|
String code = entry.has("subjectCode") ? entry.get("subjectCode").asText() : "";
|
||||||
|
if (!name.trim().isEmpty()) {
|
||||||
|
subjects.add(name.trim() + " — " + code.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (details.isObject()) {
|
||||||
|
String name = details.has("course_name") ? details.get("course_name").asText() :
|
||||||
|
(details.has("name") ? details.get("name").asText() :
|
||||||
|
(details.has("subjectName") ? details.get("subjectName").asText() : ""));
|
||||||
|
String code = details.has("course_code") ? details.get("course_code").asText() :
|
||||||
|
(details.has("code") ? details.get("code").asText() :
|
||||||
|
(details.has("subjectCode") ? details.get("subjectCode").asText() : ""));
|
||||||
|
if (!name.trim().isEmpty()) {
|
||||||
|
subjects.add(name.trim() + " — " + code.trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String subjectRoom = room.isEmpty() ? course : course + " (" + room + ")";
|
if (!subjects.isEmpty()) {
|
||||||
sb.append(String.format("%-3s | %-11s | %s\n", abbrev, truncate(timeOrPeriod, 11), subjectRoom));
|
sb.append(String.join(" / ", subjects)).append("\n");
|
||||||
hasAnyClasses = true;
|
hasAnyClasses = true;
|
||||||
}
|
} else {
|
||||||
} else if (daySchedule.isArray() && daySchedule.size() > 0) {
|
sb.append("—\n");
|
||||||
for (JsonNode details : daySchedule) {
|
}
|
||||||
String time = details.has("time") ? details.get("time").asText() : "TBA";
|
} else {
|
||||||
String course = details.has("course_name") ? details.get("course_name").asText() : "Unknown";
|
sb.append("—\n");
|
||||||
String room = details.has("room") ? details.get("room").asText() : "";
|
|
||||||
|
|
||||||
String subjectRoom = room.isEmpty() ? course : course + " (" + room + ")";
|
|
||||||
sb.append(String.format("%-3s | %-11s | %s\n", abbrev, truncate(time, 11), subjectRoom));
|
|
||||||
hasAnyClasses = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append("```");
|
|
||||||
|
|
||||||
if (!hasAnyClasses) {
|
if (!hasAnyClasses) {
|
||||||
return "📅 *Weekly Class Timetable*\n\nNo classes scheduled for this week.";
|
return "📚 WEEKLY TIMETABLE\n\nNo classes scheduled for this week.";
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString().trim();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return "⚠️ Error formatting weekly timetable data.";
|
return "⚠️ Error formatting weekly timetable data.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,4 @@ spring.h2.console.enabled=true
|
|||||||
|
|
||||||
# Encryption Secret for Passcodes (Must be 16, 24, or 32 bytes)
|
# Encryption Secret for Passcodes (Must be 16, 24, or 32 bytes)
|
||||||
bot.encryption.secret=12345678901234567890123456789012
|
bot.encryption.secret=12345678901234567890123456789012
|
||||||
whatsapp.api-token=EAAc3Wjql00oBSdoBhXozC8gKyWN9Il6cqpjvE531hZAnuFqOfHCuCBGt8hYZCICzm2dnXsH2RR3HIi3dpZAZBbNFE9Xj8Hvs3TS94nHrmxevicgThlqSQDjZCDm6SS1qFvt7NwRjiy1TWtZCuLLvcTxyjjNPUtjt91OZBr5DtddHzESLezP6R3oJEzIhSjLqlRAvNwfhW8wDYiCkkx0Qw69iO2UeodHw5E8Q86kZCPEvocldDZCyb7qZCMZAELPbYJYkWVLk8MjVyZAXjmnoGFnS5n4ZAsXBE
|
whatsapp.api-token=EAAc3Wjql00oBSUjYhQ1TZBiNJNmwNlpktCtJpqSLXycDVjWjPiP5dBWHvvFX2Deq1tGXQO2jgVOGChnJk9jsMxLVdxvUs4z7g7xlfcQtAPYiHwvQbPVSbGTTCBvjv2IvHf7Ql2iNBKL72GZCrxAJrQpmjHUG5sbQkVWmMpNfwgI52iDBw0BifU1QhQHFEOnQfiPu19KUp3hJOg6XkUbbXyfBKvbSkZB57xj0XHMv6wgpqDrQwAACOjSlSPrNEC3eZB9DbZAqWYnPkJCsX99Pz3GhA
|
||||||
|
|||||||
@@ -10,4 +10,46 @@ class WhatsappBotApplicationTests {
|
|||||||
void contextLoads() {
|
void contextLoads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFormatTodayTimetableThursday() {
|
||||||
|
String thursdayJson = "{\n" +
|
||||||
|
" \"success\": true,\n" +
|
||||||
|
" \"data\": {\n" +
|
||||||
|
" \"schedule\": {\n" +
|
||||||
|
" \"thursday\": {\n" +
|
||||||
|
" \"1\": [{\"subjectName\":\"Business Analytics\",\"subjectCode\":\"CB23531\",\"staffName\":\"FOUZIA SULTHANA K.\",\"staffCode\":\"CS84\"}],\n" +
|
||||||
|
" \"2\": [{\"subjectName\":\"Computer Networks\",\"subjectCode\":\"CS23511\",\"staffName\":\"SELVAKUMARAN S.\",\"staffCode\":\"CS91\"}],\n" +
|
||||||
|
" \"3\": [\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"DIVYA S\",\"staffCode\":\"CS193\"},\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"SARANYA S.\",\"staffCode\":\"CS85\"},\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"DR.VIDHYA M\",\"staffCode\":\"CS256\"},\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"SANDHIYARAJESHWARI K\",\"staffCode\":\"CS153\"},\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"MONIKAA R\",\"staffCode\":\"CS178\"},\n" +
|
||||||
|
" {\"subjectName\":\"Deep Learning\",\"subjectCode\":\"AD23511\",\"staffName\":\"ARTHI A.\",\"staffCode\":\"CS87\"}\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"4\": [{\"subjectName\":\"Image and Video Analytics\",\"subjectCode\":\"AD23V15\",\"staffName\":\"JOEL J\",\"staffCode\":\"CS226\"}],\n" +
|
||||||
|
" \"5\": [{\"subjectName\":\"Big Data Analytics\",\"subjectCode\":\"AD23V12\",\"staffName\":\"KAVITHA V\",\"staffCode\":\"CS253\"}],\n" +
|
||||||
|
" \"6\": [\n" +
|
||||||
|
" {\"subjectName\":\"Data Exploration and Visualization\",\"subjectCode\":\"AD23532\",\"staffName\":\"DR.VIDHYA M\",\"staffCode\":\"CS256\"},\n" +
|
||||||
|
" {\"subjectName\":\"Data Exploration and Visualization\",\"subjectCode\":\"AD23532\",\"staffName\":\"DR.VIDHYA M\",\"staffCode\":\"CS256\"}\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"7\": [{\"subjectName\":\"\",\"subjectCode\":\"\",\"staffName\":\"FOUZIA SULTHANA K.\",\"staffCode\":\"CS84\"}]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String formatted = com.rit.whatsapp.util.MessageFormatter.formatTodayTimetableForDay(thursdayJson, "thursday");
|
||||||
|
System.out.println("Formatted output:\n" + formatted);
|
||||||
|
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("📅 *Today's Classes*"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("1️⃣ *Business Analytics*\n `CB23531`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("2️⃣ *Computer Networks*\n `CS23511`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("3️⃣ *Deep Learning*\n `AD23511`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("4️⃣ *Image and Video Analytics*\n `AD23V15`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("5️⃣ *Big Data Analytics*\n `AD23V12`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("6️⃣ *Data Exploration and Visualization*\n `AD23532`"));
|
||||||
|
org.junit.jupiter.api.Assertions.assertTrue(formatted.contains("7️⃣ *Free Period*"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user