parent
1b3d564aa7
commit
fd5aa87532
@ -1,886 +0,0 @@ |
|||||||
#!/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}}) |
|
||||||
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" |
|
||||||
|
|
||||||
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) |
|
||||||
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: |
|
||||||
print(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() |
|
||||||
Loading…
Reference in new issue