分類
程序

把媒體中地理位置標籤從 WGS-84 轉換成 GCJ-02

手機拍攝的照片地理位置默認是 WGS-84 系統,但是谷歌地圖使用的卻是 GCJ-02 系統,這就會出現偏移。爲了展示正確的位置,可以通過把照片的地理位置標籤轉換成 GCJ-02 來實現。需要用到 Phil Harvey開發的 ExifTool 和 Avatar sshuair 開發的 coord-convert。前者下載exiftool.exe 到本地即可,後者可以通過 pip 安裝。

# -*- coding: utf-8 -*-

#pip install coord-convert

#Usage:
#Drage a single photo or directory with photos to this script
# OR
#python wgs2gcj.py D:\my.JPG
#Results will be wrote to gps.log at the same dir with this script

from coord_convert.transform import wgs2gcj
import subprocess,json,sys,os,time,datetime
#You may set your exiftool file here
exiftool_path = "D:\\Program Files\\portable\\exiftool.exe"

work_dir = os.getcwd()
def log42(logFile,logText):
	ts = int(time.time())
	dt = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
	
	log_file = os.path.join(work_dir,logFile+".log")
	with open(log_file, "a") as myfile:
		myfile.write(dt+" "+logText+"\n")
		print(logText)
		
		
if (exiftool_path == ""):
	exiftool_path = os.path.join(work_dir,'exiftool.exe')
if not os.path.exists(exiftool_path):
	log42("gps","Error: exiftool.exe not found neither in script directory nor in the script setting \"exiftool_path\"")
	exit()
	
file_paths_input = sys.argv[1:]
file_paths = []

for file_path_input in file_paths_input:
	if os.path.isfile(file_path_input):
		file_paths.append(file_path_input)
	elif os.path.isdir(file_path_input):
		for root,ds,fs in os.walk(file_path_input):
			for ff in fs:
				full_path = os.path.join(root,ff)
				file_paths.append(full_path)

for f in file_paths:
	output = subprocess.check_output('"'+exiftool_path+'" -struct -j -a -n "-gps*" '+f, shell=True)
	data = json.loads(output)
	if 'GPSMapDatum' in data[0]:
		log42("gps",data[0]['SourceFile']+':'+str(data[0]['GPSMapDatum'])+' '+str(data[0]['GPSLatitude'])+' '+str(data[0]['GPSLongitude']))
		if(data[0]['GPSMapDatum']=='WGS-84'):
			gcj_lon, gcj_lat = wgs2gcj(data[0]['GPSLongitude'], data[0]['GPSLatitude'])
			log42("gps",str(gcj_lat)+' '+str(gcj_lon))
			if (gcj_lat==data[0]['GPSLatitude']):
				log42("gps",'not in China')
			else:
				output = subprocess.check_output('"'+exiftool_path+'" -overwrite_original -exif:gpsmapdatum=GCJ-02 -exif:gpslatitude='+str(gcj_lat)+' -exif:gpslongitude='+str(gcj_lon)+' '+f, shell=True)
				log42("gps",output.decode())
		else:			
			log42("gps","not a wgs84 location")
	else:
		log42("gps","no gps data found")
		
log42("gps","task finished")

另請參考:使用ExifTool處理文件元數據wgs-84-gcj-02-經緯度在線轉換

分類
方法

使用谷歌位置記錄來給照片增加位置標籤

Emanon 有一些多年前旅行時拍攝的自然觀察的照片,但是現在很難回憶起照片的具體拍攝位置。好在當年手機打開了谷歌的位置記錄,現在我只要把照片的拍攝時間和谷歌位置記錄裏的時間相關聯即可。需要用到兩個工具: Scarygami 開發的 Python 腳本 Location History JSON Converter 和一個強大的開源影音管理軟件digiKam

首先要從谷歌獲取自己的位置記錄,打開 Google Takeout,按提示下載 json 格式的文件即可。然後把 location_history_json_converter.py 文件保存的本地,用來把谷歌的文件轉換成 digiKam 可用的格式,即 gpxtracks 格式。

#從定位記錄中轉換出指定範圍的數據
python location_history_json_converter.py "/home/fred/Documents/Takeout/定位記錄/定位記錄.json" 2019.gpx -f gpxtracks -s 2019-03-01 -e 2019-10-31

有了 gpx 文件後,即可參考简单使用影音管理軟件 digiKam 來給照片加上地理位置標籤了。

幾個小撇步:一、匹配位置的時候請留意「相機時區」,gpx文件中的都是 UTC,所以要選對照片拍攝的時區才準確。二、如果對位置精度要求不高,可適當增加「最大時間間隔」以提高匹配成功率。三、最後如果個別照片還是匹配不到,還可以根據前後照片的位置來手動指定其位置。

分類
软件

Linux 使用 Python 操作剪切板

還是那個簡繁轉換的需求, zhconv 似乎不能直接給它傳一段文字來轉換,只能轉換文件或者在 Python 中調用。

Fedora

先安裝 xclip 依賴,再安裝 pyperclip:

sudo dnf install xclip
sudo pip3 install pyperclip

然後新建一個 Python 腳本 /home/[YOURNAME]/scripts/s2t.py:

import pyperclip
from zhconv import convert

clipString = pyperclip.paste()
clipStringTC = convert(clipString, 'zh-hant')
pyperclip.copy(clipStringTC)

最後為了方便使用,給腳本設置一個別名

alias t='python3 /home/[YOURNAME]/scripts/s2t.py'

但是如果想讓別名保存下來,以後每次都能用,Fedora 需要把別名加到家目錄的 .bashrc 文件裏:

nano ~/.bashrc
alias t='python3 /home/[YOURNAME]/scripts/s2t.py'

Termux

Termux 無法使用 pyperclip 來操作剪切板,但是可以通過 Termux API 來操作。對應的 Python 這樣:

import subprocess
from zhconv import convert

clipString = subprocess.getoutput("termux-clipboard-get")
clipStringTC = convert(clipString, 'zh-hant')
subprocess.getoutput("termux-clipboard-set \'"+clipStringTC+"\'")

本文更新於 2022/07/29。

分類
软件

簡易中文簡繁轉換 Python 庫 zhconv

zhconv 提供基于 MediaWiki 和 OpenCC 词汇表的最大正向匹配简繁转换,支持地区词转换:zh-cn, zh-tw, zh-hk, zh-sg, zh-hans, zh-hant。Python 2、3通用。

若要求高精确度,参见 OpenCCopencc-python

用起來方便準確,轉換模式若是 zh-tw 會進行地區詞轉換,如將「软件」轉換為「軟體」。而使用 zh-hant 則只轉換簡繁,如將「软件」轉換為「軟件」。

pip install zhconv
from zhconv import convert
print(convert('他說「我幹什麼不干你事。」', 'zh-cn'))
#他说“我干什么不干你事。”
print(convert('计算机软件', 'zh-tw'))
#計算機軟體
print(convert('计算机软件', 'zh-hant'))
#計算機軟件

命令行工具

python -mzhconv [-w] {zh-cn|zh-tw|zh-hk|zh-sg|zh-hans|zh-hant|zh} < input > output
#如
python -mzhconv zh-hant <山东合村并居的真实情况.txt> 山東合村並居的真實情況.txt

歡迎大家使用我在 Heroku 上部署的在線中文轉換工具

本文更新於 2020/12/31。

分類
程序

使用python同步本地時間

服務器超售到不行,cpu時間隔一段時間就滿好多。嘗試配置了標準了自動的時間同步,效果不理想。於是用python調用worldtimeapi.org的api配合crontab來修正系統時間。

import subprocess,requests,time

def main():
    try:
        response = requests.request("GET", "http://worldtimeapi.org/api/timezone/Asia/Hong_Kong")
        timeJson=response.json()
        timeAbs = abs(timeJson['unixtime']-time.time())
        if timeAbs > 15 :
            subprocess.call(['date','+%T','-s',timeJson['datetime'][11:19]])
            print("time synced")
        else:
            print(timeAbs)
            
    except:
        print("net error")
    
if __name__ == '__main__':
    main()
#添加crontab任務
crontab -e
#每兩小時檢查一次
0 */2 * * * /usr/local/bin/python3 /home/42/time.py >> /home/42/t.log 2>&1
分類
程序

python使用pyftpdlib實現ftp服務

需要使用ftp分享文件,記得很久之前折騰過ftp服務的搭建,賬號權限設置都挺複雜,這次使用python和pyftpdlib實現,幾分鐘就搞定啦。

#安裝pyftpdlib,當然還是推薦在虛擬環境裡裝
pip install pyftpdlib

然後新建一個python文件myFtp.py,內容如下:

import os

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

def main():
    # Instantiate a dummy authorizer for managing 'virtual' users
    authorizer = DummyAuthorizer()

    # 第一行新建一個具有讀寫權限的用戶(用戶名,密碼,ftp文件夾)
    # 第二行新建匿名讀取賬戶
    authorizer.add_user('user', '12345', '.', perm='elradfmwMT')
    authorizer.add_anonymous(os.getcwd())

    # Instantiate FTP handler class
    handler = FTPHandler
    handler.authorizer = authorizer

    # 設置一個個性化歡迎語 (客戶端來連接的時候會返回給它)
    handler.banner = "基於pyftpdlib的ftp服務已準備好"

    # Specify a masquerade address and the range of ports to use for
    # passive connections.  Decomment in case you're behind a NAT.
    #handler.masquerade_address = '151.25.42.11'
    #handler.passive_ports = range(60000, 65535)

    # 監聽任意ip目標的2121端口,ftp標準端口是21
    address = ('', 2121)
    server = FTPServer(address, handler)

    # set a limit for connections
    server.max_cons = 256
    server.max_cons_per_ip = 5

    # start ftp server
    server.serve_forever()

if __name__ == '__main__':
    main()
#最後運行就可以了
python myFtp.py

其實這次也是走了彎路的,那就是先嘗試了Twisted,stackoverflow的網友說可以一行命令實現ftp服務。結果pip裝不上,需要下載了安裝包用

pip install 
裝。裝好後匿名用戶可以跑,設置了密碼就顯示密碼錯誤,搜索一番也沒找到辦法,於是使用了pyftpdlib。雖然實現ftp服務失敗了,但Twisted確實是一個很厲害的項目,有時間的話可以學習一下。 Twisted also supports many common network protocols, including SMTP, POP3, IMAP, SSHv2, and DNS.

分類
Linux

Hourly Reminder

忙起來的時候不知不覺時間就過去了,而久坐對健康絕對不是什麼好事。那麼就產生了一個需求,提醒我時間的流逝。Android上有個不錯的開源應用Hourly Reminder,但是我是在工作的時候才需要提醒,所以最好是桌面彈窗。簡單搜索發現Fedora預裝的notify-send命令就能很好的實現toast效果,搭配crontab就能滿足需求了。

crontab -e
#單行Hourly Reminder簡潔版
0 9-18 * * 1-5 notify-send -t 6000 '整點咯' 'It is ? time.'
#Hourly Reminder python 豪華版
0 9-18 * * 1-5 /home/42/Programs/p37/bin/python /home/42/eclipse-workspace/scriptsP37/hourlyReminder.py

file:/home/42/eclipse-workspace/scriptsP37/hourlyReminder.py

#!/home/42/Programs/p37/bin/python
import time,datetime,subprocess,random

ts = int(time.time())
hour = datetime.datetime.fromtimestamp(ts).strftime('%H')
title = "現在時刻"+hour+"點整"
emojiList=['?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','☕️','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?']
content = '\r        '+random.choice(emojiList)+'\r'
subprocess.check_call(['notify-send','-t','6000',title,content])

定時任務參考自crontab guru。 Emoji複製自Get Emoji

代碼里的emoji被wordpress強制轉義,從段落里複製吧emojiList=['?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','☕️','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?']

本文更新於 2021/09/13。