[INIT] first version

master
Marcel Eggert 4 years ago
parent 479ce725b8
commit c903bdf0f8
  1. 15
      .vscode/launch.json
  2. 4
      agent-azraelis.json
  3. 4
      agent.json
  4. 1
      credentials.json
  5. 1
      gPhotos-install.json
  6. 1
      gPhotos.json
  7. 13
      gdrive.json
  8. 817
      main-azraelis.py
  9. 907
      main.py
  10. 11
      requirements.txt
  11. 13
      settings.yaml
  12. BIN
      token.pickle

@ -0,0 +1,15 @@
{
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Aktuelle Datei",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}

@ -0,0 +1,4 @@
{
"completed-mission": 2682,
"banner-completed": 113
}

@ -0,0 +1,4 @@
{
"completed-mission": 8514,
"banner-completed": 398
}

@ -0,0 +1 @@
{"access_token": "ya29.A0ARrdaM837sroxsBoBREFWg8HbSgjLsP4ho2E2jvck7AJRoMvnD0UesWkzjvhKdzCdZpAsAOyy5Sz9E-Fo-z1NXVdAVmKzhDtpQG0OFtz8oFnDfi5fqnuEV35LpkJH79IFUIvVt_PwXN82aToNYA1CSGgX5Og", "client_id": "612944111509-6122l3am8pme3dengm138tr0gfv9rnmg.apps.googleusercontent.com", "client_secret": "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", "refresh_token": "1//098xAf2csdYwLCgYIARAAGAkSNwF-L9IrTNOuApnF2l92JgylIQCQDwC_-FhKW99XivSSjrvbZwJEMjeCM2j5JLx8ACXCywbU904", "token_expiry": "2022-01-15T06:39:11Z", "token_uri": "https://accounts.google.com/o/oauth2/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.A0ARrdaM837sroxsBoBREFWg8HbSgjLsP4ho2E2jvck7AJRoMvnD0UesWkzjvhKdzCdZpAsAOyy5Sz9E-Fo-z1NXVdAVmKzhDtpQG0OFtz8oFnDfi5fqnuEV35LpkJH79IFUIvVt_PwXN82aToNYA1CSGgX5Og", "expires_in": 3599, "refresh_token": "1//098xAf2csdYwLCgYIARAAGAkSNwF-L9IrTNOuApnF2l92JgylIQCQDwC_-FhKW99XivSSjrvbZwJEMjeCM2j5JLx8ACXCywbU904", "scope": "https://www.googleapis.com/auth/drive", "token_type": "Bearer"}, "scopes": ["https://www.googleapis.com/auth/drive"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"}

@ -0,0 +1 @@
{"installed":{"client_id":"612944111509-3e2rsje7h2l59soigqecneo1uoicjjn5.apps.googleusercontent.com","project_id":"quickstart-1592106916653","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}

@ -0,0 +1 @@
{"token": "ya29.A0ARrdaM9USz2zvfBIJXWnBU5XzGBIfu9NK1oIq0qLtRdTJEGzXmhxuPtFZQe2vmMNFtQSkjh76jgzS-sXTR8eu7Hbz3h19mCHN1DAKZCOBLb74HIdMmqRh89qzrM3awY8NTu3wgEBi6_9AYReoI1CRWfj1enW", "refresh_token": "1//09jtytzjAIc9ZCgYIARAAGAkSNwF-L9IrfUAFFUA2cVVpfwqATVQcPRTHVxJMhpwLpkrTWzGjNS0Mtu-MeM5cM48I7niy8KOjfmU", "id_token": null, "scopes": ["https://www.googleapis.com/auth/photoslibrary", "https://www.googleapis.com/auth/photoslibrary.sharing"], "token_uri": "https://oauth2.googleapis.com/token", "client_id": "612944111509-3e2rsje7h2l59soigqecneo1uoicjjn5.apps.googleusercontent.com", "client_secret": "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"}

@ -0,0 +1,13 @@
{
"type": "service_account",
"project_id": "quickstart-1592106916653",
"private_key_id": "23b0cf28afa950f76fb79aef7acf24a6e916fdf7",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCWeCUbuj3WQnbL\npjGBI5VGzlK6ujkTlNHDPzNBvsIgt+Z5t4mYqUmD+bOylUHQ9ptqZgqH0/XmN1ox\nu2EPTEBfscv9neF+y0bRy8F7IJKtqOZvPkWqjVhStzXVsXDUujIkTqtFLlk4eOsz\nig/+GnFl4qvldXdhpbnbEovqbEUjkWZjXmHL8Lro8sCujD5CuFBGmXPu8SF/ROCM\nYiYtT2PjPGss7PE9Cc/G1Sk3OrqnIA2SmP5dqCHbfpd+qHSI+h3LgRhNjkBfv5aG\ny3ZGvha3BeI8o11SKx55GwJqqiOaoQNsS07ovJPpHgRYPqGVSdqZNXTbRFztfPle\nF4HOTXbVAgMBAAECgf8hax/3Ua78eX1WmQBlrhPCgX4naFlE239x3bwW3f32auGg\nuSKxoJ5qHws3wxMkMVgKAFafiwY2rYI2G7DgkFgE6OXTJPRdxxEYGZaWCzg/WYz4\n3tu+vDgGJvPN7+P6yM1+sIx99YQkdG1/TgX2IHuhSdss0g6NDx0TisHRl/Ew0DCQ\n2wgT7ysXsJwe/5V2rkTjc6wUESN37tOK9O2IA8OUF4xV3XfAkqwUH7WHboNhuBbv\nGrnaHq64+H3JnnfMO518xvE4M+ueOjkdlXgaGHbuEgvU73DGIuMx0BTa6+CPD82o\n/jpSjgRLWX4St7SEnzNvD0ZmcwHDrvhVP8LgeIECgYEA0VDaGQFDthRBbFjvYHwp\nydJC0OEiaG+IUIDwaGTTvOIg2OLAcl6YEOjVcjUaVnadxb17Ck3ls1x6EiZX2HNl\ndLpxqhG/DbpipmjOSuoVOLI5K5fkBJl0LIxAj+ooZuVcIak0/27HM3TkLGrRAOuo\n6w+ZUB4KYmFH+YVQz3MEZRECgYEAuAdgymCy/FkwvWL0YsVdjtOBIz1LLFv1H+mv\n8Z2laxZW0fkyhwYj72QQG6Bd8y4tLwXFbxysunZJqxjIYj9zSI6mlNd1KSkzM2Wc\noI43rvL0Do+avl9IjLys0oy3CvKmTm50uXkCAAIDfJ4CkM6/yfrt20WLHuRvcPqF\n82XRpYUCgYEAuA/fGanw/wYk2cADD9dfb+gDdWbkOO4K8q/PuB0hzLEUrWQIUwo3\nsnbsa3ei53F7H82ViuQhH24sshUhnmcrSlBBb4oXdVz3LtpuvZXGf4rJlzoD+r9u\nV1Yl1+fTC1iZgcgnoI6rgOZDV4O+so6Ihdu7t6YS/5wIDLVc8G915+ECgYBIy4Ja\nC45Bi/Zfs/j/6RptGPUIP4Kw9V8tVH8okDeS+K83N9/o0WD9nRNSGkmPnEB7TUkf\n/rPEvm29pHv/gSHVHbh/QAs0UPvT5OnkCN218pzf9aY8j+xe33NthgQR7JIkjETX\n6SoFXsaKUOaq6V2sQ/o6tnOlsK70feTmtuwLEQKBgHnYvJQK3XX3dvs6pGWSLZ50\nZSGIZHAOzZaIGVPc6ziZjb5az9+mnxy4rygEENaYGGUgfe7XGoagViXdvn0NLzr/\npvE2dXbgyxnK7mnJLYxht+hUTYNGfMviTYSpy9/B+2vFS/c7gR3C66Ywm5/gv6HS\nTiosPaiOodBm3c5PaYwN\n-----END PRIVATE KEY-----\n",
"client_email": "bannerjack-gdrive@quickstart-1592106916653.iam.gserviceaccount.com",
"client_id": "103851937750278503595",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/bannerjack-gdrive%40quickstart-1592106916653.iam.gserviceaccount.com"
}

@ -0,0 +1,817 @@
#!/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, LINE, PHOTO, END = range(5)
daten = {}
def loadAgentConfig():
# importing the module
import json
# Opening JSON file
with open('agent-azraelis.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 = [['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'] == "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
print()
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."""
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[0]
bannerInfos['startLatitude'] = text[8]
bannerInfos['startLongitude'] = text[9]
bannerInfos['titel'] = text[1]
bannerInfos['picture'] = None
bannerInfos['formattedAddress'] = None
bannerInfos['completed'] = None
bannerInfos['missions'] = text[2]
bannerInfos['date'] = None
p = re.compile(r'^https:\/\/bannergress.com\/banner\D[\w\d-]*', re.IGNORECASE)
if p.match(text[7]):
bannerInfos['bg-link'] = text[7]
else:
bannerInfos['bg-link'] = None
bannerInfos['onyx'] = None
bannerInfos['description'] = None
bannerInfos['lengthKMeters'] = None
daten['bannerInfos'] = bannerInfos
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 = context.bot.getFile(update.message.photo[-1].file_id)['file_path']
import datetime
now = datetime.datetime.now().year
daten['bannerInfos']['picture'] = url
daten['bannerInfos']['date'] = now
daten['bannerInfos']['bg-link'] = None
daten['bannerInfos']['onyx'] = 0
daten['bannerInfos']['description'] = None
daten['bannerInfos']['lengthKMeters'] = None
verarbeitung(update, context)
return ConversationHandler.END
def verarbeitung(update: Update, context: CallbackContext):
agent = loadAgentConfig()
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")
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']['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']
daten['bannerInfos']['completed'] = int(agent['completed-mission']) + int( daten['bannerInfos']['missions'])
print()
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-azraelis.json', 'w', encoding='utf-8') as f:
json.dump(agent, f, ensure_ascii=False, indent=4)
def publishBannerInChannel(update: Update, context: CallbackContext, daten):
from telegram.utils.helpers import escape_markdown
print()
# 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", "
link = f"https://umap.openstreetmap.de/de/map/spec-ops_21235?feature={t}#18/{daten['bannerInfos']['startLatitude']}/{daten['bannerInfos']['startLongitude']}"
text = f"""<b>{daten['bannerInfos']['titel']}</b>\n\n<b>Banner-Nr:</b> \n<b>Unique Mission Completed:</b> (+)\n<b>Place:</b> {place}\n\n<a href="{link}">MAP</a>\n"""
if daten['bannerInfos']['bg-link'] is None:
text = f"""Banner: {daten['bannerInfos']['nummer']}\nName: <b>{daten['bannerInfos']['titel']}</b>\nMission: {daten['bannerInfos']['missions']}\nCountry: {daten['bannerInfos']['formattedAddress']['country']}\nCity: {daten['bannerInfos']['formattedAddress']['place']}\nLink: <a href="{link}">MAP</a>\n\nTotal: {daten['bannerInfos']['completed']}"""
else:
text = f"""Banner: {str(daten['bannerInfos']['nummer']).rjust(3, '0')}\nName: <b>{daten['bannerInfos']['titel']}</b>\nMission: {daten['bannerInfos']['missions']}\nCountry: {daten['bannerInfos']['formattedAddress']['country']}\nCity: {daten['bannerInfos']['formattedAddress']['place']}\nLinks: <a href="{link}">MAP</a> <a href="{daten['bannerInfos']['bg-link']}">Bannergress</a>\n\nTotal: {daten['bannerInfos']['completed']}"""
print()
# text = text.replace("-", "\-")
# text = text.replace("(", "\(")
# text = text.replace(")", "\)")
# text = text.replace(".", "\.")
# msg = escape_markdown(text, version=2)
context.bot.send_photo("@KnallfroschOnTour", photo=open(daten['bannerInfos']['file_path'], 'rb'), caption=text, parse_mode=ParseMode.HTML)
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:
print()
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), "banner-azraelis")
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("â", "")
fname = fname.replace("", "")
fname = fname.replace("", "")
fname = fname.replace(":", "")
fname = fname.replace("ě", "e")
fname = fname.replace("á", "a")
fname = fname.replace("ź", "z")
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': '1G2mSZczK8isZ2h-cgjidmV_mTL4SI-g6'}], 'title': daten['bannerInfos']['filename'], 'mimeType':'image/jpeg'})
file1.SetContentFile('banner/' + daten['bannerInfos']['filename'])
file1.Upload()
def checkBaseUrl(daten):
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
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
"""
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(i)
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)
return daten
def writeDataToGSheet(daten):
import pygsheets
try:
print()
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('SpecOPs - Missions')
#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
print()
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):
print()
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:
print(ex)
print()
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("5026875282:AAH09HbaQA42VL9pvIf2frhQHmklBp3GmqY")
# 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('^(LINK|LINE)$'), option)],
LINK: [MessageHandler(Filters.regex(re.compile(r'^https:\/\/bannergress.com\/banner\D[\w\d-]*', re.IGNORECASE)) & (Filters.user(username="@azraelis") | Filters.user(username="@r3f1Zul")), urlParser)],
LINE: [MessageHandler((Filters.user(username="@azraelis") | Filters.user(username="@r3f1Zul")) & (~Filters.command), lineParser)],
PHOTO: [MessageHandler(Filters.photo & (Filters.user(username="@azraelis") | 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()

@ -0,0 +1,907 @@
#!/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
print()
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']
print()
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):
print()
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
print()
# 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"""
print()
# text = text.replace("-", "\-")
# text = text.replace("(", "\(")
# text = text.replace(")", "\)")
# text = text.replace(".", "\.")
# 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:
print()
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:
print()
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
print()
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):
print()
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:
print(ex)
print()
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()

@ -0,0 +1,11 @@
geopy==2.2.0
google_api_python_client==2.37.0
google_auth_httplib2==0.1.0
google_auth_oauthlib==0.4.6
pandas==1.3.5
protobuf==3.19.4
PyDrive==1.3.1
pygsheets==2.0.5
python_telegram_bot==13.10
requests==2.26.0
telegram==0.0.1

@ -0,0 +1,13 @@
client_config_backend: settings
client_config:
client_id: 612944111509-6122l3am8pme3dengm138tr0gfv9rnmg.apps.googleusercontent.com
client_secret: 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
save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json
get_refresh_token: True
oauth_scope:
- https://www.googleapis.com/auth/drive

Binary file not shown.
Loading…
Cancel
Save