まえがき
僕は、『独学プログラマー Python言語の基本から仕事のやり方まで』(著者:コーリー・アルソフ、監訳:清水川貴之)という本でPythonを勉強した初心者です。
現在は他の書籍でネットワークやセキュリティについて勉強中ですが、内容が難しく中々学習が捗らないので、息抜きを兼ねて自作のプログラムを作ってみることにしました。
本格的な、プログラミングらしいプログラムを作りたいという軽い気持ちで作り始めた自作のプログラムですが、思い通りに動かす方法が分からなかったり、何度もエラーに頭を悩ませたりと、途中で諦めかけることもありましたが、ようやく問題なく最後まで動くプログラムが完成して嬉しかったので、Qiitaに初めて投稿してみることにしました。
Markdown記法については、名前ぐらいしか知らなかったので、書き方を調べながらの記事作成になりますが、プレビューを確認しながら頑張って最後まで書いてみます。
動作環境
- コンピューターの基本的な情報
- Windows Edition: Windows 7
- 実装メモリ(RAM):8.00 GB
- システムの種類:64ビットオペレーティングシステム
- Python バージョン
- Python 3.7.0
前提条件
- プログラム実行前にGoogle Chromeを立ち上げ、Google フォトにログインした状態にしておく。
- Google フォトのタブのままにしておく
- パソコン画面下部のタスクバーで、(Windowsスタート・メニューを0として)左から数えて6番目にGoogle Chromeアプリケーションがある
- エクスプローラーは全て閉じておく
- エクスプローラーのアプリは、タスクバーの左から5番目の位置(Google Chromeの左隣)
- IDLE (Python 3.7 64-bit) は、このプログラム一つにしてから実行する
- Pythonアプリは、タスクバーの左から7番目、Google Chromeの右隣りの位置
- Pythonは、IDLEプログラム・ファイルと、起動するShellの2つだけになるようにする
- メモ帳アプリ(テキスト ドキュメント)は全て閉じておく
- メモ帳は、タスクバーの左から8番目、Pythonアプリの右隣に開いて閉じる
- エクスプローラーのMOVE??フォルダはMOVE01、MOVE02、MOVE03と順番に並んでいること
- 録画ファイル(MP4 ビデオ)は、更新日時順かつ昇順であること
※このプログラムでは、タスクバー上のアプリケーションや、画面内の座標を利用しているため、それぞれの環境に合わせてプログラムを書き換えてみてください。
プログラム実行前の準備
- デスクトップにフォルダを作成し、その中に、このプログラム(Python File)、マウスで選択したファイル群とプログラムで選択したファイル群を比較するために用いるメモ帳(テキスト ドキュメント)、次回のプログラム利用時に使用するためにSDカード内で最も新しいファイルの絶対パスとエポック秒を記述しておくメモ帳(テキスト ドキュメント)の3つを用意しておく。
※僕の場合は、以下のような感じです。
┗━マイ・コード
┣逆算用テキスト.txt
┣最終アップロード済みファイル情報.txt
┗自動選択プログラム.py
- Python37\Lib\site-packages\pyautogui\_pyautogui_win.py のPython File(真ん中あたり)にコードを追記する
def _keyDown(key):
"""Performs a keyboard key press without the release. This will put that
key in a held down state.
NOTE: For some reason, this does not seem to cause key repeats like would
happen if a keyboard key was held down on a text field.
Args:
key (str): The key to be pressed down. The valid names are listed in
pyautogui.KEY_NAMES.
Returns:
None
"""
if key not in keyboardMapping or keyboardMapping[key] is None:
return
needsShift = pyautogui.isShiftCharacter(key)
# 追加 ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ココ!
# 多分3番目のコロン(:)だけで大丈夫だと思う。
if key == '@':
needsShift = False
if key == '^':
needsShift = False
if key == ':':
needsShift = False
"""
# OLD CODE: The new code relies on having all keys be loaded in keyboardMapping from the start.
if key in keyboardMapping.keys():
vkCode = keyboardMapping[key]
・・・ 以下略 ・・・
参考元:Python 3.x - pyautoguiを用いて「:」の入力をしたいです。|teratail
- Pythonのパッケージ:「pyautogui」と「pyperclip」をインストールしておく
プログラムを作ろうと思った経緯
- ドライブレコーダーのデータの保存を自動化したかった
- 前回アップしたファイルよりも後に録画されたデータのみを判別してくれるプログラムを作りたかった
- Google フォトにアップロードしたいけれど、プログラム内のコードにメールアドレスやパスワードを記述しておきたくなかった
- 対象ファイル数のカウントを自動化したかった
- 選択ファイルに間違いがないか正誤判定したかった
プログラム作成前に考えた大まかな設計図
- 対象ディレクトリ(僕の場合は、SD Disk(G:)、つまりGドライブ)へアクセス
- 対象の拡張子(.MP4)のみを選別
- 過去最後にアップロードしたファイルから、現在の最新のファイルまでの総数の取得
- アップロードした過去の最後の録画ファイルの更新(作成)日時と比較し、それよりも
日時が新しい物を判別する - プログラムで、キーボード(ショートカット)操作を行い、対象のファイル群を選択
- ポップアップダイアログの表示(ファイル総数、正常完了通知など)
- エラー対処(録画データが存在しない、対象となる新規ファイルが存在しない)
ここからが本題
プログラム Part 1
まず、「G:\MOVE\」ディレクトリ下に存在する「G:\MOVE\MOVE01」、「G:\MOVE\MOVE02」、「G:\MOVE\MOVE03」といったMOVE??フォルダの個数を数えるプログラム。
次に、僕の場合はMOVE??フォルダの数が9個なので、MOVE??フォルダ数が9個ならプログラムを続行し、それ以外ならプログラムを中止するプログラム。
そして、「G:\MOVE\MOVE?????_?.MP4」ファイルの数を、MOVE??フォルダ毎、またMOVEディレクトリ内(MOVE??フォルダ全体)で計算するプログラム。
それと、後付けでプログラムの実行に掛かった時間を計測したかったから、開始時間を記録しておくための変数を用意。
'''
・Pythonでディレクトリとファイルの一覧を取得するにはlistdir関数を使います。
・listdir関数はosという名前のモジュールの関数なので、listdir関数を使う場合は
必ずインポート(import os)するようにしましょう。
・ディレクトリ内にあるディレクトリとファイルの一覧を、リストの形で、
取り出す事が出来ます。
・os.path.isdir('パス')
・isdirは引数で渡されたパスがディレクトリならTrueを返し、
そうでないならFalseを返します。これをlistdirと共に使うことでディレクトリだけ、
もしくはファイルだけの一覧を取得できます。
・組み込み関数len()の引数にリストを渡すと、
そのサイズ(要素数)が「整数値」(int型)で返される。
・glob関数で、さらに細かく指定したファイルを取得する。
・グロブ(英: glob)
・"glob" という名前は "global command" の略語である。
・glob関数はglobモジュールの関数なので、必ずglobをインポートしましょう。
・globの引数には任意の文字列を意味するワイルドカード(*)や正規表現が使えるので、
特定のファイルだけを簡単に取得できます。
・例えば、現在のディレクトリに、t_1.log, t_2.log, abc.log, test101.lstのファイル
が存在したとすると、「>>> glob.glob('*.log')」の実行により、
['abc.log', 't_1.log', 't_2.log']が返却されます。
・glob で取得したファイル一覧の順番は保証されるのか。:Python:不明
・sys.exit()関数は、実行しているプログラムの中でメインプロセスを
終了させるための関数です。
・それ以降のプログラムの実行を中止。
・不要なら「#sys.exit("Error!")」でコメントアウトするか、「MOVE_directories_count == 9」の値を変更してね。
・現在主流のPython のバージョン3.xでは、標準の文字コードはUTF-8となったため、
文字コードを宣言することなく、日本語を扱えるようになっています。
・# coding: エンコーディング名
'''
# path = r"G:\MOVE\"はエラーらしい。
# coding: utf-8
import time
start = time.time()
import os
import sys
path = "G:\\MOVE\\"
MOVE_directories = list()
for directory_name in os.listdir(path):
if os.path.isdir(path + directory_name):
MOVE_directories.append(directory_name)
MOVE_directories_count = len(MOVE_directories)
print("ルートGディレクトリ【SD Disk(G:)】(Gドライブ)の中の、" + "\n" +
"MOVEディレクトリ内に存在する、" + "\n" +
'MOVE??フォルダの総数は、' + "\n" +
str(MOVE_directories_count) +
"個である。")
print("\n")
if MOVE_directories_count == 9:
print("MOVEフォルダ数は9つあり、正常")
else:
print("フォルダ数の不足もしくは超過")
print("MOVEフォルダの数が9つか確認してね")
sys.exit("Error!")
import glob
# 上の変数pathと同一の値
path = 'G:\\MOVE\\'
MP4_files = []
MP4_files_amount = 0
print('\n')
for i in MOVE_directories:
MP4files = glob.glob(path + i + '\\*.MP4')
count = len(MP4files)
print(i + "フォルダの中には、" + 'MP4ファイルが、' +
str(count) + '個ある。')
MP4_files_amount += count
print("\n")
print('MOVEディレクトリ内に存在する、' + "\n" +
'各MOVEフォルダの中の、' + "\n" +
'MP4ファイルの総数は、' + "\n" +
str(MP4_files_amount) + '個である。')
プログラム Part 2
'''
・念には念をで、正誤判定作業多め^^
・開く順番によって、メモ帳とPythonの順序が入れ替わってしまう。
→事前に起動せず、プログラムで自動起動する方法に変更。
・更新日時順(昇順、小→大、古→新)で場合分け。
・エクスプローラーでのファイルの並び順が更新日時の昇順であることを前提とする。
・取得したMP4ファイルのリストを更新日時の昇順で並び替える。
・取得したファイルを格納したリストの中身の順序と、
エクスプローラーで見ているファイルの順序が完全に同じであるように整える。
・IDLEファイル(.py)に、対象ファイル(.MP4)をドラッグ&ドロップすると、
ファイル数が単一の場合のみ、ドロップ(ペースト)した際に、フルの絶対パス
が表示される。
・しかし、2つ以上一気に移動させると、ドロップできない。
・複数ファイルは、一旦コピーして、貼り付ければ、複数のフルパスを一気に取得可能。
・MOVE01, MOVE02など、各フォルダ毎に、毎回上書き更新されるデータファイルを作成し、
ドラッグ&ドロップしたファイル群と、リスト選択したファイル群が、完全に一致する
かどうか確認作業を一度挟んでから、アップロードの流れに持って行く。
・ファイルの更新日時の判断だけで、実際に年月日時分の値を用いないのならば、
エポック秒のままでも全然良いと思う。
・対象ファイルの上からの数値(インデックス値)のみを記録し、後から、
PyAutoGUIで、下矢印やらクリックやらを操作して、Googleにアップロードする。
・プログラムの実行途中に0.何秒かの時間間隔を置いた方が良いかも知れない。
・CUI操作とGUI操作はラグも大きく違うだろうから。
・MOVE_directories変数には、Gドライブ/MOVE/MOVE01~/MOVE??までのMOVEフォルダ群が
格納されている。
・MP4_files変数は、上に書いたforループ内のローカル変数下では、その値が刻々と
変化しているが、グローバル変数として、その値は空のリストなので、そのforループ
の外で使うと、空っぽのままである。 → という訳ではなく、forループ終了時点での
最後の処理データが以降格納され続ける。(値を書き換えない限り)
・forループ内で変数を定義しても、それはローカル変数として扱われず、forループの最後の
作業が終了した時の格納値をforループの外に出ても保持する。
・appendメソッドは、値だけでなくリストの追加も可能。
・Pythonでファイルの更新日時を取得するには、os.path.getmtime関数を使う。
「os.path.getmtime(path)」 ※エポック秒での取得
・【エポック秒】
エポック (epoch) は時刻の起点のことで、これはプラットフォーム依存です。
Unix では、エポックは (UTC で) 1970 年 1 月 1 日 0 時 0 分 0 秒です。
※協定世界時: 英語: Coordinated Universal Time
与えられたプラットフォームでエポックが何なのかを知るには、
time.gmtime(0) の値を見てください。
・mtime = 「最終修正時間」 → 修正:modify (modification)と思う。
・[python] sorted のkeyってなんぞ
<https://qiita.com/inon3135/items/70b1ed6706579bd48edf>
・sorted関数の引数:lambda関数には、比較するべき要素を返す関数を指定するらしい。
・sorted()のkeyがlambda関数をとれるらしいので、os.path.getmtimeを渡して、
ファイルの更新日時の順序(指定しなければ昇順)で、ソートされる。
・引数を渡す際の注意点:「key = os.path.getmtime」のようにイコールの両隣に
スペースを入れるとエラーになる。
↑↑↑↑↑
MP4files_stored_in_update_time_orderリストは、要素としてリストを格納するリスト
だから、使えない。やり方はあるのかも知れないけど、探したけど分からなかった。
"ファイル名 エポック秒"のように要素が一つの文字列になっていれば問題なく使える
はずだけど、今回は、要素が[ファイル名, エポック秒]だから、どこがキー
(エポック秒)なのかコンピューターが理解できない模様。
・『pythonのsorted関数で使われるlambdaとは何なのか』
<https://qiita.com/n10432/items/e0315979286ea9121d57>
・lambdaは、無名関数と呼ばれており、
その名のとおり、名前の無い関数を作成する際に使います。
・a = lambda x : x*x
→lambda式を使って「引数を2乗して返す無名の関数」を変数aに代入
・ラムダ計算(ラムダけいさん、英語: lambda calculus)は、計算模型のひとつで、
計算の実行を関数への引数の評価(英語: evaluation)と適用(英語: application)
としてモデル化・抽象化した計算体系である。ラムダ算法とも言う。
関数を表現する式に文字ラムダ (λ) を使うという慣習からその名がある。
・「key=lambda x: x[1]」=「要素xを受け取り、x[1]を返す」
リスト内の要素(リスト)のインデックス1番目(つまり左から2番目)に着目。
・sorted()関数は、デフォルトで昇順ソート
・【for文】
2つ以上のイテラブルオブジェクトを引数に指定することも可能。
・取得したエポック秒は浮動小数点型みたいだから、そのまま算術計算できるね。
・録画ファイルを一つ一つ選択して行くのは繰り返し操作が多くなり過ぎてしまうため、
ファイルが更新日時の昇順に並んでいることを前提として、最初の対象ファイルの下は
全て対象になると考えられるので、その対象ファイルから最後のファイルまでを範囲
選択することにする。念のため、ファイルが一続きか確認する。(同一要素かつ
同一順序の場合のみTrue)
・PyAutoGUIのマウス操作にて選択したファイル群と比較するため、別途、プログラムで
作成した逆算用のファイル群を格納したリストを作成する。
・最初のファイルが100ファイルある中の何処にあるか分からないので、最初の
ファイルのインデックスを探し出し、スクロール操作が必要か検討する。
・time.sleepはPythonでスリープ処理を行うメソッドです。
sleepはtimeモジュールのメソッドなので、
timeをインポートして利用します。
例:time.sleep(5) ←intでもfloatでも良い
・ホットキー (hot key) = 「ショートカットキー」
・>>> pyautogui.mouseDown(button='right')
>>> pyautogui.mouseUp(button='right')
このようにマウスを押し下げる、押し上げるを分けることもできます。
・ドラッグ
>>> pyautogui.dragTo(100, 200, 3, button='left')
現在のマウスカーソル位置からx座標=100、y座標=200の位置まで
3秒かけてドラッグさせます。
この時押されるのは左クリックです。
・マウスカーソルを移動させる
>>> import pyautogui
>>> pyautogui.moveTo(100, 200)
x座標=100、y座標=200の位置まで移動させます。
・サラリーマンがハッカーを真剣に目指す
<http://bttb.s1.valueserver.jp/wordpress/blog/2017/08/24/pyautogui-%e4%bd%bf%e3%81%84%e6%96%b9-%e3%83%9e%e3%82%a6%e3%82%b9%e6%93%8d%e4%bd%9c%e7%b7%a8/>
<http://bttb.s1.valueserver.jp/wordpress/blog/2017/08/25/pyautogui%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9-%e3%82%ad%e3%83%bc%e3%83%9c%e3%83%bc%e3%83%89%e6%93%8d%e4%bd%9c%e7%b7%a8/>
・Cheat Sheet
<https://pyautogui.readthedocs.io/en/latest/cheatsheet.html>
・readlines() – ファイルを全て読み込み、1行毎に処理を行う。リスト格納。
・read() – ファイルを全て読み込み、その文字列データに対して処理を行う
・対象ファイルが少なくとも1つはある前提でプログラム組んでたけど、0個の場合を
想定してなかったから、考える。
・スクロール
>>> pyautogui.scroll(10)
>>> pyautogui.vscroll(-10)
>>> pyautogui.hscroll(20)
画面をスクロールします。
scroll、vscrollは垂直方向にスクロールでき、
引数に与えた数分クリックした量をスクロールします。
hscrollは水平方向へのスクロールです。
↓ ↓ ↓
スクロールが何故かエクスプローラー上で正常に作動してくれなかったので別の手段を取る
・ファイルの絶対パス取得のために空のIDLEファイルが必要。
・forループは入れ子で、並列に書くと、順番に完了してから処理される。
①for~
②for~
③for~
だと、①の最初の一つ、②の処理全て、③の処理全て、
①の2番目の要素、②の処理全て、③の処理全て、
といった順番。
・多重ループはややこしいから、3重にならないようにしないと、訳が分からなくなる
→3重になった場合も期待通りに動いてくれる時もあったけど、大体変な事になるから、
3重目のループは使わないように頑張った。
・https://techacademy.jp/magazine/18811
・https://qiita.com/motoki1990/items/8275dbe02d5fd5fa6d2d
・エクスプローラーの左側の窓のSD Disk(G:)の位置とその下層のMOVE等のフォルダ位置が時折
入れ替わる可能性あり。(Gドライブが展開状態になったり折り畳み状態になったり)
・「WindowsKey + R」で、MOVEフォルダを探して実行し、開く方法を取る。
・ネット検索のエポック秒は正確でない可能性が高い。
→最初ネット上の誰かが作ったエポック秒と年月日時分秒の相互変換サイトを使ってエポック秒
を算出してプログラムの動作確認をしてたけど、全然違うファイルが選択されて、座標が悪い
のかラグなのか原因が分からず困ってたんだけど、Pythonのモジュールを使ってエポック秒を
算出したら、ネット上のサイトで出した結果と違ってて、サイトの間違いだった件。
・pyautoguiでコロン:が入力できない問題 ← 大事
https://teratail.com/questions/79973
Lib > site-packages > pyautogui
・やはり三重ループになるとおかしくなる。使用厳禁。挙動が読めない。
・pyautoguiで日本語を入力するには
http://code.hounen-mansaku.com/archives/136
・Pythonでメッセージボックスを表示する(tkinter.messagebox)
https://pg-chain.com/python-messagebox
・# 指定したキーを押す
pa.press(keys="enter",presses=2,interval=0.0)
・https://pyautogui.readthedocs.io/en/latest/keyboard.html
・max()の構文、min()でも同じです。
max(iterable, *iterables[,key, default])
max(arg1, arg2, *args[, key])
・【Python】int() 関数の注意点
https://qiita.com/ringCurrent/items/1df058bb203374a4b294
・四捨五入
https://note.nkmk.me/python-round-decimal-quantize/
・②の年月日・時分秒は、int('06')で、数字の前の0が消去されて、数字の6になるから、
数字の前に0を入れても問題ない。
・ファイルのサイズ取得: os.path.getsize('パス')
単位はバイト(B)
・ファイルへの書き込み
https://note.nkmk.me/python-file-io-open-with/
・絶対パスに関して、バックスラッシュ(\)による改行接続だと空白まで含まれてしまう。
クォーテーションで繋いでも、変数扱いみたいになって、with open() as f:とかで使うとエラー。
・①~④の選択肢の④について、もしファイルが存在しなかったり、答えがノーの時に
選択肢の所に戻れるように、whileとか使ってinputに戻してあげないといけない。
・多分ループ文の途中で改行は出来ない。
・PythonではNoneの比較は==ではなくisを使う
http://monmon.hateblo.jp/entry/20110214/1297710749
https://www.python-izm.com/tips/difference_eq_is/#is
・Pythonでメッセージボックスを表示する(tkinter.messagebox)
https://pg-chain.com/python-messagebox
・Tkinter
Tcl/Tk の Tk 部分を Python で利用できるようにしたもの。
Tcl/Tk(ティクル・ティーケー)は、スクリプト言語 Tcl と、その GUIツールキット Tk を指す。
("Tk interface")
「tkinter」は「Tool Kit Interface」のことで、Python標準のGUIアプリケーションを作成するモジュールです。
↑↑↑tkというウィンドウとお知らせウィンドウの2つが出現してしまう。
・messageboxとsimpledialogのまとめ
https://qiita.com/takanorimutoh/items/bd8c2cf27a2c5bb14bc0
・withdraw:(…を)引っこめる、引く、(…を)引っ込める、引き出す、取り出す、(…を)取り上げる
・ポップアップウィンドウのOKを押さないと次のプログラムには進まない。
(time.time()のカウントも止まらない)
・forループでtime変数を使って、そのループの最後の値が入ったままなので、
一旦import timeでリセットして、goalに代入しないと、エラー。
・4択の所、無入力とか空入力だとエラーになる。
・python -v でびっくりした話
http://p15.jp/2014/04/17/000137
・エラー動作がある場合は、time.sleep()の数値を増やしてみると良いかも
'''
# pyautoguiは物理マウスの操作影響を受ける。
# path = 'ほにゃらら'と書いた後に「井桁(#)」を使うとエラーになる。
# 括弧重要!!!ちゃんと全体として閉じられていないミスが多い。
# pyautogui.click(x, y, clicks, interval, button) 全て順番に書く。でないとエラー
# pyautogui.mouseDown(button="left") button=を書かないとエラーになる
# エクスプローラーを閉じると多分エラー(処理中断)になるから、アウト。
# スクロールのプログラム、要修正、個数がバラバラだとエラー
# 変数に対してバックスラッシュでの改行接続は不可能!!!
################################################################################
#
#スクロールが正常に作動しない
#ifの条件分岐で、剰余演算による余り算出が使えるかも
# ファイル総数が26の倍数でない場合
#
################################################################################
print('\n')
print("最終アップロード録画ファイルの指定方法を次の4つから選んでね。")
print('(半角の数字・英語・記号で回答してね。)')
Epoch_time_subjected_file = None
while Epoch_time_subjected_file is None:
option = input("①エポック秒、②年月日時分秒、③ファイルパス、" + "\n" +
"④:前回最後にアップロードしたファイル情報:")
if option == "1":
Epoch_time_subjected_file = float(input("最後にアップロードした" +
"録画ファイル(mp4ファイル)の" +
"エポック秒を入力してね:"))
elif option == "2":
print('年月日・時分秒を入力してね')
year = int(input("何年?:"))
month = int(input("何月?:"))
day = int(input("何日?:"))
hour = int(input("何時?:"))
minute = int(input("何分?:"))
second = int(input("何秒?:"))
import datetime
date = datetime.datetime(year, month, day, hour, minute, second)
Epoch_time_subjected_file = date.timestamp()
elif option == "3":
print("(存在する)ファイルパスを入力してね ※スラッシュ区切り")
choice = input("①絶対パス、②相対パス、どっち?:")
if choice == "1":
absolute_pathname = input("絶対パスを入力してね:")
Epoch_time_subjected_file = os.path.getmtime(absolute_pathname)
if choice == "2":
relative_pathname = input("(MOVE??フォルダからの)" +
"相対パスを入力してね:")
Epoch_time_subjected_file = os.path.getmtime("G:/MOVE/" +
relative_pathname)
else:
if os.path.getsize('C:\\Users\\User\\Desktop\\マイ・コード\\' +
'最終アップロード済みファイル情報.txt') > 0:
print('前回のデータが見つかりました。')
with open("C:\\Users\\User\\Desktop\\マイ・コード\\最終アップロード済みファイル情報.txt",
'r') as f:
previous_data = f.read()
name_time = previous_data.split('\n')
print('ファイル名:' + name_time[0])
print('エポック秒:' + name_time[1])
response = input('上記のデータでよろしいですか?(y/n):')
if response == 'y':
Epoch_time_subjected_file = float(name_time[1])
if response == 'n':
print('選択肢に戻ります。')
else:
print('前回のデータが見つかりません。')
print('他の選択肢を選んでみてね。')
import pyautogui
import time
folder_coordinates = {"MOVE01": [431, 137],
"MOVE02": [431, 158],
"MOVE03": [431, 179],
"MOVE04": [431, 201],
"MOVE05": [431, 222],
"MOVE06": [431, 243],
"MOVE07": [431, 265],
"MOVE08": [431, 284],
"MOVE09": [431, 305],
'MOVE10': [431, 326],
'MOVE11': [431, 347],
'MOVE12': [431, 368],
'MOVE13': [431, 389],
'MOVE14': [431, 410],
'MOVE15': [431, 431],
'MOVE16': [431, 452],
'MOVE17': [431, 473]}
file_coordinates = {"0": [539, 137],
"1": [539, 157],
"2": [538, 179],
"3": [538, 199],
"4": [538, 220],
"5": [538, 241],
"6": [537, 263],
"7": [540, 284],
"8": [540, 306],
"9": [539, 326],
"10": [539, 348],
"11": [541, 369],
"12": [540, 390],
"13": [539, 409],
"14": [540, 430],
"15": [540, 452],
"16": [540, 472],
"17": [540, 493],
"18": [540, 514],
"19": [541, 535],
"20": [541, 556],
"21": [542, 577],
"22": [542, 598],
"23": [546, 621],
"24": [544, 640],
"25": [544, 662]}
import pyperclip
pyautogui.hotkey('win', 'r')
time.sleep(0.5)
pyautogui.typewrite('G:\\MOVE\\')
time.sleep(0.5)
pyautogui.press('enter')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
time.sleep(1)
targeted_files_total = 0
the_latest_file_name_and_epoch_time = []
time.sleep(1)
for folder in MOVE_directories:
MP4files_stored_in_update_time_order = []
# 変数pathの更新(グローバル・スコープ)
path = "G:\\MOVE\\" + folder + '\\*.MP4'
for file in glob.glob(path):
MP4files_stored_in_update_time_order.append([file,
os.path.getmtime(file)])
untargeted_files_amount = 0
targeted_files_amount = 0
targeted_files_indexes = list()
targeted_files_selected_by_program = []
targeted_files_selected_by_mouse = []
files_amount_in_folder = len(MP4files_stored_in_update_time_order)
the_latest_file_name_and_epoch_time.append(sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1])[-1])
time.sleep(3)
for path, mtime in sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1]):
if mtime > Epoch_time_subjected_file:
targeted_files_amount += 1
targeted_files_indexes.append(sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1]).index(list((path, mtime))))
targeted_files_selected_by_program.append(path.replace('\\', '/'))
else:
untargeted_files_amount += 1
if targeted_files_amount == 0:
print("このMOVEフォルダ内には、対象の録画ファイルが1つも存在しない。")
print('次のフォルダの処理作業に入るね')
continue
if untargeted_files_amount + targeted_files_amount \
== files_amount_in_folder:
print("第一関門突破!")
print("対象ファイル数 + 対象外ファイル数 = ファイル総数")
serial_number_list = list(range(targeted_files_indexes[0],
targeted_files_indexes[-1] + 1))
if serial_number_list == targeted_files_indexes:
print("第二関門突破!!")
print('対象のファイル群は連なっている')
time.sleep(1)
pyperclip.copy("C:\\Users\\User\\Desktop\\マイ・コード\\"
"逆算用テキスト.txt")
pyautogui.hotkey('win', 'r')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
time.sleep(0.5)
pyautogui.press('enter')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(1.5)
pyautogui.doubleClick(folder_coordinates[folder][0],
folder_coordinates[folder][1])
time.sleep(1.5)
if 1 <= targeted_files_indexes[0] + 1 <= 26:
pyautogui.moveTo(347,
file_coordinates\
[str(targeted_files_indexes[0])][1])
# 対象ファイル群の範囲選択
time.sleep(1)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(939, 702)
time.sleep(4)
pyautogui.mouseUp(button='left')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'c')
# Python IDLEの新規ファイルの起動
time.sleep(1.5)
pyautogui.click(459, 747)
time.sleep(0.5)
pyautogui.click(350, 639)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'n')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
# 対象ファイル群の絶対パスを取得
time.sleep(1)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
pyautogui.click(1339, 6)
time.sleep(1.5)
pyautogui.click(762, 449)
# メモ帳の起動、全消去(ファイルを空に)、貼り付け、保存、閉じる
time.sleep(1)
pyautogui.click(521, 747)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'a')
pyautogui.press('backspace')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 's')
pyautogui.click(1339, 6)
# メモ帳のデータを読み込み、リストに格納し、正しいか比較
time.sleep(3)
m = "C:\\Users\\User\\Desktop\\マイ・コード\\逆算用テキスト.txt"
f = open(m, "r")
memo = f.read()
f.close()
targeted_files_selected_by_mouse = memo.split("\n")
if targeted_files_amount == len(\
targeted_files_selected_by_mouse):
print("第三関門突破!!!")
print("プログラム選択ファイル数とマウス選択ファイル数が同一")
if targeted_files_selected_by_mouse == \
targeted_files_selected_by_program:
print("第四(最終)関門突破!!!!")
print("アップロード作業に移行します")
# エクスプローラーに戻り、ドラッグ&ドロップ
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(0.5)
pyautogui.moveTo(619, 662)
time.sleep(0.5)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(683, 384, 1)
time.sleep(0.5)
pyautogui.hotkey('win', '6')
time.sleep(1.5)
pyautogui.mouseUp(button='left')
print("成功!")
print("アップロード完了")
print("対象ファイル総数:" + str(targeted_files_amount))
targeted_files_total += targeted_files_amount
# エクスプローラーを一つ前に戻す
time.sleep(1.5)
pyautogui.click(336, 749)
time.sleep(1)
pyautogui.hotkey('alt', 'left')
else:
print("プログラム選択ファイル群リストと" +
"マウス選択ファイル群リストが不一致")
sys.exit("Error!")
else:
print("プログラム選択ファイル数とマウス選択ファイル数が" +
"不一致")
sys.exit("Error!")
elif 27 <= targeted_files_indexes[0] + 1 <= 100:
time.sleep(1)
pyautogui.click(560, 137)
time.sleep(1)
press_count = targeted_files_indexes[0]
pyautogui.press("down", press_count, 0.03)
pyautogui.moveTo(347, 662)
time.sleep(0.5)
# 対象ファイル群の範囲選択
time.sleep(0.5)
pyautogui.mouseDown(button='left')
pyautogui.moveTo(939, 702)
time.sleep(4)
pyautogui.mouseUp(button='left')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'c')
# Python IDLEの新規ファイルの起動
time.sleep(0.5)
time.sleep(1)
pyautogui.click(459, 747)
time.sleep(0.5)
pyautogui.click(350, 639)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'n')
time.sleep(0.5)
pyautogui.hotkey('win', 'up')
# 対象ファイル群の絶対パスを取得
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
pyautogui.click(1339, 6)
time.sleep(1)
pyautogui.click(762, 449)
time.sleep(1)
# メモ帳の起動、全消去(ファイルを空に)、貼り付け、保存、閉じる
pyautogui.click(521, 747)
time.sleep(1)
pyautogui.hotkey('ctrl', 'a')
pyautogui.press('backspace')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 's')
time.sleep(0.3)
pyautogui.click(1339, 6)
time.sleep(1.5)
# メモ帳のデータを読み込み、リストに格納し、正しいか比較
m = "C:\\Users\\User\\Desktop\\マイ・コード\\逆算用テキスト.txt"
f = open(m, "r")
memo = f.readlines()
f.close()
for absolute_path in memo:
targeted_files_selected_by_mouse.append(absolute_path.\
strip())
if targeted_files_amount == len(\
targeted_files_selected_by_mouse):
print("第三関門突破!!!")
print("プログラム選択ファイル数とマウス選択ファイル数が同一")
if targeted_files_selected_by_mouse == \
targeted_files_selected_by_program:
print("第四(最終)関門突破!!!!")
print("アップロード作業に移行します")
# エクスプローラーに戻り、ドラッグ&ドロップ
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(0.5)
pyautogui.moveTo(619, 662)
time.sleep(0.5)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(683, 384, 1)
time.sleep(0.5)
pyautogui.hotkey('win', '6')
time.sleep(1.5)
pyautogui.mouseUp(button='left')
print("成功!")
print("アップロード完了")
print("対象ファイル総数:" + str(targeted_files_amount))
targeted_files_total += targeted_files_amount
# エクスプローラーを一つ前に戻す
time.sleep(1.5)
pyautogui.click(336, 749)
time.sleep(1)
pyautogui.hotkey('alt', 'left')
else:
print("プログラム選択ファイル群リストと" +
"マウス選択ファイル群リストが不一致")
sys.exit("Error!")
else:
print("プログラム選択ファイル数とマウス選択ファイル数が" +
"不一致")
sys.exit("Error!")
else:
print("エラー!")
print("フォルダ内のMP4ファイル総数が100を越えています。")
sys.exit("Error!")
else:
print("失敗!!" + "\n" +
"対象ファイル達が連続していない。")
else:
print("失敗!" + "\n" +
"ファイル総数と、対象ファイルおよび対象外ファイルの総和が不一致!"
+ "\n" + "有り得ない。" + "\n" +
"インデックスのリストからやり直し。")
sys.exit()
time.sleep(1)
# break
print('\n')
print("ヤッター!")
print("大成功!")
print('対象ファイル総計は、' + str(targeted_files_total) + '個だよ。')
print('\n')
the_newest_epoch_time = []
for time in the_latest_file_name_and_epoch_time:
the_newest_epoch_time.append(time[1])
print('最新の録画ファイル名:' +
the_latest_file_name_and_epoch_time[the_newest_epoch_time.\
index(max(the_newest_epoch_time))][0])
print('最新の録画ファイルのエポック秒:' +
str(max(the_newest_epoch_time)))
import datetime
date = datetime.datetime.fromtimestamp(max(the_newest_epoch_time))
print('最新の録画ファイルの更新日時:' +
str(date.year) + '年' +
str(date.month) + '月' +
str(date.day) + '日' +
str(date.hour) + '時' +
str(date.minute) + '分' +
str(date.second) + '秒' + 'だよ。')
last_file_name = the_latest_file_name_and_epoch_time[the_newest_epoch_time.\
index(max(the_newest_epoch_time))][0]
last_epoch_time = str(max(the_newest_epoch_time))
character_string = last_file_name + '\n' + last_epoch_time
with open('C:\\Users\\User\\Desktop\\マイ・コード\\最終アップロード済みファイル情報.txt',
"w") as f:
f.write(character_string)
print('\n')
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.withdraw()
messagebox.showinfo('お知らせ', 'アップロードは正常に完了しました。')
import time
goal = time.time()
print('プログラム所要時間:' + str(goal - start) + '秒')
まとめ(コード全文)
### microSDカード 自動選択プログラム ###
# Google Chromeを開始前に立ち上げておくこと。
# Google Chromeブラウザ1つのみ(全画面)
# Pythonは、
# Python IDLEプログラムファイル(プログラム文書)と起動するShellの2つのみにしておく。
# クローム、パイソンだけにしておく
# エクスプローラーとメモ帳は閉じておく。
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
"""
・PyAutoGUIを使用
・マウス・カーソルの自動操作で作業を進めるため、事前の座標準備等が必要。
⇒指定されたウィンドウ上の位置にマウスが合うため、感覚(座標)次第。
⇒また、立ち上がりの時間も考慮しないと、正常に動作が進まない恐れがある。
・Google Chromeのフォトで、事前にログインしておく。(リスク・ヘッジ)
・録画ファイルが存在するフォルダ群が何個あるか確認する
・オート操作を始める前に、対象のファイル数を算出しておく。
・後にフォトで総数が合致しているか確かめる。
"""
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ハッシュ記号(#)は適当に入力して、上の様に遊んで良いけど、
# 3重クォーテーション(""" ~ """)は、3つ以上入力して遊ぶとエラーになる。
# path = r"G:\MOVE\"はエラーらしい。
# coding: utf-8
import time
start = time.time()
import os
import sys
path = "G:\\MOVE\\"
MOVE_directories = list()
for directory_name in os.listdir(path):
if os.path.isdir(path + directory_name):
MOVE_directories.append(directory_name)
MOVE_directories_count = len(MOVE_directories)
print("ルートGディレクトリ【SD Disk(G:)】(Gドライブ)の中の、" + "\n" +
"MOVEディレクトリ内に存在する、" + "\n" +
'MOVE??フォルダの総数は、' + "\n" +
str(MOVE_directories_count) +
"個である。")
print("\n")
if MOVE_directories_count == 9:
print("MOVEフォルダ数は9つあり、正常")
else:
print("フォルダ数の不足もしくは超過")
print("MOVEフォルダの数が9つか確認してね")
#sys.exit("Error!")
import glob
# 上の変数pathと同一の値
path = 'G:\\MOVE\\'
MP4_files = []
MP4_files_amount = 0
print('\n')
for i in MOVE_directories:
MP4files = glob.glob(path + i + '\\*.MP4')
count = len(MP4files)
print(i + "フォルダの中には、" + 'MP4ファイルが、' +
str(count) + '個ある。')
MP4_files_amount += count
print("\n")
print('MOVEディレクトリ内に存在する、' + "\n" +
'各MOVEフォルダの中の、' + "\n" +
'MP4ファイルの総数は、' + "\n" +
str(MP4_files_amount) + '個である。')
'''
・エクスプローラーでのファイルの並び順が更新日時の昇順であることを前提とする。
・プログラムの実行途中に0.何秒かの時間間隔を置いた方が良いかも知れない。
・pyautoguiでコロン:が入力できない問題
https://teratail.com/questions/79973
Lib > site-packages > pyautogui
・②の年月日・時分秒は、int('06')で、数字の前の0が消去されて、数字の6になるから、
数字の前に0を入れても問題ない。
・ポップアップウィンドウのOKを押さないと次のプログラムには進まない。
(time.time()のカウントも止まらない)
→処理が終了しないのも問題かもだから、時限ポップに出来れば、そうした方が良いかも
・直近のforループでtime変数を使っちゃって、そのループの最後の値が入ったままなので、
一旦import timeでリセットして、goalに代入しないと、エラー。
・①~④の4択の選択肢の所、無入力とか空入力だとエラーになる。
→入力終了後に合ってるか聞き返すか、if文で入力値が存在するか条件分岐するか、
try-except文を付けるか
・エラー動作がある場合は、time.sleep()の数値を増やしてみると良いかも
・MOVE??フォルダ数が多い時は、
import pyautogui
pyautogui.position()
でマウスカーソル位置の座標を取得して、リストに追加してみてね
・それと、エクスプローラーを全画面表示させた時の1ページに表示されるファイル数が26
ではない時は、リスト書き換えて。
'''
################################################################################
#
'''
・pyautoguiは物理マウスの操作影響を受ける。
・エクスプローラーを閉じると多分エラーになるから、アウト。
(Google フォトへのアップロード作業実行中に、
対象ファイルの選択に利用したエクスプローラーを閉じると、
アップロード処理が意図せず中断される可能性があるから注意)
'''
#
################################################################################
print('\n')
print("最終アップロード録画ファイルの指定方法を次の4つから選んでね。")
print('(半角の数字・英語・記号で回答してね。)')
Epoch_time_subjected_file = None
while Epoch_time_subjected_file is None:
option = input("①エポック秒、②年月日時分秒、③ファイルパス、" + "\n" +
"④:前回最後にアップロードしたファイル情報:")
if option == "1":
Epoch_time_subjected_file = float(input("最後にアップロードした" +
"録画ファイル(mp4ファイル)の" +
"エポック秒を入力してね:"))
elif option == "2":
print('年月日・時分秒を入力してね')
year = int(input("何年?:"))
month = int(input("何月?:"))
day = int(input("何日?:"))
hour = int(input("何時?:"))
minute = int(input("何分?:"))
second = int(input("何秒?:"))
import datetime
date = datetime.datetime(year, month, day, hour, minute, second)
Epoch_time_subjected_file = date.timestamp()
elif option == "3":
print("(存在する)ファイルパスを入力してね ※スラッシュ区切り")
choice = input("①絶対パス、②相対パス、どっち?:")
if choice == "1":
absolute_pathname = input("絶対パスを入力してね:")
Epoch_time_subjected_file = os.path.getmtime(absolute_pathname)
if choice == "2":
relative_pathname = input("(MOVE??フォルダからの)" +
"相対パスを入力してね:")
Epoch_time_subjected_file = os.path.getmtime("G:/MOVE/" +
relative_pathname)
else:
if os.path.getsize('C:\\Users\\User\\Desktop\\マイ・コード\\' +
'最終アップロード済みファイル情報.txt') > 0:
print('前回のデータが見つかりました。')
with open("C:\\Users\\User\\Desktop\\マイ・コード\\最終アップロード済みファイル情報.txt",
'r') as f:
previous_data = f.read()
name_time = previous_data.split('\n')
print('ファイル名:' + name_time[0])
print('エポック秒:' + name_time[1])
response = input('上記のデータでよろしいですか?(y/n):')
if response == 'y':
Epoch_time_subjected_file = float(name_time[1])
if response == 'n':
print('選択肢に戻ります。')
else:
print('前回のデータが見つかりません。')
print('他の選択肢を選んでみてね。')
import pyautogui
import time
folder_coordinates = {"MOVE01": [431, 137],
"MOVE02": [431, 158],
"MOVE03": [431, 179],
"MOVE04": [431, 201],
"MOVE05": [431, 222],
"MOVE06": [431, 243],
"MOVE07": [431, 265],
"MOVE08": [431, 284],
"MOVE09": [431, 305],
'MOVE10': [431, 326],
'MOVE11': [431, 347],
'MOVE12': [431, 368],
'MOVE13': [431, 389],
'MOVE14': [431, 410],
'MOVE15': [431, 431],
'MOVE16': [431, 452],
'MOVE17': [431, 473]}
file_coordinates = {"0": [539, 137],
"1": [539, 157],
"2": [538, 179],
"3": [538, 199],
"4": [538, 220],
"5": [538, 241],
"6": [537, 263],
"7": [540, 284],
"8": [540, 306],
"9": [539, 326],
"10": [539, 348],
"11": [541, 369],
"12": [540, 390],
"13": [539, 409],
"14": [540, 430],
"15": [540, 452],
"16": [540, 472],
"17": [540, 493],
"18": [540, 514],
"19": [541, 535],
"20": [541, 556],
"21": [542, 577],
"22": [542, 598],
"23": [546, 621],
"24": [544, 640],
"25": [544, 662]}
import pyperclip
pyautogui.hotkey('win', 'r')
time.sleep(0.5)
pyautogui.typewrite('G:\\MOVE\\')
time.sleep(0.5)
pyautogui.press('enter')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
time.sleep(1)
targeted_files_total = 0
the_latest_file_name_and_epoch_time = []
time.sleep(1)
for folder in MOVE_directories:
MP4files_stored_in_update_time_order = []
# 変数pathの一時的な更新(ローカル・スコープ) → ではないよね
path = "G:\\MOVE\\" + folder + '\\*.MP4'
for file in glob.glob(path):
MP4files_stored_in_update_time_order.append([file,
os.path.getmtime(file)])
untargeted_files_amount = 0
targeted_files_amount = 0
targeted_files_indexes = list()
targeted_files_selected_by_program = []
targeted_files_selected_by_mouse = []
files_amount_in_folder = len(MP4files_stored_in_update_time_order)
the_latest_file_name_and_epoch_time.append(sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1])[-1])
time.sleep(3)
for path, mtime in sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1]):
if mtime > Epoch_time_subjected_file:
targeted_files_amount += 1
targeted_files_indexes.append(sorted(MP4files_stored_in_update_time_order,
key=lambda x: x[1]).index(list((path, mtime))))
targeted_files_selected_by_program.append(path.replace('\\', '/'))
else:
untargeted_files_amount += 1
if targeted_files_amount == 0:
print("このMOVEフォルダ内には、対象の録画ファイルが1つも存在しない。")
print('次のフォルダの処理作業に入るね')
continue
if untargeted_files_amount + targeted_files_amount \
== files_amount_in_folder:
print("第一関門突破!")
print("対象ファイル数 + 対象外ファイル数 = ファイル総数")
serial_number_list = list(range(targeted_files_indexes[0],
targeted_files_indexes[-1] + 1))
if serial_number_list == targeted_files_indexes:
print("第二関門突破!!")
print('対象のファイル群は連なっている')
time.sleep(1)
pyperclip.copy("C:\\Users\\User\\Desktop\\マイ・コード\\"
"逆算用テキスト.txt")
pyautogui.hotkey('win', 'r')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
time.sleep(0.5)
pyautogui.press('enter')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(1.5)
pyautogui.doubleClick(folder_coordinates[folder][0],
folder_coordinates[folder][1])
time.sleep(1.5)
if 1 <= targeted_files_indexes[0] + 1 <= 26:
pyautogui.moveTo(347,
file_coordinates\
[str(targeted_files_indexes[0])][1])
# 対象ファイル群の範囲選択
time.sleep(1)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(939, 702)
time.sleep(4)
pyautogui.mouseUp(button='left')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'c')
# Python IDLEの新規ファイルの起動
time.sleep(1.5)
pyautogui.click(459, 747)
time.sleep(0.5)
pyautogui.click(350, 639)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'n')
time.sleep(1.5)
pyautogui.hotkey('win', 'up')
# 対象ファイル群の絶対パスを取得
time.sleep(1)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
pyautogui.click(1339, 6)
time.sleep(1.5)
pyautogui.click(762, 449)
# メモ帳の起動、全消去(ファイルを空に)、貼り付け、保存、閉じる
time.sleep(1)
pyautogui.click(521, 747)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'a')
pyautogui.press('backspace')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 's')
pyautogui.click(1339, 6)
# メモ帳のデータを読み込み、リストに格納し、正しいか比較
time.sleep(3)
m = "C:\\Users\\User\\Desktop\\マイ・コード\\逆算用テキスト.txt"
f = open(m, "r")
memo = f.read()
f.close()
targeted_files_selected_by_mouse = memo.split("\n")
if targeted_files_amount == len(\
targeted_files_selected_by_mouse):
print("第三関門突破!!!")
print("プログラム選択ファイル数とマウス選択ファイル数が同一")
if targeted_files_selected_by_mouse == \
targeted_files_selected_by_program:
print("第四(最終)関門突破!!!!")
print("アップロード作業に移行します")
# エクスプローラーに戻り、ドラッグ&ドロップ
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(0.5)
pyautogui.moveTo(619, 662)
time.sleep(0.5)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(683, 384, 1)
time.sleep(0.5)
pyautogui.hotkey('win', '6')
time.sleep(1.5)
pyautogui.mouseUp(button='left')
print("成功!")
print("アップロード完了")
print("対象ファイル総数:" + str(targeted_files_amount))
targeted_files_total += targeted_files_amount
# エクスプローラーを一つ前に戻す
time.sleep(1.5)
pyautogui.click(336, 749)
time.sleep(1)
pyautogui.hotkey('alt', 'left')
else:
print("プログラム選択ファイル群リストと" +
"マウス選択ファイル群リストが不一致")
sys.exit("Error!")
else:
print("プログラム選択ファイル数とマウス選択ファイル数が" +
"不一致")
sys.exit("Error!")
elif 27 <= targeted_files_indexes[0] + 1 <= 100:
time.sleep(1)
pyautogui.click(560, 137)
time.sleep(1)
press_count = targeted_files_indexes[0]
pyautogui.press("down", press_count, 0.03)
pyautogui.moveTo(347, 662)
time.sleep(0.5)
# 対象ファイル群の範囲選択
time.sleep(0.5)
pyautogui.mouseDown(button='left')
pyautogui.moveTo(939, 702)
time.sleep(4)
pyautogui.mouseUp(button='left')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'c')
# Python IDLEの新規ファイルの起動
time.sleep(0.5)
time.sleep(1)
pyautogui.click(459, 747)
time.sleep(0.5)
pyautogui.click(350, 639)
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'n')
time.sleep(0.5)
pyautogui.hotkey('win', 'up')
# 対象ファイル群の絶対パスを取得
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 'a')
pyautogui.hotkey('ctrl', 'c')
pyautogui.click(1339, 6)
time.sleep(1)
pyautogui.click(762, 449)
time.sleep(1)
# メモ帳の起動、全消去(ファイルを空に)、貼り付け、保存、閉じる
pyautogui.click(521, 747)
time.sleep(1)
pyautogui.hotkey('ctrl', 'a')
pyautogui.press('backspace')
time.sleep(0.5)
pyautogui.hotkey('ctrl', 'v')
pyautogui.hotkey('ctrl', 's')
time.sleep(0.3)
pyautogui.click(1339, 6)
time.sleep(1.5)
# メモ帳のデータを読み込み、リストに格納し、正しいか比較
m = "C:\\Users\\User\\Desktop\\マイ・コード\\逆算用テキスト.txt"
f = open(m, "r")
memo = f.read()
f.close()
targeted_files_selected_by_mouse = memo.split('\n')
if targeted_files_amount == len(\
targeted_files_selected_by_mouse):
print("第三関門突破!!!")
print("プログラム選択ファイル数とマウス選択ファイル数が同一")
if targeted_files_selected_by_mouse == \
targeted_files_selected_by_program:
print("第四(最終)関門突破!!!!")
print("アップロード作業に移行します")
# エクスプローラーに戻り、ドラッグ&ドロップ
time.sleep(1)
pyautogui.click(336, 749)
time.sleep(0.5)
pyautogui.moveTo(619, 662)
time.sleep(0.5)
pyautogui.mouseDown(button='left')
time.sleep(0.5)
pyautogui.moveTo(683, 384, 1)
time.sleep(0.5)
pyautogui.hotkey('win', '6')
time.sleep(1.5)
pyautogui.mouseUp(button='left')
print("成功!")
print("アップロード完了")
print("対象ファイル総数:" + str(targeted_files_amount))
targeted_files_total += targeted_files_amount
# エクスプローラーを一つ前に戻す
time.sleep(1.5)
pyautogui.click(336, 749)
time.sleep(1)
pyautogui.hotkey('alt', 'left')
else:
print("プログラム選択ファイル群リストと" +
"マウス選択ファイル群リストが不一致")
sys.exit("Error!")
else:
print("プログラム選択ファイル数とマウス選択ファイル数が" +
"不一致")
sys.exit("Error!")
else:
print("エラー!")
print("フォルダ内のMP4ファイル総数が100を越えています。")
sys.exit("Error!")
else:
print("失敗!!" + "\n" +
"対象ファイル達が連続していない。")
else:
print("失敗!" + "\n" +
"ファイル総数と、対象ファイルおよび対象外ファイルの総和が不一致!"
+ "\n" + "有り得ない。" + "\n" +
"インデックスのリストからやり直し。")
sys.exit()
time.sleep(1)
# break
print('\n')
print("ヤッター!")
print("大成功!")
print('対象ファイル総計は、' + str(targeted_files_total) + '個だよ。')
print('\n')
the_newest_epoch_time = []
for time in the_latest_file_name_and_epoch_time:
the_newest_epoch_time.append(time[1])
print('最新の録画ファイル名:' +
the_latest_file_name_and_epoch_time[the_newest_epoch_time.\
index(max(the_newest_epoch_time))][0])
print('最新の録画ファイルのエポック秒:' +
str(max(the_newest_epoch_time)))
import datetime
date = datetime.datetime.fromtimestamp(max(the_newest_epoch_time))
print('最新の録画ファイルの更新日時:' +
str(date.year) + '年' +
str(date.month) + '月' +
str(date.day) + '日' +
str(date.hour) + '時' +
str(date.minute) + '分' +
str(date.second) + '秒' + 'だよ。')
last_file_name = the_latest_file_name_and_epoch_time[the_newest_epoch_time.\
index(max(the_newest_epoch_time))][0]
last_epoch_time = str(max(the_newest_epoch_time))
character_string = last_file_name + '\n' + last_epoch_time
with open('C:\\Users\\User\\Desktop\\マイ・コード\\最終アップロード済みファイル情報.txt',
"w") as f:
f.write(character_string)
print('\n')
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.withdraw()
messagebox.showinfo('お知らせ', 'アップロードは正常に完了しました。')
import time
goal = time.time()
print('プログラム所要時間:' + str(goal - start) + '秒')
"""
【位置メモ】
※画面のサイズ:Size(width=1366, height=768)
・エクスプローラー:Point(x=336, y=749)
※ウィンドウを事前に最大化し、ウィンドウのポップ位置のズレを無くす必要性あり。
以下、最大化した後のポジション
・G:\MOVE\MOVE01:Point(x=429, y=137)
・02:Point(x=431, y=158)
・03:Point(x=431, y=179)
・04:Point(x=431, y=201)
・05:Point(x=433, y=222)
・06:Point(x=433, y=243)
・07:Point(x=430, y=265)
・08:Point(x=430, y=284)
・09:Point(x=432, y=305)
※一画面26ファイル
・G:\MOVE\MOVE09\
ファイル1:Point(x=539, y=137)
Point(x=539, y=157)
Point(x=538, y=179)
Point(x=538, y=199)
Point(x=538, y=220)
Point(x=538, y=241)
Point(x=537, y=263)
Point(x=540, y=284)
Point(x=540, y=306)
Point(x=539, y=326)
Point(x=539, y=348)
Point(x=541, y=369)
Point(x=540, y=390)
Point(x=539, y=409)
Point(x=540, y=430)
Point(x=540, y=452)
Point(x=540, y=472)
Point(x=540, y=493)
Point(x=540, y=514)
Point(x=541, y=535)
Point(x=541, y=556)
Point(x=542, y=577)
Point(x=542, y=598)
Point(x=546, y=621)
Point(x=544, y=640)
Point(x=544, y=662) 26番目
※1から8まで、100ファイル
※9のみ43ファイル
※1番目のファイルの左側空白位置:Point(x=347, y=137)
右側空白位置:Point(x=935, y=137)
真ん中位置:Point(x=633, y=136)
※ファイル群エリア外:右下の空欄位置:Point(x=939, y=702)
※Chrome位置:Point(x=398, y=748)
フォト・アップロード位置:Point(x=642, y=466)
※コピー&ペーストは出来ない模様。ドラッグ&ドロップかアップロード・ボタンからか
※メモ帳:Point(x=521, y=747)
※Python位置(2つ時) Point(x=459, y=747)
右窓:Point(x=567, y=639)
左窓:Point(x=350, y=639)
全画面表示時の×印:Point(x=1339, y=6)
保存するか否かの「いいえ」ボタン:Point(x=762, y=449)
※一番下のファイル中央位置:Point(x=619, y=662)
※クロームのミニ・ウィンドウが出た場合の位置:Point(x=394, y=641)
※スクロール長:
1番目ファイル上端:Point(x=550, y=128)
27番目ファイル上端:Point(x=486, y=673)
差:673 - 128 = 545
→最初スクロールしようと思ってたけど、1ページのファイル数が26の倍数でない場合、
特に、一番下のページは意図するファイル位置の特定が難しくなるから、
下矢印ボタンで移動させる方法にした。
"""
'''
↓ 没案(スクロールじゃ難しい)
if 1 <= targeted_files_indexes[0] + 1 <= 26:
(略)
elif 27 <= targeted_files_indexes[0] + 1 <= 52:
(略)
elif 53 <= targeted_files_indexes[0] + 1 <= 78:
(略)
elif 79 <= targeted_files_indexes[0] + 1 <= 100:
else:
'''
おわりに
手続き型プログラミングで書いたため、かなりの長文になってしまいましたが、上手く動いてくれたので嬉しい限りです。
変数が被ると大変なことになりますが、上手く被らないような長ったらしい変数に出来たので、最後のtime変数の罠に気づくまで、意識せずに変数付け出来ました。
ちなみに、プログラムの所要時間について、僕の場合は、MOVE??フォルダ数17個(MOVE01~MOVE16: 各50ファイル、MOVE17: 23ファイル)、MP4ファイル総計823個で、対象ファイル数が0個になるように指定した場合、選択肢④とyの選択、最後のOKのクリックを含めて、約69.36秒かかりました。