diff --git a/README.md b/README.md
index 0d9bc48..4b26092 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,11 @@
-**Nibras PKM** is a __web-based self-hosted open source__ system for the __long-term management__ of __personal__ information. It is a combination of a __web-based__ application intended for desktop use and where all the records are entered, and an Android __reader and note taker__ application.
+**Nibras PKM** is a __web-based self-hosted open source__ system for
+ the __long-term management__ of __personal__ information.
+ It is a combination of a __web-based__ application
+ intended for desktop use and where all the records are entered,
+ and an Android __mobile__ reader application.
![](https://raw.githubusercontent.com/mfakih294/Nibras-PKM/master/docs/images/screenshot.jpg)
@@ -25,7 +29,7 @@ It manages resources (articles, books, documents), notes, writings, tasks, goals
It was designed with large amounts of information in mind. In current usage, it manages dozens of thousands of records. With its commands and saved searches, it makes easy to navigate through all the information.
-# Features
+## Main Features
* **Flexible text-based commands** to add, update and search records, which provides powerful ways to manage information.
* **Saved searches** to save searches for later use.
@@ -38,7 +42,7 @@ It was designed with large amounts of information in mind. In current usage, it
## Documentation
-Documentation is available online at [https://mfakih294.github.io/Nibras-PKM/pages](https://mfakih294.github.io/Nibras-PKM/pages/).
+User's guide is available online at [https://mfakih294.github.io/Nibras-PKM/](https://mfakih294.github.io/Nibras-PKM/).
## Releases
diff --git a/build.gradle b/build.gradle
index 45728a5..efe1cac 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,3 +1,8 @@
+def esVersion = '7.3.0'
+ext['elasticsearch.version'] = esVersion
+ext {
+ elasticsearchVersion = esVersion
+}
buildscript {
repositories {
mavenLocal()
@@ -49,6 +54,8 @@ dependencies {
// compile files("lib/commons-logging-1.1.1.jar")
// compile files("lib/icu4j.jar")
//compile group: 'com.ibm.icu', name: 'icu4j', version: '68.2'
+// compile group: 'com.ibm.icu', name: 'icu4j', version: '68.2'
+// group=‘com.ibm.icu’, module=‘icu4j’, version=‘58.2’)
// compile files("lib/jpwgen-1.0.3.jar")
// compile files("lib/json-20140107.jar")
// compile files("lib/lombok-1.16.16.jar")
@@ -94,8 +101,12 @@ dependencies {
compile "org.grails.plugins:events"
compile "org.grails.plugins:hibernate5"
compile "org.hibernate:hibernate-core:5.1.16.Final"
+// compile "org.hibernate:hibernate-ehcache:5.1.16.Final" todo: needed?
compile "org.grails.plugins:gsp"
+ // ok compile group: 'org.apache.lucene', name: 'lucene-core', version: '8.1.0'
+ // compile 'org.grails.plugins:elasticsearch:2.7.0.RC1'
+// ok runtime 'org.elasticsearch.plugin:mapper-attachments:2.4.6'
// compile "org.grails.plugins:elasticsearch:2.4.0"
@@ -104,10 +115,11 @@ dependencies {
compile group: 'com.cronutils', name: 'cron-utils', version: '9.0.2'
// https://mvnrepository.com/artifact/com.intuit.fuzzymatcher/fuzzy-matcher
- compile group: 'com.intuit.fuzzymatcher', name: 'fuzzy-matcher', version: '1.0.4'
+ compile group: 'com.intuit.fuzzymatcher', name: 'fuzzy-matcher', version: '1.1.0'
// compile group: 'org.eclipse.mylyn.docs', name: 'org.eclipse.mylyn.wikitext.markdown.core', version: '2.6.0.v20150901-2143'
compile 'com.vladsch.flexmark:flexmark-all:0.62.2'
+ implementation 'org.jsoup:jsoup:1.15.3'
// other plugins
compile "com.nayidisha.grails.uploadr:grails3-uploadr:3.0"
@@ -119,9 +131,11 @@ dependencies {
compile 'org.grails.plugins:external-config:1.4.0'
- compile 'org.grails.plugins:quartz:2.0.13'
+ compile 'org.grails.plugins:quartz:2.0.9'
- //compile "org.grails.plugins:feeds:1.6"
+// compile "org.grails.plugins:feeds:1.6"
+ // todo: fix its range dependencies
+// compile 'org.grails.plugins:feeds:2.0.0'
compile 'org.grails.plugins:feeds:2.0.0-SNAPSHOT'
compile 'org.grails.plugins:spring-security-core:3.2.3'
@@ -142,6 +156,8 @@ dependencies {
//runtime 'mysql-connector-java:5.1.18'
runtime group: 'mysql', name: 'mysql-connector-java', version: '8.0.19'
+ runtime 'org.apache.derby:derby:10.14.2.0'
+
//compile "com.bertramlabs.plugins:asset-pipeline-grails:2.15.1"
// testCompile "org.grails:grails-gorm-testing-support"
diff --git a/docs/10.md b/docs/10.md
old mode 100644
new mode 100755
index 7ed1ff5..d4e178f
--- a/docs/10.md
+++ b/docs/10.md
@@ -88,6 +88,12 @@ username="nibras-user" password="the-password"/>`
after chaning the username and password of the account to use to access the database.
+mysql -u username -p
+execute:
+mysql
+create user 'nibras'@'%' identified by 'nibras';
+
+grant all privileges on *.* to 'nibras'@'%' with grant option;
1. install the database server MySQL, and create the database to be used by Nibras.
diff --git a/docs/README.md b/docs/README.md
new file mode 100755
index 0000000..948d539
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,85 @@
+# Nibras PKM
+
+**Nibras PKM** is a __local open source__ system for the __long-term management__ of __personal__ information. It is a combination of a __web-based__ application intended for desktop use and where all the records are entered, and an Android __mobile__ reader application.
+
+![](https://raw.githubusercontent.com/mfakih294/Nibras-PKM/master/docs/images/screenshot.jpg)
+
+
+**Local**
+
+The user has full control over his/her data, without the need for a (fast) internet connection, and without all the distractions and information overload that the internet can cause.
+
+**Open source**
+
+The user has control over the system itself too, especially when using it on the long term to manage the important personal information and files.
+
+**Comprehensize**
+
+It manages resources (articles, books, documents), notes, writings, tasks, goals, journal, planner, payments, indicators, and (study) courses and departments.
+
+**Powerful**
+
+It was designed with large amounts of information in mind. In current usage, it manages dozens of thousands of records. With its commands and saved searches, it makes easy to navigate through all the information.
+
+## Main Features
+
+* **Flexible text-based commands** to add, update and search records, which provides powerful ways to manage information.
+* **Saved searches** to save searches for later use.
+* Ability to display records on calendars and Kanban boards.
+* Full-text search of all record fields.
+* Simple file system integration so to greatly reduce the need to organize files manually.
+
+## Documentation
+
+User's guide is available online at [https://mfakih294.github.io/Nibras-PKM/](https://mfakih294.github.io/Nibras-PKM/).
+
+## Code, releases and issues
+
+Nibras PKM is hosted on GitHub [https://github.com/mfakih294/Nibras-PKM](https://github.com/mfakih294/Nibras-PKM).
+
+## Quick start guide
+
+Running Nibras requires three simple steps:
+
+- Download the bundle file corresponding to your platform, e.g. nibras-bundle-windows.zip from the [releases page](https://github.com/mfakih294/Nibras-PKM/releases) on Github.
+- Extract the zipped file to a location of your choice on your local disk.
+- Launch Nibras by double clicking on ./scripts/start file.
+
+Once Nibras has finished launching, a message like the one below will appear.
+
+`************************************************************`
+
+`* Nibras has launched. You can access it from: *`
+
+`* https://localhost:1441/nibras *`
+
+`************************************************************`
+
+Go to **https://localhost:1441/nibras** using Firefox or Chrome. On the login page, enter *nibras* for username and *nibras* for the password.
+
+Notes:
+- As it has a self-signed certificate, you need to accept and bypass the security warning that shows up at the beginning.
+- On Linux, you need to make the files inside ./scripts and ./tomcat/bin folders executable (chmod +x *).
+- To stop Nibras, you can close this window, or press ctrl+c in it, or run ./scripts/stop script.
+
+## Technical details
+
+* Nibras is developed in Grails framework 3.3.10, which is based on Groovy language, a dynamic language on top of the Java platform.
+* Grails applications run on any platform that can run Java 8 and later, so practically all platforms, including Windows, Linux, Mac.
+* For production use, Nibras uses MySQL 5 for its database, and the file system to store the files of the records. To testing and demonstration, you can run it with h2 database, with no need to configure it.
+* Apache Tomcat 8+ is the recommended application server to run it for production use.
+
+
+## Nibras Reader
+
+
+* **Nibras Reader** is available as a companion Android application to Nibras. It that connects to a Nibras PKM system (e.g. on the same WIFI network), and syncs the bookmarked records in it, so you can read them without network access whenever you go.
+
+* It also allows the user to enter quick one-line notes that will be synced to Nibras Desktop on user's choice.
+
+* To use Nibras Reader, the user has to specify first the IP and port of Nibras PKM (found on the footer region). Then, when clicking 'Sync', all bookmarked records will be available for reading on mobile.
+
+* To install it, copy the bundled .apk file to your Android phone, and install it, or get it from its Github page: [https://github.com/mfakih294/nibras-mobile](https://github.com/mfakih294/nibras-mobile).
+
+![homepage](./images/nibras-mobile-homepage.jpg)
+
diff --git a/docs/index.md b/docs/index.md
index 0d9bc48..55b0607 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -3,7 +3,8 @@
-**Nibras PKM** is a __web-based self-hosted open source__ system for the __long-term management__ of __personal__ information. It is a combination of a __web-based__ application intended for desktop use and where all the records are entered, and an Android __reader and note taker__ application.
+**Nibras PKM** is a __web-based self-hosted open source__ system for
+the __long-term management__ of __personal__ information. It is a combination of a __web-based__ application intended for desktop use and where all the records are entered, and an Android __reader and note taker__ application.
![](https://raw.githubusercontent.com/mfakih294/Nibras-PKM/master/docs/images/screenshot.jpg)
@@ -36,9 +37,9 @@ It was designed with large amounts of information in mind. In current usage, it
-## Documentation
+## User's guide
-Documentation is available online at [https://mfakih294.github.io/Nibras-PKM/pages](https://mfakih294.github.io/Nibras-PKM/pages/).
+User's guide is available online at [https://mfakih294.github.io/Nibras-PKM/pages](https://mfakih294.github.io/Nibras-PKM/pages/).
## Releases
@@ -67,12 +68,14 @@ Notes:
- On Linux, you need to make the files inside ./scripts and ./tomcat/bin folders executable (chmod +x *).
- To stop Nibras, you can close this window, or press ctrl+c in it, or run ./scripts/stop script.
-
## Technical details
-* Nibras is developed in Grails framework 3.3.10, a dynamic framework on top of the Java platform.
+* Nibras is developed in Grails framework 3.3.10, a dynamic web framework on top of the Java platform.
* Grails applications run on any platform that can run Java 8 and later, so practically all platforms, including Windows, Linux, Mac.
-* For production use, Nibras uses MySQL 5+ for its database, and the file system to store the files of the records. To testing and demonstration, it can run with h2 database, with zero extra configuration.
+* For production use, Nibras uses MySQL 5+ for its database, and the file system to store the files of the records. To testing and demonstration, you can run it with h2 database, with zera extra configurion.
+* Apache Tomcat 8+ is the recommended application server to run it for production use.
+
+
* Apache Tomcat 8+ is the recommended application server to run it for production use.
* The bundled distribution comes with Tomcat 8 and runs with a h2 database.
diff --git a/grails-app/conf/application.groovy b/grails-app/conf/application.groovy
old mode 100644
new mode 100755
index 8fdbcf1..a168a49
--- a/grails-app/conf/application.groovy
+++ b/grails-app/conf/application.groovy
@@ -23,6 +23,17 @@ grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/json/**', access: ['permitAll']], // working! 19.07.2019
[pattern: '**/json/**', access: ['permitAll']], // working! 19.07.2019
+ [pattern: '**/jabal-amel/**', access: ['permitAll']],
+ [pattern: '*/jabal-amel/**', access: ['permitAll']],
+ [pattern: '/jabal-amel/**', access: ['permitAll']],
+ [pattern: '**/indexCard/generateWritingsBook/**', access: ['permitAll']],
+ [pattern: '**/staticPage/**', access: ['permitAll']],
+ [pattern: '**/viewRecordImage/**/**', access: ['permitAll']],
+ [pattern: '*/*/viewRecordImage/**/*', access: ['permitAll']],
+ [pattern: '**/generics/viewRecordImage/**', access: ['permitAll']],
+ [pattern: '**/staticRecord/**', access: ['permitAll']],
+ [pattern: '**/download/**', access: ['permitAll']],
+ [pattern: '**//jabal-amel/**', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/js/**', access: ['permitAll']],
[pattern: '/**/plugins/**', access: ['permitAll']],
@@ -34,9 +45,11 @@ grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/**/filed/**', access: ['permitAll']],
[pattern: '/**/download/**', access: ['permitAll']],
[pattern: '/**/page/mobile*/**', access: ['permitAll']],
-
+ [pattern: '/**/page/appPile*/**', access: ['permitAll']],
+ [pattern: '/**/page/panel*/**', access: ['permitAll']],
[pattern: '/**/sync/**', access: ['permitAll']],
[pattern: '/**/css/**', access: ['permitAll']],
+ [pattern: '/**/layout/**', access: ['permitAll']],
[pattern: '/**/kickstart/**', access: ['permitAll']],
[pattern: '/**/file-icons/**', access: ['permitAll']],
// [pattern: '/**/slides/**', access: ['permitAll']],
@@ -46,12 +59,20 @@ grails.plugin.springsecurity.controllerAnnotations.staticRules = [
]
grails.plugin.springsecurity.filterChain.chainMap = [
+ [pattern: '/jabal-amel/**', filters: 'none'],
[pattern: '/assets/**', filters: 'none'],
[pattern: '/page/heartbeat*/**', filters: 'none'],
[pattern: '/page/mobile*/**', filters: 'none'],
[pattern: '/sync/**', filters: 'none'],
[pattern: '**/sync/**', filters: 'none'],
[pattern: '/**/download/**', filters: 'none'],
+ [pattern: '/**/generateWritingsBook/**', filters: 'none'],
+ [pattern: '**/generics/viewRecordImage/**', filters: 'none'],
+ [pattern: '/**/generics/viewRecordImage/**', filters: 'none'],
+ [pattern: '**/viewRecordImage/**', filters: 'none'],
+ [pattern: '/**/viewRecordImage/**', filters: 'none'],
+ [pattern: '/**/staticPage/**', filters: 'none'],
+ [pattern: '/**/download/**', filters: 'none'],
[pattern: '/**/filed/**', filters: 'none'],
[pattern: '/json/**', filters: 'none'],
[pattern: '/**/js/**', filters: 'none'],
@@ -91,3 +112,16 @@ environments {
grails.dbconsole.enabled = true
}
}
+elasticSearch.datastoreImpl = 'hibernateDatastore'
+elasticSearch.client.mode = 'local'
+elasticSearch.migration.strategy = 'delete'
+elasticSearch.disableAutoIndex = false
+elasticSearch.bulkIndexOnStartup = true
+//grails.app.enable.reload = true
+//grails.gsp.view.dir = "/nibras/sys/views"
+
+//log4j = { // not here
+// trace 'org.hibernate.type.descriptor.sql.BasicBinder'
+// error 'org.hibernate.SQL'
+// debug 'grails.app.controllers'
+//}
\ No newline at end of file
diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml
old mode 100644
new mode 100755
index eca0b14..5394404
--- a/grails-app/conf/application.yml
+++ b/grails-app/conf/application.yml
@@ -24,8 +24,8 @@ info:
version: 1.9.1
grailsVersion: '@info.app.grailsVersion@'
server:
- contextPath: '/'
- port: 1441 # The port to listen on
+ contextPath: '/nibras' # ContextPath must start with '/' and not end with '/'
+ port: 1445 # The port to listen on
session:
timeout: 720000 # 20 hours (in ms)
ssl:
@@ -112,14 +112,15 @@ hibernate:
flush:
mode: AUTO
environments:
- h2:
+ h2: #h2
grails.dbconsole:
enabled: true
# urlRoot: ${appName}/dbc
dataSource:
dbCreate: update
- url: jdbc:h2:./db/db;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;
- dialect: com.hp.opr.hibernate.dialect.H2Dialect
+ url: jdbc:h2:./db/db;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE; # MODE=MySQL
+ dialect: org.hibernate.dialect.H2Dialect
+ #org.hibernate.dialect.HSQLDialect # com.hp.opr.hibernate.dialect. # H2Dialect (MODE=MySQL; not supported in h2dialect)
driverClassName: org.h2.Driver
properties:
jmxEnabled: true
@@ -139,14 +140,24 @@ environments:
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
+ derby: #derby
+ grails.dbconsole:
+ enabled: true
+ dataSource:
+ dbCreate: update
+ url: jdbc:derby:./db;create=true
+ dialect: org.hibernate.dialect.DerbyTenSeven
+ driverClassName: org.apache.derby.jdbc.EmbeddedDriver
+ logsql: true
+
development:
dataSource:
dbCreate: update
url: jdbc:mysql://localhost:3306/db_nibras?serverTimezone=Asia/Beirut
driverClassName: com.mysql.cj.jdbc.Driver
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
- username: nibras
- password: nibras
+ username: user1
+ password: user1
properties:
jmxEnabled: true
initialSize: 5
@@ -222,3 +233,8 @@ environments:
# - classpath:'@info.app.grailsVersion@'.groovy
# - classpath:myconfig.yml
+
+
+quartz:
+ autoStartup: true
+ jdbcStore: false
\ No newline at end of file
diff --git a/grails-app/conf/logback.groovy b/grails-app/conf/logback.groovy
old mode 100644
new mode 100755
index f514780..e03fb47
--- a/grails-app/conf/logback.groovy
+++ b/grails-app/conf/logback.groovy
@@ -112,7 +112,12 @@ appender("STDOUT", ConsoleAppender) {
//logger('nibras', INFO, ['STDOUT'], false)
-logger('nibras', ERROR, ['STDOUT'], false)
+logger('nibras', INFO, ['STDOUT'], false)
+logger('org.hibernate.SQL', WARN, ['STDOUT'], false)
+logger ' org.quartz.core.QuartzScheduler ', INFO
+logger 'org.hibernate.type.descriptor.sql.BasicBinder', DEBUG
+logger 'grails.app.controllers', DEBUG
+
//logger('nibras', WARN, ['STDOUT'], false)
diff --git a/grails-app/controllers/UrlMappings.groovy b/grails-app/controllers/UrlMappings.groovy
old mode 100644
new mode 100755
index ffdd81d..3e6939b
--- a/grails-app/controllers/UrlMappings.groovy
+++ b/grails-app/controllers/UrlMappings.groovy
@@ -26,6 +26,8 @@ class UrlMappings {
"/slides"(controller: 'page', action: 'slides')
"/filed"(controller: 'operation', action: 'filed')
+ "/irfan"(controller: 'page', action: 'appIrfan')
+ // "/jabal-amel"(controller: 'indexCard', action: 'generateWritingsBook')
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
diff --git a/grails-app/controllers/app/IndexCardController.groovy b/grails-app/controllers/app/IndexCardController.groovy
old mode 100644
new mode 100755
index 7a1250f..e6a9561
--- a/grails-app/controllers/app/IndexCardController.groovy
+++ b/grails-app/controllers/app/IndexCardController.groovy
@@ -8,11 +8,16 @@ import cmn.*
import grails.converters.*
import ker.OperationController
import mcs.Book
+import mcs.Course
import mcs.Journal
import mcs.parameters.GoalType
import mcs.parameters.JournalType
import mcs.parameters.WorkStatus
import org.apache.commons.lang.StringUtils
+import security.User
+
+import java.nio.file.Files
+import java.nio.file.Paths
import java.text.SimpleDateFormat
//import jxl.*
@@ -26,6 +31,7 @@ import grails.plugin.springsecurity.annotation.Secured
class IndexCardController { // entity id = 16
def supportService
+ def springSecurityService
static allClasses = [
mcs.Goal,
@@ -478,7 +484,9 @@ class IndexCardController { // entity id = 16
n.summary = params.title//extractTitleReturn(params.description)
n.description = params.description //extractDescriptionReturn(params.description)
n.status = WorkStatus.findByCode('pending')
- n.bookmarked = true
+// n.bookmarked = true
+ if (params.goal)
+ n.goal = mcs.Goal.get(params.goal)
if (params.context)
n.context = mcs.parameters.Context.get(params.context)
n.save()
@@ -489,7 +497,7 @@ class IndexCardController { // entity id = 16
n.description = params.description //extractDescriptionReturn(params.description)
n.type = GoalType.findByCode('goal')
n.status = WorkStatus.findByCode('pending')
- n.bookmarked = true
+// n.bookmarked = true
n.save()
}
else if (params.type == 'R'){
@@ -519,6 +527,18 @@ class IndexCardController { // entity id = 16
n.priority = params.priority?.toInteger()
+ n.user = User.findByUsername(springSecurityService.currentUser.username)
+
+ def fullPath = supportService.getResourcePath(n.id, params.type, false)
+
+ if (OperationController.getPath('currentFolder.path')) {
+ def currentPath = OperationController.getPath('currentFolder.path')
+ Files.createDirectories(Paths.get(fullPath))
+ if (new File(fullPath).exists()) {
+ new File(currentPath + '/current').delete()
+ java.nio.file.Files.createSymbolicLink(Paths.get(currentPath + '/current'), Paths.get(fullPath))
+ }
+ }
render(template: "/gTemplates/recordSummary", model: [record: n, justSaved: true])
render(template: '/layouts/achtung', model: [message: 'Record saved with id: ' + n.id])
@@ -658,13 +678,14 @@ class IndexCardController { // entity id = 16
def generateWritingsBook(){
- render(template: "/appCourse/writingsBookHtml", model: [record: mcs.Course.get(params.id)])
- }
- def generateWritingsBookToFile() {
- def f = new File('/' + (OperationController.getPath('root.rps1.path') ?: '') + '/crs' + params.id + '.md')
- f.write(g.include([controller: 'indexCard', action: 'generateWritingsBook', id: params.id]).toString(), 'UTF-8')
- render 'Generation done: ' + new Date().format('HH:mm:ss')
+ params.id = params.id ?: 9263
+ render(view: "/appCourse/writingsBookHtml", model: [record: mcs.Course.get(params.id)])
}
+
+
+
+
+
def sortNotes(){
render(template: "/appCourse/sortNotes", model: [record: mcs.Course.get(params.id)])
}
diff --git a/grails-app/controllers/ker/ExportController.groovy b/grails-app/controllers/ker/ExportController.groovy
index 6c38fcf..0138ce7 100755
--- a/grails-app/controllers/ker/ExportController.groovy
+++ b/grails-app/controllers/ker/ExportController.groovy
@@ -50,6 +50,7 @@ import java.text.SimpleDateFormat
import grails.plugin.springsecurity.annotation.Secured
+import java.time.ZoneId
import java.time.format.DateTimeFormatter
import static com.cronutils.model.CronType.QUARTZ;
@@ -241,7 +242,7 @@ class ExportController {
def allCalendarEvents() {
def events = []
- Task.executeQuery("from Journal t where t.bookmarked = 1 and t.startDate between :start and :end",
+ Task.executeQuery("from Journal t where t.startDate between :start and :end", // t.bookmarked = 1 and
//[new Date(Long.parseLong(params.start) * 1000), new Date(Long.parseLong(params.end) * 1000)]).each() {
[start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
@@ -264,7 +265,7 @@ class ExportController {
url : request.contextPath + '/page/record/' + it.id + '?entityCode=J',
allDay : (it.level != 'm' || it.startDate.hours < 5 ? true : false)])
}
- Task.executeQuery("from Planner t where t.bookmarked = 1 and t.startDate between :start and :end",
+ Task.executeQuery("from Planner t where t.startDate between :start and :end", //t.bookmarked = 1
//[new Date(Long.parseLong(params.start) * 1000), new Date(Long.parseLong(params.end) * 1000)]).each() {
[start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
@@ -281,15 +282,15 @@ class ExportController {
title : StringUtils.abbreviate(title, 80),
description : it.summary + '|' + it.description,
classNames: it.completedOn != null ? ['done'] : [''],
- backgroundColor: 'Chocolate',//it.type?.color ?: '#F7F9EE',
- borderColor : 'Chocolate',
+ backgroundColor: '#92B450',//it.type?.color ?: '#F7F9EE',
+ borderColor : '#92B450',
textColor : 'white',//it.type?.style ?: '#515150',
url : request.contextPath + '/page/record/' + it.id + '?entityCode=P',
allDay : (it.level != 'm' || it.startDate.hours < 7 || it.task != null ? true : false)])
}
- Task.executeQuery("from Task t where t.bookmarked = 1 and t.endDate between :start and :end",
+ Task.executeQuery("from Task t where t.endDate between :start and :end", // t.bookmarked = 1 and
//[new Date(Long.parseLong(params.start) * 1000), new Date(Long.parseLong(params.end) * 1000)]).each() {
[start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
@@ -310,8 +311,8 @@ class ExportController {
allDay : false ])
}
-
- Task.executeQuery("from Goal t where t.bookmarked = 1 and t.endDate between :start and :end",
+/*
+ Task.executeQuery("from Goal t where t.bookmarked = 1 and t.endDate between :start and :end",
//[new Date(Long.parseLong(params.start) * 1000), new Date(Long.parseLong(params.end) * 1000)]).each() {
[start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
@@ -332,10 +333,9 @@ class ExportController {
url : request.contextPath + '/page/record/' + it.id + '?entityCode=T',
allDay : false ])
}
+*/
-
-
- Task.executeQuery("from Book t where t.bookmarked = 1 and t.readOn between :start and :end",
+ Task.executeQuery("from Book t where t.readOn between :start and :end",
//[new Date(Long.parseLong(params.start) * 1000), new Date(Long.parseLong(params.end) * 1000)]).each() {
[start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
@@ -355,22 +355,25 @@ class ExportController {
url : request.contextPath + '/page/record/' + it.id + '?entityCode=R',
allDay : false ])
}
-/*
- def cc = 1000
-
- [
- ['Oil every month on Monday', '0 15 1 * 1'],
- ['Internet every 14th of month', '0 15 14 * *'],
- ['Filter every two month on Monday', '0 15 1 /2 1'],
- ['Every Friday', '0 15 * * 5'],
- ['Every day', '0 15 * * *'],
- ['Every last of month', '0 15 29 * *']
- ].each() { jobTitle, quartzCronExpression ->
-
- //String quartzCronExpression = "0 0 1 2 7";
- CronParser quartzCronParser =
- new CronParser(CronDefinitionBuilder.instanceDefinitionFor(UNIX));
+// def cc = 1000
+
+// [
+// ['Oil every month on Monday', '0 15 1 * 1'],
+// ['Internet every 14th of month', '0 15 14 * *'],
+// ['Filter every two month on Monday', '0 15 1 /2 1'],
+// ['Every Friday', '0 15 * * 5'],
+// ['Every day', '0 15 * * *'],
+// ['Every last of month', '0 15 29 * *']
+// ]
+ Task.executeQuery('from Task where recurringCron is not null and bookmarked = true').each() {
+ def id = it.id
+ def jobTitle = it.summary
+ def quartzCronExpression = it.recurringCron
+
+ //String quartzCronExpression = "0 0 1 2 7";
+ CronParser quartzCronParser =
+ new CronParser(CronDefinitionBuilder.instanceDefinitionFor(UNIX));
// parse the QUARTZ cron expression.
Cron parsedQuartzCronExpression =
@@ -378,16 +381,14 @@ class ExportController {
// Create ExecutionTime for a given cron expression.
-
// DateTimeFormatter formatter0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a z");
// ZonedDateTime dateTime = ZonedDateTime.parse("2020-06-01 00:00:00 AM +02:00", formatter0);
- ZonedDateTime now = ZonedDateTime.now();
- ExecutionTime executionTime =
- ExecutionTime.forCron(parsedQuartzCronExpression);
+ ExecutionTime executionTime =
+ ExecutionTime.forCron(parsedQuartzCronExpression);
- // render 'quartz ' + parsedQuartzCronExpression.asString()
+ // render 'quartz ' + parsedQuartzCronExpression.asString()
// Given a Cron instance, we can ask for next/previous execution
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("w E dd.MM.yyyy HH:mm Z");
@@ -400,22 +401,37 @@ class ExportController {
// Date.from(executionTime.nextExecution(now).get().toInstant()).format("w E dd.MM.yyyy HH:mm")
// //executionTime.nextExecution(now).get().format(formatter)
// ))
+ ZonedDateTime now = ZonedDateTime.now();
- events.add([id : cc++,
- start : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm':00'").format(Date.from(executionTime.nextExecution(now).get().toInstant())),
- end : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm':00'").format(Date.from(executionTime.nextExecution(now).get().toInstant())),
- //it.type?.name +
- title : jobTitle,
- description : 'cron generated',
- backgroundColor: 'DarkRed',//it.type?.color ?: '#F7F9EE',
- borderColor : 'DarkRed',
- textColor : 'white',//it.type?.style ?: '#515150',
- url : request.contextPath + '/page/record/' + cc + '?entityCode=T',
- allDay : false ])
- }
+// for (d in (-7..+7)) {
+
+
+ def zdtStart = (new Date() - 7).toInstant().atZone(ZoneId.systemDefault())
+ def zdt = executionTime.nextExecution(zdtStart).get()
+ def zdtEnd = (new Date() + 14).toInstant().atZone(ZoneId.systemDefault())
+//def d = -7
+ while (zdt <= zdtEnd) {
+// [start: Date.parse('yyyy-MM-dd', params.start) - 20, end: Date.parse('yyyy-MM-dd', params.end) + 20]).each() {
+// d++
+// println 'new cron task: ' + it.description + ' at date ' + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm':00'").format(Date.from(zdt.toInstant()))
+ events.add([id : it.id + System.currentTimeMillis(),
+ start : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm':00'").format(Date.from(zdt.toInstant())),
+ end : new SimpleDateFormat("yyyy-MM-dd'T'HH:mm':00'").format(Date.from(zdt.toInstant())),
+ //it.type?.name +
+ title : '* ' + it.summary,
+ description : it.summary + ' | ' + it.description,
+ backgroundColor: 'DarkGray',//it.type?.color ?: '#F7F9EE',
+ borderColor : 'Black',
+ textColor : 'white',//it.type?.style ?: '#515150',
+ url : request.contextPath + '/page/record/' + id + '?entityCode=T',
+ allDay : false])
+ zdt = executionTime.nextExecution(zdt).get()
+
+ }
+
+ }
-*/
render events as JSON
}
@@ -792,7 +808,7 @@ This presentation aims to give an overview of Pomegranate PKM system.
def ref = now
def dates = []
def i = 1
- render 'Dates in the next 40 days: '
+ render 'Occurrences in the next 40 days (' + t.recurringInterval + ' times) ' + ' '
// while (Date.from(executionTime.nextExecution(now).get().toInstant()) < new Date() + 40){
while (i <= (t.recurringInterval ?: 4)){
render i++ + ': ' + Date.from(executionTime.nextExecution(now).get().toInstant())?.format('EEE dd.MM.yyyy HH:mm') + ' '
diff --git a/grails-app/controllers/ker/GenericsController.groovy b/grails-app/controllers/ker/GenericsController.groovy
index 83c0f21..84a664a 100755
--- a/grails-app/controllers/ker/GenericsController.groovy
+++ b/grails-app/controllers/ker/GenericsController.groovy
@@ -32,6 +32,8 @@ import mcs.parameters.*
import mcs.parameters.Context
import org.apache.commons.lang.StringUtils
import grails.converters.JSON
+import security.User
+
import java.nio.file.*
//import org.eclipse.mylyn.wikitext.core.parser.MarkupParser
@@ -45,7 +47,10 @@ import grails.plugin.springsecurity.annotation.Secured
import org.apache.pdfbox.PDFToImage
+
+
@Secured(['ROLE_ADMIN','ROLE_READER'])
+
class GenericsController {
static entityMapping = [
@@ -169,14 +174,14 @@ class GenericsController {
def supportService
def searchableService
-
+ def springSecurityService
def quickWritingSearch(String input) {
if (!input.startsWith(' ')) {
- findRecords('f w -- ' + params.input)
+ findRecords('w -- ' + params.input)
} else if (input.startsWith(' ')) {
- findRecords('f w :: ' + params.input)
+ findRecords('w :: ' + params.input)
}
}
@@ -189,6 +194,28 @@ class GenericsController {
}
}
+ def quickCourseSearch(String input) {
+ if (!input.startsWith(' ')) {
+ findRecords("r C${params.id} -- " + params.input)
+ findRecords("n C${params.id} -- " + params.input)
+ findRecords("w C${params.id} -- " + params.input)
+ findRecords("t C${params.id} -- " + params.input)
+ findRecords("t C${params.id} -- " + params.input)
+ findRecords("j C${params.id} -- " + params.input)
+ findRecords("p C${params.id} -- " + params.input)
+ findRecords("g C${params.id} -- " + params.input)
+ } else if (input.startsWith(' ')) {
+ findRecords("r C${params.id} :: " + params.input)
+ findRecords("n C${params.id} :: " + params.input)
+ findRecords("w C${params.id} :: " + params.input)
+ findRecords("t C${params.id} :: " + params.input)
+ findRecords("t C${params.id} :: " + params.input)
+ findRecords("j C${params.id} :: " + params.input)
+ findRecords("p C${params.id} :: " + params.input)
+ findRecords("g C${params.id} :: " + params.input)
+ }
+ }
+
def quickTextSearch(String input) {
// println params.dump()
@@ -217,7 +244,7 @@ class GenericsController {
queryKey : queryKey,
title : entityCode + ': ' + count + ' results.'
])}*/
- render '
Search results... Add a space before the term(s) to search inside the contents of the records . '
+ render "Search results for '${params.input}'... " //Add a space before the term(s) to search inside the contents of the records. '
//println 'type' + params.resultType
if (params.resultType == '*') {
[
@@ -230,24 +257,29 @@ class GenericsController {
[id: 'p', name: 'Planner', code: 'planner'],
[id: 's', name: 'Contact', code: 'contacts'],
[id: 'c', name: 'Course', code: 'courses']
- ].each() {
- if (OperationController.getPath(it.code + '.enabled') == 'yes')
+ ].each() { //todo: simplify
+ if (OperationController.getPath(it.code + '.enabled') == 'yes'){
if (input.startsWith(' '))
findRecords(it.id + ' :: ' + params.input)
else
findRecords(it.id + ' -- ' + params.input)
+ }
}
}
else {
if (input?.trim()?.isInteger())
findRecords(params.resultType.toLowerCase() + ' i' + params.input?.trim())
- else if (input.startsWith(' '))
- findRecords(params.resultType.toLowerCase() + ' :: ' + params.input)
- else
- findRecords(params.resultType.toLowerCase() + ' -- ' + params.input)
+ else {
+ if (input.startsWith(' '))
+ findRecords(params.resultType.toLowerCase() + ' :: ' + params.input)
+ else
+ findRecords(params.resultType.toLowerCase() + ' -- ' + params.input)
+ }
+
}
+
// render 'Searching contents... '
/*
[
@@ -282,6 +314,9 @@ class GenericsController {
Long actionDispatcher(String input) {
+
+ input = input.trim()
+
try {
if (input && input.trim() != '') {
@@ -591,8 +626,8 @@ YellowGreen;#9ACD32"""
}
else {
render(template: '/layouts/verification', model:
- [line: prefix?.replace('--', ' -- ') + it?.trim(),
- status: verifySmartCommand(prefix?.replace('--', ' -- ') + it?.trim()), index: index++]) // prefix + ' ' +
+ [line: prefix?.replace('--', ' -- ') + block?.trim(),
+ status: verifySmartCommand(prefix?.replace('--', ' -- ') + block?.trim()), index: index++]) // prefix + ' ' +
}
}
@@ -791,7 +826,8 @@ r (resource)
case 'e': hintResponce = 'e saved search code '
if (input.length() < 3){
SavedSearch.findAll().each(){
- hintResponce+= it.id + (it.code ? ' ' + it.code + ' ' : '') + ' - ' + it.summary + ' '
+ hintResponce+= (it.code ? ' ' + it.code + ' ' : '') + ' - ' + it.summary + ' '
+ // it.id +
}
} else {
@@ -859,7 +895,7 @@ fr"""
break
case '#':
- hintResponce += ('Types\n\n')
+ hintResponce += ('Types \n\n')
switch (entityCode) {
@@ -1202,7 +1238,11 @@ ll
def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
+
if (record) {
+ // todo: remove
+ record.user = User.findByUsername(springSecurityService.currentUser.username)
+
if (entityCode == 'O'){
if (verifySmartCommand(record?.summary + ' -- ' + record.description?.trim()) == 'correctCommand') {
@@ -1226,12 +1266,15 @@ ll
def fullPath = supportService.getResourcePath(record.id, entityCode, false)
+
+ if (OperationController.getPath('currentFolder.path')){
def currentPath = OperationController.getPath('currentFolder.path')
Files.createDirectories(Paths.get(fullPath))
if (new File(fullPath).exists()) {
new File(currentPath + '/current').delete()
java.nio.file.Files.createSymbolicLink(Paths.get(currentPath + '/current'), Paths.get(fullPath))
}
+ }
}
render(template: '/gTemplates/recordSummary', model: [record: record, showFull: 'on', mobileView: params.mobileView])
@@ -1269,9 +1312,9 @@ def markAsMarkdowned(Long id, String entityCode) {
def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
try {
record.withMarkdown = true
- render 'is ? ' + record.withMarkdown
- render 'is ? ' + record.id
- render 'is ? ' + record.hasErrors()
+// render 'is ? ' + record.withMarkdown
+// render 'is ? ' + record.id
+// render 'is ? ' + record.hasErrors()
record.save()
render(template: '/layouts/achtung', model: [message: "Record with ID ${id} has been marked as markdown"])
// render(template: '/gTemplates/recordSummary', model: [record: record])
@@ -1282,6 +1325,23 @@ def markAsMarkdowned(Long id, String entityCode) {
}
}
+ def unmarkAsMarkdowned(Long id, String entityCode) {
+ def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
+ try {
+ record.withMarkdown = false
+// render 'is ? ' + record.withMarkdown
+// render 'is ? ' + record.id
+// render 'is ? ' + record.hasErrors()
+ record.save()
+ render(template: '/layouts/achtung', model: [message: "Record with ID ${id} has been ummarked as markdown"])
+// render(template: '/gTemplates/recordSummary', model: [record: record])
+ }
+ catch (Exception) {
+ render(template: '/layouts/achtung', model: [message: "Record with ID ${id} could not be unmarked"])
+ println 'Error saving record.'
+ }
+ }
+
def openRpsFolder() {
@@ -1497,9 +1557,10 @@ def markAsMarkdowned(Long id, String entityCode) {
// newRecord.dateCreated = oldRecord.dateCreated
-
}
+ oldRecord.user = newRecord.user
+
// render(template: '/layouts/achtung', model: [message: "Record with ID ${id} deleted"])
render(template: '/gTemplates/recordSummary', model: [record: newRecord])
}
@@ -1586,7 +1647,28 @@ def markAsMarkdowned(Long id, String entityCode) {
}
- def markCompleted(Long id, String entityCode) {
+ def markPublic(Long id, String entityCode) {
+
+ def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
+
+// !'RP'.contains(entityCode) &&
+ if (record.class.declaredFields.name.contains('isPrivate')) {
+ if (record.isPrivate == true) {
+ record.isPrivate = false
+ render(template: '/layouts/achtung', model: [message: 'Record marked as public'])
+ }
+ else {
+ record.isPrivate = true
+ render(template: '/layouts/achtung', model: [message: 'Record marked as private'])
+ }
+ }
+
+ render(template: '/gTemplates/recordSummary', model: [record: record])
+
+ }
+
+
+def markCompleted(Long id, String entityCode) {
def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
@@ -1655,6 +1737,30 @@ def markAsMarkdowned(Long id, String entityCode) {
render(template: '/gTemplates/recordSummary', model: [record: record])
render(template: '/layouts/achtung', model: [message: 'Record marked as completed'])
}
+ def unmarkCompleted(Long id, String entityCode) {
+
+ def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
+
+ if ('GTP'.contains(entityCode)) {
+ record.completedOn = null
+ record.status = WorkStatus.findByCode('pending')
+ }
+
+ if ('NJ'.contains(entityCode)) {
+ record.isMerged = false
+ record.mergedOn = null
+ }
+
+
+ if ('REN'.contains(entityCode)) {
+ if (!record.readOn) {
+ record.readOn = null
+ }
+ }
+
+ render(template: '/gTemplates/recordSummary', model: [record: record])
+ render(template: '/layouts/achtung', model: [message: 'Record marked as uncompleted'])
+ }
// static def markCompletedStatic(Long id, String entityCode) {
//
@@ -1932,8 +2038,10 @@ def markAsMarkdowned(Long id, String entityCode) {
typeRepositoryPath = OperationController.getPath('root.rps2.path') + '/' + entityCode + '/'
folders.add([typeSandboxPath + '/' + (b.id)])
- if (!b.bookmarked)
- folders.add([typeRepositoryPath + '/' + (b.id)])
+
+
+// if (!r.bookmarked)
+// folders.add([typeRepositoryPath + '/' + (b.id)])
@@ -2045,6 +2153,34 @@ def markAsMarkdowned(Long id, String entityCode) {
record.endDate = new Date()
record.bookmarked = true
// else
+// record.endDate = record.endDate - 1
+
+ render(template: '/gTemplates/recordSummary', model: [record: record])
+ }
+ def setEndDate() {
+ def entityCode = params.id.substring(0, 1)
+ def id = params.id.substring(1).toLong()
+ def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
+
+ def oldEndDate = record.endDate
+
+// if (!record.endDate)
+ record.endDate = new Date() + params.i.toInteger()
+
+ if (params.i.toInteger() > 3)
+ record.bookmarked = false
+
+
+
+ if (oldEndDate) {
+ Calendar cal = GregorianCalendar.getInstance(); // turned out to be not needed, but old dates where in a different timezones!!!
+ cal.setTime(oldEndDate)
+
+// record.endDate = record.endDate.copyWith(hourOfDay: cal.get(Calendar.HOUR), minute: oldEndDate.getMinutes())
+ record.endDate.setHours(oldEndDate.getHours())
+ record.endDate.setMinutes(oldEndDate.getMinutes())
+ }
+// else
// record.endDate = record.endDate - 1
render(template: '/gTemplates/recordSummary', model: [record: record])
@@ -2603,16 +2739,20 @@ def markAsMarkdowned(Long id, String entityCode) {
}
// postToBlog(String blogId, String title, String categoriesString, String tags, String fullText) {
- sleep(2000)
- int r = supportService.postToBlog(record.blog.id, summary, categories, tags, contents, record.entityCode(), record.publishedNodeId)
-
- if (r) {
- record.publishedNodeId = r
- record.publishedOn = new Date()
- //render r
- render(template: '/layouts/achtung', model: [message: "Record published with id " + r])
- } else "Problem posting the record"
-
+ sleep(500)
+ try {
+ int r = supportService.postToBlog(record.blog.id, summary, categories, tags, contents, record.entityCode(), record.publishedNodeId, null)
+
+ if (r) {
+ record.publishedNodeId = r
+ record.publishedOn = new Date()
+ //render r
+ render(template: '/layouts/achtung', model: [message: "Record published with id " + r])
+ } else "Problem posting the record"
+ } catch (Exception e){
+ println 'Problem occurred while posting ' + e.toString()
+ render 'Problem occurred while posting ' + e.toString()
+ }
list.add(record)
}
@@ -2998,6 +3138,11 @@ def markAsMarkdowned(Long id, String entityCode) {
if (params.id)
record = grailsApplication.classLoader.loadClass(params.entityController).get(params.id)
+ if (params.id && params.entityController == 'mcs.parameters.SavedSearch')
+ render(template: '/gTemplates/recordSummary', model: [
+ title: "",
+ record: record])
+
render(template: '/gTemplates/addForm', model: [entityController: params.entityController,
fields : grailsApplication.classLoader.loadClass(params.entityController).declaredFields.name,
@@ -3017,8 +3162,11 @@ def markAsMarkdowned(Long id, String entityCode) {
contexts : contexts,
categories : categories
])
- if (params.isParameter)
- render(template: '/gTemplates/recordListing', model: [list: grailsApplication.classLoader.loadClass(params.entityController).findAll([sort: 'id', order: 'desc'])])
+
+ if (params.isParameter)
+ render(template: '/gTemplates/recordListing', model: [
+ title: "List of records",
+ list: grailsApplication.classLoader.loadClass(params.entityController).findAll([sort: 'id', order: 'desc'])])
}
catch (Exception e) {
@@ -3275,9 +3423,9 @@ def markAsMarkdowned(Long id, String entityCode) {
def queryHead = 'from ' + entityMapping[entityCode]
def queryCriteria = transformMcsNotation(input.substring(0, input.length() - 2))['queryCriteria']
- def fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by lastUpdated desc, id desc'
+ def fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by id desc' //lastUpdated desc, buggy, todo: configurable with a warning
// println 'fq ' + fullquery
- def list = Task.executeQuery(fullquery + ' order by lastUpdated desc, id desc', [], params)
+ def list = Task.executeQuery(fullquery + ' order by id desc', [], params) // lastUpdated desc,
def r
def limit = ker.OperationController.getPath('updateResultSet.max-items')?.toInteger() ?: 100
if (list.size() < limit) {
@@ -3329,7 +3477,7 @@ def markAsMarkdowned(Long id, String entityCode) {
def queryParams = ''
- fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by lastUpdated desc, id desc'
+ fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by id desc' // lastUpdated desc,
fullquerySort = 'select count(*) ' + queryHead + (queryCriteria ? ' where ' + queryCriteria : '')
def list = Task.executeQuery(fullquery, [], params)
@@ -3441,7 +3589,7 @@ def markAsMarkdowned(Long id, String entityCode) {
render(template: '/reports/genericGrouping', model: [
- items : Task.executeQuery(queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by lastUpdated desc, id desc', []),
+ items : Task.executeQuery(queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by id desc', []), // lastUpdated desc,
groups: groups, groupBy: groupBy,
title : 'HQL Query: ' + input]
)
@@ -3453,11 +3601,14 @@ def markAsMarkdowned(Long id, String entityCode) {
def queryKey
if (input.startsWith('_')) {
fullquery = session[input]
- fullquerySort = 'select count(*) ' + fullquery
+ fullquerySort = 'select count(*) ' + fullquery?.split('order by')[0] // bug: problem in h2 if "order by" is used with select count(*)
+ // println 'query sort ' + fullquery?.split('order by')[0]
queryKey = input
// println 'fullquery ' + fullquery + '\n\n'
}
else {
+
+
def entityCode = input.split(/[ ]+/)[0]?.toUpperCase()
// input = params.input.substring(params.input.indexOf(' '))
@@ -3465,9 +3616,10 @@ def markAsMarkdowned(Long id, String entityCode) {
def queryHead = 'from ' + entityMapping[entityCode]
def queryCriteria = transformMcsNotation(input)['queryCriteria']
+ // println 'queryCriteria ' + queryCriteria
def queryParams = ''
- fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by lastUpdated desc, id desc'
+ fullquery = queryHead + (queryCriteria ? ' where ' + queryCriteria : '') + ' order by id desc' // lastUpdated desc,
fullquerySort = 'select count(*) ' + queryHead + (queryCriteria ? ' where ' + queryCriteria : '')
queryKey = '_' + entityCode + '-' + new Date().format('ddMMyyHHmmss')
session[queryKey] = fullquery
@@ -3737,6 +3889,9 @@ def markAsMarkdowned(Long id, String entityCode) {
} else {
def n = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).newInstance(properties)
// n.properties = properties
+
+ n.user = User.findByUsername(springSecurityService.currentUser.username)
+
if (!n.hasErrors() && n.save()) {
render(template: '/gTemplates/recordSummary', model: [
record: n, justSaved: true, justSaved: true])
@@ -3826,9 +3981,12 @@ def markAsMarkdowned(Long id, String entityCode) {
record : n
])
- render 'Saved'
+// render 'Saved' x
+ render(template: '/layouts/achtung', model: [message: 'Changes saved'])
+
+ } else
+ render(template: '/layouts/achtung', model: [message: 'Problem occurred'])
- } else render "Problem occurred."
@@ -3928,6 +4086,7 @@ def markAsMarkdowned(Long id, String entityCode) {
def types = []
def statuses = []
def topics = []
+ def goals = []
def priorities = []
def sources = []
def departments = []
@@ -3946,6 +4105,7 @@ def markAsMarkdowned(Long id, String entityCode) {
case 'mcs.Task':
statuses = WorkStatus.list([sort: 'name'])
locations = Location.list([sort: 'name'])
+ goals = Goal.findAllByBookmarked(true, [sort: 'name'])
break
case 'mcs.Goal':
statuses = WorkStatus.list([sort: 'name'])
@@ -3955,7 +4115,7 @@ def markAsMarkdowned(Long id, String entityCode) {
case 'mcs.Planner':
statuses = WorkStatus.list([sort: 'name'])
types = PlannerType.list([sort: 'name'])
- goals = Goal.list([sort: 'summary'])
+ goals = Goal.findAllByBookmarked(true, [sort: 'name'])
break
case 'app.Payment':
@@ -3990,7 +4150,7 @@ def markAsMarkdowned(Long id, String entityCode) {
updateRegion : params.updateRegion,
entityController: entityController,
savedRecord : n,
-
+ goals: goals,
types : types,
statuses : statuses,
topcis : topics,
@@ -4013,7 +4173,7 @@ def markAsMarkdowned(Long id, String entityCode) {
fields : n.class.declaredFields.name,
record : n,
savedRecord : n,
-
+ goals : goals,
types : types,
statuses : statuses,
topcis : topics,
@@ -4025,9 +4185,9 @@ def markAsMarkdowned(Long id, String entityCode) {
locations : locations,
categories : categories
])
-// n.errors.each() {
-// render it
-// }
+ n.errors.each() {
+ render it
+ }
}
@@ -4041,16 +4201,16 @@ def markAsMarkdowned(Long id, String entityCode) {
def filter = '%'
- Writing.findAllBySummaryLike(filter, [sort: 'summary']).each() {
- responce += [value: 'w ' + it.id + ' ' + it.summary]
- }
- Goal.findAllBySummaryLike(filter, [sort: 'summary']).each() {
- responce += [value: 'g ' + it.id + ' ' + it.summary]
- }
- Task.findAllBySummaryLike(filter, [sort: 'summary']).each() {
+// Writing.findAllBySummaryLike(filter, [sort: 'summary']).each() {
+// responce += [value: 'w ' + it.id + ' ' + it.summary]
+// }
+// Goal.findAllBySummaryLike(filter, [sort: 'summary']).each() {
+// responce += [value: 'g ' + it.id + ' ' + it.summary]
+// }
+// Task.findAllBySummaryLike(filter, [sort: 'summary']).each() {
// responce += (it.summary + '|t' + '' + it.id + '\n')
- responce += [value: 't ' + it.id + ' ' + it.summary]
- }
+// responce += [value: 't ' + it.id + ' ' + it.summary]
+// }
if (1 == 2 && input && input.contains(' ') && input.split(/[ ]+/).size() >= 2) {
@@ -4093,7 +4253,9 @@ def markAsMarkdowned(Long id, String entityCode) {
}
- Book.findAllByStatus(ResourceStatus.get(1), [sort: 'title']).each() { // only textbooks
+
+
+ Book.findAll([sort: 'lastUpdated', order: 'desc', max: 100]).each() {
responce += [id: it.id, value: 'r ' + it.id + ' ' + it.title, text: 'r ' + '' + it.id + '\n']
}
//
@@ -4104,21 +4266,30 @@ def markAsMarkdowned(Long id, String entityCode) {
def r = new Relationship()
+
+ /*
+ id: 11909
+entityCode: N
+type: 1
+recordB: r 23451 الدين والأخلاق" بقلم العلامة الشيخ أحمد عارف الزين
+
+
+ */
// the child
- r.entityA = entityMapping[params.entityCode]
+ r.entityA = params.entityCode
r.entityACode = params.entityCode
r.recordA = params.id.toLong()
- def child = grailsApplication.classLoader.loadClass(r.entityA).get(r.recordA)
+ def child = grailsApplication.classLoader.loadClass(entityMapping[r.entityA]).get(r.recordA)
// the parent
def parentEntityCode = params.recordB.substring(0, 1).toUpperCase()
- r.entityB = entityMapping[parentEntityCode]
+ r.entityB = parentEntityCode
r.entityBCode = parentEntityCode
r.recordB = params.recordB.split(' ')[1].toLong()
- def parent = grailsApplication.classLoader.loadClass(r.entityB).get(r.recordB)
+ def parent = grailsApplication.classLoader.loadClass(entityMapping[r.entityB]).get(r.recordB)
r.type = RelationshipType.get(params.type)
@@ -4250,6 +4421,9 @@ def markAsMarkdowned(Long id, String entityCode) {
record.description = description
+
+ record.user = User.findByUsername(springSecurityService.currentUser.username)
+
if (!record.hasErrors() && record.save()) {
render(template: '/gTemplates/recordSummary', model: [
record: record, justSaved: true])
@@ -4302,9 +4476,9 @@ def markAsMarkdowned(Long id, String entityCode) {
record.description += ('\n' + params.text + ' (' + new Date().format('dd.MM.yyyy') + ')')
// record.description += ('\n\n' + params.text)
- render params.text
- render ' '
- render ' '
+// render params.text
+// render ' '
+// render ' '
render(template: '/gTemplates/recordSummary', model: [record: record])
//render(template: '/gTemplates/recordDetails', model: [record: record])
@@ -4824,7 +4998,7 @@ def markAsMarkdowned(Long id, String entityCode) {
description = input.substring(input.indexOf('::') + 2).trim()
properties[descriptionFieldName] = description
if (entityCode == 'R')
- queryCriteria.add("fullText like '%" + description + "%' or description like '%" + description + "%'")
+ queryCriteria.add("(fullText like '%" + description + "%' or description like '%" + description + "%')")
else
queryCriteria.add(descriptionFieldName + " like '%" + description + "%'")
@@ -5195,10 +5369,10 @@ def addTagToAll(String input) {
def savedSearch = SavedSearch.get(id)
- if (params.reportType != 'tab') {
- render(template: '/gTemplates/recordSummary', model: [record: savedSearch])
- render(' ')
- }
+// if (params.reportType != 'tab') {
+// render(template: '/gTemplates/recordSummary', model: [record: savedSearch])
+// render(' ')
+// }
if (savedSearch.queryType == 'random' || params.reportType == 'random') {
@@ -5274,11 +5448,14 @@ def addTagToAll(String input) {
if (params.reportType == 'tab') {
params.max = null
- render(view: '/page/kanbanCrs', model: [groups: groups, groupBy: groupBy,
+ render(view: '/page/kanbanCrs',
+ model: [groups: groups, groupBy: groupBy,
+// reportType: params.reportType,
title : savedSearch.summary,
ssId : savedSearch.id,
items : Task.executeQuery(input, [])])
} else {
+
render(template: '/reports/genericGrouping', model: [groups: groups, groupBy: groupBy,
title : savedSearch.summary,
ssId : savedSearch.id,
@@ -5311,6 +5488,7 @@ def addTagToAll(String input) {
params.max = null
render(view: '/page/kanbanCrs', model: [
ssId : id,
+// reportType: params.reportType,
searchResultsTotal: savedSearch.countQuery ? Task.executeQuery(savedSearch.countQuery)[0] : '',
totalHits : savedSearch.countQuery ? Task.executeQuery(savedSearch.countQuery)[0] : '',
list : Task.executeQuery(savedSearch.query, []),
@@ -5324,7 +5502,8 @@ def addTagToAll(String input) {
searchResultsTotal: savedSearch.countQuery ? Task.executeQuery(savedSearch.countQuery)[0] : '',
totalHits : savedSearch.countQuery ? Task.executeQuery(savedSearch.countQuery)[0] : '',
list : list,
- title : savedSearch.summary
+ title : savedSearch.summary,
+ query: savedSearch.query
])
}
}
@@ -5338,12 +5517,14 @@ def addTagToAll(String input) {
} else if (savedSearch.queryType == 'lucene') {
render(template: '/gTemplates/recordListing', model: [
list : searchableService.search(savedSearch.query, [max: 100]),
+ query: savedSearch.query,
title: savedSearch.summary + " (" + savedSearch.query + ")"])
} else if (savedSearch.queryType == 'adhoc') {
render(template: '/reports/adHocQueryResults', model: [
list : mcs.Task.executeQuery(savedSearch.query),
ssId : savedSearch.id,
- title: '' + savedSearch.summary + " (" + savedSearch.query + ")"
+ title: '' + savedSearch.summary,
+ query: savedSearch.query
])
} else
render(template: '/layouts/achtung', model: [message: 'Unknown query type'])
@@ -5368,27 +5549,17 @@ def addTagToAll(String input) {
def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
// TODO: fix
if (record.description) {
- record.description = record.description?.replace(' وَ ', ' وَ')?.replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/^و /, ' و')
- .replace(/^وَ /, '\n وَ').replace(' و ', ' و').replace('ی', 'ي').replace('ک', 'ك')
+ record.description = fixText(record.description)
record.save(flush: true)
render(record.description.replace('\n', ' '))
}
if (record.notes) {
- record.notes = record.notes?.replace(' وَ ', ' وَ')?.replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/^و /, 'و')
- .replaceAll(/\nو /, '\nو')
- .replace(/^وَ /, '\n وَ').replace(' و ', ' و').replace('ی', 'ي').replace('ک', 'ك')
+ record.notes = fixText(record.notes)
record.save(flush: true)
render(record.notes.replace('\n', ' '))
}
if (record.class.declaredFields.name.contains('fullText') && record.fullText) {
- record.fullText = record.fullText?.replace(' وَ ', ' وَ')?.replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/\nوَ /, ' وَ')
- .replaceAll(/^و /, ' و')
- .replace(/^وَ /, '\n وَ').replace(' و ', ' و').replace('ی', 'ي').replace('ک', 'ك')
+ record.fullText = fixText(record.fullText)
record.save(flush: true)
render(record.fullText.replace('\n', ' '))
}
@@ -5397,9 +5568,21 @@ def addTagToAll(String input) {
}
- def publish() {
- def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
+ static long staticPublish(String entityCode, Long id) {
+
+// params.id = id
+// params.entityCode = entityCode
+
+// publish()
+
+ }
+
+ def publish(String entityCode, Long id) {
+
+
+
+ def record = grailsApplication.classLoader.loadClass(entityMapping[entityCode]).get(id)
def tags = ''
record.tags.each() {
@@ -5415,7 +5598,7 @@ def addTagToAll(String input) {
String summary, contents, type
- switch (params.entityCode) {
+ switch (entityCode) {
case 'W': summary = record.summary
contents = //ys.wikiparser.WikiParser.renderXHTML(record.description)?.decodeHTML()
(record.language == 'ar' ? ('' + record.descriptionHTML + '
') : record.descriptionHTML)
@@ -5432,20 +5615,57 @@ def addTagToAll(String input) {
//record.description//?.encodeAsHTML()
type = record.type?.name
break
+
+ case 'R': summary = record.title
+ contents = record.fullText//ys.wikiparser.WikiParser.renderXHTML(record.description)?.decodeHTML()
+ //record.description//?.encodeAsHTML()
+ type = record.type?.name
+ break
}
- // postToBlog(String blogId, String title, String categoriesString, String tags, String fullText) {
- int r = supportService.postToBlog(record.blog.id, record.code ?: record.id?.toString(), summary, categories, tags,
- contents, record.shortDescription, params.entityCode, record.publishedNodeId)
+ def coverPath
+
+ if (new File(supportService.getResourcePath(record.id, entityCode, false) + '/cover.jpg').exists()){
+ coverPath = supportService.getResourcePath(record.id, entityCode, false) + '/cover.jpg'
+ }
+ else coverPath = null
+
+
+ String[] files = []
+
+ if (new File(supportService.getResourcePath(record.id, entityCode, false)).exists()) {
+ new File(supportService.getResourcePath(record.id, entityCode, false)).listFiles().each() {
+ if (it.name != 'cover.jpg' && it.isFile()) {
+ files += it.name
+ }
+ }
+ }
+// else
+// files = null
+
+ // int postToBlog(Long blogId, String code, String title, String categoriesString, String tags, String fullText,
+ // String excerpt, String entityCode, Integer publishedNodeId) {
+ if (!record.blog)
+ record.blog = Blog.findByBookmarked(true)
+
+
+ int r = supportService.postToBlog(record.blog ? record.blog.id : null, record.code ?: record.id?.toString(), summary, categories, tags,
+ contents,
+ // record.shortDescription,
+ record.description,
+ entityCode, record.publishedNodeId, coverPath,
+ files, "https://jabal-amel.khuta.org/wp-content/uploads"
+ )
if (r) {
record.publishedNodeId = r
record.publishedOn = new Date()
- record.status = WritingStatus.findByCode('pub')
+// record.status = WritingStatus.findByCode('pub')
record.save(flush: true)
render 'Published with id : ' + r //+ ' class ' + r.class
render(template: '/layouts/achtung', model: [message: "Record published with id " + r])
+ return r
} else "Problem posting the record"
}
@@ -5916,6 +6136,7 @@ def addTagToAll(String input) {
//println 'here 555'
+
String pdfPath = params.path
if (params.module == 'E')
@@ -5933,13 +6154,18 @@ def addTagToAll(String input) {
try {
// will output "my_image_2.jpg"
+
+ new File( getRecordPaths(params.module, params.id.toLong())[0]).mkdirs()
+
PDFToImage.main(args_2);
def ant = new AntBuilder()
ant.move(file: args_2[5] + '1.jpg', tofile: (args_2[5] + ''))
+ render 'Cover generated to ' + args_2[5]
}
catch (Exception e) {
e.printStackTrace()
+ render 'Problem generating the cover ' + e.toString()
}
}
@@ -6029,6 +6255,11 @@ def addTagToAll(String input) {
def viewRecordImage() {
+ params.entityCode = params.entityCode ?: 'R'
+ if (params.id.contains('.'))
+ params.id = params.id?.split('.')[0]
+
+
def paths = getRecordPaths(params.entityCode, params.id.toLong())
def f
paths.each(){
@@ -6395,4 +6626,77 @@ def body
render "All operations have been marked as settled"
}
+ String fixText(String text){
+ return text?.replace(' وَ ', ' وَ')?.replaceAll(/\nوَ /, ' وَ')
+ .replaceAll(/\nوَ /, ' وَ')
+ .replaceAll(/ـ/, '')
+ .replaceAll(/[ ]+/, / /)
+ .replaceAll(/^[ ]+/, '')
+ .replace(' ,', ',')
+ .replace(' :', ':')
+ .replace(' ،', '،')
+ .replace(' .', '.')
+ .replaceAll(/^و /, ' و')
+ .replace(/^وَ /, '\n وَ').replace(' و ', ' و').replace('ی', 'ي').replace('ک', 'ك')
+ }
+
+
+ def generateWritingsBookToFile() {
+
+ def siteRecords = []
+ def ant = new AntBuilder()
+ def coverPath
+
+ for (h in app.IndexCard.executeQuery('from IndexCard where course = ? and priority >= ?', [Course.get(params.id), 2])) {
+
+ siteRecords.push([entity: 'N', id: h.id])
+
+ if (h.tags)
+ for (t in h.tags?.sort() { i, j -> i.name.toLowerCase().compareTo(j.name.toLowerCase()) }) {
+
+// t.bookmarked = true
+// t.save(flush: true)
+
+ for (r in mcs.Book.createCriteria().list() { tags { idEq(t.id.toLong()) } }) {
+ siteRecords.push([entity: 'R', id: r.id])
+
+
+ def f = new File('/home/maitham/sites/jabal-amel/posts/' + r.id + '.html')
+ f.write(g.include([controller: 'page', action: 'staticPage', id: r.id]).toString(), 'UTF-8')
+
+// coverPath = supportService.getResourcePath(r.id, 'R', false) + '/cover.jpg'
+// if (new File(coverPath).exists())
+// ant.copy(file: coverPath,
+// tofile: '/home/maitham/sites/jabal-amel/covers' + '/' + r.id + '.jpg')
+
+ def recordPath = supportService.getResourcePath(r.id, 'R', false)
+
+ // publish('R', r.id)
+
+ if (new File(recordPath).exists()) {
+ new File(recordPath).listFiles().each() {
+ if (it.name != 'cover.jpg' && it.isFile()) {
+ ant.copy(file: it.path,
+ tofile: '/home/maitham/sites/jabal-amel/files' + '/' + r.id + '/' + it.name)
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ println 'Site records: ' + siteRecords.size()
+
+// ' + (OperationController.getPath('root.rps1.path') ?: '')
+ def sitePath = '/home/maitham/sites/jabal-amel/' + 'index' + '.html'
+ def f = new File(sitePath)
+ f.write(g.include([controller: 'indexCard', action: 'generateWritingsBook', id: params.id]).toString(), 'UTF-8')
+ render 'Generation done: ' + new Date().format('HH:mm:ss') + '. Site saved to: ' + sitePath
+
+
+
+
+
+ }
}
diff --git a/grails-app/controllers/ker/ImportController.groovy b/grails-app/controllers/ker/ImportController.groovy
index 1212796..02aa518 100755
--- a/grails-app/controllers/ker/ImportController.groovy
+++ b/grails-app/controllers/ker/ImportController.groovy
@@ -36,12 +36,15 @@ import grails.plugin.springsecurity.annotation.Secured
import com.gravity.goose.Article
import com.gravity.goose.Configuration
import com.gravity.goose.Goose
+import security.User
@Secured(['ROLE_ADMIN','ROLE_READER'])
class ImportController {
def supportService
+ def springSecurityService
+
static entityMapping = [
'G': 'mcs.Goal',
@@ -199,8 +202,15 @@ class ImportController {
} else {
b = grailsApplication.classLoader.loadClass(entityMapping[entityCode.toUpperCase()]).newInstance()
b.summary = title
- finalName = entityCode.toLowerCase() + '.' + ext
+// if (ext == 'jpg') {
+// finalName = 'cover' + '.' + ext
+// }
+// else {
+// finalName = b.id + entityCode.toLowerCase() + '.' + ext
+// }
+
+// finalName = entityCode.toLowerCase() + '.' + ext
}
@@ -214,7 +224,9 @@ class ImportController {
// println 'text is ' + folder.text
//b.description = 'Imported on ' + new Date().format(OperationController.getPath('date.format') ?: 'dd.MM.yyyy')
- } else {
+ }
+
+ else {
b = grailsApplication.classLoader.loadClass(entityMapping[entityCode.toUpperCase()]).newInstance()
b.properties = GenericsController.transformMcsNotation(title)['properties']
@@ -224,9 +236,10 @@ class ImportController {
}
- finalName = entityCode.toLowerCase() + '.' + ext
+
}
+
if (ext == 'txt') {
if (entityCode.toLowerCase() == 'r')
b.fullText = folder.text
@@ -236,8 +249,23 @@ class ImportController {
//b.notes = 'Imported on ' + new Date().format(OperationController.getPath('date.format') ?: 'dd.MM.yyyy')
+
+ b.user = User.findByUsername(springSecurityService.currentUser.username)
+// println ' imported file from ' + User.findByUsername(springSecurityService.currentUser.username)
+
+
+
if (!b.hasErrors() && b.save(flush: true)) {
+
+ if (ext == 'jpg') {
+ finalName = 'cover' + '.' + ext
+ }
+ else {
+ finalName = b.id + entityCode.toLowerCase() + '.' + ext
+ }
+
+
render(template: '/gTemplates/recordSummary', model: [record: b])
def ant = new AntBuilder()
if (entityCode == 'R') {
@@ -249,11 +277,11 @@ class ImportController {
ant.move(file: path, tofile: rootPath + '/' + entityCode +
(resourceNestedByType ? '/' + type.code : '') +
(resourceNestedById ? '/' + (b.id / 100).toInteger() : '') +
- '/' + b.id + '/' + b.id + '' + finalName)
+ '/' + b.id + '/' + finalName)
} else
//ant.move(file: path, tofile: OperationController.getPath('module.sandbox.' + entityCode + '.path') + '/' + b.id + '' + finalName)
// inline move 22.10.2016
- ant.move(file: path, tofile: rootPath + '/' + entityCode + '/' + b.id + '/' + b.id + finalName)
+ ant.move(file: path, tofile: rootPath + '/' + entityCode + '/' + b.id + '/' + finalName)
} else {
b.errors.each() {
@@ -311,7 +339,8 @@ class ImportController {
if (OperationController.getPath('resourceNestedByType') == 'yes')
resourceNestedByType = true
-
+ b.user = User.findByUsername(springSecurityService.currentUser.username)
+ println ' imported folder from ' + User.findByUsername(springSecurityService.currentUser.username)
if (!b.hasErrors() && b.save(flush: true)) {
diff --git a/grails-app/controllers/ker/OperationController.groovy b/grails-app/controllers/ker/OperationController.groovy
index 3d6759b..1591581 100755
--- a/grails-app/controllers/ker/OperationController.groovy
+++ b/grails-app/controllers/ker/OperationController.groovy
@@ -27,8 +27,11 @@ import groovy.io.FileType
import mcs.*
import mcs.parameters.*
import grails.plugin.springsecurity.annotation.Secured
+import org.apache.commons.lang.StringUtils
import org.apache.pdfbox.PDFToImage
+import security.User
+import java.nio.file.*
@Secured(['ROLE_ADMIN','ROLE_READER'])
class OperationController {
@@ -57,8 +60,13 @@ class OperationController {
'Y': 'cmn.Setting',
'X': 'mcs.parameters.SavedSearch'
]
+
+
def supportService
def searchableService
+
+ def springSecurityService
+
private java.lang.Object object
def actions() {
@@ -777,6 +785,11 @@ class OperationController {
return Setting.findByName(code)?.value?.replace(/[appFolder]/, '.')
}
+ static def setPath(String code, String newValue) {
+
+ return Setting.findByName(code)?.value = newValue
+ }
+
def generateBibEntry(Long id) {
render OperationController.generateBibEntrySt(id)
@@ -1096,7 +1109,7 @@ date = "${r.year ?: ''}"
if (field == 'blog') {
Blog.findAll([sort: 'code']).each() {
responce += [value: it.id,
- text : it.code]
+ text : it.summary]
}
} else if (field == 'pomegranate') {
Pomegranate.findAll([sort: 'code']).each() {
@@ -1121,12 +1134,12 @@ date = "${r.year ?: ''}"
n.department)
}
else {
- courses = Course.executeQuery('from Course c order by c.summary asc')
+ courses = Course.executeQuery('from Course c order by c.code asc, c.summary asc')
}
courses.each() {
responce += [value: it.id,
- text : '[' + it.code + '] ' + it.summary]
+ text : '' + it.code + ' - ' + it.summary]
}
// } else
// responce += [value: 0,
@@ -1466,6 +1479,7 @@ date = "${r.year ?: ''}"
def rps1Folder
def rps2Folder
+ def rps2Folder2 // legacy case
if (params.entityCode == 'R') {
rps1Folder =
OperationController.getPath('root.rps1.path') + '/R' +
@@ -1478,6 +1492,12 @@ date = "${r.year ?: ''}"
(resourceNestedByType ? '/' + b.type.code : '') +
(resourceNestedById ? '/' + (params.id.toLong()/ 100).toInteger() : '') +
'/' + params.id
+ rps2Folder2 =
+ OperationController.getPath('root.rps2.path') + '/R' +
+ (resourceNestedByType ? '/' + b.type.code : '') +
+ (resourceNestedById ? '/' + (params.id.toLong()/ 100).toInteger() : '')
+ //+
+ // '/' + params.id
} else {
rps1Folder = OperationController.getPath('root.rps1.path') + '/' + params.entityCode + '/' + params.id
rps2Folder = OperationController.getPath('root.rps2.path') + '/' + params.entityCode + '/' + params.id
@@ -1491,6 +1511,13 @@ date = "${r.year ?: ''}"
}
}
+
+ if (rps2Folder2 && new File(rps2Folder2).exists()) {
+ new File(rps2Folder2).eachFileMatch(~/${params.id}[\S\s]*\.[\S\s]*/) {
+ filesList.add(it)
+ }
+ }
+
def ant = new AntBuilder()
filesList.each() { f ->
@@ -1693,7 +1720,7 @@ date = "${r.year ?: ''}"
if (new File(folder[0]).exists()) {
new File(folder[0]).eachFileMatch(~/${b.id}[a-z][\S\s]*\.[\S\s]*/) {
filesCount++
- filesList += it.name// + '\n'
+ filesList += it.name + '|' + it.size()// + '\n'
}
}
}
@@ -1708,13 +1735,13 @@ date = "${r.year ?: ''}"
folders.each() { folder ->
// println 'fld ' + folder + ' class ' + folder.class
if (new File(folder[0]).exists()) {
- new File(folder[0]).eachFileRecurse() {
+ new File(folder[0]).eachFile() { //Recurse
//Match(~/[\S\s]*\.[\S\s]*/) { //ToDo: only files with extensions!
- if (!it.isFile())
- filesList += '*** ' + it.name
- else {
+ if (it.isFile()){
+// filesList += '*** ' + it.name
+// else {
filesCount++
- filesList += it.name
+ filesList += it.name + '|' + it.size()
}
}
}
@@ -1760,17 +1787,15 @@ switch (entityCode){
if (!b.bookmarked)
folders.add([typeRepositoryPath + '/' + (b.id)])
-
-
folders.each() { folder ->
if (new File(folder[0]).exists()) {
- new File(folder[0]).eachFileRecurse() {
+ new File(folder[0]).eachFile() { //Recurse
//Match(~/[\S\s]*\.[\S\s]*/) { //ToDo: only files with extensions!
- if (!it.isFile())
- filesList += '*** ' + it.name
- else {
+ if (it.isFile()) {
+// filesList += '*** ' + it.name
+// else {
filesCount++
- filesList += it.name
+ filesList += it.name + '|' + it.size()
}
}
}
@@ -1976,7 +2001,7 @@ past.each(){
// j.level = 'd'
// else
j.level = 'm'
- j.bookmarked = true
+ // j.bookmarked = true
if (params.task && params.task != 'null')
j.task = Task.get(params.task.toLong())
@@ -2002,6 +2027,8 @@ past.each(){
// if (j.level == 'd')
// j.endDate = null
+ j.user = User.findByUsername(springSecurityService.currentUser.username)
+
if (!j.hasErrors()) {
j.save(flash: true)
// render 'Saved with id: ' + ' ' + j.id + ': ' + j.summary
@@ -2067,15 +2094,15 @@ past.each(){
n.wbsNumber = j+1
// sub++
n.save(flush: true)
- // println 'found a child with id ' + n.id // + +'.' + (sub++) + '\n'
+ println 'found a child with id ' + n.id +'.' + (sub++) + ' ' + n.summary + '\n'
} else {
-// sub = 1
+ sub = 1
n.wbsParent = null
n.orderNumber = roots
n.wbsNumber = roots
n.save(flush: true)
roots++
- // println 'found a root with id ' + n.orderNumber// + +'.' + (sub++) + '\n'
+ println 'found a root with id ' + n.orderNumber + '.' + (sub++) + n.summary + '\n'
}
}
@@ -2104,7 +2131,7 @@ past.each(){
def dumpAllWritings(){
- Writing.list().each() {
+ Writing.executeQuery('from Writing where type.code != ?', ['surah']).each() {
dumpRecordForImport(it.id, 'W')
}
@@ -2395,5 +2422,121 @@ margin: 5px 2px;
+ def makeSymbolicLink() {
+
+ try {
+ def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
+
+ // def relativePath = supportService.getResourcePath(record.id, params.entityCode, true)
+ def fullPath = supportService.getResourcePath(record.id, params.entityCode, false)
+
+ def name = params.entityCode == 'R' ? record.title : record.summary
+
+ def target = OperationController.getPath('root.rps1.path') + '/new/' + '/' + name
+
+ // render 'target ' + target + ' '
+ // render 'source ' + fullPath + ' '
+// render ' count is ' + Files.list(Paths.get(fullPath)).count() + ' '
+
+ // Files.createDirectories(Paths.get(target).getParent())
+ Files.createDirectories(Paths.get(fullPath))
+ if (java.nio.file.Files.createSymbolicLink(Paths.get(target), Paths.get(fullPath)))
+// render ''
+ render(template: '/layouts/achtung', model: [message: 'Link created on ' + OperationController.getPath('root.rps1.path') + '/new/'])
+ else
+ render(template: '/layouts/achtung', model: [message: 'Problem creating the link'])
+
+ } catch (Exception e){
+ render(template: '/layouts/achtung', model: [message: 'Problem creating the link ' + e])
+ e.printStackTrace()
+ }
+
+
+ }
+
+
+
+ def rescheduleEvent = {
+
+ def m
+
+ def scheduledStart = Date.parse('dd.MM.yyyy HH:mm', params.newStartTime)
+ def scheduledEnd = new Date(scheduledStart.time + 30 * 60 * 1000)
+
+ switch(params.entityCode){
+
+ case 'J':
+ m = Journal.get(params.title)
+ break
+case 'P':
+ m = Planner.get(params.title)
+ break
+case 'T':
+ m = Task.get(params.title)
+ break
+
+ }
+
+
+ m.startDate = scheduledStart
+ m.endDate = scheduledEnd
+
+
+ // scheduledStart + 600//
+// println 's e:: ' + scheduledStart + ' -> ' + scheduledEnd
+
+
+
+ render(template: '/layouts/achtung', model: [message: 'Plan rescheduled'])
+// if (keepProcessing && scheduledStart.minutes == 45) {
+
+
+ }
+ def resizeEvent = {
+
+// println "id: = " + params.title
+ def m = Planner.get(params.title)
+
+// def scheduledStart = Date.parse('dd.MM.yyyy HH:mm', params.end)
+ def scheduledEnd = Date.parse('dd.MM.yyyy HH:mm', params.end) //new Date(scheduledStart.time + 30 * 60 * 1000)
+ // scheduledStart + 600//
+// println 's e:: ' + scheduledStart + ' -> ' + scheduledEnd
+
+// m.startDate = scheduledStart
+ m.endDate = scheduledEnd
+
- } // end of class
\ No newline at end of file
+ render(template: '/layouts/achtung', model: [message: 'Plan resized'])
+// if (keepProcessing && scheduledStart.minutes == 45) {
+
+
+ }
+
+
+ def createUser() { // todo
+ def username = params.username?.trim()
+ def standardRole = security.Role.findByAuthority('ROLE_READER')
+// println ' is it ' + standardRole
+ def standardUser = new security.User(username: username, password: username).save()
+ security.UserRole.create(standardUser, standardRole, true)
+
+ render 'User created with username ' + username + ' and password ' + username
+
+ }
+
+ def toggleMetadataLine(){
+
+ if (OperationController.getPath('metadataLine.hidden') == 'yes'){
+
+ Setting.findByName('metadataLine.hidden').value = 'no'
+
+ render 'Metadata line visible. Refresh view to take effect.'
+ }
+ else {
+ Setting.findByName('metadataLine.hidden').value = 'yes'
+
+ render 'Metadata line hidden. Refresh view to take effect.'
+ }
+
+ }
+} // end of class
\ No newline at end of file
diff --git a/grails-app/controllers/ker/PageController.groovy b/grails-app/controllers/ker/PageController.groovy
index bdca5cc..853a331 100755
--- a/grails-app/controllers/ker/PageController.groovy
+++ b/grails-app/controllers/ker/PageController.groovy
@@ -54,6 +54,9 @@ import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
+
+import java.time.format.DateTimeFormatter
+
//import java.io.StringWriter;
//import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
//import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;
@@ -122,6 +125,7 @@ class PageController {
def appMain() {
+
//
// ['IPs.show', 'add-import-panel.enabled', 'advanced-panel.enabled', 'calendar.enabled', 'commandbar.enabled', 'copyright.show', 'course.enabled', 'extra-panes.enabled', 'notes.enabled', 'open-record-folders.enabled', 'quick-add-form.enabled', 'review.enabled', 'rss.enabled', 'scans.enabled', 'selection-actions.enabled', 'tasks.enabled', 'today-report.enabled',
// 'convert-records.enabled',
@@ -132,7 +136,7 @@ class PageController {
// }
- def types = []
+ def types = [ [id: 'C', name: 'Course', code: 'courses']]
[
[id: 'T', name: 'Task', code: 'tasks'],
@@ -141,6 +145,7 @@ class PageController {
[id: 'W', name: 'Writing', code: 'writings'],
[id: 'J', name: 'Journal', code: 'journal'],
// [id: 'Jt', name: 'Yesterday journal', code: 'journal'],
+ [id: 'P', name: 'Planner', code: 'planner'],
[id: 'R', name: 'Resource', code: 'resources']
].each(){
if (OperationController.getPath(it.code + '.enabled') == 'yes')
@@ -288,7 +293,8 @@ class PageController {
["updateResultSet.max-items","100"],
["upload-cover.enabled","no"],
["upload-files.enabled","yes"],
- ["writings.enabled","no"]
+ ["writings.enabled","no"],
+ ["metadataLine.hidden","no"]
].each() {
new cmn.Setting([name: it[0], value: it[1]]).save(flush: true)
}
@@ -312,10 +318,12 @@ class PageController {
// }
def recentRecords = []
- recentClasses.each() {
+
+ if (1 == 2) {
+ recentClasses.each() {
// recentRecords += it.findAllByDateCreatedGreaterThanAndDeletedOnIsNull(new Date() - 2, [sort: 'dateCreated', order: 'desc', max: 1])?.reverse()
- recentRecords += it.findAll([sort: 'dateCreated', order: 'desc', max: 1])?.reverse()
- }
+ recentRecords += it.findAll([sort: 'dateCreated', order: 'desc', max: 1])?.reverse()
+ }
// def filledInDates = ''
// Journal.executeQuery("select DATE_FORMAT(startDate, '%c/%e/%Y') from Journal group by date(startDate) order by startDate asc").each() {
@@ -323,18 +331,18 @@ class PageController {
// }
// session['log'] = 1
- session['J'] = 1
- session['P'] = 1
+ session['J'] = 1
+ session['P'] = 1
- session['showLine1Only'] = 'on'
- session['showFullCard'] = 'off'
+ session['showLine1Only'] = 'on'
+ session['showFullCard'] = 'off'
// MarkupParser markupParser = new MarkupParser();
// markupParser.setMarkupLanguage(new MarkdownLanguage());
// String htmlContent = markupParser.parseToHtml(text);
- def r = ''
- // def c = 0
+ def r = ''
+ // def c = 0
// def f = ker.OperationController.getPath('editBox.path')
// if (f) {
// new File(f)?.listFiles().each(){
@@ -345,26 +353,26 @@ class PageController {
// }
// }
- def resources =
- Book.executeQuery('from Book r where r.course.bookmarked = ? ' +
+ def resources =
+ Book.executeQuery('from Book r where r.course.bookmarked = ? ' +
// in ' +
// '(select course from Planner p where p.startDate < current_date and p.endDate > current_date and p.course is not null)' +
- ' and r.priority >= ? and r.readOn is not null' +
- ' and (r.lastReviewed < ? or r.lastReviewed is null) and r.reviewCount < ?' +
- ' order by r.orderNumber asc, r.reviewCount asc',
- [true, 3, new Date() + 7, 5])
- def excerpts =
- Book.executeQuery('from Excerpt r where r.book.course.bookmarked = ? ' +
+ ' and r.priority >= ? and r.readOn is not null' +
+ ' and (r.lastReviewed < ? or r.lastReviewed is null) and r.reviewCount < ?' +
+ ' order by r.orderNumber asc, r.reviewCount asc',
+ [true, 3, new Date() + 7, 5])
+ def excerpts =
+ Book.executeQuery('from Excerpt r where r.book.course.bookmarked = ? ' +
// ' in' +
// ' (select course from Planner p where p.startDate < current_date and p.endDate > current_date and p.course is not null)' +
- ' and r.priority >= ? and r.readOn is not null' +
- ' and (r.lastReviewed < ? or r.lastReviewed is null) and r.reviewCount < ?' +
- ' order by r.orderNumber asc, r.reviewCount asc',
- [true, 3, new Date() + 7, 5])
+ ' and r.priority >= ? and r.readOn is not null' +
+ ' and (r.lastReviewed < ? or r.lastReviewed is null) and r.reviewCount < ?' +
+ ' order by r.orderNumber asc, r.reviewCount asc',
+ [true, 3, new Date() + 7, 5])
// println 'r ' + resources
// println 'e ' + excerpts
-
+ }
def ips = []
def ip
def interf
@@ -392,7 +400,7 @@ class PageController {
// [mcs.Book, 'Resource'],
[mcs.Planner, 'Plan'],
[mcs.Journal, 'Journal'], [app.IndexCard, 'Note']]) {
- for (t in c[0].findAllByDateCreatedGreaterThan(new Date() - 90, [sort: 'dateCreated', order: 'asc'])) {
+ for (t in c[0].findAllByDateCreatedGreaterThan(new Date() - 14, [sort: 'dateCreated', order: 'asc'])) {
def date = t.dateCreated.format('yyyy-MM-dd')
if (!datesHb[date])
datesHb[date] = ['Goal' : 0,
@@ -415,8 +423,10 @@ class PageController {
def user = springSecurityService.currentUser
+
+
// def rpsSize = '/home/maitham/job/rps1/bin/rps0size.sh'.execute().text
- render(view: '/appMain/main', model: [
+ render(view: '/appMain/main2', model: [
htmlContent : null,
ips : ips,
// rpsSize : rpsSize,
@@ -424,7 +434,7 @@ class PageController {
editFileCount : 0, // todo: fix
dates: datesHb,
username : user.username,
- reviewPileSize : resources.size() + excerpts.size(),
+// reviewPileSize : resources.size() + excerpts.size(),
types: types,
tasksActiveNotStarted: tasksActiveNotStarted,
// environment: environment
@@ -445,13 +455,16 @@ class PageController {
def types = []
[
+ [id: 'N', name: 'Note', code: 'notes'],
+ [id: 'W', name: 'Writing', code: 'writings'],
+
[id: 'T', name: 'Task', code: 'tasks'],
[id: 'P', name: 'Plan', code: 'plans'],
[id: 'G', name: 'Goal', code: 'goals'],
- [id: 'N', name: 'Note', code: 'notes'],
- [id: 'W', name: 'Writing', code: 'writings'],
+
[id: 'J', name: 'Journal', code: 'journal'],
// [id: 'Jt', name: 'Yesterday journal', code: 'journal'],
+ [id: 'P', name: 'Planner', code: 'planner'],
[id: 'R', name: 'Resource', code: 'resources']
].each(){
if (OperationController.getPath(it.code + '.enabled') == 'yes')
@@ -511,7 +524,13 @@ class PageController {
])
}
def appPile() {
- render(view: '/appPile/main', model: [ ])
+
+
+ response.setHeader("Access-Control-Allow-Origin", "*")
+ response.setHeader("Access-Control-Allow-Methods", "*")
+
+ render(view: '/appPile/main', model: [ ])
+
}
def appKanban() {
@@ -570,6 +589,7 @@ def appPile() {
[id: 'W', name: 'Writing', code: 'writings'],
[id: 'J', name: 'Journal', code: 'journal'],
// [id: 'Jt', name: 'Yesterday journal', code: 'journal'],
+ [id: 'P', name: 'Planner', code: 'planner'],
[id: 'R', name: 'Resource', code: 'resources']
].each() {
if (OperationController.getPath(it.code + '.enabled') == 'yes')
@@ -665,6 +685,9 @@ def appPile() {
max = app.IndexCard.executeQuery('select count(*) from IndexCard i where i.priority >= ? and i.type.code = ? and length(i.summary) > 80 and length(i.summary) < 800', [4, 'aya'])[0].toInteger()
+
+
+
def overdue = supportService.getOverdueTasks()
def pile = supportService.getTasksPile()
def todayInProgress = supportService.getTasksTodayInProgress()
@@ -676,7 +699,7 @@ def appPile() {
render(view: '/appCalendar/main', model: [
- prayersText: prayersText,
+ prayersText: prayersTimes(),
random: Math.floor(Math.random() * max),
overdue: overdue,
pile: pile,
@@ -684,6 +707,7 @@ def appPile() {
courses: mcs.Course.findAllByBookmarked(true),
completed: todayCompleted,
notStarted: todayNotStarted
+
])
}
def appMobileCalendar() {
@@ -699,8 +723,15 @@ def appPile() {
def record() {
def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
if (record)
- render(view: '/page/record', model: [record:record
- ])
+ render(view: '/page/record', model: [record:record])
+ else render 'Record not found.'
+ }
+
+ def staticPage() {
+ params.entityCode = params.entityCode ?: 'R'
+ def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
+ if (record)
+ render(view: '/page/staticPage', model: [record: record])
else render 'Record not found.'
}
def rssPage() {
@@ -711,8 +742,14 @@ def appPile() {
}
def panel() {
+
+ response.setHeader("Access-Control-Allow-Origin", "*")
+ response.setHeader("Access-Control-Allow-Methods", "*")
+
def record = grailsApplication.classLoader.loadClass(entityMapping[params.entityCode]).get(params.id)
+// supportService.updateBookmarkedRecordsFileCount()
+
def typeSandboxPath
def resourceNestedById = false
@@ -777,8 +814,11 @@ def coverPath
def htmlText = ''
+// record.entityCode() == 'N' &&
+ if ('NRW'.contains(record.entityCode()) && record.description) {
+
+
- if (record.entityCode() == 'N' && record.description) {
MutableDataSet options = new MutableDataSet();
options.setFrom(ParserEmulationProfile.MARKDOWN);
@@ -796,7 +836,8 @@ def htmlText = ''
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
// You can re-use parser and renderer instances
- Node document = parser.parse(record.description?.replaceAll('\n', '\n \n'));
+ def reposFilesUrl = ker.OperationController.getPath('repository.url')
+ Node document = parser.parse(record.description?.replaceAll('\n', '\n \n').replace('](', '](' + reposFilesUrl + '/W/' + record.id + '/'));
String html = renderer.render(document); // "This is Sparta
\n"
record.descriptionHTML = html//?.replaceAll('\n', ' \n')?.replaceAll(' ', ' \n')
// println 'html ' + html
@@ -1090,11 +1131,18 @@ YellowGreen;#9ACD32"""
}
+
+ def appIrfan() {
+ render(view: '/appIrfan/main', model: [])
+
+ }
+
def settingsMain() {
render(template: '/page/settings', model: [full: false])
}
+
def settingsFull() {
render(template: '/page/settings', model: [full: true])
@@ -1115,6 +1163,8 @@ YellowGreen;#9ACD32"""
result = "ok"
}
+ response.setHeader("Access-Control-Allow-Origin", "*")
+ response.setHeader("Access-Control-Allow-Methods", "*")
render(status: 200, contentType: 'application/json', text: json)
}
@@ -1153,4 +1203,48 @@ YellowGreen;#9ACD32"""
}
+ String prayersTimes(){
+
+ double latitude = 33.8933182;
+ double longitude = 35.5015717;
+ double timezone = ker.OperationController.getPath('prayers.timezone') ?ker.OperationController.getPath('prayers.timezone').toInteger(): 3 ;
+ // Test Prayer times here
+ PrayTime prayers = new newpackage.PrayTime();
+
+ prayers.setTimeFormat(prayers.Time12NS);
+ prayers.setCalcMethod(prayers.Jafari);
+ prayers.setAsrJuristic(prayers.Shafii);
+ prayers.setAdjustHighLats(prayers.AngleBased);
+ int[] offsets = [0, 1, 0, 0, 0, 3, 5]; // {Fajr,Sunrise,Dhuhr,Asr,Sunset,Maghrib,Isha}
+ prayers.tune(offsets);
+
+ Date now = new Date();
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(now);
+
+ ArrayList prayerTimes = prayers.getPrayerTimes(cal,
+ latitude, longitude, timezone);
+ ArrayList prayerNames = prayers.getTimeNames();
+
+ def prayersText = ''
+// for (int i = 0; i < prayerTimes.size(); i++) {
+ prayersText += (prayerNames.get(0) + ": " + prayerTimes.get(0) + '\n')
+ prayersText += (prayerNames.get(1) + ": " + prayerTimes.get(1) + '\n')
+ prayersText += (prayerNames.get(2) + ": " + prayerTimes.get(2) + '\n')
+ prayersText += (prayerNames.get(3) + ": " + prayerTimes.get(3) + '\n')
+ prayersText += (prayerNames.get(4) + ": " + prayerTimes.get(4) + '\n')
+ prayersText += (prayerNames.get(5) + ": " + prayerTimes.get(5) + '\n')
+// prayersText += (prayerNames.get(6) + ": " + prayerTimes.get(6) + '\n')
+// }
+
+
+ return prayersText
+
+ }
+
+
+ def tasksTable (){
+ render(view: '/reports/taskTable', model: [])
+
+ }
} // end of class
\ No newline at end of file
diff --git a/grails-app/controllers/ker/ReportController.groovy b/grails-app/controllers/ker/ReportController.groovy
old mode 100644
new mode 100755
index a5ddcc1..7d8cec5
--- a/grails-app/controllers/ker/ReportController.groovy
+++ b/grails-app/controllers/ker/ReportController.groovy
@@ -28,7 +28,6 @@ import mcs.Planner
import mcs.Writing
import mcs.parameters.ResourceStatus
-
import com.intuit.fuzzymatcher.component.MatchService;
import com.intuit.fuzzymatcher.domain.Document;
import com.intuit.fuzzymatcher.domain.Element;
@@ -40,7 +39,10 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+import grails.converters.JSON
+import grails.web.JSONBuilder
+import com.ibm.icu.text.Transliterator;
import grails.plugin.springsecurity.annotation.Secured
@@ -258,6 +260,32 @@ def enterJournalWithType() {
}
+ def updateIps() {
+
+ def ips = []
+ def ip
+ def interf
+
+ def interfaces = NetworkInterface.getNetworkInterfaces()
+
+ while (interfaces.hasMoreElements()) {
+
+ interf = interfaces.nextElement()
+ def addresses = interf.getInetAddresses()
+
+ while (addresses.hasMoreElements()) {
+ ip = addresses.nextElement().getHostAddress().toString()
+ if (ip && ip != '' && !ip.contains(':') && !ip.startsWith('127'))
+ ips.add([name: interf.getName(), title: interf.getDisplayName(), ip: ip]) //?.split(/\(/)[0]
+// println (addresses.nextElement().getCanonicalHostName())
+// println (addresses.nextElement().hostAddress)
+ }
+ }
+
+
+ render(template: '/reports/ips', model: [ips: ips])
+ }
+
def tagCloud() {
Tag.list().each() { t ->
@@ -344,27 +372,18 @@ def enterJournalWithType() {
// journals: Journal.findAll('from Journal where date(startDate) >= ? and date(endDate) <= ?', [startDate, endDate]),
// startDate: startDate, endDate: endDate])
//
- def title = 'Activity log and agenda for: ' +
+ def title = // 'Activity log and agenda for: ' +
(startDate.format('dd.MM.yyyy') == endDate.format('dd.MM.yyyy') ? startDate.format('EE dd.MM.yyyy') :
- startDate.format('EE dd.MM.yyyy') + ' - ' + endDate.format('EE dd.MM.yyyy')) + ' '
- if (session['Kanban'] == 1)
- render(template: '/reports/kanbanCalendar', model: [startDate: startDate, endDate: endDate])
- if (session['P'] == 1)
- render(template: '/reports/pCalendar', model: [startDate: startDate, endDate: endDate])
- if (session['J'] == 1)
- render(template: '/reports/jCalendar', model: [startDate: startDate, endDate: endDate])
-
- if (session['Jtrk'] == 1)
- render(template: '/reports/jtrkReport', model: [startDate: startDate, endDate: endDate])
+ startDate.format('EE dd.MM.yyyy') + ' - ' + endDate.format('EE dd.MM.yyyy')) + ''
- if (session['Qtrans'] == 1)
- render(template: '/reports/financialReportTrans', model: [startDate: startDate, endDate: endDate])
- if (session['Qacc'] == 1)
- render(template: '/reports/financialReportAcc', model: [startDate: startDate, endDate: endDate])
+ def list = []
+ for (c in [
+ mcs.Goal, mcs.Task]) {
+ list += c.executeQuery(' from ' + c.name + ' where endDate between ? and ? ', [startDate, endDate])
+ }
if (session['log'] == 1) {
- def list = []
for (c in [
mcs.Goal, mcs.Task, mcs.Planner, mcs.Journal,
mcs.Writing, app.IndexCard, mcs.Book]) {
@@ -379,10 +398,32 @@ def enterJournalWithType() {
app.Payment, app.IndicatorData]) {
list += c.executeQuery(' from ' + c.name + ' where date between ? and ? ', [startDate, endDate])
}
+ }
+
+ render(template: '/gTemplates/recordListing', model: [list: list, title: title])
+
+
+// if (session['Kanban'] == 1)
+ render(template: '/reports/kanbanCalendar', model: [startDate: startDate, endDate: endDate])
+// if (session['P'] == 1)
+ render(template: '/reports/pCalendar', model: [startDate: startDate, endDate: endDate])
+// if (session['J'] == 1)
+ render(template: '/reports/jCalendar', model: [startDate: startDate, endDate: endDate])
- render(template: '/gTemplates/recordListing', model: [list: list, title: title])
+// if (session['Jtrk'] == 1)
+ render(template: '/reports/jtrkReport', model: [startDate: startDate, endDate: endDate])
+
+// if (session['Qtrans'] == 1)
+ if (ker.OperationController.getPath('payments.enabled')?.toLowerCase() == 'yes') {
+ render(template: '/reports/financialReportTrans', model: [startDate: startDate, endDate: endDate])
+
+// if (session['Qacc'] == 1)
+
+ render(template: '/reports/financialReportAcc', model: [startDate: startDate, endDate: endDate])
}
+
+
// Planner.executeQuery('from Planner where (date(dateCreated) >= ? and date(dateCreated) <= ?) or (date(startDate) >= ? and date(startDate) <= ?) order by dateCreated desc', [startDate, endDate, startDate, endDate]) +
//
//
@@ -600,17 +641,47 @@ def enterJournalWithType() {
}
+ def duplicateCandidates(){
+
+
+ def results = []
+ Goal.list([sort: 'id', order: 'desc']).each(){a->
+ Goal.findAllByIdLessThan(a.id, [sort: 'id', order: 'desc']).each() { b ->
+
+ if (supportService.similarity(a.summary, b.summary) > 0.85)
+ results.add(a)
+ results.add(b)
+
+ }
+
+ }
+
+ render(template: '/gTemplates/recordListing', model: [list: results])
+
+ }
+
def duplicatesList2(){
+
+
+
+
+// String anything = "ш щ ч ц х ф г я चंब्रिद्गॆ цамбридге كَمبرِدگِ かんぶりでげ";
+ String id = "Any-Latin";
+
+
+ ;
+
+
String[][] input = [
];
+ def summary = ''
Goal.list().each(){
- input += [[it.id.toString(), it.summary?: it.id.toString(), '']]
+ summary = it.summary + ' ' + Transliterator.getInstance(id).transform(it.summary?: it.id.toString())
+ input += [[it.id.toString(), summary , '']]
}
-
// println input
-
List documentList = Arrays.asList(input).stream().map({contact ->
return new Document.Builder(contact[0])
.addElement(new Element.Builder().setValue(contact[0]).setType(NAME).createElement())
@@ -625,7 +696,10 @@ def enterJournalWithType() {
result.entrySet().forEach({ entry ->
entry.getValue().forEach({ match ->
- render("Data: " + match.getData() + " Matched With: " + match.getMatchedWith() + " Score: " + new java.text.DecimalFormat('#.##').format(match.getScore().getResult()) + ' ');
+//
+ render(" f g i" + match.getData().getKey() + ' -- ' + match.getData() + // " Matched With: " + match.getMatchedWith() + " Score: " + new java.text.DecimalFormat('#.##').format(match.getScore().getResult()) + ' ');
+ " f g i" + match.getMatchedWith().getKey() + ' -- ' + match.getMatchedWith() ) // " Matched With: " + match.getMatchedWith() + " Score: " + new java.text.DecimalFormat('#.##').format(match.getScore().getResult()) + ' ');
+ // render("Data: " + match.getData() + " Matched With: " + match.getMatchedWith() + " Score: " + new java.text.DecimalFormat('#.##').format(match.getScore().getResult()) + ' ');
});
});
@@ -659,4 +733,57 @@ render (view: '/reports/customReport1', model: [list: list, i: 1])
}
+
+// trn charts
+ def chartData = {
+
+
+ def dataAll = []
+
+ def x = []
+ def y = []
+ def data = [:]
+ def lastValue = 0
+
+ for (c in [
+ [app.IndexCard, 'IndexCard', 'Notes', 'fa8042'],
+ [mcs.Book, 'Book', 'Resources', 'c38ea3'],
+ [mcs.Journal, 'Journal', 'Jounal', '90accf'],
+ [mcs.Planner, 'Planner', 'Planner', '238cCC'],
+ [mcs.Goal, 'Goal', 'Goals', 'a1c650'],
+ [mcs.Task, 'Task', 'Tasks', 'cbe0a1']
+ ]) {
+
+ x = []
+ y = []
+ data = [:]
+ lastValue = 0
+
+ for (t in c[0].executeQuery('select date(dateCreated), count(*) from ' + c[1] + ' where dateCreated > ? group by date(dateCreated) order by date(dateCreated)',
+ [new Date() - 14])) {
+// def date = t[0].format('yyyy-MM-dd')
+ x+= t[0].format('yyyy-MM-dd') // + '-' + t[1] + t[2] // '-01'//
+// println 'in chart data ' + t[0]
+// println 'in chart data ' + t[0].class
+// println 'in chart data ' + t[0].format('yyyy-MM-dd')
+ println ''
+ println ''
+// x+= date
+ y += t[1] // + lastValue // cumulative value
+// lastValue = t[2] + lastValue
+ }
+
+ data = [x: x[1..-1], y: y[1..-1],
+ name: '' + c[2] + ' ',
+ type: 'line', // scatter, lines, markers,
+ line: [
+ color: "#${c[3]}", // 'rgb(' + Math.random() * 255 + ', ' + Math.random() * 255 + ',' + Math.random() * 255 + ')',
+ width: 2
+ ]
+ ]
+ dataAll += [data]
+ }
+ render dataAll as JSON
+ }
+
} // end of class
\ No newline at end of file
diff --git a/grails-app/controllers/ker/SyncController.groovy b/grails-app/controllers/ker/SyncController.groovy
old mode 100644
new mode 100755
index 37eccec..ae2f8e6
--- a/grails-app/controllers/ker/SyncController.groovy
+++ b/grails-app/controllers/ker/SyncController.groovy
@@ -2,6 +2,8 @@ package ker
import app.IndexCard
import app.parameters.*
+import cmn.Setting
+import mcs.Department
import mcs.Operation
import mcs.parameters.*
import grails.converters.XML
@@ -15,6 +17,7 @@ import grails.converters.JSON
import org.grails.web.json.JSONObject
import org.json.JSONArray
import org.springframework.http.HttpRequest
+import security.User
import sun.reflect.generics.factory.GenericsFactory
@@ -94,6 +97,7 @@ class SyncController {
}
}
+
def rssPile() {
render(feedType: "rss", feedVersion: "2.0") {
title = "PKM RSS"
@@ -174,6 +178,7 @@ class SyncController {
}
}
+
def fetchFullText() {
def b = mcs.Book.get(params.id)
def t = ''
@@ -258,8 +263,22 @@ class SyncController {
def builder = new JSONBuilder()
def records = []
- for (i in mcs.Planner.executeQuery("from Planner where startDate >= ? and startDate <= ? and completedOn is null order by startDate asc",
- [new Date() - 4, new Date() + 4])) {
+ for (i in mcs.Planner.executeQuery("from Planner t where t.startDate >= ? and t.startDate <= ? and t.completedOn is null and (t.user.username = ? or t.isPrivate = true) order by t.startDate asc",
+ [new Date() - 7, new Date() + 7, params.id])) {
+ records += [type : 'P', id: i.id, ecode: 'P',
+ meta : i?.startDate?.format('dd-MM-yyyy-HH-mm'),
+ date : i?.startDate?.format('dd-MM-yyyy'),
+ datediff: i?.startDate - new Date(),
+ color : 'darkblue',
+ filesList : i.filesList,
+ nbFiles : i.nbFiles,
+ summary : (i.task ? ('[' + i.task?.summary + '] ') : '') + i.summary,
+ language: i.language,
+ body : i.description ? i.description?.replace('\n', ' ') : '']
+ }
+
+ for (i in mcs.Planner.executeQuery("from Planner t where t.bookmarked = true and (t.user.username = ? or t.isPrivate = true) order by t.startDate asc",
+ [params.id])) { // new Date() - 20, new Date() + 20
records += [type : 'P', id: i.id, ecode: 'P',
meta : i?.startDate?.format('dd-MM-yyyy-HH-mm'),
date : i?.startDate?.format('dd-MM-yyyy'),
@@ -282,11 +301,17 @@ class SyncController {
}
def exportJsonJ = {
+
+ supportService.updateBookmarkedRecordsFileCount()
+
+
def builder = new JSONBuilder()
+// println ' in jsonJ, username: ' + params.id
+
def records = []
- for (i in mcs.Planner.executeQuery("from Journal where startDate >= ? and startDate <= ? and bookmarked = ? order by startDate desc ",
- [new Date() - 14, new Date() + 7, true])) {
+ for (i in mcs.Planner.executeQuery("from Journal t where t.startDate >= ? and t.startDate <= ? and t.bookmarked = ? and (t.user.username = ? or t.isPrivate = true) order by t.startDate desc ",
+ [new Date() - 4, new Date() + 1, true, params.id])) {
records += [type : 'J',
id : i.id,
ecode : 'J',
@@ -345,12 +370,15 @@ class SyncController {
def records = []
def priorityMap = [5: 'p5', 4: 'p4', 3: 'p3', 2: 'p2', 1: 'p1']
- for (i in Task.executeQuery("from Task t where t.bookmarked = ? order by t.priority desc, t.id desc", [true])) {
+ for (i in Task.executeQuery("from Task t where t.bookmarked = ? and (t.user.username = ? or t.isPrivate = true) order by t.priority desc, t.id desc", [true, params.id])) {
// t.context.code asc, t.priority todo: fix
records += [type : (i.isTodo == true ? 'Todo' : 'T'),
id : i.id,
ecode : 'T',
meta : (i.context ? '@' + i.context?.code : '-') + ' ' + (i.priority ? priorityMap[i.priority] : ''),
+ context : (i.context ? '@' + i.context?.code : '-'),
+ date : i?.endDate?.format('dd-MM-yyyy-HH-mm'),
+ textDate : i?.endDate?.format('EEE dd, HH-mm'),
color : 'lightgreen',
summary : i.summary,
filesList : i.filesList,
@@ -359,16 +387,34 @@ class SyncController {
description: i.description ? i.description?.replace('\n', ' ') : '']
}
- for (i in Task.executeQuery("from Task t where t.endDate >= ? and t.endDate <= ? order by t.priority desc, t.id desc", [new Date() - 3, new Date() + 3])) {
+ def json = builder.build {
+ result = "ok"
+ data = records
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+ }
+
+def exportJsonV = {
+ def builder = new JSONBuilder()
+
+ def records = []
+ def priorityMap = [5: 'p5', 4: 'p4', 3: 'p3', 2: 'p2', 1: 'p1']
+
+
+ for (i in Task.executeQuery("from Task t where t.endDate >= ? and t.endDate <= ? and t.completedOn is null and (t.user.username = ? or t.isPrivate = true) order by t.priority desc, t.id desc", [new Date() - 14, new Date() + 32, params.id])) {
// t.context.code asc, t.priority todo: fix
records += [type : (i.isTodo == true ? 'Todo' : 'T'),
id : i.id,
ecode : 'T',
meta : (i.context ? '@' + i.context?.code : '-') + ' ' + (i.priority ? priorityMap[i.priority] : ''),
+ context : (i.context ? '@' + i.context?.code : '-'),
+ date : i?.endDate ? i?.endDate?.format('dd-MM-yyyy-HH-mm') : null,
color : 'lightgreen',
summary : i.summary,
filesList : i.filesList,
nbFiles : i.nbFiles,
+ bookmarked: i.bookmarked ? '1' : '0',
language : i.language,
description: i.description ? i.description?.replace('\n', ' ') : '']
}
@@ -412,20 +458,20 @@ class SyncController {
def records = []
def priorityMap = [5: 'p5', 4: 'p4', 3: 'p3', 2: 'p2', 1: 'p1']
// order by department.orderNumber asc, course.orderNumber asc, orderNumber asc
- for (i in IndexCard.executeQuery("from Book where bookmarked = ? order by priority desc, id desc",
- [true])) {
+ for (i in IndexCard.executeQuery("from Book b where b.bookmarked = ? and (b.user.username = ? or b.isPrivate = true) order by b.id desc", // b.priority desc // b.type.code asc, b.title asc
+ [true, params.id])) {
// OperationController.countResourceFiles(i.id)
records += [type : 'R',
id : i.id,
resourceType: i?.type?.code,
ecode : 'R',
- meta : '#' + i.type?.code + (i.publishedOn ? ' ' + i.publishedOn?.format('yyyy') + '' : ''),
+ meta : '#' + i.type?.code, // + (i.publishedOn ? ' ' + i.publishedOn?.format('yyyy') + '' : ''),
color : 'DarkSlateBlue',
language : i.language,
filesList : i.filesList,
nbFiles : i.nbFiles,
summary : i.title + (i.legacyTitle ? ' [' + i.legacyTitle + ' ]' : ''),
- description : (i.description ? i.description?.replace('\n', ' '): '') + ' --- ' + (i.fullText?.replace('\n', ' ')?.replaceAll(/http[\S\.]*/, '')
+ description : (i.description ? i.description?.replace('\n', ' '): '') + ' ' + (i.fullText?.replace('\n', ' ')?.replaceAll(/http[\S\.]*/, '')
?.replaceAll(/www[\S\.]*/, '') ?: '')]
}
@@ -439,14 +485,15 @@ class SyncController {
def exportJsonG = {
- // syncMobile(params.tosync)
+ // syncMobile(params.tosync)
+//println ' in jsonG' + params.id
def builder = new JSONBuilder()
def records = []
def priorityMap = [5: 'p5', 4: 'p4', 3: 'p3', 2: 'p2', 1: 'p1']
- for (i in Task.executeQuery("from Goal g where g.bookmarked = ? order by g.priority desc, g.id desc", [true])) {
+ for (i in Task.executeQuery("from Goal g where g.bookmarked = ? and (g.user.username = ? or g.isPrivate = true) order by g.priority desc, g.id desc", [true, params.id])) {
// g.department.code asc, g.priority desc todo:
records += [type : 'G',
id : i.id,
@@ -541,6 +588,10 @@ class SyncController {
color : 'lightorange',
summary : i.summary,
language : i.language,
+
+ filesList : i.filesList,
+ nbFiles : i.nbFiles,
+
description: (i.description ? i.description?.replace('\n', ' ') : '') +
(i.notes ? ' === ' + i.notes?.replace('\n', ' ')?.replace('__________________________________________________', '---') : '')]
}
@@ -559,7 +610,7 @@ class SyncController {
def records = []
def priorityMap = [5: 'p5', 4: 'p4', 3: 'p3', 2: 'p2', 1: 'p1']
- for (i in IndexCard.executeQuery("from IndexCard where bookmarked = ? order by priority desc, lastUpdated desc", [true])) {
+ for (i in IndexCard.executeQuery("from IndexCard t where t.bookmarked = ? and (t.user.username = ? or t.isPrivate = true) order by t.lastUpdated desc", [true, params.id])) {
records += [type : 'N',
id : i.id,
ecode : 'N',
@@ -672,24 +723,39 @@ class SyncController {
def mobilePush() {
+
+ if (Setting.findByName('lastMobileSync'))
+ OperationController.setPath('lastMobileSync', new Date().format('dd.MM.yyyy HH:mm'))
+ else {
+ new Setting([name: 'lastMobileSync', value: new Date().format('dd.MM.yyyy HH:mm')]).save(flush: true)
+ }
+
+
def builder = new JSONBuilder()
def json
- //new File('d:/test.log').write(request.JSON.data, 'UTF-8')
+
+// try {
+// new File('/nbr/mbl.log').write('\n Mobile push request, ' + new Date()?.format('dd.MM.yyyy HH:mm') + ':\n')
+// new File('/nbr/mbl.log').write(request.JSON.data?.toString(), 'UTF-8')
+// } catch (Exception e){
+// println 'Error write mobile push log file'
+// }
def data = request.JSON.data
- println 'new data ' + data
+// println 'new data ' + data
def c = 0
+
// println 'in mobile push json ' + params.dump()
// println 'in mobile push json ' + params.tosyncText
//println 'dump ' + params.dump()
if (params.tosyncText)
- println 'array ' + params.tosyncText
+// println 'array ' + params.tosyncText
data.each() { r ->
// r = JSON.parse(r)
- println ' processing row ' + r
+// println ' processing row ' + r
c++
// println GenericsController.markCompletedStatic(r.substring(1).toLong(), r.substring(0, 1).toUpperCase())
@@ -760,8 +826,14 @@ if (!record.notes)
}
}
- render c
- }
+
+
+ json = builder.build {
+ result = c + ' processed updates'
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+}
def mobilePush0() {
def c = 0
@@ -834,7 +906,7 @@ if (!record.notes)
}
}
- render c
+ render (c + ' processed updates')
}
@@ -925,7 +997,7 @@ if (!record.notes)
def json
// new File('/home/maitham/test.log').write(request.JSON.data, 'UTF-8')
def data = request.JSON.data
- println 'data is ' + data
+ // println 'data is ' + data
/** for non-json requests!!! ionic 6
* def data = JSON.parse(params['data'])
@@ -966,7 +1038,13 @@ if (!record.notes)
}
- record.bookmarked = true
+
+ // if set to true, new records will be synced back to reader
+
+ // record.bookmarked = true
+
+
+ record.department = Department.findByCode(o.department)
record.priority = o.priority
record.nbFiles = o.nbFiles
record.filesList = o.filesList?.join(',')
@@ -985,38 +1063,54 @@ if (!record.notes)
record.publishedOn = Date.parse('dd.MM.yyyy_HHmm', o.textDate)
- def savedRecord = record.save(flush: true)
- def newPath = supportService.getResourcePath(savedRecord.id, module.toUpperCase(), false)
+// println ' entered by ' + request.JSON.username + ' is found ' + security.User.findByUsername(request.JSON.username)
+ record.user = security.User.findByUsername(request.JSON.username)
- def path
- if (new File(OperationController.getPath('root.rps1.path') + '/new').exists()) {
- new File(OperationController.getPath('root.rps1.path') + '/new').eachFileMatch(~/${o.operationId} [\S\s]*/) { f ->
- path = f.path
- }
- if (path) {
- //println 'found a folder for this operation'
- //OperationController.getPath('root.rps1.path') + '/O/' + o.id
- new File(newPath).mkdirs()
- def ant = new AntBuilder()
- new File(path).eachFile() {
- ant.move(file: it.path,
- tofile: newPath + '/' + it.name)
+// def savedRecord = record.save(flush: true)
+
+ if (!record.hasErrors() && record.save(flush: true)) {
+
+ def newPath = supportService.getResourcePath(record.id, module.toUpperCase(), false)
+
+ def path
+
+ if (new File(OperationController.getPath('root.rps1.path') + '/new').exists()) {
+ new File(OperationController.getPath('root.rps1.path') + '/new').eachFileMatch(~/${o.operationId} [\S\s]*/) { f ->
+ path = f.path
}
- new File(path).delete()
- }
+ if (path) {
+ //println 'found a folder for this operation'
+ //OperationController.getPath('root.rps1.path') + '/O/' + o.id
+ new File(newPath).mkdirs()
+ def ant = new AntBuilder()
+ new File(path).eachFile() {
+ ant.move(file: it.path,
+ tofile: newPath + '/' + it.name)
+ }
+ new File(path).delete()
+ }
- }
+
+ }
// println data.size() + ' records found.'
// n.save(flush: true)
- json = builder.build {
- result = 'Record committed with id ' + savedRecord.id
+ json = builder.build {
+ result = 'Record imported to Nibras Desktop'// with id ' + record.id
+ }
+ }
+
+ else {
+
+ println 'Errors in record ' + record.dump() + ' errors are: '
+ record.errors.each() { println it }
+
}
} else {
json = builder.build {
@@ -1028,6 +1122,122 @@ if (!record.notes)
}
+ ////
+
+ def types() {
+
+// println 'here in modules \n\n\n'
+
+ def types = []
+
+ [
+ [id: 'T', name: 'Task', code: 'tasks'],
+ [id: 'P', name: 'Plan', code: 'plans'],
+ [id: 'G', name: 'Goal', code: 'goals'],
+ [id: 'N', name: 'Note', code: 'notes'],
+ [id: 'W', name: 'Writing', code: 'writings'],
+ [id: 'J', name: 'Journal', code: 'journal'],
+// [id: 'Jt', name: 'Yesterday journal', code: 'journal'],
+ [id: 'P', name: 'Planner', code: 'planner'],
+ [id: 'R', name: 'Resource', code: 'resources']
+ ].each(){
+ if (OperationController.getPath(it.code + '.enabled') == 'yes'){
+ types += it
+// println 'here in modules \n\n\n' + it.name
+ }
+
+ }
+
+
+
+
+ def builder = new JSONBuilder()
+ def json
+
+ json = builder.build {
+ result = 'yes'
+ modules = types
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+ }
+
+ def departments() {
+
+// println 'here in deparmtns \n\n\n'
+ def builder = new JSONBuilder()
+ def json
+
+ json = builder.build {
+ result = 'yes'
+ departments = Department.findAllByBookmarked(true, [sort: 'code', order: 'asc'])
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+
+
+ }
+
+ def nibrasFilesNestedById() {
+
+ def builder = new JSONBuilder()
+ def json
+ // def result = 'no'
+//
+ def resourceNestedById = 'no'
+
+ if (OperationController.getPath('resourceNestedById') == 'yes') {
+ resourceNestedById = 'yes'
+
+
+ json = builder.build {
+ result = 'yes'
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+ }
+
+ else {
+ json = builder.build {
+ result = 'no'
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+
+ }
+ }
+
+ def nibrasFilesNestedByType() {
+
+ def builder = new JSONBuilder()
+ def json
+ // def result = 'no'
+//
+ def resourceNestedByType = 'no'
+
+ if (OperationController.getPath('resourceNestedByType') == 'yes') {
+ resourceNestedByType = 'yes'
+
+
+ json = builder.build {
+ result = 'yes'
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+ }
+ else {
+ json = builder.build {
+ result = 'no'
+ }
+
+ render(status: 200, contentType: 'application/json', text: json)
+ }
+
+
+
+ }
+
+
def exportGold = {
def result = ''
for (i in mcs.Planner.executeQuery("from Planner where bookmarked = ? order by startDate desc ", [true])) {
diff --git a/grails-app/domain/app/Contact.groovy b/grails-app/domain/app/Contact.groovy
index 4d7355e..f433afa 100755
--- a/grails-app/domain/app/Contact.groovy
+++ b/grails-app/domain/app/Contact.groovy
@@ -92,8 +92,8 @@ class Contact implements Comparable { // entity id = 26
static mapping = {
// name (index:'name_index')
- description(sqlType: 'longtext')
- notes(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
}
diff --git a/grails-app/domain/app/IndexCard.groovy b/grails-app/domain/app/IndexCard.groovy
index 90f9069..d0673f4 100755
--- a/grails-app/domain/app/IndexCard.groovy
+++ b/grails-app/domain/app/IndexCard.groovy
@@ -139,7 +139,7 @@ class IndexCard implements Comparable { // entity id = 16
Boolean bookmarked = false
Boolean keepSecret = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
Boolean isMerged = false
Date mergedOn
@@ -172,17 +172,17 @@ class IndexCard implements Comparable { // entity id = 16
}
static mapping = {
- description(sqlType: 'longtext')
- shortDescription(sqlType: 'longtext')
- descriptionHTML(sqlType: 'longtext')
- mainHighlights(sqlType: 'longtext')
- sideHighlights(sqlType: 'longtext')
- reaction(sqlType: 'longtext')
- extractedWords(sqlType: 'longtext')
- sourceFree(sqlType: 'longtext')
- url(sqlType: 'longtext')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ shortDescription(sqlType: 'long varchar')
+ descriptionHTML(sqlType: 'long varchar')
+ mainHighlights(sqlType: 'long varchar')
+ sideHighlights(sqlType: 'long varchar')
+ reaction(sqlType: 'long varchar')
+ extractedWords(sqlType: 'long varchar')
+ sourceFree(sqlType: 'long varchar')
+ url(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// password type: GormEncryptedStringType
}
diff --git a/grails-app/domain/app/Indicator.groovy b/grails-app/domain/app/Indicator.groovy
index 40535a8..2af9d6f 100755
--- a/grails-app/domain/app/Indicator.groovy
+++ b/grails-app/domain/app/Indicator.groovy
@@ -85,9 +85,9 @@ class Indicator implements Comparable { // entity id = 22
}
static mapping = {
-
+ table 'indicators'
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
diff --git a/grails-app/domain/app/IndicatorData.groovy b/grails-app/domain/app/IndicatorData.groovy
index 645f588..86b2ebd 100755
--- a/grails-app/domain/app/IndicatorData.groovy
+++ b/grails-app/domain/app/IndicatorData.groovy
@@ -55,7 +55,7 @@ class IndicatorData implements Comparable { // entity id = 21
Integer priority
Boolean bookmarked = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
static constraints = {
indicator(nullable: false)
@@ -71,8 +71,8 @@ class IndicatorData implements Comparable { // entity id = 21
static mapping = {
// name (index:'name_index')
- description(sqlType: 'longtext')
- notes(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/Payment.groovy b/grails-app/domain/app/Payment.groovy
index 2f685c2..524e509 100755
--- a/grails-app/domain/app/Payment.groovy
+++ b/grails-app/domain/app/Payment.groovy
@@ -81,13 +81,13 @@ class Payment implements Comparable { // entity id = 24
static mapping = {
table 'payment'
- description(sqlType: 'longtext')
- intendedUse(sqlType: 'longtext')
- reality(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ intendedUse(sqlType: 'long varchar')
+ reality(sqlType: 'long varchar')
// name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/PaymentCategory.groovy b/grails-app/domain/app/PaymentCategory.groovy
index abb3d1f..e2dc6d1 100755
--- a/grails-app/domain/app/PaymentCategory.groovy
+++ b/grails-app/domain/app/PaymentCategory.groovy
@@ -65,7 +65,7 @@ class PaymentCategory implements Comparable { // entity id = 23
static mapping = {
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
public String entityCode() {
diff --git a/grails-app/domain/app/Rating.groovy b/grails-app/domain/app/Rating.groovy
deleted file mode 100755
index b24195b..0000000
--- a/grails-app/domain/app/Rating.groovy
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2018. Mohamad F. Fakih (mail@khuta.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see
- */
-
-package app
-
-class Rating implements Comparable { // entity id = 26
-
- // Fields
-
- String source
- String title
- String link
- Integer rating
- String tag
-
- Date newsDate
-
- Date dateCreated
- Date lastUpdated
-
-
- static constraints = {
-// summary(blank: false, nullable: false)
- }
-
- static mapping = {
- // name (index:'name_index')
- title(sqlType: 'longtext')
- }
-
- int compareTo(obj) {
- if (id && obj.id)
- return id.compareTo(obj.id)
- else return 1
- }
-
-} // end of class
diff --git a/grails-app/domain/app/Tag.groovy b/grails-app/domain/app/Tag.groovy
index 1b50dd7..ad042a6 100755
--- a/grails-app/domain/app/Tag.groovy
+++ b/grails-app/domain/app/Tag.groovy
@@ -56,7 +56,7 @@ class Tag implements Comparable { // entity id = 12
static mapping = {
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/parameters/Blog.groovy b/grails-app/domain/app/parameters/Blog.groovy
old mode 100644
new mode 100755
index d002bf7..c40d54e
--- a/grails-app/domain/app/parameters/Blog.groovy
+++ b/grails-app/domain/app/parameters/Blog.groovy
@@ -18,6 +18,8 @@
package app.parameters
import cmn.DataChangeAudit
+import security.User
+
//import com.bloomhealthco.jasypt.GormEncryptedStringType
class Blog implements Comparable { // entity id = 20
@@ -27,6 +29,10 @@ class Blog implements Comparable { // entity id = 20
// Fields
+ User user
+
+ Boolean bookmarked = false
+
String summary
String code
@@ -37,6 +43,8 @@ class Blog implements Comparable { // entity id = 20
String notes
+ String language
+
Date dateCreated
Date lastUpdated
Date deletedOn
@@ -51,7 +59,7 @@ class Blog implements Comparable { // entity id = 20
}
static mapping = {
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// password type: GormEncryptedStringType
}
diff --git a/grails-app/domain/app/parameters/CommandPrefix.groovy b/grails-app/domain/app/parameters/CommandPrefix.groovy
old mode 100644
new mode 100755
index f9802fb..27b8d61
--- a/grails-app/domain/app/parameters/CommandPrefix.groovy
+++ b/grails-app/domain/app/parameters/CommandPrefix.groovy
@@ -18,6 +18,7 @@
package app.parameters
import cmn.DataChangeAudit
+import security.User
class CommandPrefix implements Comparable { // entity id = 29
@@ -25,6 +26,9 @@ class CommandPrefix implements Comparable { // entity id = 29
// static searchable = [only:['name', 'notes' ]]
// Fields
+
+ User user
+
String code
String summary
String module
@@ -54,7 +58,7 @@ class CommandPrefix implements Comparable { // entity id = 29
static mapping = {
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/parameters/Markup.groovy b/grails-app/domain/app/parameters/Markup.groovy
old mode 100644
new mode 100755
index 2d2f6e8..a4539ec
--- a/grails-app/domain/app/parameters/Markup.groovy
+++ b/grails-app/domain/app/parameters/Markup.groovy
@@ -18,6 +18,7 @@
package app.parameters
import cmn.DataChangeAudit
+import security.User
class Markup implements Comparable { // entity id = 20
@@ -26,6 +27,8 @@ class Markup implements Comparable { // entity id = 20
// Fields
+ User user
+
String summary
String code
@@ -47,7 +50,7 @@ class Markup implements Comparable { // entity id = 20
}
static mapping = {
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/parameters/Module.groovy b/grails-app/domain/app/parameters/Module.groovy
old mode 100644
new mode 100755
index ccfdc6b..a3db904
--- a/grails-app/domain/app/parameters/Module.groovy
+++ b/grails-app/domain/app/parameters/Module.groovy
@@ -18,6 +18,7 @@
package app.parameters
import cmn.DataChangeAudit
+import security.User
class Module implements Comparable { // entity id = 20
@@ -26,6 +27,8 @@ class Module implements Comparable { // entity id = 20
// Fields
+ User user
+
String summary
String code
@@ -53,7 +56,7 @@ class Module implements Comparable { // entity id = 20
}
static mapping = {
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/app/parameters/ResourceType.groovy b/grails-app/domain/app/parameters/ResourceType.groovy
old mode 100644
new mode 100755
index 9f34e24..9a4aca7
--- a/grails-app/domain/app/parameters/ResourceType.groovy
+++ b/grails-app/domain/app/parameters/ResourceType.groovy
@@ -18,6 +18,7 @@
package app.parameters
import cmn.DataChangeAudit
+import security.User
class ResourceType implements Comparable { // entity id = 29
@@ -25,6 +26,9 @@ class ResourceType implements Comparable { // entity id = 29
// static searchable = [only:['name', 'notes' ]]
// Fields
+
+ User user
+
String code
String name
String style
@@ -54,7 +58,7 @@ class ResourceType implements Comparable { // entity id = 29
static mapping = {
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/cmn/DataChangeAudit.groovy b/grails-app/domain/cmn/DataChangeAudit.groovy
old mode 100644
new mode 100755
index 129c49c..48728d7
--- a/grails-app/domain/cmn/DataChangeAudit.groovy
+++ b/grails-app/domain/cmn/DataChangeAudit.groovy
@@ -53,8 +53,8 @@ class DataChangeAudit implements Comparable { // entity id = 18
}
static mapping = {
- operationDetails(sqlType: 'longtext')
- exactOperation(sqlType: 'longtext')
+ operationDetails(sqlType: 'long varchar')
+ exactOperation(sqlType: 'long varchar')
datePerformed(sqlType: 'datetime')
table 'data_change_audits'
diff --git a/grails-app/domain/cmn/Setting.groovy b/grails-app/domain/cmn/Setting.groovy
old mode 100644
new mode 100755
index 01d2ebc..956a01f
--- a/grails-app/domain/cmn/Setting.groovy
+++ b/grails-app/domain/cmn/Setting.groovy
@@ -17,8 +17,12 @@
package cmn
+import security.User
+
class Setting { // entity id = 51
+ User user
+
String name
String summary
String value
@@ -39,13 +43,13 @@ class Setting { // entity id = 51
}
static mapping = {
- // table "SETTINGS"
- value(sqlType: 'longtext')
- summary(sqlType: 'longtext')
- description(sqlType: 'longtext')
- allowedValues(sqlType: 'longtext')
- explanation(sqlType: 'longtext')
- notes(sqlType: 'longtext')
+ // table "SETTINGS"
+ value(sqlType: 'long varchar')
+// summary(sqlType: 'long varchar')
+ description(sqlType: 'long varchar')
+ allowedValues(sqlType: 'long varchar')
+ explanation(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
}
public String entityCode() {
diff --git a/grails-app/domain/mcs/Book.groovy b/grails-app/domain/mcs/Book.groovy
index b8ba1db..373577d 100755
--- a/grails-app/domain/mcs/Book.groovy
+++ b/grails-app/domain/mcs/Book.groovy
@@ -72,6 +72,7 @@ class Book implements Comparable { // entity id = 134
String shortFileName
String description
+ String descriptionHTML
String fullText
@@ -125,14 +126,14 @@ class Book implements Comparable { // entity id = 134
Contact person
String journal
String month
- String year
+ String resourceYear
String volume
String number
String series
Boolean bookmarked = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
Boolean keepSecret = false
@@ -168,9 +169,15 @@ class Book implements Comparable { // entity id = 134
// Blog blog
// String blogCode
- Date publishedOn
+// Date publishedOn
// Integer publishedNodeId
+ Blog blog
+ String blogCode
+ Date publishedOn
+ Integer publishedNodeId
+
+
String textTags
String notes
@@ -205,29 +212,30 @@ class Book implements Comparable { // entity id = 134
static mapping = {
//id(generator: 'assigned')
- title(sqlType: 'longtext')
- author(sqlType: 'longtext')
- authorInfo(sqlType: 'longtext')
- description(sqlType: 'longtext')
- fullText(sqlType: 'longtext')
- bibEntry(sqlType: 'longtext')
- highlights(sqlType: 'longtext')
- comments(sqlType: 'longtext')
- reviewHistory(sqlType: 'longtext')
- stepsHistory(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+// title(sqlType: 'long varchar')
+// author(sqlType: 'long varchar')
+ authorInfo(sqlType: 'long varchar')
+ description(sqlType: 'long varchar')
+ descriptionHTML(sqlType: 'long varchar')
+ fullText(sqlType: 'long varchar')
+ bibEntry(sqlType: 'long varchar')
+ highlights(sqlType: 'long varchar')
+ comments(sqlType: 'long varchar')
+ reviewHistory(sqlType: 'long varchar')
+ stepsHistory(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
table 'book'
//sort "id":"desc"
//name (index:'name_index')
- textTags(sqlType: 'longtext')
- notes(sqlType: 'longtext')
- imageUrl(sqlType: 'longtext')
- url(sqlType: 'longtext')
- citation(sqlType: 'longtext')
- citationText(sqlType: 'longtext')
- citationHtml(sqlType: 'longtext')
- citationAsciicode(sqlType: 'longtext')
+ textTags(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
+ imageUrl(sqlType: 'long varchar')
+ url(sqlType: 'long varchar')
+ citation(sqlType: 'long varchar')
+ citationText(sqlType: 'long varchar')
+ citationHtml(sqlType: 'long varchar')
+ citationAsciicode(sqlType: 'long varchar')
// excerpts: Excerpt cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Course.groovy b/grails-app/domain/mcs/Course.groovy
index 2e60bb6..901813f 100755
--- a/grails-app/domain/mcs/Course.groovy
+++ b/grails-app/domain/mcs/Course.groovy
@@ -99,13 +99,13 @@ class Course implements Comparable { // entity id = 130
}
static mapping = {
- description(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
table 'course'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Department.groovy b/grails-app/domain/mcs/Department.groovy
index 582297d..756e007 100755
--- a/grails-app/domain/mcs/Department.groovy
+++ b/grails-app/domain/mcs/Department.groovy
@@ -64,7 +64,7 @@ class Department { // entity id = 131
//long getNumberOfTasks() { return tasks ? tasks.size() : 0 }
static constraints = {
- code(unique: true)
+ code(nullable: true, unique: true)
summary(nullable: false, blank: false)
courses()
@@ -79,7 +79,7 @@ class Department { // entity id = 131
table 'department'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// courses: Course cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Excerpt.groovy b/grails-app/domain/mcs/Excerpt.groovy
index e23d204..c1d3c6e 100755
--- a/grails-app/domain/mcs/Excerpt.groovy
+++ b/grails-app/domain/mcs/Excerpt.groovy
@@ -98,9 +98,9 @@ class Excerpt implements Comparable { // entity id = 143
table 'excerpt'
//sort "id":"desc"
//name (index:'name_index')
- description(sqlType: 'longtext')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Goal.groovy b/grails-app/domain/mcs/Goal.groovy
index 1a9fe78..0630e9a 100755
--- a/grails-app/domain/mcs/Goal.groovy
+++ b/grails-app/domain/mcs/Goal.groovy
@@ -81,7 +81,7 @@ class Goal implements Comparable { // entity id = 126
Date endDate
Boolean bookmarked = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
// new value - migrate to it
WorkStatus status
@@ -126,14 +126,14 @@ class Goal implements Comparable { // entity id = 126
}
static mapping = {
- summary(sqlType: 'longtext')
+ // summary(sqlType: 'long varchar')
table 'goal'
- description(sqlType: 'longtext')
- stepsHistory(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ stepsHistory(sqlType: 'long varchar')
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Journal.groovy b/grails-app/domain/mcs/Journal.groovy
index 57382c6..a73b60e 100755
--- a/grails-app/domain/mcs/Journal.groovy
+++ b/grails-app/domain/mcs/Journal.groovy
@@ -92,7 +92,7 @@ class Journal implements Comparable { // entity id = 125
Boolean keepSecret = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
Integer reviewCount = 0
@@ -138,9 +138,9 @@ class Journal implements Comparable { // entity id = 125
table 'journal'
//sort "id":"desc"
//name (index:'name_index')
- description(sqlType: 'longtext')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Operation.groovy b/grails-app/domain/mcs/Operation.groovy
old mode 100644
new mode 100755
index f901926..191e0c0
--- a/grails-app/domain/mcs/Operation.groovy
+++ b/grails-app/domain/mcs/Operation.groovy
@@ -66,12 +66,12 @@ class Operation implements Comparable { // entity id =
}
static mapping = {
- description(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
table 'operation'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Planner.groovy b/grails-app/domain/mcs/Planner.groovy
index c2a20b6..42073ab 100755
--- a/grails-app/domain/mcs/Planner.groovy
+++ b/grails-app/domain/mcs/Planner.groovy
@@ -106,7 +106,7 @@ class Planner implements Comparable { // entity id = 137
Boolean isDayChallenge
Boolean bookmarked
- Boolean isPrivate = false
+ Boolean isPrivate = true
@@ -128,7 +128,9 @@ class Planner implements Comparable { // entity id = 137
static constraints = {
level(inList: ['l', 'y', 'e', 'A', 'M', 'r', 'w', 'd', 'm', 'i'])
- startDate(nullable: false, unique: ['task'])
+
+ startDate(nullable: false)
+
endDate()
description()
@@ -141,14 +143,14 @@ class Planner implements Comparable { // entity id = 137
}
static mapping = {
- description(sqlType: 'longtext')
- reality(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ reality(sqlType: 'long varchar')
table 'planner'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Relationship.groovy b/grails-app/domain/mcs/Relationship.groovy
old mode 100644
new mode 100755
index 70b4d4c..64ea8e9
--- a/grails-app/domain/mcs/Relationship.groovy
+++ b/grails-app/domain/mcs/Relationship.groovy
@@ -23,7 +23,9 @@ package mcs
import cmn.*
import grails.converters.*
- import java.text.SimpleDateFormat
+import security.User
+
+import java.text.SimpleDateFormat
class Relationship implements Comparable { // entity id = 453
@@ -36,7 +38,9 @@ class Relationship implements Comparable { // entity id = 453
// static searchable = [only:['entityA', 'entityB', 'type', 'recordA', 'recordB', 'notes' ]]
// Fields
-
+
+ User user
+
String entityA
String entityACode
@@ -73,7 +77,7 @@ class Relationship implements Comparable { // entity id = 453
static mapping = {
table 'relationship'
- notes (sqlType: 'longtext')
+ notes (sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/mcs/Task.groovy b/grails-app/domain/mcs/Task.groovy
index 777ef9e..3e00dff 100755
--- a/grails-app/domain/mcs/Task.groovy
+++ b/grails-app/domain/mcs/Task.groovy
@@ -92,7 +92,7 @@ class Task implements Comparable { // entity id = 127
Boolean isTopic = false
Boolean bookmarked
- Boolean isPrivate = false
+ Boolean isPrivate = true
String notes
@@ -132,14 +132,14 @@ class Task implements Comparable { // entity id = 127
}
static mapping = {
- description(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
table 'task'
//sort "id":"desc"
//name (index:'name_index')
- description(sqlType: 'longtext')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/Writing.groovy b/grails-app/domain/mcs/Writing.groovy
index f06f553..0a5cfcc 100755
--- a/grails-app/domain/mcs/Writing.groovy
+++ b/grails-app/domain/mcs/Writing.groovy
@@ -93,7 +93,7 @@ class Writing implements Comparable { // entity id = 144
Date bornOn
Boolean bookmarked = false
- Boolean isPrivate = false
+ Boolean isPrivate = true
Boolean keepSecret = false
Integer priority = 2
@@ -143,15 +143,15 @@ class Writing implements Comparable { // entity id = 144
}
static mapping = {
- description(sqlType: 'longtext')
- shortDescription(sqlType: 'longtext')
- descriptionHTML(sqlType: 'longtext')
+ description(sqlType: 'long varchar')
+ shortDescription(sqlType: 'long varchar')
+ descriptionHTML(sqlType: 'long varchar')
table 'writing'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
- filesList(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
+ filesList(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/Context.groovy b/grails-app/domain/mcs/parameters/Context.groovy
old mode 100644
new mode 100755
index 71e0567..b82971b
--- a/grails-app/domain/mcs/parameters/Context.groovy
+++ b/grails-app/domain/mcs/parameters/Context.groovy
@@ -18,6 +18,7 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class Context implements Comparable { // entity id = 156
@@ -26,6 +27,8 @@ class Context implements Comparable { // entity id = 156
// Fields
+ User user
+
String code
String name
@@ -54,7 +57,7 @@ class Context implements Comparable { // entity id = 156
table 'work_location'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/Country.groovy b/grails-app/domain/mcs/parameters/Country.groovy
old mode 100644
new mode 100755
index 9187153..be3ea34
--- a/grails-app/domain/mcs/parameters/Country.groovy
+++ b/grails-app/domain/mcs/parameters/Country.groovy
@@ -18,6 +18,7 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class Country implements Comparable { // entity id = 156
@@ -26,6 +27,8 @@ class Country implements Comparable { // entity id = 156
// Fields
+ User user
+
String code
String name
@@ -53,7 +56,7 @@ class Country implements Comparable { // entity id = 156
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/GoalType.groovy b/grails-app/domain/mcs/parameters/GoalType.groovy
old mode 100644
new mode 100755
index fc3b434..8966a1a
--- a/grails-app/domain/mcs/parameters/GoalType.groovy
+++ b/grails-app/domain/mcs/parameters/GoalType.groovy
@@ -18,6 +18,7 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class GoalType implements Comparable { // entity id = 139
@@ -26,6 +27,8 @@ class GoalType implements Comparable { // entity id = 139
// Fields
+ User user
+
String code
String name
@@ -56,7 +59,7 @@ class GoalType implements Comparable { // entity id = 139
table 'goal_type'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/JournalType.groovy b/grails-app/domain/mcs/parameters/JournalType.groovy
old mode 100644
new mode 100755
index 657820a..ad4776b
--- a/grails-app/domain/mcs/parameters/JournalType.groovy
+++ b/grails-app/domain/mcs/parameters/JournalType.groovy
@@ -18,6 +18,7 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class JournalType implements Comparable { // entity id = 141
@@ -26,13 +27,16 @@ class JournalType implements Comparable { // entity id = 141
// Fields
+ User user
+
String code
String color
String style
String name
Integer metaType
- Integer category
+// Integer category
+
String indicatorCode
String notes
@@ -58,7 +62,7 @@ class JournalType implements Comparable { // entity id = 141
table 'journal_type'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/Location.groovy b/grails-app/domain/mcs/parameters/Location.groovy
old mode 100644
new mode 100755
index 06fbcdb..5e9257a
--- a/grails-app/domain/mcs/parameters/Location.groovy
+++ b/grails-app/domain/mcs/parameters/Location.groovy
@@ -18,6 +18,7 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class Location implements Comparable { // entity id = 156
@@ -26,6 +27,9 @@ class Location implements Comparable { // entity id = 156
// Fields
+ User user
+
+
Country country
String code
String name
@@ -55,7 +59,7 @@ class Location implements Comparable { // entity id = 156
table 'location'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/PlannerType.groovy b/grails-app/domain/mcs/parameters/PlannerType.groovy
old mode 100644
new mode 100755
index caee346..bf8a34f
--- a/grails-app/domain/mcs/parameters/PlannerType.groovy
+++ b/grails-app/domain/mcs/parameters/PlannerType.groovy
@@ -30,7 +30,7 @@ class PlannerType implements Comparable { // entity id = 157
String color
String style
String name
- Integer category
+// Integer category
String notes
@@ -56,7 +56,7 @@ class PlannerType implements Comparable { // entity id = 157
table 'planner_type'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/RelationshipType.groovy b/grails-app/domain/mcs/parameters/RelationshipType.groovy
old mode 100644
new mode 100755
index 10f8cc0..537e7c2
--- a/grails-app/domain/mcs/parameters/RelationshipType.groovy
+++ b/grails-app/domain/mcs/parameters/RelationshipType.groovy
@@ -62,7 +62,7 @@ class RelationshipType implements Comparable { // entity id = 452
static mapping = {
table 'relationship_type'
- notes (sqlType: 'longtext')
+ notes (sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/mcs/parameters/ResourceStatus.groovy b/grails-app/domain/mcs/parameters/ResourceStatus.groovy
old mode 100644
new mode 100755
index b1e6a1e..2e9b760
--- a/grails-app/domain/mcs/parameters/ResourceStatus.groovy
+++ b/grails-app/domain/mcs/parameters/ResourceStatus.groovy
@@ -53,7 +53,7 @@ class ResourceStatus implements Comparable { // entity id = 158
table 'resource_status'
// sort "id":"desc"
// name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/SavedSearch.groovy b/grails-app/domain/mcs/parameters/SavedSearch.groovy
old mode 100644
new mode 100755
index 40aec0b..516887e
--- a/grails-app/domain/mcs/parameters/SavedSearch.groovy
+++ b/grails-app/domain/mcs/parameters/SavedSearch.groovy
@@ -23,7 +23,9 @@ import mcs.*
import cmn.*
import grails.converters.*
- import java.text.SimpleDateFormat
+import security.User
+
+import java.text.SimpleDateFormat
class SavedSearch implements Comparable { // entity id = 451
@@ -37,6 +39,7 @@ class SavedSearch implements Comparable { // entity id = 451
// Fields
+ User user
String queryType = 'hql'
String reportType = 'list'
@@ -92,9 +95,9 @@ class SavedSearch implements Comparable { // entity id = 451
static mapping = {
table 'saved_search'
- query (sqlType: 'longtext')
- countQuery (sqlType: 'longtext')
- notes (sqlType: 'longtext')
+ query (sqlType: 'long varchar')
+ countQuery (sqlType: 'long varchar')
+ notes (sqlType: 'long varchar')
}
static namedQueries = {
diff --git a/grails-app/domain/mcs/parameters/WorkStatus.groovy b/grails-app/domain/mcs/parameters/WorkStatus.groovy
old mode 100644
new mode 100755
index 6145c13..b649dfa
--- a/grails-app/domain/mcs/parameters/WorkStatus.groovy
+++ b/grails-app/domain/mcs/parameters/WorkStatus.groovy
@@ -18,13 +18,16 @@
package mcs.parameters
import cmn.DataChangeAudit
+import security.User
class WorkStatus implements Comparable { // entity id = 138
static searchable = [only: ['name', 'notes']]
+
// Fields
+ User user
String code
Boolean isActive
@@ -56,7 +59,7 @@ class WorkStatus implements Comparable { // entity id = 138
table 'work_status'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/WritingStatus.groovy b/grails-app/domain/mcs/parameters/WritingStatus.groovy
old mode 100644
new mode 100755
index 798b12b..7b02d3f
--- a/grails-app/domain/mcs/parameters/WritingStatus.groovy
+++ b/grails-app/domain/mcs/parameters/WritingStatus.groovy
@@ -53,7 +53,7 @@ class WritingStatus implements Comparable { // entity id = 145
table 'writing_status'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/domain/mcs/parameters/WritingType.groovy b/grails-app/domain/mcs/parameters/WritingType.groovy
old mode 100644
new mode 100755
index 0b9f5a7..4f27799
--- a/grails-app/domain/mcs/parameters/WritingType.groovy
+++ b/grails-app/domain/mcs/parameters/WritingType.groovy
@@ -54,7 +54,7 @@ class WritingType implements Comparable { // entity id = 155
table 'writing_type'
//sort "id":"desc"
//name (index:'name_index')
- notes(sqlType: 'longtext')
+ notes(sqlType: 'long varchar')
// null cascade: 'persist,merge,save-update'
}
diff --git a/grails-app/init/nibras/BootStrap.groovy b/grails-app/init/nibras/BootStrap.groovy
index 7f0d1ab..72289eb 100644
--- a/grails-app/init/nibras/BootStrap.groovy
+++ b/grails-app/init/nibras/BootStrap.groovy
@@ -2,10 +2,12 @@ package nibras
import ker.OperationController
import security.*
-
+import grails.core.GrailsApplication
class BootStrap {
+ GrailsApplication grailsApplication
+
def init = { servletContext ->
if (User.count() == 0) {
@@ -41,12 +43,16 @@ class BootStrap {
"""
+
+ def port = grailsApplication.config.getProperty('server.port')
+ def contextPath = grailsApplication.config.getProperty('server.contextPath')
+
println ''
println ' ************************************************************'
println ' * *'
println ' * Nibras has launched. You can access it from: *'
println ' * *'
- println ' * https://localhost:1441/ *'
+ println " * https://localhost:${port}${contextPath} "
println ' * *'
// println ' * Note: To stop Nibras, press ctrl+c in this window, or *'
// println ' * run ./scripts/stop script. *'
@@ -56,9 +62,9 @@ class BootStrap {
println ''
if (org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS) {
- """c:\\windows\\explorer "" https://localhost:1441/""".execute()
+ """c:\\windows\\explorer "" https://localhost:${port}/${contextPath}""".execute()
} else if (org.apache.commons.lang.SystemUtils.IS_OS_LINUX){
- """/usr/bin/xdg-open https://localhost:1441/""".execute()
+ """/usr/bin/xdg-open https://localhost:${port}${contextPath}""".execute()
}
diff --git a/grails-app/services/SupportService.groovy b/grails-app/services/SupportService.groovy
old mode 100644
new mode 100755
index 82a93db..c05d6a6
--- a/grails-app/services/SupportService.groovy
+++ b/grails-app/services/SupportService.groovy
@@ -23,6 +23,8 @@ import mcs.Goal
//import mcs.WritingType
import net.bican.wordpress.CustomField
+import net.bican.wordpress.MediaItem
+import net.bican.wordpress.MediaItemUploadResult
//import net.bican.wordpress.Post
@@ -49,6 +51,58 @@ class SupportService {
// private static final log = LogFactory.getLog(this)
+ static entityMapping = [
+ 'G' : 'mcs.Goal',
+ 'ه' : 'mcs.Goal',
+ 'T' : 'mcs.Task',
+ 'ع' : 'mcs.Task',
+ 'P' : 'mcs.Planner',
+ 'خ' : 'mcs.Planner',
+
+ 'W' : 'mcs.Writing',
+ 'ك' : 'mcs.Writing',
+ 'N' : 'app.IndexCard',
+ 'ن' : 'app.IndexCard',
+
+ 'J' : 'mcs.Journal',
+ 'ذ' : 'mcs.Journal',
+ 'I' : 'app.IndicatorData',
+ 'K' : 'app.Indicator',
+
+ 'Q' : 'app.Payment',
+ 'د' : 'app.Payment',
+ 'L' : 'app.PaymentCategory',
+
+ 'R' : 'mcs.Book',
+ 'م' : 'mcs.Book',
+ 'C' : 'mcs.Course',
+ 'و' : 'mcs.Course',
+ 'D' : 'mcs.Department',
+ 'ج' : 'mcs.Department',
+ 'E' : 'mcs.Excerpt',
+ 'ف' : 'mcs.Excerpt',
+ 'S' : 'app.Contact',
+ 'Tag' : 'app.Tag',
+
+ 'Y' : 'cmn.Setting',
+ 'X' : 'mcs.parameters.SavedSearch',
+ 'A' : 'app.parameters.CommandPrefix',
+ 'O' : 'mcs.Operation',
+//todo for all params
+ 'ResourceType' : 'app.parameters.ResourceType',
+ 'WorkStatus' : 'mcs.parameters.WorkStatus',
+ 'WritingStatus': 'mcs.parameters.WritingStatus',
+ 'GoalType' : 'mcs.parameters.GoalType',
+ 'JournalType' : 'mcs.parameters.JournalType',
+ 'PlannerType' : 'mcs.parameters.PlannerType',
+ 'WritingType' : 'mcs.parameters.WritingType',
+ 'Context' : 'mcs.parameters.Context',
+ 'Blog' : 'app.parameters.Blog'
+
+ ]
+
+
+
String getResourcePath(Long id, String type, Boolean relative) {
if (type == 'R') {
@@ -392,7 +446,7 @@ class SupportService {
if (i.path)
result = countFolder(i.path, i.extensions)
else if (i.query)
- result = Goal.executeQuery("" + i.query)[0]
+ result = Goal.executeQuery("select count(*)" + i.query)[0] // todo: why select count(*) was removed!
return result
}
@@ -422,14 +476,24 @@ class SupportService {
}
- int postToBlog(Long blogId, String code, String title, String categoriesString, String tags, String fullText, String excerpt, String entityCode, Integer publishedNodeId) {
+ int postToBlog(Long blogId, String code, String title, String categoriesString, String tags, String fullText,
+ String excerpt, String entityCode, Integer publishedNodeId, String coverPath, String[] files, String uploadBase) {
+
try {
def username
def password
def link
ArrayList categories = categoriesString.split(',')
- Blog blog = Blog.get(blogId)
+
+
+ Blog blog
+
+ if (blogId)
+ blog = Blog.get(blogId)
+ else
+ blog = Blog.findByCode(OperationController.getPath('blog.current.code'))
+
username = blog.username
password = blog.password
link = blog.link
@@ -484,11 +548,39 @@ class SupportService {
post.setPost_title(title)
post.setPost_excerpt(excerpt)
+
+ def links = []
+
+ if (files){
+ files.each(){
+ links += '' + it + ' '
+
+ }
+ }
+ if (fullText && links)
+ post.setPost_content(fullText + 'Files: ' + links.join(' '))
+ else if (fullText && !links)
post.setPost_content(fullText)
+ else if (!fullText && links)
+ post.setPost_content( 'Files: ' + links.join(' '))
// post.setPage_status('published')
post.setPost_status('publish')
post.setPost_name(code)
+// def mi = new MediaItem()
+// mi.setLink('https://khuta.org/cover.jpg')
+
+if (coverPath) {
+ InputStream media = new FileInputStream(new File(coverPath))
+ final String fileName = "cover.jpg";
+ final MediaItemUploadResult mediaUploaded = wp.uploadFile(media, fileName);
+ final MediaItem r = wp.getMediaItem(mediaUploaded.getId());
+ post.setPost_thumbnail(r);
+}
+// Integer p = wp.newPost(post);
+
+// post.setPost_thumbnail(mi)
+
final List terms = wp.getTerms("post_tag");
def postTags = []
@@ -582,7 +674,11 @@ class SupportService {
// result = wp.getPost(publishedNodeId.intValue())
}
-// println 'resut is: ' + result
+ println 'resut is: ' + result
+
+ println 'post link is: ' + post.getLink()
+// render 'post link is: ' + post.getLink()
+
if (!publishedNodeId ) {
// println 'here'
return result
@@ -735,5 +831,104 @@ class SupportService {
return list
}
+ def updateBookmarkedRecordsFileCount(){
+
+// println 'In support service counting files...'
+
+
+
+ if (OperationController.getPath('panel.integrations.currentPlan.enabled') == 'yes') {
+ def path = OperationController.getPath('panel.integrations.currentPlan.path')
+ if (mcs.Planner.executeQuery('select count(*) from Planner where startDate <= ? and endDate >= ? ', [new Date(), new Date()])[0] > 0) {
+ def p =
+ mcs.Planner.executeQuery('from Planner where startDate <= ? and endDate >= ? ', [new Date(), new Date()])[0]
+
+ new File(path).write('>' + p.endDate?.format('HH:mm') + ' ' + p.summary, 'UTF-8')
+ } else {
+ new File(path).write('*** No plan set!', 'UTF-8')
+ }
+ }
+
+
+ def results = []
+ [mcs.Course,
+ mcs.Goal,
+ mcs.Task,
+ mcs.Planner,
+ mcs.Journal,
+
+ mcs.Writing,
+ app.IndexCard,
+
+ mcs.Book,
+ mcs.Excerpt,
+ app.Contact
+ ].each() {
+ it.findAllByBookmarked(true).each(){
+ OperationController.countResourceFilesStatic(it.id, it.entityCode())
+ }
+ }
+
+
+
+ }
+
+ def loadRecord(String entitCode, Long id){
+ return grailsApplication.classLoader.loadClass(entityMapping[entitCode]).get(id)
+ }
+
+
+
+ /**
+ * Calculates the similarity (a number within 0 and 1) between two strings.
+ */
+ public static double similarity(String s1, String s2) {
+ String longer = s1, shorter = s2;
+ if (s1.length() < s2.length()) { // longer should always have greater length
+ longer = s2; shorter = s1;
+ }
+ int longerLength = longer.length();
+ if (longerLength == 0) { return 1.0; /* both strings are zero length */ }
+ /* // If you have StringUtils, you can use it to calculate the edit distance:
+ return (longerLength - StringUtils.getLevenshteinDistance(longer, shorter)) /
+ (double) longerLength; */
+ return (longerLength - editDistance(longer, shorter)) / (double) longerLength;
+
+ }
+
+ // Example implementation of the Levenshtein Edit Distance
+ // See http://r...content-available-to-author-only...e.org/wiki/Levenshtein_distance#Java
+ public static int editDistance(String s1, String s2) {
+ s1 = s1.toLowerCase();
+ s2 = s2.toLowerCase();
+
+ int[] costs = new int[s2.length() + 1];
+ for (int i = 0; i <= s1.length(); i++) {
+ int lastValue = i;
+ for (int j = 0; j <= s2.length(); j++) {
+ if (i == 0)
+ costs[j] = j;
+ else {
+ if (j > 0) {
+ int newValue = costs[j - 1];
+ if (s1.charAt(i - 1) != s2.charAt(j - 1))
+ newValue = Math.min(Math.min(newValue, lastValue),
+ costs[j]) + 1;
+ costs[j - 1] = lastValue;
+ lastValue = newValue;
+ }
+ }
+ }
+ if (i > 0)
+ costs[s2.length()] = lastValue;
+ }
+ return costs[s2.length()];
+ }
+
+ public static void printSimilarity(String s, String t) {
+// System.out.println
+ render (String.format(
+ "%.3f is the similarity between \"%s\" and \"%s\"", similarity(s, t), s, t));
+ }
}
diff --git a/grails-app/taglib/pkm/PkmTagLib.groovy b/grails-app/taglib/pkm/PkmTagLib.groovy
old mode 100644
new mode 100755
index 11d2618..43599bf
--- a/grails-app/taglib/pkm/PkmTagLib.groovy
+++ b/grails-app/taglib/pkm/PkmTagLib.groovy
@@ -58,7 +58,7 @@ class PkmTagLib {
def text = attrs.text ? attrs.text.encodeAsHTML() : ''
def length = attrs.length
- out << StringUtils.abbreviate(text, length ? length.toInteger() : 80)?.replaceAll('>', ' ')?.replaceAll('<', ' ')?.encodeAsHTML()?.decodeHTML()
+ out << StringUtils.abbreviate(text, length ? length.toInteger() : 80)?.replaceAll('>', ' ')?.replaceAll('<', ' ')?.trim()//?.encodeAsHTML()?.replaceAll('\n', ' ')?.decodeHTML()
} else {
out << ''
}
@@ -159,13 +159,16 @@ ${i.isFile() ? '('+ prettySizeMethod(i.size()) + ')' : ''}
}
def listRecordFiles = { attrs ->
+
def module = attrs.module
def fileClass = attrs.fileClass
def recordId = attrs.recordId
def type = attrs.type
- def isStatic = attrs.static
+ def isStatic = attrs.isStatic
+ def abridged = attrs.abridged
def filesList = []
+
def resourceNestedById = false
def resourceNestedByType = false
@@ -225,9 +228,14 @@ ${i.isFile() ? '('+ prettySizeMethod(i.size()) + ')' : ''}
folders = [
typeSandboxPath +
(resourceNestedById ? '/' + (recordId / 100).toInteger() : ''),
- typeRepositoryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : ''),
- typeLibraryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '')
+// typeRepositoryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : ''),
+
]
+
+ if (isStatic != 'yes') {
+ folders += (typeRepositoryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : ''))
+ folders += (typeLibraryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : ''))
+ }
folders.each() { folder ->
if (new File(folder).exists()) {
@@ -237,13 +245,20 @@ ${i.isFile() ? '('+ prettySizeMethod(i.size()) + ')' : ''}
}
}
folders = [
- typeSandboxPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId,
+ typeSandboxPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId
// typeLibraryPath + '/' + (recordId / 100).toInteger() + '/' + recordId,
- typeRepositoryPath +(resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId,
- typeLibraryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId
+// typeRepositoryPath +(resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId,
+// typeLibraryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId
]
- def b = Book.get(recordId)
+
+ if (isStatic != 'yes') {
+ folders += (typeRepositoryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId)
+ folders += (typeLibraryPath + (resourceNestedById ? '/' + (recordId / 100).toInteger() : '') + '/' + recordId)
+ }
+
+
+ def b = Book.get(recordId)
// if (b.code){
// folders.add(typeSandboxPath + '/' + b.code)
// folders.add(typeRepositoryPath + '/' + b.code)
@@ -279,22 +294,33 @@ ${i.isFile() ? '('+ prettySizeMethod(i.size()) + ')' : ''}
out << ''
print 'Problem in listing record folder: ' + e.printStackTrace()
}
- def output = filesList.size() > 0 ? ""
+ output += ""
@@ -743,7 +776,7 @@ source src="${createLink(controller: 'operation', action: 'download', id: fileId
}
} else {
color = 'darkorange'
- output = "" + name + " "
+ output = "" + name + " "
out << output.decodeHTML()
}
@@ -827,7 +860,7 @@ source src="${createLink(controller: 'operation', action: 'download', id: fileId
def prettyDuration = { attrs ->
// out << supportService.toWeekDate(attrs.date)
-
+//println 'here in pretty' + attrs.dump()
if (attrs.date1) {
try {
Instant start = attrs.date1.toInstant()
@@ -836,12 +869,14 @@ source src="${createLink(controller: 'operation', action: 'download', id: fileId
long years = dur.toDays() / 365;
long months = (dur.toDays() % 365 ) / 30;
long days = ((dur.toDays() % 365 ) % 30) ;
-// long hours = dur.toDays();
-// long minutes = dur.toHours();
+ long hours = ((dur.toHours() % 365 ) % 30) % 24;
+ long minutes = (((dur.toMinutes() % 365 ) % 30) % 24 ) % 60;
+
+// todo: fine tune the display
+ out << (minutes ? minutes + 'min ' : '') + (hours ? hours + 'h ' : '') +(days ? days + 'd ' : '') + (months ? months + 'm ' : '') + (years ? years + 'y ' : '')
- out << (days ? days + 'd ' : '') + (months ? months + 'm ' : '') + (years ? years + 'y ' : '')
} catch(Exception e){
out << 'WD error!'
}
diff --git a/grails-app/views/appCalendar/_west.gsp b/grails-app/views/appCalendar/_west.gsp
new file mode 100755
index 0000000..f6e24e9
--- /dev/null
+++ b/grails-app/views/appCalendar/_west.gsp
@@ -0,0 +1,143 @@
+
+ %{--todo: dynamic height --}%
+
+
Add task/goal
+
+
+
+
+
+
+ Priority:
+
+ Context:
+
+ Goal:
+
+ Course:
+
+
+
+ %{-- todo: parametric language list--}%
+
+ %{-- --}%
+ %{-- --}%
+
+ %{-- --}%
+
+
+ %{-- --}%
+
+
+
+ %{-- --}%
+
+
+
Bookmarked tasks without goals
+
+
+
+ %{-- --}%
+
+ %{--@${c} --}%
+
+
+
+
+
+
+
+ @${c}
+
+
+
+
+
+
+ %{-- --}%
+
+ @${c}
+
+
+
+
+
+
+ %{--Overdue --}%
+ %{-- --}%
+
+ %{--@${c} --}%
+
+
+
+
+
+
+
+
+ %{-- --}%
+
+ %{--@${c} --}%
+
+
+
+
+
+
+
+
+
+
Goals and their tasks
+
+ %{--@${c} --}%
+ %{----}%
+
+
+ %{-- --}%
+
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+ %{--@${c} --}%
+ %{----}%
+ %{-- --}%
+ %{-- --}%
+ %{-- --}%
+
+
diff --git a/grails-app/views/appCalendar/main.gsp b/grails-app/views/appCalendar/main.gsp
index e3ad283..8c9a463 100755
--- a/grails-app/views/appCalendar/main.gsp
+++ b/grails-app/views/appCalendar/main.gsp
@@ -1,4 +1,4 @@
-<%@ page import="mcs.Goal; ker.OperationController; java.time.temporal.ChronoUnit; mcs.parameters.JournalType; mcs.Journal; mcs.Planner; mcs.parameters.PlannerType" %>
+<%@ page import="mcs.Task; mcs.Goal; ker.OperationController; java.time.temporal.ChronoUnit; mcs.parameters.JournalType; mcs.Journal; mcs.Planner; mcs.parameters.PlannerType" %>
@@ -52,6 +52,24 @@
%{-- --}%
+
+
+
+
+
+
+
+
+ %{----}%
+ %{----}%
+ %{-- --}%
+
+
+
+
+
+
+
@@ -67,7 +85,94 @@
+
+
+
+
+
+
+
+
+
+
+ Welcome to Jabal Amil website!
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+ %{--
--}%
+ Below are the applications that you are allowed to access.
+
+
+
+
+
+
+
+
+
+ ${n.wbsNumber} ${n.summary}
+ %{--[${n.id}]--}%
+
+ %{--${n.description}--}%
+ ${n.descriptionHTML ? raw(n.descriptionHTML) : raw(n.description?.replace("\n", " "))}
+
+
+
+
+
+
+
+
+
+
+
+ %{--
Create Account --}%
+
+
+
+
+
+
+
+
+
+
+ %{--
--}%
+ %{--
--}%
+ %{--${app.englishName}--}%
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+
+ %{--
--}%
+ %{----}%
+ %{--
--}%
+
+
+ %{--
--}%
+ %{--A BEAUTIFUL LANDSCAPE HERE--}%
+ %{-- --}%
+
+ ${app.description}
+
+
+
+
+
+
+
+
+
+
+
+ © 2022 -
+ Created by KickOff
+ | Built with
+
+
+
+
-
-
\ No newline at end of file
+
+
+
+%{----}%
+
+
+
+
+
+
+%{----}%
+%{----}%
+%{----}%
+%{----}%
+%{----}%
+
+
+
+
diff --git a/grails-app/views/appCourse/writingsBookHtml.gsp b/grails-app/views/appCourse/writingsBookHtml.gsp
new file mode 100755
index 0000000..5880ec7
--- /dev/null
+++ b/grails-app/views/appCourse/writingsBookHtml.gsp
@@ -0,0 +1,400 @@
+<%@ page import="app.IndexCard" %>
+
+
+
+
+
+
+ ${record?.summary}
+
+
+
+
+
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+
+ %{--
--}%
+
+
+
+
+
+
+ %{--
--}%
+ %{--
--}%
+
+
+ %{--
--}%
+
+
+ %{----}%
+ %{----}%
+ %{----}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+%{--
--}%
+ %{----}%
+ %{--
--}%
+ %{----}%
+ %{--
--}%
+ %{--أهلاً وسهلاً بكم في موقع مشروع جبل عامل--}%
+ %{-- --}%
+
+ %{----}%
+ %{----}%
+ %{-- --}%
+ %{--
--}%
+%{-- --}%
+
+
+
+
+
+
+
+%{--
--}%
+ %{--أهلاً وسهلاً بكم في موقع جبل عامل--}%
+
+
+
+
+
+ %{--
--}%
+ الإصدار الرابع - آخر تحديث:
+ 3 كانون الأول 2022
+
+
+
+
+
+
+
+ %{--
+ %{----}%
+
+
+
+
+
+ ${n.wbsNumber} - ${n.summary}
+
+
+
+ ${raw(n.description?.replace("\n", " "))}
+
+
+
+ %{-- ${n.wbsNumber} - ${n.summary} --}%
+ %{--[${n.id}]--}%
+ %{----}%
+ %{--${n.description}--}%
+ %{--${raw(n.description?.replace("\n", " "))}--}%
+ %{--n.description ? raw(n.description) :--}%
+ %{--
--}%
+
+
+ %{-- --}%
+
+
+
+
+
+
+
+
+
+ %{--
Create Account --}%
+
+
+
+
+
+
+
+
+
+
+ %{--
--}%
+ %{--
--}%
+ %{--${app.englishName}--}%
+ %{--
--}%
+ %{--
--}%
+ %{--
--}%
+
+ %{--
--}%
+ %{----}%
+ %{--
--}%
+
+
+ %{--
--}%
+ %{--A BEAUTIFUL LANDSCAPE HERE--}%
+ %{-- --}%
+
+ ${app.description}
+
+
+
+
+
+
+
+
+
+
+
+ © 2022 -
+ Created by KickOff
+ | Built with
+
+
+
+
+
+%{--
--}%
+
+
+
+
+
+
+
+%{----}%
+%{----}%
+%{----}%
+%{----}%
+%{----}%
+
+%{----}%
+
+
+
diff --git a/grails-app/views/appMain/_east.gsp b/grails-app/views/appMain/_east.gsp
old mode 100644
new mode 100755
index 755a802..5b76845
--- a/grails-app/views/appMain/_east.gsp
+++ b/grails-app/views/appMain/_east.gsp
@@ -1,5 +1,7 @@
<%@ page import="mcs.parameters.ResourceStatus; mcs.Goal; org.apache.commons.lang.StringUtils; mcs.Book; app.parameters.ResourceType; mcs.Writing; mcs.Department; mcs.parameters.WritingType; app.Tag; cmn.Setting; mcs.Course; mcs.Journal; mcs.Planner; app.IndexCard; mcs.Task; ker.OperationController" %>
-
+
%{--
--}%
-
+ %{-- --}%
diff --git a/grails-app/views/appMain/_north-old.gsp b/grails-app/views/appMain/_north-old.gsp
old mode 100644
new mode 100755
index fb7bba9..f5c861b
--- a/grails-app/views/appMain/_north-old.gsp
+++ b/grails-app/views/appMain/_north-old.gsp
@@ -1,6 +1,522 @@
<%@ page import="ker.OperationController; cmn.Setting;" %>
+
+
+
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+%{--/* ********* */--}%
+
+
diff --git a/grails-app/views/appMain/_north.gsp b/grails-app/views/appMain/_north.gsp
index fbaeca0..da1dcc4 100755
--- a/grails-app/views/appMain/_north.gsp
+++ b/grails-app/views/appMain/_north.gsp
@@ -1,510 +1,232 @@
<%@ page import="ker.OperationController; java.text.DecimalFormat; cmn.Setting; grails.util.Metadata" %>
-
diff --git a/grails-app/views/appMain/_regions.gsp b/grails-app/views/appMain/_regions.gsp
index a2d23ad..67e3adf 100755
--- a/grails-app/views/appMain/_regions.gsp
+++ b/grails-app/views/appMain/_regions.gsp
@@ -1,6 +1,13 @@
<%@ page import="mcs.parameters.ResourceStatus; mcs.Goal; org.apache.commons.lang.StringUtils; mcs.Book; app.parameters.ResourceType; mcs.Writing; mcs.Department; mcs.parameters.WritingType; app.Tag; cmn.Setting; mcs.Course; mcs.Journal; mcs.Planner; app.IndexCard; mcs.Task; ker.OperationController" %>
%{--${ker.OperationController.getPath('app.headers.background') ?: '#5b7a59'}--}%
+
@@ -61,7 +68,7 @@
style="margin: 0px !important; width: 100% !important; padding-bottom: 0px !important;">
@@ -103,20 +110,15 @@
-
-
+
Clear
- N++
- --
-
+
@@ -127,10 +129,15 @@
%{-- --}%
%{-- --}%
%{-- --}%
-
-
+
@@ -525,6 +551,20 @@
\ No newline at end of file
diff --git a/grails-app/views/appMain/_west.gsp b/grails-app/views/appMain/_west.gsp
old mode 100644
new mode 100755
index e662dc9..97b65f1
--- a/grails-app/views/appMain/_west.gsp
+++ b/grails-app/views/appMain/_west.gsp
@@ -71,6 +71,8 @@
%{-- --}%
%{--Calendar report includes:--}%
+
+
Show:
@@ -81,9 +83,11 @@
${type}
+
%{-- --}%
+
%{--
--}%
%{--
--}%
@@ -473,7 +477,7 @@
-
+
+ %{----}%
+ %{----}%
+ %{--
--}%
+
+
+
+
+
+
+
+
+ %{--
--}%
+
+
+
+
-