OpenProject 翻譯
我在進行OpenProject翻譯時,把特殊的部分列出來(後續在咖啡偶之書更新):
Placeholder Users -> 非專案成員 ── 原本翻譯成佔位符用戶
Repository -> 版本庫 ── 大部分都翻譯成儲存庫,但在Open project很確定是版本控管git or svn
要抓特定檔案裏面特定字串,可執行以下指令
find . -name '特定檔案' | xargs egrep "特定字串"
我在進行OpenProject翻譯時,把特殊的部分列出來(後續在咖啡偶之書更新):
Placeholder Users -> 非專案成員 ── 原本翻譯成佔位符用戶
Repository -> 版本庫 ── 大部分都翻譯成儲存庫,但在Open project很確定是版本控管git or svn
要抓特定檔案裏面特定字串,可執行以下指令
find . -name '特定檔案' | xargs egrep "特定字串"
公司有個RedHat 5.x伺服器系統,安裝git 2.9 ,多年以來使用上一直相安無事;沒想到因為全面停用tls 1.0,導致git無法使用。
RedHat Linux系統在無法升級的情況下,git就再起不能;最後我指定其中一台windows主機,安裝RaiDrive透過sftp掛載Linux伺服器的git目錄,使其變成windows其中的一個磁碟,再透過windows的git用戶端,達到讓Linux伺服器裡面的資料能上git版控的目標。
就在我在windows主機上,順利掛載Linux目錄後,接著準備將資料push到git server,豈料出現一大堆檔案呈現已修改狀態,提示我這些檔案要commit,但是實際上這些檔案沒有任何異動修改;我追查了一下,發現是換行字元搞的鬼,Linux換行只有\n ,windows則為\r\n;
windows掛載Linux檔案,因為換行字元不同,當然會被誤認檔案被修改過。
解決方式,在windows掛載linux情況下,執行以下git指令,就可以解決了。
git config --global core.autocrlf true
git config core.filemode false
git status
linux的排程為cron,可以設定將作業(job)所產生的結果,透過郵件回報。
[root@localhost~]# crontab -l
SHELL=/bin/bash
PATH=/usr/local/java/bin:/sbin:/bin:/usr/sbin:/usr/bin:
HOME=/
MAILFROM=postmaster@test.com.tw
MAILTO=it@test.com.tw
若要停用單一作業,可以將輸出結果,丟到null去。
*/5 * * * * xxx.sh >/dev/null 2>&1
guacamole是很棒的網頁版遠端連線工具,就差在切換輸入法不是那麼簡便。
公司可以安裝酪梨醬,綁定員工帳號只能連到員工主機,也不開放員工自行設定連線,搭配現在guacamole已經可以設定遠端開機,就可以讓員工遠距連線工作,而公司方面可以計算員工工時,若員工加班也能有所憑證。
我安裝的酪梨醬使用mysql,計算工時的語法如下:
# 可計算同一天連線小時(小數第二位)
SELECT username ,DATE_FORMAT(start_date, "%Y%m%d") the_same_date, cast(sum(TIMESTAMPDIFF(MINUTE,start_date,end_date))/60 as decimal(9,2)) overtime_hour
from guacamole_connection_history
group by username,the_same_date
order by username,the_same_date desc
#若資料庫時區沒有調整,預設是UTC,可暫時使用CONVERT_TZ轉換正確時區
SELECT username ,DATE_FORMAT(CONVERT_TZ(start_date,'+00:00','+08:00'), "%Y%m%d") the_same_date, cast(sum(TIMESTAMPDIFF(MINUTE,start_date,end_date))/60 as decimal(9,2)) overtime_hour
from guacamole_connection_history
group by username,the_same_date
order by username,the_same_date desc
# 排除每次連線低於30分鐘
SELECT username ,DATE_FORMAT(start_date, "%Y%m%d") the_same_date, cast(sum(TIMESTAMPDIFF(MINUTE,start_date,end_date))/60 as decimal(9,2)) overtime_hour
from guacamole_connection_history
where TIMESTAMPDIFF(MINUTE,start_date,end_date) >= 30
group by username,the_same_date
order by username,the_same_date desc
#若資料庫時區沒有調整,預設是UTC,可暫時使用CONVERT_TZ轉換正確時區
SELECT username ,DATE_FORMAT(CONVERT_TZ(start_date,'+00:00','+08:00'), "%Y%m%d") the_same_date, cast(sum(TIMESTAMPDIFF(MINUTE,start_date,end_date))/60 as decimal(9,2)) overtime_hour
from guacamole_connection_history
where TIMESTAMPDIFF(MINUTE,start_date,end_date) >= 30
group by username,the_same_date
order by username,the_same_date desc
為了員工健康,要設定上線時間
另外酪梨醬預設60分鐘沒有任何遠端連線,會整個登出。
可搭配遠端桌面連線相關設定
vi guacamole.properties
##### 修改30分鐘整個網頁登出(必須在沒有任何連線的情況下)
api-session-timeout:30
可以搭配設定閒置30分鐘後,遠端桌面連線自動登出,此時酪梨醬沒有任何連線了,過30分鐘也跟著登出了。
bookstack 真是越來愈好用,其「變動日誌」類似git版控系統commit messages功能,可以記錄修改原因。
https://book.kafeiou.pw/books/bookstack/page/bookstackiso
我有一台13年前的pentium老電腦4GB ram,安裝windows 10、windows 11都覺得好慢好慢,偶然間看到「雲爸的私處」寫的一篇文章「低端電腦救星 ReviOS Windows 11精簡版系統」,文章推薦的「Revision」是開源軟體。該軟體以前會提供整個windows iso檔,讓人下載後直接安裝;後來改成「腳本」方式,我們只要正常安裝windows,再執行AME Wizard優化程式,載入Revision的腳本,就可以讓舊電腦優化了。
我的軟體工程概念很差,最近遇到一個案子,我想要找人一起,但是那個同事主管說要寫提案,了解後才會分配資源。
於是我想到了「SRS(Software Request Spec)軟體需求規格」當作提案,但是又不想要用傳統的word檔案書寫(很難維護),於是上網找了一下軟體需求與功能規格書的範例,終於找到滿意的書寫格式-使用gitbook
https://mason1762.gitbook.io/samxinbakery/gong-neng-ge
可惜gitbook自架很麻煩,於是我又找到相似而且可以自架、開源的系統-bookstack
bookstack宣稱是wiki軟體,也可以當知識管理,以書架、書本為基本架構的系統
https://demo.bookstackapp.com/books
安裝方式很簡單,我這次寫在網誌裡,也沒放在svn系統(https://docs.kafeiou.pw/!/#iammis),而是直接現學現賣,把安裝方式寫在自架的bookstack上。
另外有個很棒bookstack網站建議大家參考一下 BUBU 知識庫 & 秉迅資訊.Studio 。
原來不是這麼簡單
private static final String[] VALID_IP_HEADER_CANDIDATES = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR" }; public static String getClientIpAddress(HttpServletRequest request) { for (String header : VALID_IP_HEADER_CANDIDATES) { String ipAddress = request.getHeader(header); if (ipAddress != null && ipAddress.length() != 0 && !"unknown".equalsIgnoreCase(ipAddress)) { return ipAddress; } } return request.getRemoteAddr(); }