You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
898 lines
32 KiB
898 lines
32 KiB
#!/usr/bin/env python
|
|
# pylint: disable=C0116,W0613
|
|
# This program is dedicated to the public domain under the CC0 license.
|
|
|
|
"""
|
|
Simple Bot to send timed Telegram messages.
|
|
|
|
This Bot uses the Updater class to handle the bot and the JobQueue to send
|
|
timed messages.
|
|
|
|
First, a few handler functions are defined. Then, those functions are passed to
|
|
the Dispatcher and registered at their respective places.
|
|
Then, the bot is started and runs until we press Ctrl-C on the command line.
|
|
|
|
Usage:
|
|
Basic Alarm Bot example, sends a message after a set time.
|
|
Press Ctrl-C on the command line or send a signal to the process to stop the
|
|
bot.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update, ParseMode
|
|
from telegram.ext import Updater, CommandHandler, ConversationHandler, CallbackContext
|
|
from telegram.ext import MessageHandler, Filters
|
|
import re
|
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
|
from google.auth.transport.requests import AuthorizedSession
|
|
from google.oauth2.credentials import Credentials
|
|
import json
|
|
import os.path
|
|
import argparse
|
|
import logging
|
|
|
|
|
|
# Enable logging
|
|
logging.basicConfig(
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
OPTION, LINK, JSON, LINE, PHOTO, END = range(6)
|
|
|
|
daten = {}
|
|
|
|
|
|
def loadAgentConfig():
|
|
# importing the module
|
|
import json
|
|
|
|
# Opening JSON file
|
|
with open('agent.json') as json_file:
|
|
data = json.load(json_file)
|
|
|
|
return data
|
|
|
|
agent = loadAgentConfig()
|
|
|
|
def get_authorized_session(auth_token_file):
|
|
|
|
scopes=['https://www.googleapis.com/auth/photoslibrary',
|
|
'https://www.googleapis.com/auth/photoslibrary.sharing']
|
|
|
|
cred = None
|
|
|
|
if auth_token_file:
|
|
try:
|
|
cred = Credentials.from_authorized_user_file(auth_token_file, scopes)
|
|
except OSError as err:
|
|
logging.debug("Error opening auth token file - {0}".format(err))
|
|
except ValueError:
|
|
logging.debug("Error loading auth tokens - Incorrect format")
|
|
|
|
|
|
if not cred:
|
|
cred = auth(scopes)
|
|
|
|
session = AuthorizedSession(cred)
|
|
|
|
if auth_token_file:
|
|
try:
|
|
save_cred(cred, auth_token_file)
|
|
except OSError as err:
|
|
logging.debug("Could not save auth tokens - {0}".format(err))
|
|
|
|
return session
|
|
def auth(scopes):
|
|
flow = InstalledAppFlow.from_client_secrets_file(
|
|
'gPhotos.json',
|
|
scopes=scopes)
|
|
|
|
credentials = flow.run_local_server(host='localhost',
|
|
port=8080,
|
|
authorization_prompt_message="",
|
|
success_message='The auth flow is complete; you may close this window.',
|
|
open_browser=True)
|
|
|
|
return credentials
|
|
|
|
|
|
|
|
|
|
def save_cred(cred, auth_file):
|
|
|
|
cred_dict = {
|
|
'token': cred.token,
|
|
'refresh_token': cred.refresh_token,
|
|
'id_token': cred.id_token,
|
|
'scopes': cred.scopes,
|
|
'token_uri': cred.token_uri,
|
|
'client_id': cred.client_id,
|
|
'client_secret': cred.client_secret
|
|
}
|
|
|
|
with open(auth_file, 'w') as f:
|
|
print(json.dumps(cred_dict), file=f)
|
|
|
|
# Generator to loop through all albums
|
|
|
|
def getAlbums(session, appCreatedOnly=False):
|
|
|
|
params = {
|
|
'excludeNonAppCreatedData': appCreatedOnly
|
|
}
|
|
|
|
while True:
|
|
|
|
albums = session.get('https://photoslibrary.googleapis.com/v1/albums', params=params).json()
|
|
|
|
logging.debug("Server response: {}".format(albums))
|
|
|
|
if 'albums' in albums:
|
|
|
|
for a in albums["albums"]:
|
|
yield a
|
|
|
|
if 'nextPageToken' in albums:
|
|
params["pageToken"] = albums["nextPageToken"]
|
|
else:
|
|
return
|
|
|
|
else:
|
|
return
|
|
|
|
def create_or_retrieve_album(session, album_title):
|
|
|
|
# Find albums created by this app to see if one matches album_title
|
|
|
|
for a in getAlbums(session, True):
|
|
if a["title"].lower() == album_title.lower():
|
|
album_id = a["id"]
|
|
logging.info("Uploading into EXISTING photo album -- \'{0}\'".format(album_title))
|
|
return album_id
|
|
|
|
# No matches, create new album
|
|
|
|
create_album_body = json.dumps({"album":{"title": album_title}})
|
|
#print(create_album_body)
|
|
resp = session.post('https://photoslibrary.googleapis.com/v1/albums', create_album_body).json()
|
|
|
|
logging.debug("Server response: {}".format(resp))
|
|
|
|
if "id" in resp:
|
|
logging.info("Uploading into NEW photo album -- \'{0}\'".format(album_title))
|
|
return resp['id']
|
|
else:
|
|
logging.error("Could not find or create photo album '\{0}\'. Server Response: {1}".format(album_title, resp))
|
|
return None
|
|
|
|
def upload_photos(session, photo_file_list, album_name):
|
|
import time
|
|
album_id = create_or_retrieve_album(session, album_name) if album_name else None
|
|
|
|
# interrupt upload if an upload was requested but could not be created
|
|
if album_name and not album_id:
|
|
return
|
|
|
|
session.headers["Content-type"] = "application/octet-stream"
|
|
session.headers["X-Goog-Upload-Protocol"] = "raw"
|
|
|
|
for photo_file_name in photo_file_list:
|
|
time.sleep(5)
|
|
try:
|
|
photo_file = open(photo_file_name, mode='rb')
|
|
photo_bytes = photo_file.read()
|
|
except OSError as err:
|
|
logging.error("Could not read file \'{0}\' -- {1}".format(photo_file_name, err))
|
|
continue
|
|
|
|
session.headers["X-Goog-Upload-File-Name"] = os.path.basename(photo_file_name)
|
|
|
|
logging.info("Uploading photo -- \'{}\'".format(photo_file_name))
|
|
|
|
upload_token = session.post('https://photoslibrary.googleapis.com/v1/uploads', photo_bytes)
|
|
|
|
if (upload_token.status_code == 200) and (upload_token.content):
|
|
|
|
create_body = json.dumps({"albumId":album_id, "newMediaItems":[{"description":"","simpleMediaItem":{"uploadToken":upload_token.content.decode()}}]}, indent=4)
|
|
|
|
resp = session.post('https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate', create_body).json()
|
|
|
|
logging.debug("Server response: {}".format(resp))
|
|
|
|
if "newMediaItemResults" in resp:
|
|
status = resp["newMediaItemResults"][0]["status"]
|
|
if status.get("code") and (status.get("code") > 0):
|
|
logging.error("Could not add \'{0}\' to library -- {1}".format(os.path.basename(photo_file_name), status["message"]))
|
|
else:
|
|
logging.info("Added \'{}\' to library and album \'{}\' ".format(os.path.basename(photo_file_name), album_name))
|
|
else:
|
|
logging.error("Could not add \'{0}\' to library. Server Response -- {1}".format(os.path.basename(photo_file_name), resp))
|
|
|
|
else:
|
|
logging.error("Could not upload \'{0}\'. Server Response - {1}".format(os.path.basename(photo_file_name), upload_token))
|
|
|
|
try:
|
|
del(session.headers["Content-type"])
|
|
del(session.headers["X-Goog-Upload-Protocol"])
|
|
del(session.headers["X-Goog-Upload-File-Name"])
|
|
except KeyError:
|
|
pass
|
|
|
|
session = get_authorized_session("gPhotos.json")
|
|
|
|
# Define a few command handlers. These usually take the two arguments update and
|
|
# context. Error handlers also receive the raised TelegramError object in error.
|
|
# Best practice would be to replace context with an underscore,
|
|
# since context is an unused local variable.
|
|
# This being an example and not having context present confusing beginners,
|
|
# we decided to have it present as context.
|
|
def start(update: Update, context: CallbackContext) -> None:
|
|
"""Sends explanation on how to use the bot."""
|
|
update.message.reply_text('Hi! Use /set <seconds> to set a timer')
|
|
|
|
def banner(update: Update, context: CallbackContext) -> None:
|
|
"""Sends explanation on how to use the bot."""
|
|
reply_keyboard = [['JSON', 'LINK', 'LINE']]
|
|
|
|
daten = {}
|
|
update.message.reply_text(
|
|
'Moin, lasst uns anfang ein Banner zu deiner Liste hinzu zufügen.\n\n'
|
|
'Wie willst Banner Daten hinzufügen?',
|
|
reply_markup=ReplyKeyboardMarkup(
|
|
reply_keyboard, one_time_keyboard=True, input_field_placeholder='Wie willst Banner Daten hinzufügen?'
|
|
),
|
|
)
|
|
|
|
return OPTION
|
|
|
|
def option(update: Update, context: CallbackContext) -> int:
|
|
"""Stores the selected gender and asks for a photo."""
|
|
user = update.message.from_user
|
|
logger.info("Gender of %s: %s", user.first_name, update.message.text)
|
|
update.message.reply_text(
|
|
'I see! Please send me a photo of yourself, '
|
|
'so I know what you look like, or send /skip if you don\'t want to.',
|
|
reply_markup=ReplyKeyboardRemove(),
|
|
)
|
|
|
|
daten['type'] = update.message.text
|
|
|
|
if daten['type'] == "JSON":
|
|
return JSON
|
|
|
|
if daten['type'] == "LINK":
|
|
return LINK
|
|
|
|
if daten['type'] == "LINE":
|
|
return LINE
|
|
|
|
|
|
def urlParser(update: Update, context: CallbackContext) -> int:
|
|
"""Sends explanation on how to use the bot."""
|
|
update.message.reply_text(f'{update.message.chat_id} 1')
|
|
|
|
import json
|
|
import urllib.request
|
|
|
|
|
|
tmp = update.message.text.split("/")
|
|
url = f"https://api.bannergress.com/bnrs/{tmp[len(tmp)-1]}"
|
|
with urllib.request.urlopen(url) as response:
|
|
read_data = response.read()
|
|
obj = json.loads(read_data)
|
|
|
|
import datetime
|
|
now = datetime.datetime.now().year
|
|
bannerInfos = {}
|
|
bannerInfos['nummer'] = None
|
|
bannerInfos['startLatitude'] = obj['startLatitude']
|
|
bannerInfos['startLongitude'] = obj['startLongitude']
|
|
bannerInfos['titel'] = obj['title']
|
|
bannerInfos['picture'] = f"https://api.bannergress.com{obj['picture']}"
|
|
bannerInfos['formattedAddress'] = None
|
|
bannerInfos['completed'] = None
|
|
bannerInfos['missions'] = None
|
|
bannerInfos['date'] = now
|
|
|
|
p = re.compile(r'^https:\/\/bannergress.com\/banner\D[\w\d-]*', re.IGNORECASE)
|
|
if p.match(update.message.text):
|
|
bannerInfos['bg-link'] = update.message.text
|
|
else:
|
|
bannerInfos['bg-link'] = None
|
|
bannerInfos['onyx'] = None
|
|
bannerInfos['description'] = obj['description']
|
|
bannerInfos['lengthKMeters'] = None
|
|
daten['bannerInfos'] = bannerInfos
|
|
|
|
|
|
verarbeitung(update, context)
|
|
|
|
return ConversationHandler.END
|
|
|
|
def lineParser(update: Update, context: CallbackContext) -> int:
|
|
"""Sends explanation on how to use the bot."""
|
|
update.message.reply_text(f'{update.message.chat_id} 2')
|
|
|
|
text = update.message.text
|
|
text = text.split(",")
|
|
|
|
# load agent.yaml
|
|
# with open("agent.yaml") as f:
|
|
# config = yaml.load(f)
|
|
# nummer startLatitude startLongitude titel picture formattedAddress completed missions date bg-link onyx description lengthKMeters
|
|
bannerInfos = {}
|
|
bannerInfos['nummer'] = text[4]
|
|
bannerInfos['startLatitude'] = text[0]
|
|
bannerInfos['startLongitude'] = text[1]
|
|
bannerInfos['titel'] = text[2]
|
|
bannerInfos['picture'] = text[3]
|
|
bannerInfos['formattedAddress'] = None
|
|
bannerInfos['completed'] = text[6]
|
|
bannerInfos['missions'] = text[7]
|
|
bannerInfos['date'] = text[8]
|
|
p = re.compile(r'^https:\/\/bannergress.com\/banner\D[\w\d-]*', re.IGNORECASE)
|
|
if p.match(text[9]):
|
|
bannerInfos['bg-link'] = text[9]
|
|
else:
|
|
bannerInfos['bg-link'] = None
|
|
bannerInfos['onyx'] = text[10]
|
|
bannerInfos['description'] = None
|
|
bannerInfos['lengthKMeters'] = None
|
|
daten['bannerInfos'] = bannerInfos
|
|
|
|
verarbeitung(update, context)
|
|
|
|
return ConversationHandler.END
|
|
|
|
|
|
def fileParser(update: Update, context: CallbackContext) -> int:
|
|
"""Sends explanation on how to use the bot."""
|
|
update.message.reply_text(f'{update.message.chat_id} 3')
|
|
|
|
daten['json-file'] = context.bot.getFile(update.message.document.file_id)
|
|
|
|
update.message.reply_text("Sende mir Banner Bild")
|
|
|
|
return PHOTO
|
|
|
|
def getPhoto(update: Update, context: CallbackContext) -> int:
|
|
import requests
|
|
|
|
update.message.reply_text(f'{update.message.chat_id} 4')
|
|
|
|
url = requests.get(daten['json-file']['file_path'])
|
|
text = url.text
|
|
obj = json.loads(text)
|
|
|
|
import datetime
|
|
now = datetime.datetime.now().year
|
|
|
|
bannerInfos = {}
|
|
bannerInfos['nummer'] = None
|
|
bannerInfos['startLatitude'] = obj['missions'][0]['portals'][0]['location']['latitude']
|
|
bannerInfos['startLongitude'] = obj['missions'][0]['portals'][0]['location']['longitude']
|
|
bannerInfos['titel'] = obj['missionSetName']
|
|
bannerInfos['picture'] = context.bot.getFile(update.message.photo[-1].file_id)['file_path']
|
|
bannerInfos['formattedAddress'] = None
|
|
bannerInfos['completed'] = None
|
|
bannerInfos['missions'] = obj['plannedBannerLength']
|
|
bannerInfos['date'] = now
|
|
bannerInfos['bg-link'] = None
|
|
bannerInfos['onyx'] = 0
|
|
bannerInfos['description'] = obj['missionSetDescription']
|
|
bannerInfos['lengthKMeters'] = None
|
|
daten['bannerInfos'] = bannerInfos
|
|
|
|
verarbeitung(update, context)
|
|
|
|
return ConversationHandler.END
|
|
|
|
def verarbeitung(update: Update, context: CallbackContext):
|
|
|
|
agent = loadAgentConfig()
|
|
|
|
if daten['type'] == "JSON":
|
|
logger.info("JSON PArse MODE")
|
|
if daten['bannerInfos']['nummer'] is None:
|
|
daten['bannerInfos']['nummer'] = agent['banner-completed']
|
|
if daten['bannerInfos']['formattedAddress'] is None:
|
|
daten['bannerInfos']['formattedAddress'] = getFormattedAddress(daten['bannerInfos']['startLatitude'], daten['bannerInfos']['startLongitude'])
|
|
if daten['bannerInfos']['completed'] is None:
|
|
daten['bannerInfos']['completed'] = int(agent['completed-mission']) + int(daten['bannerInfos']['missions'])
|
|
uploadJsonToGDrive(daten)
|
|
|
|
|
|
if daten['type'] == "LINK":
|
|
logger.info("LINK PArse MODE")
|
|
if daten['bannerInfos']['nummer'] is None:
|
|
daten['bannerInfos']['nummer'] = agent['banner-completed']
|
|
if daten['bannerInfos']['formattedAddress'] is None:
|
|
daten['bannerInfos']['formattedAddress'] = getFormattedAddress(daten['bannerInfos']['startLatitude'], daten['bannerInfos']['startLongitude'])
|
|
|
|
if daten['bannerInfos']['missions'] is None:
|
|
daten['bannerInfos']['missions'] = getBgInfos(daten['bannerInfos']['bg-link'], "numberOfMissions")
|
|
if daten['bannerInfos']['completed'] is None:
|
|
daten['bannerInfos']['completed'] = int(agent['completed-mission']) + int(daten['bannerInfos']['missions'])
|
|
if daten['bannerInfos']['onyx'] is None:
|
|
# zahl = int(int(daten['bannerInfos']['completed']) / 500)
|
|
# zahl /= zahl
|
|
daten['bannerInfos']['onyx'] = 0
|
|
|
|
if daten['bannerInfos']['lengthKMeters'] is None and not daten['bannerInfos']['bg-link'] is None:
|
|
daten['bannerInfos']['lengthKMeters'] = getBgInfos(daten['bannerInfos']['bg-link'], "lengthMeters")
|
|
if daten['bannerInfos']['lengthKMeters'] > 1000:
|
|
daten['bannerInfos']['lengthKMeters'] = daten['bannerInfos']['lengthKMeters'] / 1000
|
|
else:
|
|
daten['bannerInfos']['lengthKMeters']
|
|
if daten['type'] == "LINE":
|
|
logger.info("LINE PArse MODE")
|
|
if daten['bannerInfos']['formattedAddress'] is None:
|
|
daten['bannerInfos']['formattedAddress'] = getFormattedAddress(daten['bannerInfos']['startLatitude'], daten['bannerInfos']['startLongitude'])
|
|
|
|
if daten['bannerInfos']['description'] is None and not daten['bannerInfos']['bg-link'] is None:
|
|
daten['bannerInfos']['description'] = getBgInfos(daten['bannerInfos']['bg-link'], "description")
|
|
|
|
if daten['bannerInfos']['lengthKMeters'] is None and not daten['bannerInfos']['bg-link'] is None:
|
|
daten['bannerInfos']['lengthKMeters'] = getBgInfos(daten['bannerInfos']['bg-link'], "lengthMeters")
|
|
if daten['bannerInfos']['lengthKMeters'] > 1000:
|
|
daten['bannerInfos']['lengthKMeters'] = daten['bannerInfos']['lengthKMeters'] / 1000
|
|
else:
|
|
daten['bannerInfos']['lengthKMeters']
|
|
|
|
uploadPictureToGDrive(daten)
|
|
|
|
uploadPictureToGPhotos(daten)
|
|
|
|
getPublicLink(daten)
|
|
|
|
writeDataToGSheet(daten)
|
|
|
|
publishBannerInChannel(update, context, daten)
|
|
|
|
agent = { "completed-mission": daten['bannerInfos']['completed'], "banner-completed": int(daten['bannerInfos']['nummer']) + 1}
|
|
|
|
import json
|
|
with open('agent.json', 'w', encoding='utf-8') as f:
|
|
json.dump(agent, f, ensure_ascii=False, indent=4)
|
|
|
|
def uploadJsonToGDrive(daten):
|
|
|
|
import requests
|
|
import time
|
|
import json
|
|
|
|
agent = loadAgentConfig()
|
|
|
|
fname = daten['bannerInfos']['titel'].replace(" ", "-")
|
|
fname = fname.replace("/", "")
|
|
fname = fname.replace("[", "")
|
|
fname = fname.replace("]", "")
|
|
|
|
fname = fname.replace("ü", "ue")
|
|
fname = fname.replace("ö", "oe")
|
|
fname = fname.replace("ä", "ae")
|
|
fname = fname.replace("ń", "n")
|
|
|
|
nr = int(daten['bannerInfos']['nummer'])
|
|
date = int(daten['bannerInfos']['date'])
|
|
file_path = f'json/{nr:05d}_{fname}_{date}.json'
|
|
daten['bannerInfos']['json_file_path'] = file_path
|
|
daten['bannerInfos']['json_filename'] =f"{nr:05d}_{fname}_{date}.json"
|
|
|
|
# print(file_path)
|
|
|
|
url = requests.get(daten['json-file']['file_path'])
|
|
text = url.text
|
|
obj = json.loads(text)
|
|
|
|
with open(daten['bannerInfos']['json_file_path'], 'w', encoding='utf-8') as f:
|
|
json.dump(obj, f, ensure_ascii=False, indent=4)
|
|
|
|
time.sleep(2)
|
|
|
|
from pydrive.auth import GoogleAuth
|
|
from pydrive.drive import GoogleDrive
|
|
|
|
gauth = GoogleAuth()
|
|
|
|
# Try to load saved client credentials
|
|
gauth.LoadCredentialsFile("GoogleDriveCredentials.txt")
|
|
if gauth.credentials is None:
|
|
# Authenticate if they're not there
|
|
gauth.LocalWebserverAuth()
|
|
elif gauth.access_token_expired:
|
|
# Refresh them if expired
|
|
# print("Google Drive Token Expired, Refreshing")
|
|
gauth.Refresh()
|
|
else:
|
|
# Initialize the saved creds
|
|
gauth.Authorize()
|
|
# Save the current credentials to a file
|
|
gauth.SaveCredentialsFile("GoogleDriveCredentials.txt")
|
|
drive = GoogleDrive(gauth)
|
|
|
|
file1 = drive.CreateFile({'parents': [{'id': '1cp3wfWLDB-BcY7ji-X-_HOW75ODISbzR'}], 'title': daten['bannerInfos']['json_filename'], 'mimeType':'application/json'})
|
|
|
|
file1.SetContentFile(daten['bannerInfos']['json_file_path'])
|
|
file1.Upload()
|
|
|
|
def publishBannerInChannel(update: Update, context: CallbackContext, daten):
|
|
from telegram.utils.helpers import escape_markdown
|
|
|
|
|
|
# https://umap.openstreetmap.de/de/map/r3f1zul-on-tour_19893?feature=xmas%20panda#18/53.50648/13.74733
|
|
t = daten['bannerInfos']['titel'].replace(" ", "%20")
|
|
place = f"{daten['bannerInfos']['formattedAddress']['place']}, {daten['bannerInfos']['formattedAddress']['country']}"
|
|
#place = f"Orainienburg, Deutschalnd"
|
|
link = f"https://umap.openstreetmap.de/de/map/r3f1zul-on-tour_19893?feature={t}#18/{daten['bannerInfos']['startLatitude']}/{daten['bannerInfos']['startLongitude']}"
|
|
text = f"""<b>{daten['bannerInfos']['titel']}</b>\n\n<b>Banner-Nr:</b> {daten['bannerInfos']['nummer']}\n<b>Unique Mission Completed:</b> {daten['bannerInfos']['completed']} (+{daten['bannerInfos']['missions']})\n<b>Place:</b> {place}\n\n<a href="{link}">MAP</a>\n"""
|
|
|
|
# msg = escape_markdown(text, version=2)
|
|
context.bot.send_photo("@r3f1sworld", photo=open(daten['bannerInfos']['file_path'], 'rb'), caption=text, parse_mode=ParseMode.HTML, protect_content=True)
|
|
update.message.reply_text("Fertig")
|
|
|
|
|
|
def getPublicLink(daten):
|
|
import os
|
|
import pickle
|
|
import json
|
|
from googleapiclient.discovery import build
|
|
from google.auth.transport.requests import Request
|
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
|
import google_auth_httplib2 # This gotta be installed for build() to work
|
|
|
|
# Setup the Photo v1 API
|
|
SCOPES = ['https://www.googleapis.com/auth/photoslibrary.readonly']
|
|
creds = None
|
|
if(os.path.exists("token.pickle")):
|
|
with open("token.pickle", "rb") as tokenFile:
|
|
creds = pickle.load(tokenFile)
|
|
if not creds or not creds.valid:
|
|
if (creds and creds.expired and creds.refresh_token):
|
|
creds.refresh(Request())
|
|
else:
|
|
flow = InstalledAppFlow.from_client_secrets_file('gPhotos-install.json', SCOPES)
|
|
creds = flow.run_local_server(port = 0)
|
|
with open("token.pickle", "wb") as tokenFile:
|
|
pickle.dump(creds, tokenFile)
|
|
service = build('photoslibrary', 'v1', credentials = creds,static_discovery=False)
|
|
# albums = session.get('https://photoslibrary.googleapis.com/v1/albums', params=params).json()
|
|
# Call the Photo v1 API
|
|
|
|
from pprint import pprint
|
|
# from init_photo_service import service
|
|
import pandas as pd
|
|
|
|
|
|
"""
|
|
list method
|
|
"""
|
|
response = service.mediaItems().list().execute()
|
|
|
|
lst_medias = response.get('mediaItems')
|
|
nextPageToken = response.get('nextPageToken')
|
|
|
|
while nextPageToken:
|
|
response = service.mediaItems().list(
|
|
pageToken=nextPageToken
|
|
).execute()
|
|
|
|
if(len(response) == 2):
|
|
lst_medias.extend(response.get('mediaItems'))
|
|
nextPageToken = response.get('nextPageToken')
|
|
else:
|
|
break
|
|
|
|
for item in lst_medias:
|
|
|
|
if item['filename'] == daten['bannerInfos']['filename']:
|
|
daten['bannerInfos']['baseUrl'] = item['baseUrl']
|
|
|
|
def uploadPictureToGPhotos(daten):
|
|
import glob
|
|
|
|
filelist = glob.glob(os.path.join("banner", daten['bannerInfos']['filename']))
|
|
# for infile in sorted(filelist):
|
|
# filename = os.fsdecode(infile)
|
|
|
|
upload_photos(session, sorted(filelist), "bannerJack")
|
|
|
|
def uploadPictureToGDrive(daten):
|
|
import urllib.request
|
|
import time
|
|
|
|
fname = daten['bannerInfos']['titel'].replace(" ", "-")
|
|
fname = fname.replace("/", "")
|
|
fname = fname.replace("[", "")
|
|
fname = fname.replace("]", "")
|
|
|
|
fname = fname.replace("ü", "ue")
|
|
fname = fname.replace("ö", "oe")
|
|
fname = fname.replace("ä", "ae")
|
|
fname = fname.replace("ń", "n")
|
|
|
|
nr = int(daten['bannerInfos']['nummer'])
|
|
date = int(daten['bannerInfos']['date'])
|
|
file_path = f'banner/{nr:05d}_{fname}_{date}.png'
|
|
daten['bannerInfos']['file_path'] = file_path
|
|
daten['bannerInfos']['filename'] =f"{nr:05d}_{fname}_{date}.png"
|
|
|
|
# print(file_path)
|
|
|
|
if daten['bannerInfos']['picture'][len(daten['bannerInfos']['picture'])-1] == "=":
|
|
link = daten['bannerInfos']['picture'][:-1]
|
|
else:
|
|
link = daten['bannerInfos']['picture']
|
|
|
|
|
|
urllib.request.urlretrieve(f"{link}", f"{file_path}")
|
|
time.sleep(2)
|
|
|
|
|
|
from pydrive.auth import GoogleAuth
|
|
from pydrive.drive import GoogleDrive
|
|
|
|
gauth = GoogleAuth()
|
|
|
|
# Try to load saved client credentials
|
|
gauth.LoadCredentialsFile("GoogleDriveCredentials.txt")
|
|
if gauth.credentials is None:
|
|
# Authenticate if they're not there
|
|
gauth.LocalWebserverAuth()
|
|
elif gauth.access_token_expired:
|
|
# Refresh them if expired
|
|
# print("Google Drive Token Expired, Refreshing")
|
|
gauth.Refresh()
|
|
else:
|
|
# Initialize the saved creds
|
|
gauth.Authorize()
|
|
# Save the current credentials to a file
|
|
gauth.SaveCredentialsFile("GoogleDriveCredentials.txt")
|
|
drive = GoogleDrive(gauth)
|
|
|
|
file1 = drive.CreateFile({'parents': [{'id': '1TymjzUMWidVvrdTbgNy85dfEA8q7DJtg'}], 'title': daten['bannerInfos']['filename'], 'mimeType':'image/jpeg'})
|
|
|
|
file1.SetContentFile('banner/' + daten['bannerInfos']['filename'])
|
|
file1.Upload()
|
|
|
|
def checkBaseUrl(daten):
|
|
if 'baseUrl' in daten['bannerInfos']:
|
|
import os
|
|
import pickle
|
|
import json
|
|
from googleapiclient.discovery import build
|
|
from google.auth.transport.requests import Request
|
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
|
import google_auth_httplib2 # This gotta be installed for build() to work
|
|
|
|
# Setup the Photo v1 API
|
|
SCOPES = ['https://www.googleapis.com/auth/photoslibrary.readonly']
|
|
creds = None
|
|
if(os.path.exists("token.pickle")):
|
|
with open("token.pickle", "rb") as tokenFile:
|
|
creds = pickle.load(tokenFile)
|
|
if not creds or not creds.valid:
|
|
if (creds and creds.expired and creds.refresh_token):
|
|
creds.refresh(Request())
|
|
else:
|
|
flow = InstalledAppFlow.from_client_secrets_file('client_secrets.json', SCOPES)
|
|
creds = flow.run_local_server(port = 0)
|
|
with open("token.pickle", "wb") as tokenFile:
|
|
pickle.dump(creds, tokenFile)
|
|
service = build('photoslibrary', 'v1', credentials = creds,static_discovery=False)
|
|
# albums = session.get('https://photoslibrary.googleapis.com/v1/albums', params=params).json()
|
|
# Call the Photo v1 API
|
|
|
|
from pprint import pprint
|
|
# from init_photo_service import service
|
|
import pandas as pd
|
|
import time
|
|
|
|
"""
|
|
list method
|
|
"""
|
|
response = service.mediaItems().list().execute()
|
|
|
|
lst_medias = response.get('mediaItems')
|
|
nextPageToken = response.get('nextPageToken')
|
|
|
|
while nextPageToken:
|
|
response = service.mediaItems().list(
|
|
pageToken=nextPageToken
|
|
).execute()
|
|
|
|
if(len(response) == 2):
|
|
lst_medias.extend(response.get('mediaItems'))
|
|
nextPageToken = response.get('nextPageToken')
|
|
else:
|
|
break
|
|
|
|
import pygsheets
|
|
|
|
gc = pygsheets.authorize(service_file='gdrive.json')
|
|
|
|
#open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet)
|
|
sh = gc.open('Banner Liste')
|
|
|
|
#select the first sheet
|
|
wks = sh[0]
|
|
|
|
i = 1
|
|
|
|
for item in lst_medias:
|
|
# print(f"{i}/{len(lst_medias)}")
|
|
cells = wks.get_all_values(include_tailing_empty_rows=False, include_tailing_empty=False, returnas='matrix')
|
|
|
|
not_in = True
|
|
for cell in cells:
|
|
banner_name = item['filename'].split("_")
|
|
if banner_name[1] == cell[1]:
|
|
not_in = False
|
|
break
|
|
|
|
if not_in:
|
|
last_row = len(cells)
|
|
new_row = [ last_row, banner_name[1], item['baseUrl']]
|
|
worksheet = wks.insert_rows(last_row, values=new_row, inherit=True)
|
|
time.sleep(1)
|
|
i += 1
|
|
|
|
|
|
if not 'baseUrl' in daten['bannerInfos']:
|
|
daten['bannerInfos']['baseUrl'] = "Bitte Url nachtragen"
|
|
import pygsheets
|
|
|
|
gc = pygsheets.authorize(service_file='gdrive.json')
|
|
|
|
#open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet)
|
|
sh = gc.open('Banner Liste')
|
|
|
|
#select the first sheet
|
|
wks = sh[0]
|
|
|
|
i = 1
|
|
|
|
cells = wks.get_all_values(include_tailing_empty_rows=False, include_tailing_empty=False, returnas='matrix')
|
|
|
|
not_in = True
|
|
banner_name = daten['bannerInfos']['filename'].split("_")
|
|
|
|
for cell in cells:
|
|
if banner_name[1] == cell[1]:
|
|
daten['bannerInfos']['baseUrl'] = cell[2]
|
|
break
|
|
|
|
|
|
|
|
return daten
|
|
|
|
def writeDataToGSheet(daten):
|
|
import pygsheets
|
|
try:
|
|
|
|
gc = pygsheets.authorize(service_file='gdrive.json')
|
|
|
|
daten = checkBaseUrl(daten)
|
|
|
|
# Create a column
|
|
# nummer startLatitude startLongitude titel picture formattedAddress completed missions date bg-link onyx description lengthKMeters
|
|
new_row = [daten['bannerInfos']['nummer'], daten['bannerInfos']['startLatitude'], daten['bannerInfos']['startLongitude'], daten['bannerInfos']['titel'],
|
|
daten['bannerInfos']['baseUrl'], daten['bannerInfos']['formattedAddress']['place'], daten['bannerInfos']['formattedAddress']['country'] , daten['bannerInfos']['completed'], daten['bannerInfos']['missions'], daten['bannerInfos']['date'],
|
|
daten['bannerInfos']['bg-link'], daten['bannerInfos']['onyx'], daten['bannerInfos']['description'], daten['bannerInfos']['lengthKMeters']]
|
|
|
|
#open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet)
|
|
sh = gc.open('Meine Banner')
|
|
|
|
#select the first sheet
|
|
wks = sh[1]
|
|
|
|
#update the first sheet with df, starting at cell B2.
|
|
# wks.set_dataframe(df,(1,1))
|
|
|
|
cells = wks.get_all_values(include_tailing_empty_rows=False, include_tailing_empty=False, returnas='matrix')
|
|
|
|
last_row = len(cells)
|
|
worksheet = wks.insert_rows(last_row, values=new_row, inherit=True)
|
|
except Exception as ex:
|
|
print(ex)
|
|
|
|
def getBgInfos(bgLink, field):
|
|
import json
|
|
import urllib.request
|
|
|
|
|
|
tmp = bgLink.split("/")
|
|
url = f"https://api.bannergress.com/bnrs/{tmp[len(tmp)-1]}"
|
|
with urllib.request.urlopen(url) as response:
|
|
read_data = response.read()
|
|
obj = json.loads(read_data)
|
|
return obj[field]
|
|
|
|
def getFormattedAddress(startLatitude, startLongitude):
|
|
|
|
from geopy.geocoders import Nominatim
|
|
try:
|
|
geolocator = Nominatim(user_agent="BannerJack TG BOT")
|
|
location = geolocator.reverse(f"{startLatitude}, {startLongitude}", addressdetails=True)
|
|
# print(location.address)
|
|
l = location.raw
|
|
|
|
loc = {}
|
|
loc ['country'] = l['address']['country']
|
|
if 'state' in l['address']:
|
|
loc['state'] = l['address']['state']
|
|
|
|
|
|
if 'city' in l['address']:
|
|
loc['place'] = l['address']['city']
|
|
elif 'village' in l['address']:
|
|
loc['place'] = l['address']['village']
|
|
elif 'town' in l['address']:
|
|
loc['place'] = l['address']['town']
|
|
else:
|
|
loc['place'] = l['address']['state']
|
|
|
|
return loc
|
|
except Exception as ex:
|
|
logging.debug(ex)
|
|
|
|
return ConversationHandler.END
|
|
|
|
def cancel(update: Update, context: CallbackContext) -> int:
|
|
"""Cancels and ends the conversation."""
|
|
user = update.message.from_user
|
|
logger.info("User %s canceled the conversation.", user.first_name)
|
|
update.message.reply_text(
|
|
'Bye! I hope we can talk again some day.', reply_markup=ReplyKeyboardRemove()
|
|
)
|
|
|
|
return ConversationHandler.END
|
|
|
|
def main() -> None:
|
|
"""Run bot."""
|
|
|
|
# session = get_authorized_session("client_id.json")
|
|
|
|
|
|
# Create the Updater and pass it your bot's token.
|
|
updater = Updater("991032533:AAHMYX0bqSk82m1cUReJ9KefuzXFTBAIfkw")
|
|
|
|
|
|
# Get the dispatcher to register handlers
|
|
dispatcher = updater.dispatcher
|
|
|
|
# on different commands - answer in Telegram
|
|
dispatcher.add_handler(CommandHandler("start", start))
|
|
dispatcher.add_handler(CommandHandler("help", start))
|
|
|
|
conv_handler = ConversationHandler(
|
|
entry_points=[CommandHandler('banner', banner)],
|
|
# Filters.document.file_extension("json") & Filters.user(username="@r3f1Zul"), fileParser)],
|
|
states= {
|
|
OPTION: [MessageHandler(Filters.regex('^(JSON|LINK|LINE)$'), option)],
|
|
LINK: [MessageHandler(Filters.regex(re.compile(r'^https:\/\/bannergress.com\/banner\D[\w\d-]*', re.IGNORECASE)) & Filters.user(username="@r3f1Zul"), urlParser)],
|
|
JSON: [MessageHandler(Filters.document.file_extension("json") & Filters.user(username="@r3f1Zul"), fileParser)],
|
|
LINE: [MessageHandler(Filters.regex(re.compile(r'^[0-9]+.[0-9]+,', re.IGNORECASE)) & Filters.user(username="@r3f1Zul"), lineParser)],
|
|
PHOTO: [MessageHandler(Filters.photo & Filters.user(username="@r3f1Zul"), getPhoto)]
|
|
},
|
|
|
|
fallbacks=[CommandHandler('cancel', cancel)],
|
|
)
|
|
|
|
dispatcher.add_handler(conv_handler)
|
|
|
|
|
|
# Start the Bot
|
|
updater.start_polling()
|
|
|
|
# Block until you press Ctrl-C or the process receives SIGINT, SIGTERM or
|
|
# SIGABRT. This should be used most of the time, since start_polling() is
|
|
# non-blocking and will stop the bot gracefully.
|
|
updater.idle()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|