Просмотр исходного кода

Merge branch 'laravel' into laravel-migrate-wbw

Bhikkhu-Kosalla 4 лет назад
Родитель
Сommit
769d7204b4
61 измененных файлов с 814 добавлено и 297 удалено
  1. 3 4
      .env.example
  2. 44 4
      app/Console/Commands/Install.php
  3. 29 31
      app/Console/Commands/InstallPaliSeries.php
  4. 51 1
      app/Console/Commands/InstallWordAll.php
  5. 45 1
      app/Console/Commands/InstallWordIndex.php
  6. 47 1
      app/Console/Commands/InstallWordStatistics.php
  7. 3 0
      app/Models/WordIndex.php
  8. 2 0
      app/Models/WordList.php
  9. 2 0
      app/Models/WordStatistic.php
  10. 16 3
      change-logs.md
  11. 2 0
      config/app.php
  12. 1 0
      deploy/.gitignore
  13. 3 3
      deploy/README.md
  14. 4 2
      deploy/group_vars/all.yml
  15. 4 2
      deploy/mint.yml
  16. 24 0
      deploy/roles/certbot-nginx/tasks/main.yml
  17. 11 6
      deploy/roles/mint-assets/tasks/main.yml
  18. 1 1
      deploy/roles/mint-assets/templates/nginx.conf.j2
  19. 0 63
      deploy/roles/mint-clone/main.yml
  20. 96 0
      deploy/roles/mint-clone/tasks/main.yml
  21. 1 1
      deploy/roles/mint-clone/templates/config-v1.js.j2
  22. 14 14
      deploy/roles/mint-clone/templates/config-v1.php.j2
  23. 23 22
      deploy/roles/mint-clone/templates/env-v2.j2
  24. 2 2
      deploy/roles/mint-www/tasks/main.yml
  25. 24 14
      deploy/roles/mint-www/templates/nginx.conf.j2
  26. 0 7
      deploy/roles/os/tasks/init.yml
  27. 5 5
      deploy/roles/os/tasks/main.yml
  28. 4 4
      deploy/roles/os/tasks/ulimits.yml
  29. 5 2
      deploy/roles/php/tasks/main.yml
  30. 12 14
      deploy/roles/ubuntu/tasks/main.yml
  31. 5 0
      deploy/roles/ubuntu/tasks/zsh.yml
  32. 44 0
      deploy/scripts/assets.sh
  33. 6 0
      deploy/staging/hosts
  34. 6 1
      public/app/config.dir.php
  35. 1 3
      public/app/config.sample.js
  36. 0 2
      public/app/config.sample.php
  37. 4 4
      public/app/config.table.php
  38. 19 17
      public/app/dict/dict_lookup.php
  39. 1 1
      public/app/install/db_insert_palitext_cli.php
  40. 1 1
      public/app/install/db_update_palitext_cli.php
  41. 5 8
      public/app/palicanon/book_tag.php
  42. 5 8
      public/app/palicanon/get_chapter_children.php
  43. 5 8
      public/app/palicanon/get_chapter_info.php
  44. 35 12
      public/app/pcdl/head_bar.php
  45. 1 1
      public/app/public/lang/zh-cn.json
  46. 1 1
      public/app/public/lang/zh-tw.json
  47. 3 1
      public/app/redis/function.php
  48. 3 1
      public/app/studio/index.php
  49. 4 2
      public/app/studio/index_head.php
  50. 9 1
      public/app/term/note.js
  51. 4 4
      public/app/users_guide/zh-cn/grammar_fut.md
  52. 1 0
      storage/app/.gitignore
  53. 2 0
      storage/app/tmp/.gitignore
  54. 8 8
      v1/scripts/migrations/20211125155700_pali_sent_org.php
  55. 6 6
      v1/scripts/migrations/20211127214800_sent_sim.php
  56. 27 0
      v1/windows/install1.bat
  57. 26 0
      v1/windows/install2.bat
  58. 26 0
      v1/windows/install3.bat
  59. 26 0
      v1/windows/install4.bat
  60. 26 0
      v1/windows/install5.bat
  61. 26 0
      v1/windows/install6.bat

+ 3 - 4
.env.example

@@ -57,8 +57,7 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
 
 RPC_SERVER="https://rpc.wikipali.org"
 ASSETS_SERVER="https://assets-hk.wikipali.org"
-HELP_SERVER="https://help-hk.wikipali.org"
-GRAMMAR_SERVER="https://grammar-hk.wikipali.org"
 
-SNOWFLAKE_DATACENTER_ID = 1
-SNOWFLAKE_WORKER_ID = 1
+
+SNOWFLAKE_DATA_CENTER_ID = 1
+SNOWFLAKE_WORKER_ID = 1

+ 44 - 4
app/Console/Commands/Install.php

@@ -11,7 +11,7 @@ class Install extends Command
      *
      * @var string
      */
-    protected $signature = 'install {--queue}';
+    protected $signature = 'install {--test}';
 
     /**
      * The console command description.
@@ -35,11 +35,51 @@ class Install extends Command
      *
      * @return int
      */
+	/*
+	php ../../public/app/install/db_insert_templet_cli.php 1 217
+	php ../../public/app/install/db_update_toc_cli.php 1 217 pali
+	php ../../public/app/install/db_update_toc_cli.php 1 217 zh-hans
+	php ../../public/app/install/db_update_toc_cli.php 1 217 zh-hant
+	php ../../public/app/install/db_insert_palitext_cli.php 1 217
+	php ../../public/app/install/db_update_palitext_cli.php 1 217
+	php ../../public/app/install/db_insert_bookword_from_csv_cli.php 1 217
+	php ../../public/app/install/db_insert_word_from_csv_cli.php 1 217
+	php ../../public/app/install/db_insert_wordindex_from_csv_cli.php
+
+	php ./migrations/20211202084900_init_pali_serieses.php
+	php ./migrations/20211125155600_word_statistics.php
+	php ./migrations/20211125155700_pali_sent_org.php
+	php ./migrations/20211125165700-pali_sent-upgrade.php
+	php ./migrations/20211126220400-pali_sent_index-upgrade.php
+	php ./migrations/20211127214800_sent_sim.php
+	php ./migrations/20211127214900-sent_sim_index.php
+
+	php ../../public/app/fts/sql.php
+
+	php ../../public/app/admin/word_index_weight_refresh.php 1 217
+	*/
     public function handle()
     {
-		$this->call('install:wbwtemplate', [
-			'from' => 1, 'to' => 217
-		]);
+		$isTest = $this->option('test');
+		if($isTest){
+			$this->call('install:wbwtemplate', ['from' => 1]);
+		}else{
+			$this->call('install:wbwtemplate');	
+			$this->call('install:palitext');	
+			$this->call('install:wordbook');	
+			$this->call('install:wordall');	
+			$this->call('install:wordindex');
+
+			$this->call('upgrade:palitext');	
+			$this->call('upgrade:palitoc',['lang'=>'pali']);	
+			$this->call('upgrade:palitoc',['lang'=>'zh-hans']);	
+			$this->call('upgrade:palitoc',['lang'=>'zh-hant']);	
+
+			$this->call('install:paliseries');	
+			$this->call('install:wordstatistics');	
+			
+		}
+
         return 0;
     }
 }

+ 29 - 31
app/Console/Commands/InstallPaliSeries.php

@@ -40,41 +40,39 @@ class InstallPaliSeries extends Command
      */
     public function handle()
     {
-		$this->info("upgrade pali text");
+		$this->info("upgrade pali serieses");
 		$startTime = time();
 
+		DB::transaction(function () {
+			#删除目标数据库中数据
+			BookTitle::where('book','>',0)->delete();
 
+		// 打开csv文件并读取数据										
+			$strFileName = config("app.path.pali_title") . "/pali_serieses.csv";
+			if(!file_exists($strFileName)){
+				return 1;
+			}		
+			$inputRow = 0;
+			if (($fp = fopen($strFileName, "r")) !== false) {
+				while (($data = fgetcsv($fp, 0, ',')) !== false) {
+					if($inputRow>0){
+						$newData = [
+							'book'=>$data[1],
+							'paragraph'=>$data[2],
+							'title'=>$data[3],
+						];
 
-					DB::transaction(function () {
-						#删除目标数据库中数据
-						BookTitle::where('book','>',0)->delete();
-
-					// 打开csv文件并读取数据										
-						$strFileName = config("app.path.pali_title") . "/pali_serieses.csv";
-						if(!file_exists($strFileName)){
-							return 1;
-						}						
-						$inputRow = 0;
-						if (($fp = fopen($strFileName, "r")) !== false) {
-							while (($data = fgetcsv($fp, 0, ',')) !== false) {
-								if($inputRow>0){
-									$newData = [
-										'book'=>$data[1],
-										'paragraph'=>$data[2],
-										'title'=>$data[3],
-									];
-		
-									BookTitle::create($newData);									
-								}
-								$inputRow++;
-							}
-							fclose($fp);
-							Log::info("res load:" .$strFileName);
-						} else {
-							$this->error("can not open csv $strFileName");
-							Log::error("can not open csv $strFileName");
-						}
-					});
+						BookTitle::create($newData);							
+					}
+					$inputRow++;
+				}
+				fclose($fp);
+				Log::info("res load:" .$strFileName);
+			} else {
+				$this->error("can not open csv $strFileName");
+				Log::error("can not open csv $strFileName");
+			}
+		});
 		$this->info("ok");
         return 0;
     }

+ 51 - 1
app/Console/Commands/InstallWordAll.php

@@ -3,6 +3,9 @@
 namespace App\Console\Commands;
 
 use Illuminate\Console\Command;
+use App\Models\WordList;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 
 class InstallWordAll extends Command
 {
@@ -11,7 +14,7 @@ class InstallWordAll extends Command
      *
      * @var string
      */
-    protected $signature = 'command:name';
+    protected $signature = 'install:wordall {from?} {to?}';
 
     /**
      * The console command description.
@@ -37,6 +40,53 @@ class InstallWordAll extends Command
      */
     public function handle()
     {
+		$startTime = time();
+
+		$this->info("instert word in palibook ");
+		Log::info("instert word in palibook ");
+
+		$_from = $this->argument('from');
+		$_to = $this->argument('to');
+		if(empty($_from) && empty($_to)){
+			$_from = 1;
+			$_to = 217;
+		}else if(empty($_to)){
+			$_to = $_from;
+		}
+
+		$bar = $this->output->createProgressBar($_to-$_from+1);
+
+		for ($book=$_from; $book <= $_to; $book++) { 
+			Log::info("doing ".($book));
+			DB::transaction(function ()use($book) {
+				$fileSn = $book-1;
+				if (($fpoutput = fopen(config("app.path.paliword_book") . "/{$fileSn}_words.csv", "r")) !== false){
+					#删除目标数据库中数据
+					WordList::where('book', $book)->delete();			
+					while (($data = fgetcsv($fpoutput, 0, ',')) !== false)  
+					{
+						$newData = [
+							'sn'=>$data[0],
+							'book'=>$data[1],
+							'paragraph'=>$data[2],
+							'wordindex'=>$data[3],
+							'bold'=>$data[4],
+						];
+						WordList::create($newData);				
+					}
+					return 0;			
+				}else{
+					Log::error("open csv fail");
+					return 1;
+				}
+			});
+			$bar->advance();
+		}
+		$bar->finish();
+
+		$msg = "all done in ". time()-$startTime . "s";
+		$this->info($msg.PHP_EOL);
+		Log::info($msg);
         return 0;
     }
 }

+ 45 - 1
app/Console/Commands/InstallWordIndex.php

@@ -3,6 +3,9 @@
 namespace App\Console\Commands;
 
 use Illuminate\Console\Command;
+use App\Models\WordIndex;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 
 class InstallWordIndex extends Command
 {
@@ -11,7 +14,7 @@ class InstallWordIndex extends Command
      *
      * @var string
      */
-    protected $signature = 'command:name';
+    protected $signature = 'install:wordindex';
 
     /**
      * The console command description.
@@ -37,6 +40,47 @@ class InstallWordIndex extends Command
      */
     public function handle()
     {
+		$startTime = time();
+
+		$info = "instert word in palibook ";
+		$this->info($info);
+		Log::info($info);
+
+		#删除目标数据库中数据
+		WordIndex::where('id', '>',-1)->delete();	
+
+		$scan = scandir(config("app.path.paliword_index"));
+		$bar = $this->output->createProgressBar(count($scan));
+		foreach($scan as $filename) {
+			$bar->advance();
+			$filename = config("app.path.paliword_index")."/".$filename;
+			if (is_file($filename)) {
+				Log::info("doing ".$filename);
+				DB::transaction(function ()use($filename) {
+				if (($fpoutput = fopen($filename, "r")) !== false) {
+						$count = 0;
+						while (($data = fgetcsv($fpoutput, 0, ',')) !== false) {
+							$newData = [
+								'id'=>$data[0],
+								'word'=>$data[1],
+								'word_en'=>$data[2],
+								'normal'=>$data[3],
+								'bold'=>$data[4],
+								'is_base'=>$data[5],
+								'len'=>$data[6],
+							];
+							WordIndex::create($newData);	
+							$count++;
+						}
+						Log::info("insert ".$count);
+					}
+				});				
+			}
+		}
+		$bar->finish();
+		$msg = "all done in ". time()-$startTime . "s";
+		Log::info($msg);
+		$this->info($msg);
         return 0;
     }
 }

+ 47 - 1
app/Console/Commands/InstallWordStatistics.php

@@ -3,6 +3,9 @@
 namespace App\Console\Commands;
 
 use Illuminate\Console\Command;
+use App\Models\WordStatistic;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
 
 class InstallWordStatistics extends Command
 {
@@ -11,7 +14,7 @@ class InstallWordStatistics extends Command
      *
      * @var string
      */
-    protected $signature = 'command:name';
+    protected $signature = 'install:wordstatistics';
 
     /**
      * The console command description.
@@ -37,6 +40,49 @@ class InstallWordStatistics extends Command
      */
     public function handle()
     {
+		$startTime = time();
+
+		$info = "instert wordstatistics ";
+		$this->info($info.PHP_EOL);
+		Log::info($info);
+
+		#删除目标数据库中数据
+		WordStatistic::where('id', '>',-1)->delete();	
+
+		$scan = scandir(config("app.path.word_statistics"));
+		$bar = $this->output->createProgressBar(count($scan));
+		foreach($scan as $filename) {
+			$bar->advance();
+			$filename = config("app.path.word_statistics")."/".$filename;
+			if (is_file($filename)) {
+				Log::info("doing ".$filename);
+				DB::transaction(function ()use($filename) {
+				if (($fpoutput = fopen($filename, "r")) !== false) {
+						$count = 0;
+						while (($data = fgetcsv($fpoutput, 0, ',')) !== false) {
+							$newData = [
+								'bookid'=>$data[0],
+								'word'=>$data[1],
+								'count'=>$data[2],
+								'base'=>$data[3],
+								'end1'=>$data[4],
+								'end2'=>$data[5],
+								'type'=>$data[6],
+								'length'=>$data[7],
+							];
+							WordStatistic::create($newData);	
+							$count++;
+						}
+						Log::info("insert ".$count);
+					}
+				});				
+			}
+		}
+		$bar->finish();
+		$msg = "all done in ". time()-$startTime . "s";
+		Log::info($msg);
+		$this->info($msg);
+        return 0;
         return 0;
     }
 }

+ 3 - 0
app/Models/WordIndex.php

@@ -8,4 +8,7 @@ use Illuminate\Database\Eloquent\Model;
 class WordIndex extends Model
 {
     use HasFactory;
+	protected $fillable = ['id' , 'word' , 'word_en' , 'count' , 'normal' , 'bold' , 'is_base' , 'len'  ];
+
+	
 }

+ 2 - 0
app/Models/WordList.php

@@ -8,4 +8,6 @@ use Illuminate\Database\Eloquent\Model;
 class WordList extends Model
 {
     use HasFactory;
+	protected $fillable = ['sn','book' , 'paragraph', 'wordindex' , 'bold' , 'weight' ];
+
 }

+ 2 - 0
app/Models/WordStatistic.php

@@ -8,4 +8,6 @@ use Illuminate\Database\Eloquent\Model;
 class WordStatistic extends Model
 {
     use HasFactory;
+	protected $fillable = ['bookid','word' , 'count', 'base' , 'end1' , 'end2','type', 'length'];
+
 }

+ 16 - 3
change-logs.md

@@ -34,8 +34,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - rename RPC_DOMAIN_NAME -> RPC_SERVER in config.sample.js
 - add RPC_SERVER to .env.example
 
-## [1.0.4] - 2022-01-19
+## [1.0.4] - 2022-01-21
 
 - add SNOWFLAKE to .env.example
-- add snowflake to database.php
-- add dependency godruoyi/php-snowflake
+- add SnowFlake to config.sample.php
+- add SnowFlakeDate to config.table.php
+- add dependency godruoyi/php-snowflake
+
+## [1.0.5] - 2022-01-24
+
+- add 帮助文件路径 URL_HELP to config.dir.php
+- add 巴利语手册路径 URL_PALI_HANDBOOK to config.dir.php
+- add help & handbook link 
+
+## [1.0.6]- 2022-01-27
+
+- remove HELP_SERVER GRAMMAR_SERVER from .env.example
+- remove HELP_SERVER GRAMMAR_SERVER from config.sample.php
+- remove HELP_SERVER GRAMMAR_SERVER from config.sample.php

+ 2 - 0
config/app.php

@@ -247,5 +247,7 @@ return [
 		'pali_title' => public_path('pali_title'),
 		'paliword' => public_path('paliword'),
 		'paliword_book' => public_path('paliword')."/book",
+		'paliword_index' => public_path('paliword')."/index",
+		'word_statistics' => public_path('dependence')."/word_statistics/data",
 	],
 ];

+ 1 - 0
deploy/.gitignore

@@ -1,2 +1,3 @@
 /clients/
+/tmp/
 *.log

+ 3 - 3
deploy/README.md

@@ -18,11 +18,11 @@ ssh-copy-id -i .ssh/id_ed25519 USER@HOST
 
 ```bash
 # test ssh connections
-peony -i staging ping.yml
+peony -i clients/CLUSTER ping.yml
 # run on all hosts
-peony -i staging pi.yml
+peony -i clients/CLUSTER ping.yml
 # run on only group
-peony -i staging pi.yml -l GROUP
+peony -i clients/CLUSTER ping.yml -l GROUP
 ```
 
 ## System image

+ 4 - 2
deploy/group_vars/all.yml

@@ -3,6 +3,8 @@ ansible_python_interpreter: /usr/bin/python3
 ansible_ssh_private_key_file: "{{ inventory_dir }}/.ssh/id_ed25519"
 #ansible_ssh_private_key_file: "{{inventory_dir}}/.ssh/id_rsa"
 
-app_www_deploy_target: "/var/www/{{ inventory_hostname }}/{{ ansible_date_time.iso8601_basic }}"
+app_deploy_target: "/var/www/{{ inventory_hostname }}/{{ ansible_date_time.iso8601_basic }}"
+app_downloads: "{{ ansible_env.HOME }}/downloads"
+app_backup: "{{ ansible_env.HOME }}/backups"
 app_python_version: "3.11"
-app_php_version: "8.0"
+app_php_version: "8.1"

+ 4 - 2
deploy/mint.yml

@@ -1,18 +1,20 @@
 - hosts: all
   roles:
-    - os
     - ubuntu
+    - os
     - python3
     - php
-    - mint-clone
 
 - hosts: www
   roles:
+    - mint-clone
     - mint-www
+    - certbot-nginx
 
 - hosts: assets
   roles:
     - mint-assets
+    - certbot-nginx
 
 - hosts: db
   roles:

+ 24 - 0
deploy/roles/certbot-nginx/tasks/main.yml

@@ -0,0 +1,24 @@
+- name: Remove file nginx default host
+  become: true
+  ansible.builtin.file:
+    path: /etc/nginx/sites-enabled/default
+    state: absent
+
+- name: add Let's Encrypt support
+  become: true
+  ansible.builtin.shell:
+    cmd: certbot --nginx --non-interactive --agree-tos -m {{ app_master_email }} --domains {{ inventory_hostname }}
+
+- name: restart nginx
+  become: true
+  ansible.builtin.systemd:
+    state: restarted
+    name: nginx
+
+- name: enable certbot sync
+  become: true
+  ansible.builtin.cron:
+    name: "renew certbot every month"
+    special_time: monthly
+    job: "/usr/bin/certbot renew --force-renewal"
+

+ 11 - 6
deploy/roles/mint-assets/tasks/main.yml

@@ -1,16 +1,21 @@
+# - name: Upload assets folder
+#   become: true
+#   ansible.builtin.copy:
+#     src: public
+#     dest: /var/www/{{ inventory_hostname }}
+#     owner: www-data
+#     group: www-data
+
 - name: Upload assets folder
-  become: true
-  ansible.builtin.copy:
+  ansible.posix.synchronize:
     src: public
     dest: /var/www/{{ inventory_hostname }}
-    owner: www-data
-    group: www-data
 
 - name: upload nginx.conf
-  bacame: true
+  become: true
   ansible.builtin.template:
     src: nginx.conf.j2
-    dest: "/etc/nginx/sites-enabled/{{ inventory_hostname }}"
+    dest: "/etc/nginx/sites-enabled/{{ inventory_hostname }}.conf"
     owner: www-data
     group: www-data
     mode: '0400'

+ 1 - 1
deploy/roles/mint-assets/templates/nginx.conf.j2

@@ -3,7 +3,7 @@ server {
 
     gzip on;
     server_name {{ inventory_hostname }};
-    root /var/www/{{ inventory_hostname }};
+    root /var/www/{{ inventory_hostname }}/public;
 
     access_log off;
     error_log /var/log/nginx/{{ inventory_hostname }}.error.log warn;

+ 0 - 63
deploy/roles/mint-clone/main.yml

@@ -1,63 +0,0 @@
-- name: Creates directory
-  become: true
-  file:
-    path: "/var/www/{{ inventory_hostname }}"
-    state: directory
-    owner: "{{ ansible_user }}"
-
-- name: Git checkout source code
-  ansible.builtin.git:
-    repo: 'https://github.com/iapt-platform/mint.git'
-    dest: "{{ app_www_deploy_target }}"
-    version: laravel
-
-- name: Install v2 php dependencies
-  ansible.builtin.shell: composer install
-  args:
-    chdir: "{{ app_www_deploy_target }}"
-
-- name: Install v2 nodejs dependencies
-  ansible.builtin.shell: npm install
-  args:
-    chdir: "{{ app_www_deploy_target }}"
-
-# TODO will remove in future
-- name: Install v1 php dependencies
-  ansible.builtin.shell: composer install
-  args:
-    chdir: "{{ app_www_deploy_target }}/public"
-
-# TODO will remove in future
-- name: Install v1 nodejs dependencies
-  ansible.builtin.shell: npm install
-  args:
-    chdir: "{{ app_www_deploy_target }}/public"
-
-- name: .env(v2)
-  bacame: true
-  ansible.builtin.template:
-    src: env-v2.j2
-    dest: "{{ app_www_deploy_target }}/.env"
-    owner: www-data
-    group: www-data
-    mode: '0400'
-
-# TODO will remove in future
-- name: config.php(v1)
-  bacame: true
-  ansible.builtin.template:
-    src: config-v1.php.j2
-    dest: "{{ app_www_deploy_target }}/public/app/config.php"
-    owner: www-data
-    group: www-data
-    mode: '0400'
-
-# TODO will remove in future
-- name: config.js(v1)
-  bacame: true
-  ansible.builtin.template:
-    src: config-v1.js.j2
-    dest: "{{ app_www_deploy_target }}/public/app/config.js"
-    owner: www-data
-    group: www-data
-    mode: '0400'

+ 96 - 0
deploy/roles/mint-clone/tasks/main.yml

@@ -0,0 +1,96 @@
+- name: Creates deploy directory
+  become: true
+  file:
+    path: "/var/www/{{ inventory_hostname }}"
+    state: directory
+    owner: "{{ ansible_user }}"
+
+- name: Git checkout source code
+  ansible.builtin.git:
+    repo: 'https://github.com/iapt-platform/mint.git'
+    dest: "{{ app_deploy_target }}"
+    version: laravel
+
+- name: Setup storage folder
+  become: true
+  ansible.builtin.file:
+    path: "{{ app_deploy_target }}/storage"
+    state: directory
+    recurse: true
+    owner: www-data
+    group: www-data
+
+
+- name: Install v2 php dependencies
+  ansible.builtin.shell: "php{{ app_php_version }} {{ ansible_env.HOME }}/.local/bin/composer install"
+  args:
+    chdir: "{{ app_deploy_target }}"
+
+# - name: Install v2 nodejs dependencies
+#   ansible.builtin.shell: npm install
+#   args:
+#     chdir: "{{ app_deploy_target }}"
+- name: Install v2 nodejs dependencies
+  ansible.builtin.file:
+    src: "/var/www/{{ inventory_hostname }}/node_modules/v2"
+    dest: "{{ app_deploy_target }}/node_modules"
+    state: link
+
+# TODO will remove in future
+- name: Install v1 php dependencies
+  ansible.builtin.shell: "php{{ app_php_version }} {{ ansible_env.HOME }}/.local/bin/composer install"
+  args:
+    chdir: "{{ app_deploy_target }}/public"
+
+# TODO will remove in future
+# - name: Install v1 nodejs dependencies
+#   ansible.builtin.shell: npm install
+#   args:
+#     chdir: "{{ app_deploy_target }}/public"
+- name: Install v1 nodejs dependencies
+  ansible.builtin.file:
+    src: "/var/www/{{ inventory_hostname }}/node_modules/v1"
+    dest: "{{ app_deploy_target }}/public/node_modules"
+    state: link
+
+# TODO will remove in future
+- name: Install v1 tmp
+  ansible.builtin.file:
+    src: "/var/www/{{ inventory_hostname }}/tmp"
+    dest: "{{ app_deploy_target }}/public/tmp"
+    state: link
+
+- name: .env(v2)
+  become: true
+  ansible.builtin.template:
+    src: env-v2.j2
+    dest: "{{ app_deploy_target }}/.env"
+    owner: www-data
+    group: www-data
+    mode: '0400'
+
+# TODO will remove in future
+- name: config.php(v1)
+  become: true
+  ansible.builtin.template:
+    src: config-v1.php.j2
+    dest: "{{ app_deploy_target }}/public/app/config.php"
+    owner: www-data
+    group: www-data
+    mode: '0400'
+
+# TODO will remove in future
+- name: config.js(v1)
+  become: true
+  ansible.builtin.template:
+    src: config-v1.js.j2
+    dest: "{{ app_deploy_target }}/public/app/config.js"
+    owner: www-data
+    group: www-data
+    mode: '0400'
+
+- name: Create a current link
+  ansible.builtin.file:
+    src: "{{ app_deploy_target }}"
+    dest: /var/www/{{ inventory_hostname }}/current
+    state: link

+ 1 - 1
deploy/roles/mint-clone/templates/config-v1.js.j2

@@ -11,4 +11,4 @@ var RPC_SERVER="https://rpc.wikipali.org";
   |------------------------
 */
 
-var ASSETS_SERVER = "https://assets-hk.wikipali.org"
+var ASSETS_SERVER = "https://assets-{{ app_cluster_id }}.wikipali.org"

+ 14 - 14
deploy/roles/mint-clone/templates/config-v1.php.j2

@@ -1,9 +1,8 @@
 <?php
-#目录设置,不能更改
-require_once __DIR__."/config.dir.php";
 
 #域名设置
 define("RPC_SERVER","https://rpc.wikipali.org");
+define("ASSETS_SERVER","https://assets-{{ app_cluster_id }}.wikipali.org");
 /*
 电子邮件设置
 PHPMailer
@@ -11,11 +10,11 @@ PHPMailer
 define("Email", [
 				 "Host"=>"smtp.gmail.com",//Set the SMTP server to send through
 				 "SMTPAuth"=>true,//Enable SMTP authentication
-				 "Username"=>'your@gmail.com',//SMTP username
-				 "Password"=>'your_password',//SMTP password
+				 "Username"=>'{{ app_smtp_username }}',//SMTP username
+				 "Password"=>'{{ app_smtp_password }}',//SMTP password
 				 "Port"=>465,//TCP port to connect to 465; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
-				 "From"=>"your@gmail.com",
-				 "Sender"=>"sender"
+				 "From"=>"{{ app_smtp_username }}",
+				 "Sender"=>"webmaster"
 				 ]);
 
 /*
@@ -23,12 +22,12 @@ define("Email", [
 */
 define("Database",[
 	"type"=>"pgsql",
-	"server"=>"localhost",
-	"port"=>5432,
-	"name"=>"mint",
+	"server"=>"{{ app_postgresql_host }}",
+	"port"=>{{ app_postgresql_port }},
+	"name"=>"{{ app_postgresql_name }}",
 	"sslmode" => "disable",
-	"user" => "postgres",
-	"password" => "123456"
+	"user" => "{{ app_postgresql_user }}",
+	"password" => "{{ app_postgresql_password }}"
 ]);
 
 
@@ -47,14 +46,15 @@ define("SnowFlake",[
 	"DatacenterId"=>1,
 	"WorkerId"=>1
 ]);
+
+#目录设置,不能更改
+require_once __DIR__."/config.dir.php";
+
 /*
 数据表
 */
 #表设置,此行不能更改
 require_once __DIR__."/config.table.php";
 
-#表名设置,此行不能更改
-require_once __DIR__."/config.migrate.php";
-
 
 ?>

+ 23 - 22
deploy/roles/mint-clone/templates/env-v2.j2

@@ -1,26 +1,26 @@
-BASE_DIR="/workspace/.env.global"
+BASE_DIR="{{ app_deploy_target }}/.env.global"
 CACHE_DIR="${BASE_DIR}/cache"
 TMP_DIR="${BASE_DIR}/tmp"
 
-APP_NAME={{  }}
-APP_ENV=local
-APP_KEY=
-APP_DEBUG=true
-APP_URL=http://localhost
+APP_NAME=wikipali
+APP_ENV=production
+APP_KEY="{{ app_laravel_key }}"
+APP_DEBUG=false
+APP_URL="https://{{ inventory_hostname }}"
 
 LOG_CHANNEL=stack
 LOG_DEPRECATIONS_CHANNEL=null
-LOG_LEVEL=debug
+LOG_LEVEL=info
 
-DB_CONNECTION=mysql
-DB_HOST=127.0.0.1
-DB_PORT=3306
-DB_DATABASE=mint_new
-DB_USERNAME=root
-DB_PASSWORD=
+DB_CONNECTION=postgresql
+DB_HOST={{ app_postgresql_host }}
+DB_PORT={{ app_postgresql_port }}
+DB_DATABASE={{ app_postgresql_name }}
+DB_USERNAME={{ app_postgresql_user }}
+DB_PASSWORD="{{ app_postgresql_password }}"
 
 BROADCAST_DRIVER=log
-CACHE_DRIVER=file
+CACHE_DRIVER=redis
 FILESYSTEM_DRIVER=local
 QUEUE_CONNECTION=sync
 SESSION_DRIVER=file
@@ -28,18 +28,18 @@ SESSION_LIFETIME=120
 
 MEMCACHED_HOST=127.0.0.1
 
-REDIS_HOST=127.0.0.1
+REDIS_HOST={{ app_redis_host }}
 REDIS_PASSWORD=null
 REDIS_PORT=6379
 
 MAIL_MAILER=smtp
-MAIL_HOST=mailhog
-MAIL_PORT=1025
-MAIL_USERNAME=null
-MAIL_PASSWORD=null
-MAIL_ENCRYPTION=null
-MAIL_FROM_ADDRESS=null
-MAIL_FROM_NAME="${APP_NAME}"
+MAIL_HOST=smtp.gmail.com
+MAIL_PORT=465
+MAIL_USERNAME={{ app_smtp_username }}
+MAIL_PASSWORD="{{ app_smtp_password }}"
+MAIL_ENCRYPTION=ssl
+MAIL_FROM_ADDRESS={{ app_smtp_username }}
+MAIL_FROM_NAME="webmaster"
 
 AWS_ACCESS_KEY_ID=
 AWS_SECRET_ACCESS_KEY=
@@ -56,3 +56,4 @@ MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
 
 ASSETS_SERVER="https://assets-{{ app_cluster_id }}.wikipali.org"
+RPC_SERVER="https://rpc.wikipali.org"

+ 2 - 2
deploy/roles/mint-www/tasks/main.yml

@@ -1,8 +1,8 @@
 - name: upload nginx.conf
-  bacame: true
+  become: true
   ansible.builtin.template:
     src: nginx.conf.j2
-    dest: "/etc/nginx/sites-enabled/{{ inventory_hostname }}"
+    dest: "/etc/nginx/sites-enabled/{{ inventory_hostname }}.conf"
     owner: www-data
     group: www-data
     mode: '0400'

+ 24 - 14
deploy/roles/mint-www/templates/nginx.conf.j2

@@ -1,33 +1,43 @@
+# https://laravel.com/docs/8.x/deployment#nginx
+
 server {
     listen 80;
+    listen [::]:80;
+
+    add_header X-Frame-Options "SAMEORIGIN";
+    add_header X-Content-Type-Options "nosniff";
 
     gzip on;
     server_name {{ inventory_hostname }};
-    root {{ app_www_deploy_target }};
+    root {{ app_deploy_target }}/public;
     client_max_body_size 16M;
+    index index.php;
+    charset utf-8;
 
-    access_log off;
+    access_log /var/log/nginx/{{ inventory_hostname }}.access.log;
     error_log /var/log/nginx/{{ inventory_hostname }}.error.log warn;
 
     location / {
-        index index.html index.php;
+        try_files $uri $uri/ /index.php?$query_string;
     }
 
-    location ~ /.git/ {
-        deny all;
+    location = /favicon.ico {
+        log_not_found off;
+    }
+    location = /robots.txt  {
+        log_not_found off;
     }
 
-    location ~ \.php$ {
-        try_files $fastcgi_script_name =404;
+    error_page 404 /index.php;
 
+    location ~ \.php$ {
+        fastcgi_pass unix:/var/run/php/php{{ app_php_version }}-fpm.sock;
+        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
         include fastcgi_params;
+    }
 
-        fastcgi_pass			unix:/run/php/php{{ app_php_version }}-fpm.sock;
-        fastcgi_index			index.php;
-        fastcgi_buffers			8 16k;
-        fastcgi_buffer_size		32k;
-
-        fastcgi_param DOCUMENT_ROOT     $realpath_root;
-        fastcgi_param SCRIPT_FILENAME   $realpath_root$fastcgi_script_name;
+    location ~ /\.(?!well-known).* {
+        deny all;
     }
+
 }

+ 0 - 7
deploy/roles/os/tasks/init.yml

@@ -1,10 +1,3 @@
-- name: create deploy folder
-  become: true
-  ansible.builtin.file:
-    path: "{{ app_deploy_target }}"
-    state: directory
-    owner: "{{ ansible_user }}"
-
 - name: create downloads folder
   become: true
   ansible.builtin.file:

+ 5 - 5
deploy/roles/os/tasks/main.yml

@@ -1,8 +1,8 @@
-- include: init.yml
-- include: sshd.yml
-- include: ulimits.yml
+- import_tasks: init.yml
+- import_tasks: sshd.yml
+- import_tasks: ulimits.yml
 
-- name: Setup sudo without password 
+- name: Setup sudo without password
   become: true
   ansible.builtin.template:
     src: sudo.conf.j2
@@ -25,7 +25,7 @@
   become: true
   shell: timedatectl set-timezone UTC
 
-- name: Setup journald storage 
+- name: Setup journald storage
   become: true
   lineinfile:
     path: /etc/systemd/journald.conf

+ 4 - 4
deploy/roles/os/tasks/ulimits.yml

@@ -56,17 +56,17 @@
     path: /etc/security/limits.conf
     line: root        soft nofile 10240
 
-- name: Set user level ppen file limits for {{ansible_user}}
+- name: Set user level open file limits for {{ ansible_user }}
   become: true
   lineinfile:
     path: /etc/security/limits.conf
-    line: "{{ansible_user}}        soft nofile 10240"
+    line: "{{ ansible_user }}        soft nofile 10240"
 
 # https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/changing-kernel-parameter-values.html#GUID-FB0CC366-61C9-4AA2-9BE7-233EB6810A31
 - name: Setup file max
   become: true
   lineinfile:
-    path: "/etc/sysctl.d/100-{{app_vendor}}.conf"
+    path: "/etc/sysctl.d/100-fs.conf"
     state: present
     line: fs.file-max = 6815744
     create: true
@@ -74,7 +74,7 @@
 - name: Setup file max
   become: true
   lineinfile:
-    path: "/etc/sysctl.d/100-{{app_vendor}}.conf"
+    path: "/etc/sysctl.d/100-fs.conf"
     state: present
     line: fs.inotify.max_user_watches = 512000
     create: true

+ 5 - 2
deploy/roles/php/tasks/main.yml

@@ -24,14 +24,17 @@
       - php{{ app_php_version }}-redis
       - php{{ app_php_version }}-bcmath
 
+- name: Creates composer install directory
+  file:
+    path: "{{ ansible_env.HOME }}/.local/bin"
+    state: directory
+
 # https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
 - name: Download composer
   get_url:
     url: https://getcomposer.org/download/latest-stable/composer.phar
     dest: "{{ ansible_env.HOME }}/.local/bin/composer"
     mode: 0755
-  args:
-    creates: "{{ ansible_env.HOME }}/.local/bin/composer"
 
 - name: Restart php-fpm
   become: true

+ 12 - 14
deploy/roles/ubuntu/tasks/main.yml

@@ -79,6 +79,7 @@
       - unzip
       - nginx
       - certbot
+      - python3-certbot-nginx
       - openvpn
       - snmpd
       - systemd-cron
@@ -90,12 +91,15 @@
       - python3-pip
       - python3-distutils
       - python3-dev
+      - nodejs
+      - npm
+      - yarnpkg
       - libssl-dev
       - libpq-dev
       - libmysqlclient-dev
 
 
-- include: locales.yml
+- import_tasks: locales.yml
 
 - name: Set default editor to vim
   become: true
@@ -109,7 +113,7 @@
   become: true
   shell: git config --global pull.rebase false
 
-- include: zsh.yml
+- import_tasks: zsh.yml
 
 # ---------------------------------------------------
 
@@ -118,7 +122,7 @@
     path: /etc/friendlyelec-release
   register: app_os_friendlyelec
 
-- include: friendly-core.yml
+- import_tasks: friendly-core.yml
   when: app_os_friendlyelec.stat.islnk is defined and app_os_friendlyelec.stat.isreg
 
 - name: check if armbian
@@ -126,13 +130,13 @@
     path: /etc/armbian-release
   register: app_os_armbian
 
-- include: armbian.yml
+- import_tasks: armbian.yml
   when: app_os_armbian.stat.islnk is defined and app_os_armbian.stat.isreg
 
-- include: raspbian.yml
+- import_tasks: raspbian.yml
   when: ansible_distribution == 'Raspbian'
 
-- include: pi.yml
+- import_tasks: pi.yml
   when: ansible_distribution == 'Raspbian' or (app_os_armbian.stat.islnk is defined and app_os_armbian.stat.isreg) or (app_os_friendlyelec.stat.islnk is defined and app_os_friendlyelec.stat.isreg)
 
 # ---------------------------------------------------
@@ -147,16 +151,10 @@
 - name: enable cron service
   become: true
   ansible.builtin.systemd:
-    name: cron-target
+    name: cron
     enabled: yes
     masked: no
 
-- name: enable certbot sync
-  ansible.builtin.cron:
-    name: "renew certbot"
-    special_time: monthly
-    job: "/usr/bin/certbot renew --force-renewal"
-
 - name: enable ssh service
   become: true
   ansible.builtin.systemd:
@@ -172,4 +170,4 @@
     masked: no
 
 
-- include: clean.yml
+- import_tasks: clean.yml

+ 5 - 0
deploy/roles/ubuntu/tasks/zsh.yml

@@ -21,6 +21,11 @@
     remote_src: true
     mode: 0600
 
+- name: Enable $HOME/.local
+  ansible.builtin.lineinfile:
+    path: "{{ansible_env.HOME}}/.zshrc"
+    line: 'export PATH=$HOME/.local/bin:$PATH'
+
 - name: Use zsh
   become: true
   shell: chsh -s /bin/zsh {{ansible_user}}

+ 44 - 0
deploy/scripts/assets.sh

@@ -0,0 +1,44 @@
+#!/bin/bash
+
+set -e
+
+# rclone copy --drive-shared-with-me $1:assets assets
+
+export WORKSPACE=$PWD
+
+function build_book(){
+    local target=$WORKSPACE/tmp/$1/$2
+    local dist=$WORKSPACE/roles/mint-assets/files/public/$1/$2
+    if [ ! -d $target ]
+    then
+        git clone -b $2 "https://github.com/iapt-platform/$1.git" $target
+    fi
+    cd $target
+    git pull
+    if [ -d $dist ]
+    then
+        rm -r $dist
+    fi
+    mkdir -p $dist
+    $HOME/.local/bin/mdbook build --dest-dir $dist
+}
+
+declare -a languages=(
+    "zh-Hans"
+)
+
+declare -a books=(
+    "pali-handbook"
+    "help"
+)
+
+for b in "${books[@]}"
+do
+    for l in "${languages[@]}"
+    do
+        build_book $b $l
+    done
+done
+
+echo 'done.'
+exit 0

+ 6 - 0
deploy/staging/hosts

@@ -14,4 +14,10 @@
 app_vendor="iapt-platform.mint"
 ; openssl rand -base64 32
 app_secret_key="4i3WKUvKtSGl59htK7XjUNsjalhkG5s7RJCmZruT2m4="
+; php artisan key:generate --show
+app_laravel_key="base64:IQD4vkmAN1oEsc8rVu1nRadQWPUX/LH/jaSbyFbmf/w="
+app_postgresql_host="db-hk-1.wikipali.org"
+app_postgresql_port=5433
+app_postgresql_password=change-me
+app_redis_host="ch-hk-1.wikipali.org"
 

+ 6 - 1
public/app/config.dir.php

@@ -56,4 +56,9 @@ define("_DIR_USER_IMG_LINK_", "../../tmp/user/media/3");
 define("_DIR_MYDOCUMENT_", "/my_document");
 
 # 逐词解析字典文件
-define("_FILE_DB_WBW1_",  __DIR__ . "/../tmp/user/wbw.db3");
+define("_FILE_DB_WBW1_",  __DIR__ . "/../tmp/user/wbw.db3");
+
+# 帮助文件路径
+define("URL_HELP",ASSETS_SERVER."/help");
+# 巴利语手册路径
+define("URL_PALI_HANDBOOK",ASSETS_SERVER."/pali-handbook");

+ 1 - 3
public/app/config.sample.js

@@ -11,6 +11,4 @@ var RPC_SERVER = "https://rpc.wikipali.org";
   |------------------------
 */
 
-var ASSETS_SERVER = "https://assets-hk.wikipali.org"
-var HELP_SERVER = "https://help-hk.wikipali.org"
-var GRAMMAR_SERVER = "https://grammar-hk.wikipali.org"
+var ASSETS_SERVER = "https://assets-hk.wikipali.org"

+ 0 - 2
public/app/config.sample.php

@@ -5,8 +5,6 @@
 
 define("RPC_SERVER","https://rpc.wikipali.org");
 define("ASSETS_SERVER","https://assets-hk.wikipali.org");
-define("HELP_SERVER","https://help-hk.wikipali.org");
-define("GRAMMAR_SERVER","https://grammar-hk.wikipali.org");
 
 /*
 电子邮件设置

+ 4 - 4
public/app/config.table.php

@@ -532,10 +532,10 @@ define("_TABLE_WORD_STATISTICS_", _PG_TABLE_WORD_STATISTICS_);
 
 */
 
-define("_FILE_DB_PALI_SENTENCE_", _SQLITE_DB_PALI_SENTENCE_);
-define("_TABLE_PALI_SENT_", _SQLITE_TABLE_PALI_SENT_);
-define("_TABLE_PALI_SENT_ORG_", _SQLITE_TABLE_PALI_SENT_ORG_);
-define("_TABLE_PALI_SENT_INDEX_", _SQLITE_TABLE_PALI_SENT_INDEX_);
+define("_FILE_DB_PALI_SENTENCE_", _PG_DB_PALI_SENTENCE_);
+define("_TABLE_PALI_SENT_", _PG_TABLE_PALI_SENT_);
+define("_TABLE_PALI_SENT_ORG_", _PG_TABLE_PALI_SENT_ORG_);
+define("_TABLE_PALI_SENT_INDEX_", _PG_TABLE_PALI_SENT_INDEX_);
 
 /*
 相似句

+ 19 - 17
public/app/dict/dict_lookup.php

@@ -1,18 +1,18 @@
 <?php
 //查询参考字典
 include("../log/pref_log.php");
-require_once '../config.php';
-require_once '../public/casesuf.inc';
-require_once '../public/union.inc';
-require_once "../public/_pdo.php";
-require_once "../public/load_lang.php"; //语言文件
-require_once "../public/function.php";
-require_once "../search/word_function.php";
-require_once "../ucenter/active.php";
-require_once "../ucenter/function.php";
-require_once "../dict/p_ending.php";
-require_once "../redis/function.php";
-require_once "../dict/grm_abbr.php";
+require_once __DIR__.'/../config.php';
+require_once __DIR__.'/../public/casesuf.inc';
+require_once __DIR__.'/../public/union.inc';
+require_once __DIR__."/../public/_pdo.php";
+require_once __DIR__."/../public/load_lang.php"; //语言文件
+require_once __DIR__."/../public/function.php";
+require_once __DIR__."/../search/word_function.php";
+require_once __DIR__."/../ucenter/active.php";
+require_once __DIR__."/../ucenter/function.php";
+require_once __DIR__."/../dict/p_ending.php";
+require_once __DIR__."/../redis/function.php";
+require_once __DIR__."/../dict/grm_abbr.php";
 
 global $redis;
 $redis = redis_connect();
@@ -45,7 +45,8 @@ $right_word_list = "";
 
         PDO_Connect("" . _FILE_DB_REF_);
         //直接查询
-        $query = "SELECT dict.dict_id,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN info ON dict.dict_id = info.id where word = ? limit 0,100";
+
+        $query = "SELECT dict.dict_id,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN "._TABLE_DICT_REF_NAME_." as info ON dict.dict_id = info.id where word = ? limit 100";
 
         $Fetch = PDO_FetchAll($query, array($word));
         $iFetch = count($Fetch);
@@ -106,8 +107,9 @@ $right_word_list = "";
 				}
 
 				
-                $query = "SELECT dict.id,dict.dict_id,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN info ON dict.dict_id = info.id where word = ? limit 30";
-                $Fetch = PDO_FetchAll($query, array($x));
+                //$query = "SELECT dict.dict_id,dict.mean,dn.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN "._TABLE_DICT_REF_NAME_." as dn ON dict.dict_id = dn.id where word = ? limit 30";
+
+				$Fetch = PDO_FetchAll($query, array($x));
                 $iFetch = count($Fetch);
                 $count_return += $iFetch;
                 if ($iFetch > 0) {
@@ -171,7 +173,7 @@ $right_word_list = "";
 			if (count($arrBase) > 0) {
 				foreach ($arrBase as $x => $x_value) {
 					
-					$query = "SELECT dict.dict_id,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN info ON dict.dict_id = info.id where word = ? limit 0,30";
+					$query = "SELECT dict.dict_id,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN "._TABLE_DICT_REF_NAME_." as info ON dict.dict_id = info.id where word = ? limit 30";
 					$Fetch = PDO_FetchAll($query, array($x));
 					$iFetch = count($Fetch);	
 					$count_return += $iFetch;
@@ -245,7 +247,7 @@ $right_word_list = "";
             $word1 = $org_word;
             $wordInMean = "%$org_word%";
             echo "包含 $org_word 的:<br />";
-            $query = "SELECT dict.dict_id,dict.word,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN info ON dict.dict_id = info.id where mean like ? limit 0,30";
+            $query = "SELECT  dict.dict_id,dict.word,dict.mean,info.shortname from " . _TABLE_DICT_REF_ . " LEFT JOIN "._TABLE_DICT_REF_NAME_." as info ON dict.dict_id = info.id where mean like ? limit 30";
             $Fetch = PDO_FetchAll($query, array($wordInMean));
             $iFetch = count($Fetch);
             $count_return += $iFetch;

+ 1 - 1
public/app/install/db_insert_palitext_cli.php

@@ -1,4 +1,4 @@
-<?php
+<?php
 /*
 生成 巴利原文段落表
  */

+ 1 - 1
public/app/install/db_update_palitext_cli.php

@@ -1,4 +1,4 @@
-<?php
+<?php
 /*
 生成 巴利原文段落表
  */

+ 5 - 8
public/app/palicanon/book_tag.php

@@ -1,12 +1,9 @@
 <?php
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
+require_once __DIR__.'/../redis/function.php';
 
-try {
-    $redis = new redis();
-    $r_conn = $redis->connect('127.0.0.1', 6379);
-} catch (Exception $e) {
-    $r_conn = false;
-}
+
+$redis = redis_connect();
 
 $tag = str_getcsv($_GET["tag"], ","); //
 $arrBookTag = json_decode(file_get_contents("../public/book_tag/en.json"), true);
@@ -50,7 +47,7 @@ foreach ($output as $key => $value) {
         if ($paraInfo) {
             # 查进度
             $paraProgress = false;
-            if ($r_conn) {
+            if ($redis) {
                 $count = $redis->hLen("progress_chapter_{$book}_{$para}");
                 if ($count > 0) {
                     $prog = $redis->hGetAll("progress_chapter_{$book}_{$para}");

+ 5 - 8
public/app/palicanon/get_chapter_children.php

@@ -1,12 +1,9 @@
 <?php
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
+require_once __DIR__.'/../redis/function.php';
 
-try {
-    $redis = new redis();
-    $r_conn = $redis->connect('127.0.0.1', 6379);
-} catch (Exception $e) {
-    $r_conn = false;
-}
+
+$redis = redis_connect();
 
 $dns = _FILE_DB_PALI_TOC_;
 $dbh_toc = new PDO($dns, _DB_USERNAME_, _DB_PASSWORD_, array(PDO::ATTR_PERSISTENT => true));
@@ -44,7 +41,7 @@ if ($paraInfo) {
         foreach ($paraList as $key => $value) {
             # 查进度
             $paraProgress = false;
-            if ($r_conn) {
+            if ($redis) {
                 $count = $redis->hLen("progress_chapter_{$value["book"]}_{$value["para"]}");
                 if ($count > 0) {
                     $prog = $redis->hGetAll("progress_chapter_{$value["book"]}_{$value["para"]}");

+ 5 - 8
public/app/palicanon/get_chapter_info.php

@@ -1,12 +1,9 @@
 <?php
-require_once '../config.php';
+require_once __DIR__.'/../config.php';
+require_once __DIR__.'/../redis/function.php';
 
-try {
-    $redis = new redis();
-    $r_conn = $redis->connect('127.0.0.1', 6379);
-} catch (Exception $e) {
-    $r_conn = false;
-}
+
+$redis = redis_connect();
 
 $dns = _FILE_DB_PALI_TOC_;
 $dbh_toc = new PDO($dns, _DB_USERNAME_, _DB_PASSWORD_, array(PDO::ATTR_PERSISTENT => true));
@@ -34,7 +31,7 @@ $paraInfo = $stmt->fetch(PDO::FETCH_ASSOC);
 if ($paraInfo) {
     # 查进度
     $paraProgress = array();
-    if ($r_conn) {
+    if ($redis) {
         $count = $redis->hLen("progress_chapter_{$book}_{$para}");
         if ($count > 0) {
             $prog = $redis->hGetAll("progress_chapter_{$book}_{$para}");

+ 35 - 12
public/app/pcdl/head_bar.php

@@ -445,7 +445,19 @@
 		}
 	}
 </style>
-
+<?php
+$help_lang = '';
+switch($_COOKIE['language']){
+	case "zh-cn":
+		$help_lang = "zh-Hans";
+		break;
+	case "zh-tw":
+		$help_lang = "zh-Hans";
+		break;
+	default:
+		$help_lang = "zh-Hans";
+}
+?>
 <!-- new tool bar begin-->
 <header>
 	<div class="head-logo">
@@ -468,27 +480,38 @@
 			<li class="nav_link"><a href="../wiki/"><?php echo $_local->gui->encyclopedia; ?></a></li>
 			<li class="nav_link"><a href="../dict/"><?php echo $_local->gui->dictionary; ?></a></li>
 			<li class="nav_link"><a href="../collect/"><?php echo $_local->gui->composition; ?></a></li>
+			<li class="nav_link"><a href="<?php echo URL_HELP.'/'.$help_lang ?>"  target="_blank"><?php echo $_local->gui->help; ?></a></li>
 			<li class="nav_link more_btn">
 				<div id="more" class="dropdown" onmouseover="switchMenu(this,'nav-more')" onmouseout="hideMenu()">
 					<button class="dropbtn icon_btn" style="all:unset;" onClick="switchMenu(this,'nav-more')" id="more_button">
 						<?php echo $_local->gui->more; ?>
 					</button>
 					<ul class="header-dropdown-content left-content" style="display: none;" id="nav-more">
-					<li><a href="https://visuddhinanda.gitbook.io/pali-handbook/" target="_blank">
+						<li>
+							<a href="<?php echo URL_PALI_HANDBOOK.'/'.$help_lang ?>" target="_blank">
 								<div class="nav_link"><?php echo $_local->gui->palihandbook; ?></div>
-							</a></li>
-						<li><a href="../calendar/" target="_blank">
+							</a>
+						</li>
+						<li>
+							<a href="../calendar/" target="_blank">
 								<div class="nav_link"><?php echo $_local->gui->buddhist_calendar; ?></div>
-							</a></li>
-						<li><a href="../tools/unicode.html" target="_blank">
+							</a>
+						</li>
+						<li>
+							<a href="../tools/unicode.html" target="_blank">
 								<div class="nav_link"><?php echo $_local->gui->code_convert; ?></div>
-							</a></li>
-						<li><a href="../statistics" target="_blank">
+							</a>
+						</li>
+						<li>
+							<a href="../statistics" target="_blank">
 								<div class="nav_link"><?php echo $_local->gui->corpus_statistics; ?></div>
-							</a></li>
-						<li><a href="../calendar/history.html" target="_blank">
-							<div class="nav_link"><?php echo $_local->gui->history; ?></div>
-						</a></li>
+							</a>
+						</li>
+						<li>
+							<a href="../calendar/history.html" target="_blank">
+								<div class="nav_link"><?php echo $_local->gui->history; ?></div>
+							</a>
+						</li>
 					</ul>
 			</li>
 			<li class="nav_link nav-mobile"><a href="../calendar/">

+ 1 - 1
public/app/public/lang/zh-cn.json

@@ -392,7 +392,7 @@
 		"function_introduce": "Wikipāḷi功能介绍",
 		"vedio_link": "视频链接",
 		"project_introduce": "三藏翻译会议简报",
-		"help_doc": "开发者必读",
+		"help_doc": "帮助文档",
 		"code_add": "代码查看及下载",
 		"test_declare": "此网址仅供功能测试,目前无法保证对用户个人数据的保留。",
 		"project_introduce_inbrief": "巴利圣典翻译工程整体思路",

+ 1 - 1
public/app/public/lang/zh-tw.json

@@ -388,7 +388,7 @@
 		"add_to_folder": "加入資料夾",
 		"rename": "重新命名",
 		"collaborate": "協作",
-		"help": "幫助",
+		"help": "幫助文件",
 		"function_introduce": "Wikipāḷi功能介紹",
 		"vedio_link": "視訊連結",
 		"project_introduce": "三藏翻譯會議簡報",

+ 3 - 1
public/app/redis/function.php

@@ -6,8 +6,10 @@ function redis_connect()
 		//code...
 		$redis = new redis();
 		$r_conn = $redis->connect(Redis["host"], Redis["port"]);
-		$redis->auth(Redis["password"]);
 		if ($r_conn) {
+			if(Redis["password"] !== ""){
+				$redis->auth(Redis["password"]);
+			}		
 			return $redis;
 		} else {
 			return false;

+ 3 - 1
public/app/studio/index.php

@@ -289,7 +289,8 @@ else{
 		<div class="htlp_title"><?php echo $_local->gui->start;?></div>
 		<ul style="list-style-type: none;">
 			<li><a href="../studio/index_pc.php" target="_block"><?php echo $_local->gui->newproject;?></a></li>
-			<li><a href="" target="_block">自学教程(建設中)</a></li>
+			<li ><a href="<?php echo URL_PALI_HANDBOOK.'/zh-Hans' ?>" target="_blank"><?php echo $_local->gui->palihandbook; ?></a></li>
+			<li><a href="" target="_block">教程(建設中)</a></li>
 		</ul>
 	</div>
 	<div class="help_div">
@@ -304,6 +305,7 @@ else{
 		<?php echo $_local->gui->help;?>
 		</div>
 		<ul style="list-style-type: none;">
+		<li ><a href="<?php echo URL_HELP.'/zh-Hans' ?>" target="_blank"><?php echo $_local->gui->help; ?></a></li>
 			<li><?php echo $_local->gui->function_introduce;?>&nbsp;&nbsp;&nbsp;
 				<a href="https://www.youtube.com/playlist?list=PL_1iJBQvNPFFNLOaZh2u3VwDYUyJuK_xa" target="_block">
 					<svg class="icon">

+ 4 - 2
public/app/studio/index_head.php

@@ -61,6 +61,9 @@ require_once '../public/load_lang.php';
 	<script src="../public/js/jquery-ui-1.12.1/jquery-ui.js"></script>
 	<link type="text/css" rel="stylesheet" href="../public/js/jquery-ui-1.12.1/jquery-ui.css"/>	
 
+	<script src="../../node_modules/marked/marked.min.js"></script>
+	<script src="../../node_modules/mermaid/dist/mermaid.min.js"></script>
+
 	<script src="../term/term.js"></script>
 	<script src="../term/note.js"></script>
 	<script src="../term/term_popup.js"></script>
@@ -69,8 +72,7 @@ require_once '../public/load_lang.php';
 	<script language="javascript" src="../guide/guide.js"></script>
 	<link type="text/css" rel="stylesheet" href="../guide/guide.css"/>
 
-	<script src="../../node_modules/marked/marked.min.js"></script>
-	<script src="../../node_modules/mermaid/dist/mermaid.min.js"></script>
+
 
 
 	<script src="../widget/iframe_modal_win.js"></script>

+ 9 - 1
public/app/term/note.js

@@ -12,6 +12,12 @@ var _channalData;
 var MAX_NOTE_NEST = 2;
 
 var gBuildinDictIsOpen = false;
+
+var note_renderer = new marked.Renderer();
+note_renderer.code = function(code, language) {
+    if (language == "mermaid") return '<pre class="mermaid">' + code + "</pre>";
+    else return "<pre><code>" + code + "</code></pre>";
+};
 /*
 {{203-1654-23-45@11@en@*}}
 <note>203-1654-23-45@11@en@*</note>
@@ -78,7 +84,7 @@ function note_init(input,channel="",editor="",lang="en") {
 	if (input) {
 		let output = "<div>";
 		//output += marked(input);
-		output += marked(term_std_str_to_tran(input, channel, editor, lang));
+		output += marked(term_std_str_to_tran(input, channel, editor, lang), { renderer: note_renderer });
 
 		output += "</div>";
 
@@ -193,6 +199,8 @@ function note_refresh_new(callback = null) {
 						splite_pali_word();
 						//处理编辑框消息
 						tran_sent_textarea_event_init();
+						//初始化mermaid
+						mermaid.initialize();
 						if (callback) {
 							callback();
 						}

+ 4 - 4
public/app/users_guide/zh-cn/grammar_fut.md

@@ -1,6 +1,6 @@
 # 将来时
 
-**动词**变位之一,表示将要发生或将要做(的事情),动作。相当于英语的一般将来时
+**动词**变位之一,表示将要发生或将要做(的事情),动作。相当于英语的各种将来有关的时态
 
 |语种|缩写|全称|
 |-|-|-|
@@ -12,6 +12,6 @@
 
 |将来时|单数|复数|
 | -- | -- | -- |
-|第三人称|~(i)ssati<br>TA**将**~|~(i)ssanti<br>TA们**将**~|
-|第二人称|~(i)ssasi<br>你**将**~|~(i)ssatha<br>你们**将**~|
-|第一人称|~(i)ssāmi<br>我**将**~|~(i)ssāma<br>我们**将**~|
+|第三人称|-(i)ssati<br>TA**将**~|-(i)ssanti<br>TA们**将**~|
+|第二人称|-(i)ssasi<br>你**将**~|-(i)ssatha<br>你们**将**~|
+|第一人称|-(i)ssāmi<br>我**将**~|-(i)ssāma<br>我们**将**~|

+ 1 - 0
storage/app/.gitignore

@@ -1,3 +1,4 @@
 *
 !public/
+!tmp/
 !.gitignore

+ 2 - 0
storage/app/tmp/.gitignore

@@ -0,0 +1,2 @@
+*
+!.gitignore

+ 8 - 8
v1/scripts/migrations/20211125155700_pali_sent_org.php

@@ -64,13 +64,13 @@ try{
 while($srcData = $stmtSrc->fetch(PDO::FETCH_ASSOC)){
 	#插入目标表
 	$data = array(
-					(int)$srcData["id"],
-					(int)$srcData["book"],
-					(int)$srcData["paragraph"],
-					(int)$srcData["begin"],
-					(int)$srcData["end"],
-					(int)$srcData["length"],
-					(int)$srcData["count"],
+					$srcData["id"],
+					$srcData["book"],
+					$srcData["paragraph"],
+					$srcData["begin"],
+					$srcData["end"],
+					$srcData["length"],
+					$srcData["count"],
 					$srcData["text"],
 					$srcData["html"],
 					$srcData["sim_sents"]
@@ -89,7 +89,7 @@ while($srcData = $stmtSrc->fetch(PDO::FETCH_ASSOC)){
 
 // 提交更改
 $PDO_DEST->commit();
-fwrite(STDOUT, "done".PHP_EOL);
+fwrite(STDOUT, "done insert {$count} rows".PHP_EOL);
 
 
 

+ 6 - 6
v1/scripts/migrations/20211127214800_sent_sim.php

@@ -62,11 +62,11 @@ try{
 while($srcData = $stmtSrc->fetch(PDO::FETCH_ASSOC)){
 	#插入目标表
 	$data = array(
-					(int)$srcData["sent1"],
-					(int)$srcData["sent2"],
-					(int)$srcData["sim"]
-	);
-	try{					
+					$srcData["sent1"],
+					$srcData["sent2"],
+					$srcData["sim"]
+				);
+	try{
 		$stmtDEST->execute($data);		
 	}catch(PDOException $e){
 		fwrite(STDERR,"error:".$e->getMessage().PHP_EOL);
@@ -83,7 +83,7 @@ while($srcData = $stmtSrc->fetch(PDO::FETCH_ASSOC)){
 
 // 提交更改
 $PDO_DEST->commit();
-fwrite(STDOUT, "done".PHP_EOL);
+fwrite(STDOUT, "done insert {$count} rows".PHP_EOL);
 
 
 

+ 27 - 0
v1/windows/install1.bat

@@ -0,0 +1,27 @@
+php ../app/install/db_insert_templet_cli.::php 1 217
+php ../app/install/db_update_toc_cli.::php 1 217 pali
+php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+::php ../app/install/db_insert_palitext_cli.::php 1 217
+::php ../app/install/db_update_palitext_cli.::php 1 217
+::php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+::php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+
+::php ../app/install/db_insert_wordindex_from_csv_cli.php
+::php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+::php ./migaration/20211202084900_init_pali_serieses.php
+::php ./migaration/20211125155600_word_statistics.php
+::php ./migaration/20211125155700_pali_sent_org.php
+::php ./migaration/20211125165700-pali_sent-upgrade.php
+::php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+::php ./migaration/20211127214800_sent_sim.php
+::php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1

+ 26 - 0
v1/windows/install2.bat

@@ -0,0 +1,26 @@
+::php ../app/install/db_insert_templet_cli.::php 1 217
+::php ../app/install/db_update_toc_cli.::php 1 217 pali
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+php ../app/install/db_insert_palitext_cli.::php 1 217
+php ../app/install/db_update_palitext_cli.::php 1 217
+php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+::php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+::php ../app/install/db_insert_wordindex_from_csv_cli.php
+::php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+::php ./migaration/20211202084900_init_pali_serieses.php
+::php ./migaration/20211125155600_word_statistics.php
+::php ./migaration/20211125155700_pali_sent_org.php
+::php ./migaration/20211125165700-pali_sent-upgrade.php
+::php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+::php ./migaration/20211127214800_sent_sim.php
+::php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1

+ 26 - 0
v1/windows/install3.bat

@@ -0,0 +1,26 @@
+::php ../app/install/db_insert_templet_cli.::php 1 217
+::php ../app/install/db_update_toc_cli.::php 1 217 pali
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+::php ../app/install/db_insert_palitext_cli.::php 1 217
+::php ../app/install/db_update_palitext_cli.::php 1 217
+::php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+::php ../app/install/db_insert_wordindex_from_csv_cli.php
+::php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+::php ./migaration/20211202084900_init_pali_serieses.php
+::php ./migaration/20211125155600_word_statistics.php
+::php ./migaration/20211125155700_pali_sent_org.php
+::php ./migaration/20211125165700-pali_sent-upgrade.php
+::php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+::php ./migaration/20211127214800_sent_sim.php
+::php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1

+ 26 - 0
v1/windows/install4.bat

@@ -0,0 +1,26 @@
+::php ../app/install/db_insert_templet_cli.::php 1 217
+::php ../app/install/db_update_toc_cli.::php 1 217 pali
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+::php ../app/install/db_insert_palitext_cli.::php 1 217
+::php ../app/install/db_update_palitext_cli.::php 1 217
+::php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+::php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+php ../app/install/db_insert_wordindex_from_csv_cli.php
+php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+::php ./migaration/20211202084900_init_pali_serieses.php
+::php ./migaration/20211125155600_word_statistics.php
+::php ./migaration/20211125155700_pali_sent_org.php
+::php ./migaration/20211125165700-pali_sent-upgrade.php
+::php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+::php ./migaration/20211127214800_sent_sim.php
+::php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1

+ 26 - 0
v1/windows/install5.bat

@@ -0,0 +1,26 @@
+::php ../app/install/db_insert_templet_cli.::php 1 217
+::php ../app/install/db_update_toc_cli.::php 1 217 pali
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+::php ../app/install/db_insert_palitext_cli.::php 1 217
+::php ../app/install/db_update_palitext_cli.::php 1 217
+::php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+::php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+::php ../app/install/db_insert_wordindex_from_csv_cli.php
+::php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+php ./migaration/20211202084900_init_pali_serieses.php
+php ./migaration/20211125155600_word_statistics.php
+php ./migaration/20211125155700_pali_sent_org.php
+php ./migaration/20211125165700-pali_sent-upgrade.php
+php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+::php ./migaration/20211127214800_sent_sim.php
+::php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1

+ 26 - 0
v1/windows/install6.bat

@@ -0,0 +1,26 @@
+::php ../app/install/db_insert_templet_cli.::php 1 217
+::php ../app/install/db_update_toc_cli.::php 1 217 pali
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hans
+::php ../app/install/db_update_toc_cli.::php 1 217 zh-hant
+::耗时30min
+::php ../app/install/db_insert_palitext_cli.::php 1 217
+::php ../app/install/db_update_palitext_cli.::php 1 217
+::php ../app/install/db_insert_bookword_from_csv_cli.::php 1 217
+::耗时9min
+::php ../app/install/db_insert_word_from_csv_cli.::php 1 217
+::耗时22min
+
+::php ../app/install/db_insert_wordindex_from_csv_cli.php
+::php ../app/admin/word_index_weight_refresh.::php 1 217
+::耗时51min
+::php ./migaration/20211202084900_init_pali_serieses.php
+::php ./migaration/20211125155600_word_statistics.php
+::php ./migaration/20211125155700_pali_sent_org.php
+::php ./migaration/20211125165700-pali_sent-upgrade.php
+::php ./migaration/20211126220400-pali_sent_index-upgrade.php
+::耗时15min
+php ./migaration/20211127214800_sent_sim.php
+php ./migaration/20211127214900-sent_sim_index.php
+::耗时53min
+php ../app/fts/sql.php
+net time \\127.0.0.1