Skip to content

Commit 8afbc81

Browse files
committed
new config file based version
1 parent fb11949 commit 8afbc81

4 files changed

Lines changed: 86 additions & 77 deletions

File tree

README.md

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,39 @@ As the plex server is not compatible with xmp metadata inside photos, this pytho
1313

1414
## what you need to change
1515

16-
### change values to fit your installation in plexUsers.py
16+
### change values to fit your installation in config.py
1717

1818
```python
19-
#if you do not have a token you have to supply your credentials
20-
PLEX_LOGIN = ''
21-
PLEX_PASS = ''
22-
# if you already have a token pass it here
23-
PLEX_TOKEN = ''
24-
# the plex server url
25-
PLEX_URL = 'http://192.168.0.200:32400' # including http(s) (local url is best)
26-
# provide the usernames for which the rating should be updated
27-
# when users have a pin we need this, otherwise set it to ''
28-
USERDATA = { 'user': '1234' }
29-
30-
# for the access tokens we need the exact server name
31-
SERVERNAME = 'plex'
32-
33-
# path of the photo library in plex
34-
PHOTOS_LIBRARY_PATH = '/share/Photos'
19+
####################### Change HERE #######################
20+
#if you do not have a token you have to supply your credentials
21+
PLEX_LOGIN = ''
22+
PLEX_PASS = ''
23+
24+
# if you already have a token pass it here
25+
PLEX_TOKEN = ''
26+
27+
# the plex server url
28+
PLEX_URL = 'http://192.168.0.200:32400' # including http(s) (local url is best)
29+
30+
# provide the usernames for which the rating should be updated
31+
# when users have a pin we need this, otherwise set it to ''
32+
USERDATA = { 'user': '1234' }
33+
34+
# for the access tokens we need the exact server name
35+
SERVERNAME = 'plexserver'
36+
37+
# path of the photo library in plex (absolute path)
38+
PHOTOS_LIBRARY_PATH_PLEX = '/<some path>/'
39+
40+
# for the correct path creation we need the path to the
41+
# photo library from the view of the script (absolute path)
42+
# Linux/Mac: "/<some path>/"
43+
# Windows: "C:\\some folder\\some folder\\" # (paths need escaping)
44+
PHOTOS_LIBRARY_PATH = "/<some path>/"
45+
46+
# start an update at the start of the script
47+
FORCE_RUN_AT_START = True
48+
###########################################################
3549
```
3650

3751
For getting a valid token you can enter you login credentials and run the script.
@@ -40,18 +54,7 @@ It will then output this:
4054
```
4155
use this token
4256
xxxxxxxxxxxxxxxxxxxxxxx
43-
and put it into plexUsers.py file after PLEX_TOKEN:
44-
```
45-
46-
### change values to fit your installation in ppTag.py
47-
48-
Adjust the paths for the photos (for ppTag)
49-
50-
```python
51-
if system == "Linux":
52-
photosPath = "/Photos/" # Running in Docker
53-
else:
54-
photosPath = "P:\\" # Windows
57+
and put it into the file config.py after PLEX_TOKEN:
5558
```
5659

5760
## how it works
@@ -67,5 +70,5 @@ Images are scanned for adobe lightroom tags and rating written to the XMP data i
6770
## Docker Container
6871

6972
You can use the provided docker file and docker-compose to run ppTag inside docker.
70-
The Container needs to Volumes. One for the photos and the second for the app.
73+
The Container needs two Volumes. One for the photos and the second for the app.
7174
This way it is easy to make changes to the files (config)

config.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
3+
class ppTagConfig():
4+
"""A simple class holding the config for ppTag"""
5+
####################### Change HERE #######################
6+
#if you do not have a token you have to supply your credentials
7+
PLEX_LOGIN = ''
8+
PLEX_PASS = ''
9+
10+
# if you already have a token pass it here
11+
PLEX_TOKEN = ''
12+
13+
# the plex server url
14+
PLEX_URL = 'http://192.168.0.200:32400' # including http(s) (local url is best)
15+
16+
# provide the usernames for which the rating should be updated
17+
# when users have a pin we need this, otherwise set it to ''
18+
USERDATA = { 'user': '1234' }
19+
20+
# for the access tokens we need the exact server name
21+
SERVERNAME = 'plexserver'
22+
23+
# path of the photo library in plex (absolute path)
24+
PHOTOS_LIBRARY_PATH_PLEX = '/<some path>/'
25+
26+
# for the correct path creation we need the path to the
27+
# photo library from the view of the script (absolute path)
28+
# Linux/Mac: "/<some path>/"
29+
# Windows: "C:\\some folder\\some folder" # (paths need escaping)
30+
PHOTOS_LIBRARY_PATH = "/<some path>/"
31+
32+
# start an update at the start of the script
33+
FORCE_RUN_AT_START = True
34+
###########################################################

plexUsers.py

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from plexapi.myplex import MyPlexAccount
1212
from plexapi.myplex import MyPlexDevice
1313
from uuid import uuid3, NAMESPACE_URL
14+
from config import ppTagConfig
1415

1516
class userData(object):
1617
"""a simple class that holds some user data"""
@@ -30,36 +31,17 @@ def setToken(self, token):
3031
self.token = token
3132

3233
class plexUsers():
34+
"""A class to get user data (token, library id) for plex"""
3335

34-
####################### Change HERE #######################
35-
#if you do not have a token you have to supply your credentials
36-
PLEX_LOGIN = ''
37-
PLEX_PASS = ''
38-
# if you already have a token pass it here
39-
PLEX_TOKEN = ''
40-
# the plex server url
41-
PLEX_URL = 'http://192.168.0.200:32400'
42-
# provide the usernames for which the rating should be updated
43-
# when users have a pin we need this, otherwise set it to ''
44-
USERDATA = { 'user': '1234' }
45-
46-
# for the access tokens we need the exact server name
47-
SERVERNAME = 'plexserver'
48-
49-
# path of the photo library in plex
50-
PHOTOS_LIBRARY_PATH = '/share/Photos/'
51-
52-
###########################################################
53-
54-
def fetchPlexApi(self, path='', method='GET', getFormPlextv=False, token=PLEX_TOKEN, params=None):
36+
def fetchPlexApi(self, path='', method='GET', getFormPlextv=False, token=ppTagConfig.PLEX_TOKEN, params=None):
5537
"""a helper function that fetches data from and put data to the plex server"""
5638
headers = {'X-Plex-Token': token,
5739
'Accept': 'application/json'}
5840
if getFormPlextv:
5941
url = 'plex.tv'
6042
connection = http.client.HTTPSConnection(url)
6143
else:
62-
url = self.PLEX_URL.rstrip('/').replace('http://','')
44+
url = ppTagConfig.PLEX_URL.rstrip('/').replace('http://','')
6345
connection = http.client.HTTPConnection(url)
6446

6547
try:
@@ -101,29 +83,29 @@ def fetchPlexApi(self, path='', method='GET', getFormPlextv=False, token=PLEX_TO
10183
def getAccessTokenForUser(self):
10284
for user in self.users:
10385
params = urllib.parse.urlencode({'pin': user.pin, 'X-Plex-Client-Identifier': self.clientId})
104-
data = self.fetchPlexApi('/api/v2/home/users/{uuid}/switch'.format(uuid=user.uuid), 'POST', True, self.PLEX_TOKEN, params)
86+
data = self.fetchPlexApi('/api/v2/home/users/{uuid}/switch'.format(uuid=user.uuid), 'POST', True, ppTagConfig.PLEX_TOKEN, params)
10587
if 'authToken' in data:
10688
authToken = data['authToken']
10789
data = self.fetchPlexApi('/api/resources?includeHttps=1&includeRelay=1&X-Plex-Client-Identifier={clientid}'.format(clientid=self.clientId), 'GET', True, authToken)
10890
for device in data['MediaContainer']['Device']:
10991
if isinstance(device, dict):
110-
if device.get('@provides') == 'server' and device.get('@name') == self.SERVERNAME:
92+
if device.get('@provides') == 'server' and device.get('@name') == ppTagConfig.SERVERNAME:
11193
self.serverId = device.get('@clientIdentifier')
11294
user.setToken(device.get('@accessToken'))
11395
break
11496

11597
def __init__(self):
11698
## some initial tests
117-
if len(self.PLEX_TOKEN) == 0:
99+
if len(ppTagConfig.PLEX_TOKEN) == 0:
118100
# get a token
119101
try:
120-
account = MyPlexAccount(self.PLEX_LOGIN, self.PLEX_PASS)
102+
account = MyPlexAccount(ppTagConfig.PLEX_LOGIN, ppTagConfig.PLEX_PASS)
121103
except Exception as e:
122104
raise("Error fetching from Plex API: {err}".format(err=e))
123105
# print the Token and message to enter it here
124106
print('use this token')
125107
print (account.authenticationToken)
126-
print('and put it into this file PLEX_TOKEN: plexUsers.py')
108+
print('and put it into the file config.py after PLEX_TOKEN: ')
127109
raise
128110

129111
# some lists for data
@@ -134,7 +116,7 @@ def __init__(self):
134116
# creating the client id
135117
self.clientId = uuid3(NAMESPACE_URL, "pptag").hex
136118

137-
self.plex = PlexServer(self.PLEX_URL, self.PLEX_TOKEN)
119+
self.plex = PlexServer(ppTagConfig.PLEX_URL, ppTagConfig.PLEX_TOKEN)
138120

139121

140122
apiUsers = self.fetchPlexApi("/api/home/users","GET",True)
@@ -149,8 +131,8 @@ def __init__(self):
149131

150132
for user in users:
151133
if isinstance(user, dict):
152-
if user['@title'] in self.USERDATA.keys():
153-
pin = self.USERDATA.get(user['@title'])
134+
if user['@title'] in ppTagConfig.USERDATA.keys():
135+
pin = ppTagConfig.USERDATA.get(user['@title'])
154136
u = userData(user['@id'],user['@uuid'],user['@title'], pin)
155137
self.users.append(u)
156138

pptag.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import logging
99
import urllib
1010
import time
11-
import platform
1211
from threading import Timer
1312
from watchdog.observers import Observer
1413
from watchdog.events import PatternMatchingEventHandler
@@ -19,21 +18,12 @@
1918
from plexUsers import plexUsers
2019
from lightroomTags import parse_xmp_for_lightroom_tags
2120

22-
logger = exif_log.get_logger()
23-
24-
system = platform.system()
21+
from config import ppTagConfig
2522

26-
####################### Change HERE #######################
27-
28-
if system == "Linux":
29-
photosPath = "/Photos/"
30-
else: # Windows
31-
photosPath = "P:\\"
23+
logger = exif_log.get_logger()
3224

33-
###########################################################
34-
3525
doUpdate = []
36-
firstRun = True
26+
firstRun = ppTagConfig.FORCE_RUN_AT_START
3727

3828
# plex
3929
p = None
@@ -122,7 +112,7 @@ def updateTagsAndRating(key, filename):
122112

123113
#exif_log.setup_logger(debug, color)
124114

125-
filename = photosPath + filename
115+
filename = ppTagConfig.PHOTOS_LIBRARY_PATH + filename
126116

127117
try:
128118
img_file = open(str(filename), 'rb')
@@ -202,7 +192,7 @@ def loopThroughAllPhotos():
202192
if mediaType != "photo":
203193
continue
204194
key = photo["ratingKey"]
205-
src = photo["Media"][0]["Part"][0]["file"].replace(plexUsers.PHOTOS_LIBRARY_PATH,"", 1)
195+
src = photo["Media"][0]["Part"][0]["file"].replace(ppTagConfig.PHOTOS_LIBRARY_PATH_PLEX,"", 1)
206196

207197
if src in doUpdateTemp or firstRun:
208198

@@ -236,7 +226,7 @@ def process(self, event):
236226
if (event.event_type == 'modified' or event.event_type == 'created' or event.event_type == 'moved'):
237227
if not event.is_directory:
238228
# put file into forced update list
239-
doUpdate.append(event.src_path.replace(photosPath,"", 1))
229+
doUpdate.append(event.src_path.replace(ppTagConfig.PHOTOS_LIBRARY_PATH,"", 1))
240230
triggerLoopThroughAllPhotos()
241231

242232
def on_modified(self, event):
@@ -250,7 +240,7 @@ def on_created(self, event):
250240

251241
# setup observer
252242
observer = Observer()
253-
observer.schedule(PhotoHandler(), path=photosPath, recursive=True)
243+
observer.schedule(PhotoHandler(), path=ppTagConfig.PHOTOS_LIBRARY_PATH, recursive=True)
254244

255245
# setup timer
256246
# wait 120 sec after change was detected

0 commit comments

Comments
 (0)