2025年7月21日 星期一

只要點兩下,就可以將資料夾input內的所有Word通通轉成一個PDF

系列文章:
3. 只要點兩下,就能將一堆的Doc與Docx 轉成 PDF
3.https://skjhcreator.blogspot.com/2023/05/docdocx-pdf.html
4.https://skjhcreator.blogspot.com/2023/06/jpgpdfjpgpdf.html
5.只要點兩下,就能將放進input的一堆PDF轉成各自的WORD
5.https://skjhcreator.blogspot.com/2023/10/inputpdfword.html
6.只要點兩下,就能將放進input的一堆PDF轉成在ouput資料夾內的各自的WORD 
6.https://skjhcreator.blogspot.com/2023/10/inputpdfouputword.html

7.只要點兩下,就能夠將InputAndOutput資料夾底下的子子孫孫資料夾內所有Word通通轉成PDF

     最近在行政處室內聽聞,常常要將很多的Word轉成一個個相對應的PDF,再將一個個對應的PDF合併成一個PDF。而那個PDF就是要交給上級的檔案。特別是要送課程計畫時候,常常會忙到忘了到底是哪個Word轉到哪個PDF?合併後的PDF會不會少哪個PDF?聽到這些聲音,就開始思考能不能將這些步驟省略,直接將很多Word轉一個PDF?

        Recently, I heard in the administrative office that there is often a need to convert many Word documents into corresponding PDFs, and then merge those PDFs into a single PDF. This final PDF is required to be submitted to superiors. Especially when submitting course plans, it often gets so busy that one forgets which Word document corresponds to which PDF, and whether any PDFs are missing after merging. Hearing these concerns, I started to think about whether it is possible to skip these steps and directly convert multiple Word documents into a single PDF.

下載檔案解壓密碼:demo1234
Here is the website where you can download the program and find instructions:
Download。Extraction Password: demo1234
使用教學(Instructional videos):



以下是開發過程與原始碼 (Development process and code):
 
安裝套件pypiwin32 、 PyPDF2 
指令(command):
pip install pypiwin32
pip install PyPDF2
 
程式名稱(Program name):AllWord2OnePDF.py
程式內容(Code):

import glob
import os
from win32com import client
import time
from PyPDF2 import PdfFileMerger

# Word轉PDF
path=os.getcwd()
os.chdir(path+'\\input\\')
word = client.Dispatch("Word.Application")

for i in glob.glob('*.doc'):
    doc = word.Documents.Open(path+'\\input\\'+i)
    doc.SaveAs("{}.pdf".format(path+'\\output\\'+i[:-4]),17)
    doc.Close()
for i in glob.glob('*.docx'):
    docx = word.Documents.Open(path+'\\input\\'+i)
    docx.SaveAs("{}.pdf".format(path+'\\output\\'+i[:-5]),17)
    docx.Close()

word.Quit()
print("WORD轉PDF 完成!!")
# PDF合併
pdf_lst = list()
# 設定Input為目標路徑
os.chdir(path+'\\output')
target_path=str(os.path.abspath(os.getcwd()))
# 列出目標路徑內的pdf
for f in os.listdir(target_path):
    if f.endswith('.pdf'):
        pdf_lst.append(os.path.join(target_path,f))

# pdf 合併
file_merger = PdfFileMerger()
for pdf in pdf_lst:
    file_merger.append(pdf)

output_name =path+"\\"+"merge"+str(time.strftime("%H-%M-%S",time.localtime()))+".pdf"
file_merger.write(output_name)
print("PDF合併 完成!!")  

資料來源:

2025年6月29日 星期日

Laravel 12 Model 資料庫中的資料表,並提供與資料庫互動的介面

相關系列文章:

         在Laravel 中,Model 代表資料庫中的資料表,並提供與資料庫互動的介面。 
它使用Eloquent ORM,讓開發者可以更直觀地操作資料庫,而不需要寫大量的SQL 語法。 Model 實體對應到資料表的一列數據,可以進行新增、讀取、更新和刪除等操作。

一、建立一個 Student 的 Model
php artisan make:model Student


二、加上-mc 建立一個Teachers 的 Model 
php artisan make:model Teachers -mc

就會建立三個,分別是 Model、Controller、Migration
在 2025_06_29_113017_create_teachers_table.php , 可以加上
            $table->string('name');

如下圖:

然後,命令列輸入
 php artisan migrate

並隨意增加幾個數據,

1.在 routes/web.php 寫入
Route::get('teachers',function(){
    return Teachers::all();
});

接下來進行測試:
php artisan serve
在網頁網址上打上:http://127.0.0.1:8000/teachers/


通常我們不會像上述的方法來寫,而是向下面的方式來寫:
2.在 routes/web.php 寫入
Route::get('teachers',[TeachersController::class,'index']);
在/app/http/controllers/TeachersController.php 寫入
    public function index()
    {
        return Teachers::all();
    }

在網頁網址上打上http://127.0.0.1:8000/teachers/,一樣可以看到

接下來,增加一名老師,名叫Test Name,並觀察資料庫的變化
3.在 routes/web.php 寫入
Route::get('add-teacher',[TeachersController::class,'add']);

在/app/http/controllers/TeachersController.php 寫入

    public function add() {
        $item = new Teachers();
        $item->name = 'Test Name';
        $item->save();

        return 'Added Successfully';
    }

啟用伺服器
php artisan serve
在網址打上 127.0.0.1:8000/add-teacher
                
然後在資料庫,可發現

接下來,如何在網頁上取得這位老師的資料,並呈現出來。
4.在/app/http/controllers/TeachersController.php 寫入

    public function show($id) {
        $item = Teachers::findOrFail($id);
        return $item;
    }


 routes/web.php 寫入
Route::get('show-teacher/{id}',[TeachersController::class,'show']);
接下來,在網址列輸入http://127.0.0.1:8000/show-teacher/7

接下來,要如何更新這位老師的資料,並呈現出來
5.在/app/http/controllers/TeachersController.php 寫入
    public function update($id) {
        $item = Teachers::findOrFail($id);
        $item->name = 'Updated Teacher';
        $item->update();
        return 'updated Successfully';
    }
 routes/web.php 寫入
Route::get('update-teacher/{id}',[TeachersController::class,'update']);
在資料庫的資料為

接下來,要來刪除這筆資料
6.在/app/http/controllers/TeachersController.php 寫入
    public function delete($id) {
        $item = Teachers::findOrFail($id);
        $item->delete();
        return 'Deleted Successfully.';
    }
 routes/web.php 寫入
在資料庫

2025年6月24日 星期二

Ubuntu 24.04 的 Apache2 設定 Permissions-Policy




1.Apache2 啟用 mod_headers.so
$sudo a2enmod headers

2.編輯default-ssl.conf,設定#Permissions-Policy
$sudo nano /etc/apache2/sites-available/default-ssl.conf
加入
#Permissions-Policy
Header always set Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"

3.重啟 Apache2
$sudo service apache2 restart

資料來源:
2.

Ubuntu 24.04 的 Apache2 設定 Cookies marked as HttpOnly


1.Apache2 啟用 mod_headers.so
$sudo a2enmod headers

2.編輯default-ssl.conf, 設定 HttpOnly;Secure;XSRF
$sudo nano /etc/apache2/sites-available/default-ssl.conf
加入
# HttpOnly;Secure;XSRF
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=strict


3.重啟 Apache2
$sudo service apache2 restart

4.如何檢測是否設定成功
假設該網站為https://www.example.com
$curl -I https://www.example.com

資料來源:

2025年6月19日 星期四

Ubuntu 24.04 的 Apache2 解決 TLS/SSL Weak Cipher Suites

1.apache2 啟用 SSL 模組
$sudo a2enmod ssl

2.使用nmap 檢查本機的漏洞
#掃RDP的3389
$nmap --script ssl-enum-ciphers -p 3389 127.0.0.1

#掃https的443
$nmap --script ssl-enum-ciphers -p 443 127.0.0.1

3.編輯 /etc/apache2/sites-available/default-ssl.conf
$sudo nano  /etc/apache2/sites-available/default-ssl.conf
將下面寫入

# 伺服器使用自己定義的 Cipher 排序(不要讓 client 決定)
SSLHonorCipherOrder on

# 停用 SSL 壓縮(防止 CRIME 攻擊)
SSLCompression off

# 安全 Cipher 套件組合
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305

SSLSessionTickets off

 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

 # Security headers
 ## X-Content-Type-Options
 Header set X-Content-Type-Options "nosniff"
    
 ## Content-Security-Policy
 Header set Content-Security-Policy "frame-ancestors 'self';"
    
 ## Strict Transport Security (HSTS)
 Header set Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"


4.檢查設定語法是否正確
$sudo apache2ctl configtest

Ubuntu 24.04 的 Apache2 設定 HTTP Strict Transport Security(HSTS)與檢測方法

1.啟用 apache headers 模組 
$sudo a2enmod headers

2.重新啟動 apache 
$sudo service apache2 restart

3.編輯 /etc/apache2/conf-available/security.conf ,加上 header 設定
$sudo nano /etc/apache2/conf-available/security.conf

    Header always set Strict-Transport-Security "max-age=31536000;includeSubdomains; preload"
步驟3.的方式會將整個設定複雜化,可以直接將
Header always set Strict-Transport-Security "max-age=31536000;includeSubdomains; preload"
寫入到/etc/apache2/sites-available/default-ssl.conf 。這樣設定會比較單純。所以
3.1 編輯 /etc/apache2/sites-available/default-ssl.conf

Header always set Strict-Transport-Security "max-age=31536000;includeSubdomains; preload"


4.重新載入設定 
$sudo service apache2 reload

5.檢測https://www.example.com.tw指令:
$curl -s -D - https://www.example.com.tw -o /dev/null

資料來源:



Laravel 網站遇到Host header attack 解決方法及python檢測漏洞方法

1.設定.env的APP_ENV為production
APP_ENV=production

2.問Chat everywhere 的 prompt
host header attack apache 解決方案
host header attack apache 解決方案 https
host header attack apache 解決方案 https://www.example.com.tw
經過上述三段式的prompt,就可得到比較完整

步驟(1).修改/etc/apache2/sites-available/000-default.conf
確保 Apache 僅接受您擁有的域名的請求
<VirtualHost *:80>
    ServerName www.example.com.tw
    ServerAlias example.com.tw

    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\.example\.com\.tw$ [NC]
    RewriteRule ^ - [F]

<Directory /home/webadmin/html/example/public> Options -Indexes AllowOverride All Require all granted </Directory>

Redirect permanent / https://www.example.com/

</VirtualHost>

步驟(2).修改/etc/apache2/sites-available/default-ssl.conf
<VirtualHost *:443>
    ServerName www.example.com
    ServerAlias example.com

<Directory "/home/webadmin/html/example/public/"> Options -Indexes AllowOverride All Require all granted </Directory>

    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
    RewriteRule ^ - [F]
    
    SSLEngine on
    SSLCertificateFile /path/to/certificate.crt
    SSLCertificateKeyFile /path/to/private.key
    SSLCertificateChainFile /path/to/chainfile.pem
</VirtualHost>

3.問Chat everywhere 的 prompt
給我一個python 檢測 https://www.example.com.tw 的host header attack 漏洞
安裝套件:
pip install requests

檢測程式:
import requests

# 目標 URL
url = "https://www.example.com.tw"

# 攻擊的 Host 標頭
malicious_host = "malicious.com"

# 自定義請求頭
headers = {
    "Host": malicious_host
}

try:
    # 發送請求
    response = requests.get(url, headers=headers)

    # 檢查響應
    if response.status_code == 200:
        print(f"可能存在 Host Header Attack 漏洞,響應內容:\n{response.text}")
    else:
        print(f"響應碼:{response.status_code},未檢測到漏洞。")
except requests.exceptions.RequestException as e:
    print(f"請求出錯:{e}")

測試結果:
資料來源:

2025年6月10日 星期二

Laravel 12 Migration 遷移-資料庫版本控制


Migration 是名詞,代表的是準備用來變更資料庫結構的檔案,但本身無法執行。 Migrate 是動詞,它是用來執行 Migration 的內容。

一、預設的Migration指令
指令:php artisan migrate

二、完成migrations的檔案位置:
database/migrations/
三、設定資料庫為mysql
1.修改.env設定

2.在命令提示字元,打上 
php artisan migrate

3.在網址打上:http://localhost:8080/phpmyadmin/index.php?route=/database/structure&db=students
就可以看到新增students資料庫,裡面資料表已建立完成。
四、如何建立自己的migration
1.指令:
php artisan make:migration StudentsTable

就會建立自己的migration,但是內部的程式碼只有兩個空函式,分別是up與down。

2.指令:
php artisan make:migration create_students_table

就會建立自己的migration,但是內部的程式碼只有兩個函式,分別是up與down,並建立基本的欄位。

3.在函式up裡面,出現兩個欄位 id() 與 timestamps() 
            $table->id();
            $table->timestamps();
其中 id() 是主鍵,timestamps()是時間戳記。
此時,下指令:php artisan migrate
就會得到三個欄位,分別是id、created_at、updated_at
如果想了解更多,請到https://laravel.com/docs/12.x/migrations#creating-columns
接下來新增三個欄位
            $table->string('name');
            $table->string('email');
            $table->integer('age');
然後下指令:php artisan migrate
這時如果出現Nothing to migrate
則可以先用 
php artisan migrate:rollback
再用
php artisan migrate
就可以得到相對應的資料表欄位

五、若要在"使用中的資料表"中新增欄位,要怎麼做呢?
1.在命令提示列中,
php artisan make:migrations addDateOfBirthToStudents --table=students

2.在新增的2025_06_27_070357_add_date_of_birth_to_students.php進行編輯

    $table->dateTime('date_of_birth')->nullable();
$table->enum('gender', ['f','m'])->default('m');
            $table->dropColumn('date_of_birth');
            $table->dropColumn('gender');
如下圖:

接下來使用
php artisan migrate


3.在命令提示列中,
php artisan make:migration addUserIdToStudents --table=students
此時會新增2025_06_29_050439_add_user_id_to_students.php
裡面會有兩個func,分別是up()與down()
up()要加入限制
 $table->foreignId('user_id')->constrained('users')->onDelete('cascade')->onUpdate('cascade');
down()要加入
$table->dropforeign(['user_id']);
$table->dropColumn(['user_id']);
六、取消變更的指令
1.取消變更的指令:
php artisan migrate:rollback

2.取消變更幾次的指令:
php artisan migrate:rollback --step=2


3.取消變更到初始位置的指令:
php artisan migrate:reset

接下來再來處理:
                            php artisan migrate

就會建立起所有的表格。

4.清除所有變更再建立起所有的表格的指令:
php artisan migrate:fresh

該指令的效果php artisan migrate:reset + php artisan migrate



資料來源:
1.Laravel 12 – Introduction to Migrations: Manage Your Database Efficiently


只要點兩下,就可以將資料夾input內的所有Word通通轉成一個PDF

系列文章: 1. python 不管何時何地,只要點兩下,資料夾內的所有pdf都會合併成一個pdf https://skjhcreator.blogspot.com/2022/06/pythonpdfpdf.html 2. python 只要點兩下,分別對各資料夾內的pdf合併,...