#!/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(user): # importing the module import json # Opening JSON file with open(f'agent-{user.username}.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 to set a timer') def banner(update: Update, context: CallbackContext) -> None: """Sends explanation on how to use the bot.""" reply_keyboard = [['JSON', 'LINK', 'LINE']] user = update.message.from_user conn = create_connection() if select_user(conn, user.username): daten[user.username] = {} update.message.reply_text( 'Moin, let\'s start by adding a banner to your list.\n\n' 'How will Banner add data?', reply_markup=ReplyKeyboardMarkup( reply_keyboard, one_time_keyboard=True, input_field_placeholder='How will Banner add data?' ), ) else: context.bot.send_message(chat_id=user.id, text="Please get in touch with @r3f1Zul.") return OPTION def create_connection(): import sqlite3 """ create a database connection to the SQLite database specified by the db_file :param db_file: database file :return: Connection object or None """ conn = None try: conn = sqlite3.connect("bannerList.sqlite3") except Exception as e: print(e) return conn def select_user(conn, username): """ Query tasks by priority :param conn: the Connection object :param priority: :return: """ cur = conn.cursor() cur.execute("SELECT * FROM user WHERE username=?", (username,)) rows = cur.fetchone() if rows is not None: return True else: return False 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( 'Now send me the data', reply_markup=ReplyKeyboardRemove(), ) daten[user.username]['type'] = update.message.text if daten[user.username]['type'] == "JSON": return JSON if daten[user.username]['type'] == "LINK": return LINK if daten[user.username]['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') user = update.message.from_user 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[user.username]['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') user = update.message.from_user 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[user.username]['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') user = update.message.from_user daten[user.username]['json-file'] = context.bot.getFile(update.message.document.file_id) update.message.reply_text("Now send me the banner image") return PHOTO def getPhoto(update: Update, context: CallbackContext) -> int: import requests user = update.message.from_user update.message.reply_text(f'{update.message.chat_id} 4') url = requests.get(daten[user.username]['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[user.username]['bannerInfos'] = bannerInfos verarbeitung(update, context) return ConversationHandler.END def verarbeitung(update: Update, context: CallbackContext): user = update.message.from_user agent = loadAgentConfig(user) if daten[user.username]['type'] == "JSON": logger.info("JSON PArse MODE") if daten[user.username]['bannerInfos']['nummer'] is None: daten[user.username]['bannerInfos']['nummer'] = agent['banner-completed'] if daten[user.username]['bannerInfos']['formattedAddress'] is None: daten[user.username]['bannerInfos']['formattedAddress'] = getFormattedAddress(daten[user.username]['bannerInfos']['startLatitude'], daten[user.username]['bannerInfos']['startLongitude']) if daten[user.username]['bannerInfos']['completed'] is None: daten[user.username]['bannerInfos']['completed'] = int(agent['completed-mission']) + int(daten[user.username]['bannerInfos']['missions']) uploadJsonToGDrive(user, daten) if daten[user.username]['type'] == "LINK": logger.info("LINK PArse MODE") if daten[user.username]['bannerInfos']['nummer'] is None: daten[user.username]['bannerInfos']['nummer'] = agent['banner-completed'] if daten[user.username]['bannerInfos']['formattedAddress'] is None: daten[user.username]['bannerInfos']['formattedAddress'] = getFormattedAddress(daten[user.username]['bannerInfos']['startLatitude'], daten[user.username]['bannerInfos']['startLongitude']) if daten[user.username]['bannerInfos']['missions'] is None: daten[user.username]['bannerInfos']['missions'] = getBgInfos(daten[user.username]['bannerInfos']['bg-link'], "numberOfMissions") if daten[user.username]['bannerInfos']['completed'] is None: daten[user.username]['bannerInfos']['completed'] = int(agent['completed-mission']) + int(daten[user.username]['bannerInfos']['missions']) if daten[user.username]['bannerInfos']['onyx'] is None: # zahl = int(int(daten['bannerInfos']['completed']) / 500) # zahl /= zahl daten[user.username]['bannerInfos']['onyx'] = 0 if daten[user.username]['bannerInfos']['lengthKMeters'] is None and not daten[user.username]['bannerInfos']['bg-link'] is None: daten[user.username]['bannerInfos']['lengthKMeters'] = getBgInfos(daten[user.username]['bannerInfos']['bg-link'], "lengthMeters") if daten[user.username]['bannerInfos']['lengthKMeters'] > 1000: daten[user.username]['bannerInfos']['lengthKMeters'] = daten[user.username]['bannerInfos']['lengthKMeters'] / 1000 else: daten[user.username]['bannerInfos']['lengthKMeters'] if daten[user.username]['type'] == "LINE": logger.info("LINE PArse MODE") if daten[user.username]['bannerInfos']['formattedAddress'] is None: daten[user.username]['bannerInfos']['formattedAddress'] = getFormattedAddress(daten[user.username]['bannerInfos']['startLatitude'], daten[user.username]['bannerInfos']['startLongitude']) if daten[user.username]['bannerInfos']['description'] is None and not daten[user.username]['bannerInfos']['bg-link'] is None: daten[user.username]['bannerInfos']['description'] = getBgInfos(daten[user.username]['bannerInfos']['bg-link'], "description") if daten[user.username]['bannerInfos']['lengthKMeters'] is None and not daten[user.username]['bannerInfos']['bg-link'] is None: daten[user.username]['bannerInfos']['lengthKMeters'] = getBgInfos(daten[user.username]['bannerInfos']['bg-link'], "lengthMeters") if daten[user.username]['bannerInfos']['lengthKMeters'] > 1000: daten[user.username]['bannerInfos']['lengthKMeters'] = daten[user.username]['bannerInfos']['lengthKMeters'] / 1000 else: daten[user.username]['bannerInfos']['lengthKMeters'] uploadPictureToGDrive(daten, user, agent) # uploadPictureToGPhotos(daten, user) # getPublicLink(daten) writeDataToGSheet(daten, user, agent) publishBannerInChannel(update, context, daten, agent) agent["completed-mission"] = daten[user.username]['bannerInfos']['completed'] agent["banner-completed"] = int(daten[user.username]['bannerInfos']['nummer']) + 1 import json with open(f'agent-{user.username}.json', 'w', encoding='utf-8') as f: json.dump(agent, f, ensure_ascii=False, indent=4) def uploadJsonToGDrive(user, daten): import requests import time import json agent = loadAgentConfig() fname = daten[user.username]['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[user.username]['bannerInfos']['nummer']) date = int(daten[user.username]['bannerInfos']['date']) file_path = f'json/{nr:05d}_{fname}_{date}.json' daten[user.username]['bannerInfos']['json_file_path'] = file_path daten[user.username]['bannerInfos']['json_filename'] =f"{nr:05d}_{fname}_{date}.json" # print(file_path) url = requests.get(daten[user.username]['json-file']['file_path']) text = url.text obj = json.loads(text) with open(daten[user.username]['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': agent['gd-json']}], 'title': daten[user.username]['bannerInfos']['json_filename'], 'mimeType':'application/json'}) file1.SetContentFile(daten[user.username]['bannerInfos']['json_file_path']) file1.Upload() def publishBannerInChannel(update: Update, context: CallbackContext, daten, agent): from telegram.utils.helpers import escape_markdown user = update.message.from_user # https://umap.openstreetmap.de/de/map/r3f1zul-on-tour_19893?feature=xmas%20panda#18/53.50648/13.74733 t = daten[user.username]['bannerInfos']['titel'].replace(" ", "%20") place = f"{daten[user.username]['bannerInfos']['formattedAddress']['place']}, {daten[user.username]['bannerInfos']['formattedAddress']['country']}" #place = f"Orainienburg, Deutschalnd" link = f"https://umap.openstreetmap.de/de/map/r3f1zul-on-tour_19893?feature={t}#18/{daten[user.username]['bannerInfos']['startLatitude']}/{daten[user.username]['bannerInfos']['startLongitude']}" text = f"""{daten[user.username]['bannerInfos']['titel']}\n\nBanner-Nr: {daten[user.username]['bannerInfos']['nummer']}\nUnique Mission Completed: {daten[user.username]['bannerInfos']['completed']} (+{daten[user.username]['bannerInfos']['missions']})\nPlace: {place}\n\nMAP\n""" # msg = escape_markdown(text, version=2) context.bot.send_photo(agent['channel'], photo=open(daten[user.username]['bannerInfos']['file_path'], 'rb'), caption=text, parse_mode=ParseMode.HTML) update.message.reply_text("Fertig") def getPublicLink(daten, user): 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[user.username]['bannerInfos']['filename']: daten[user.username]['bannerInfos']['baseUrl'] = item['baseUrl'] def uploadPictureToGPhotos(daten, user): import glob filelist = glob.glob(os.path.join("banner", daten[user.username]['bannerInfos']['filename'])) # for infile in sorted(filelist): # filename = os.fsdecode(infile) upload_photos(session, sorted(filelist), "bannerJack") def uploadPictureToGDrive(daten, user, agent): import urllib.request import time fname = daten[user.username]['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[user.username]['bannerInfos']['nummer']) date = int(daten[user.username]['bannerInfos']['date']) file_path = f'banner/{user.username}/{nr:05d}_{fname}_{date}.png' daten[user.username]['bannerInfos']['file_path'] = file_path daten[user.username]['bannerInfos']['filename'] =f"{nr:05d}_{fname}_{date}.png" # print(file_path) if daten[user.username]['bannerInfos']['picture'][len(daten[user.username]['bannerInfos']['picture'])-1] == "=": link = daten[user.username]['bannerInfos']['picture'][:-1] else: link = daten[user.username]['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': '1nZJEAGh1OdzveuKdgHqA4P9yaSorDLYH'}] file1 = drive.CreateFile({'parents': [{'id': agent['gd-id']}], 'title': daten[user.username]['bannerInfos']['filename'], 'mimeType':'image/jpeg'}) file1.SetContentFile(f'banner/{user.username}/' + daten[user.username]['bannerInfos']['filename']) file1.Upload() def checkBaseUrl(daten, user, agent): if 'baseUrl' in daten[user.username]['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[user.username]['bannerInfos']: daten[user.username]['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[user.username]['bannerInfos']['filename'].split("_") for cell in cells: if banner_name[1] == cell[1]: daten[user.username]['bannerInfos']['baseUrl'] = cell[2] break return daten def writeDataToGSheet(daten, user, agent): import pygsheets try: gc = pygsheets.authorize(service_file='gdrive.json') daten[user.username]['bannerInfos']['baseUrl'] = "Bitte Url nachtragen" # Create a column # nummer startLatitude startLongitude titel picture formattedAddress completed missions date bg-link onyx description lengthKMeters new_row = [daten[user.username]['bannerInfos']['nummer'], daten[user.username]['bannerInfos']['startLatitude'], daten[user.username]['bannerInfos']['startLongitude'], daten[user.username]['bannerInfos']['titel'], daten[user.username]['bannerInfos']['baseUrl'], daten[user.username]['bannerInfos']['formattedAddress']['place'], daten[user.username]['bannerInfos']['formattedAddress']['country'] , daten[user.username]['bannerInfos']['completed'], daten[user.username]['bannerInfos']['missions'], daten[user.username]['bannerInfos']['date'], daten[user.username]['bannerInfos']['bg-link'], daten[user.username]['bannerInfos']['onyx'], daten[user.username]['bannerInfos']['description'], daten[user.username]['bannerInfos']['lengthKMeters']] #open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet) sh = gc.open(agent['liste']) #select the first sheet wks = sh[1] #update the first sheet with df, starting at cell B2. # wks.set_dataframe(df,(1,1)) cells = wks.get_all_values(include_tailing_empty_rows=False, include_tailing_empty=False, returnas='matrix') last_row = len(cells) worksheet = wks.insert_rows(last_row, values=new_row, inherit=True) except Exception as ex: print(ex) def getBgInfos(bgLink, field): import json import urllib.request tmp = bgLink.split("/") url = f"https://api.bannergress.com/bnrs/{tmp[len(tmp)-1]}" with urllib.request.urlopen(url) as response: read_data = response.read() obj = json.loads(read_data) return obj[field] def getFormattedAddress(startLatitude, startLongitude): from geopy.geocoders import Nominatim try: geolocator = Nominatim(user_agent="BannerJack TG BOT") location = geolocator.reverse(f"{startLatitude}, {startLongitude}", addressdetails=True) # print(location.address) l = location.raw loc = {} loc ['country'] = l['address']['country'] if 'state' in l['address']: loc['state'] = l['address']['state'] if 'city' in l['address']: loc['place'] = l['address']['city'] elif 'village' in l['address']: loc['place'] = l['address']['village'] elif 'town' in l['address']: loc['place'] = l['address']['town'] else: loc['place'] = l['address']['state'] return loc except Exception as ex: logging.debug(ex) return ConversationHandler.END def cancel(update: Update, context: CallbackContext) -> int: """Cancels and ends the conversation.""" user = update.message.from_user logger.info("User %s canceled the conversation.", user.first_name) update.message.reply_text( 'Bye! I hope we can talk again some day.', reply_markup=ReplyKeyboardRemove() ) return ConversationHandler.END def main() -> None: """Run bot.""" # session = get_authorized_session("client_id.json") # Create the Updater and pass it your bot's token. updater = Updater("5343492604:AAF-ATG3X5n30VSNUIErhfYQJpBSvZKAxec") # 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)], 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)), urlParser)], JSON: [MessageHandler(Filters.document.file_extension("json"), fileParser)], LINE: [MessageHandler(Filters.regex(re.compile(r'^[0-9]+.[0-9]+,', re.IGNORECASE)), lineParser)], PHOTO: [MessageHandler(Filters.photo, 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()