DigitalSignage with Raspberry Pi

# DigitalSignage with Raspberry Pi
## はじめに
こちらは **みんなのラズパイコンテスト2019**でラズベリーパイ財団賞を頂いた，**デジタルサイネージ with Raspberry Pi**の記事となります。
紙の連絡掲示板をデジタル化して楽に置き換えられるものを目指して製作しました。

## 使用パーツ
- Raspberry Pi 3 model B
- HDMIケーブル
- 液晶ディスプレイ
- 電源

## 環境
- Raspbian
- Python3

```text
pydrive (Google Drive API)
pdf2image
PIL
tkinter
```
## 処理の流れ
### 概要
1.	連携しているアカウントのGoogle Driveに「ScanPDF」フォルダが存在するか確認(存在しない場合は「ScanPDF」フォルダを生成し，そのフォルダのidを記憶)
2.	記憶したidのフォルダ配下のPDFファイルをすべて取得してローカルの一時フォルダに格納
3.	一時フォルダ内のPDFをディスプレイに表示
4.	複数のPDFファイルが有る場合は一定時間ごとに表示するPDFファイルを変更
5.	以降2~5を繰り返す

### 認証
Google Oauthを使用してアカウントにGoogle Drive APIとプロジェクトのアクセスを許可

```python:Main.py
gauth = GoogleAuth()
drive = GoogleDrive(gauth)
files = os.listdir('./data/')
count = len(files)
dirtxt = 'dirdata.txt'
```
### 保存用フォルダ生成・検索
初回連携時には`ScanPDF`フォルダが生成されます。
それ以降は該当フォルダを取得します。

```python:Main.py
if not os.path.isfile(dirtxt):
    folder = drive.CreateFile({
        'title': 'ScanPDF',
        'mimeType': 'application/vnd.google-apps.folder'
    })
    folder.Upload()
    with open(dirtxt, mode='w') as f:
        f.write(folder['id'])
        dir_id = folder['id']
else:
    with open(dirtxt) as f:
        dir_id = f.read()
```

### PDFファイル取得
ユーザーは`ScanPDF`フォルダにサイネージに表示したいPDFファイルを追加します。
その後，フォルダ内がスキャンされると液晶に追加したPDFが表示されます。

```python:Main.py
  def scan(self):
    global count
    404img_path = "./data/404.png"
    tmp_dir = "./tmp/"
    shutil.rmtree(tmp_dir)
    os.mkdir(tmp_dir)
    i = 1
    query = f"'{dir_id}' in parents and trashed=false"
    try:
        for file_list in drive.ListFile({'q': query, 'maxResults': 100}):
            for file in file_list:
                if file['mimeType'] == 'application/vnd.google-apps.folder':
                    pass
                else:
                    file.GetContentFile(f'./tmp/{i+1}.pdf')
                    i += 1
    except Exception as e:
        print(e)
    files = os.listdir(tmp_dir)
    count = len(files)
    if os.path.isfile(404img_path):
        os.remove(404img_path)
    if count == 0:
        shutil.copy('404.png', 404img_path)
        shutil.rmtree(tmp_dir)
        os.mkdir(tmp_dir)
    else:
        for i in range(0, count):
            shutil.copy(f'./tmp/{i+1}.pdf',
                        f'./data/{i+1}.pdf')
        files = os.listdir('./data/')
```
### ファイル表示
```python:Main.py
image = convert_from_path(f'./data/{cnt % (count) + 1}.pdf')
tmp = image[0].rotate(90, expand=True).resize((sw, sh))
self.img = ImageTk.PhotoImage(tmp)
self.canvas.itemconfig(self.imgArea, image=self.img)
```
※ ファイルが複数枚ある場合は30秒ごとに表示されるファイルが変更されます
※ ファイルに複数ページが有る場合は1ページ目のみ表示されます
※ また，ファイルが存在しない場合はプリセットされた「404 NotFound」(右図)が表示されます。

![Digital Signage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311807/2b9cb2a1-5949-a590-abc2-0807c0b206ba.png)

## 動作画像
![Digital Signage1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311807/3130f5b2-28e5-dd49-b273-73520fec621a.png)![Digital Signage3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311807/fa4c72a4-54e5-8665-4cff-e2df0da90d33.png)


## 終わりに
ファイル保管場所にGoogle Driveのフォルダを使用しているので，外出中でも更新することができます。更に,フォルダへのアクセス権限を設定することで複数人で更新することもできます。
ラズパイ自体はほぼ場所を取らないので，コンパクトさに関しては液晶の薄さによります。
現在このシステムを大学の研究室の連絡掲示板として導入していますがうまく動作しています。
セキュリティ的な問題は考慮しておりません。

**プルリク・ツッコミ歓迎しております。是非よろしくお願いします**