Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tRQ0 committed Dec 24, 2023
0 parents commit d50ac2f
Show file tree
Hide file tree
Showing 8 changed files with 965 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**/refresh.txt
**/data/
__pycache__/
*.code-workspace
**/log/
**/credentials/
.vscode
venv/
28 changes: 28 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog for Bing Ads script

## v1

- For authentication now the application does not redirects directly to the web browser, instead authenticaion link is printed in the console
- Cleanup is now a part of the main script and does not require a separate cron
- Implement logger
- Add next script execution time to spreadsheet
- fix static paths in the main script
- fix unable to create data folder and log/app.log file if not exist
- Sort data in descending order of data
- Remove script related outputs
- Data should not inlude todays date data

### v1.1
- Installed new dependency package i.e **CurrencyConverter**
- Change sorting order for data, now data is sorted date wise i.e. all account data is shown for a single date
- Add new column (**Cost (converted)**) that contains converted **SPEND** value
- Add new column (**Avg. CPC (converted)**) that contains converted **AverageCpc** value
- Add new column (**Total conv. value**) that contains converted **Spend** value
- Create pivot table for previous day data in **Sheet 6**

## ToDo

- Add environment file
- fix error flow
- add accurate script execution status
- implement logging to external script or word file
29 changes: 29 additions & 0 deletions cleanup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import os
import shutil
import logging
import logger

def clear_folder(folder_path):
try:
# Check if the folder exists
if os.path.exists(folder_path):
# Iterate over the files and subdirectories in the folder
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)

# Check if it's a file or directory
if os.path.isfile(file_path):
# Remove file
os.remove(file_path)
elif os.path.isdir(file_path):
# Remove directory and its contents
shutil.rmtree(file_path)

logger.log_message(f"Contents of '{folder_path}' cleared successfully.")
return (f"Contents of '{folder_path}' cleared successfully.")
else:
logger.log_message(f"The folder '{folder_path}' does not exist.", level=logging.WARNING)
return(f"The folder '{folder_path}' does not exist.")
except Exception as e:
logger.log_message(e, level=logging.ERROR)
return(f"An error occurred: {e}")
143 changes: 143 additions & 0 deletions gs_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
'''Google Sheets Interface
This module is used to interface with the google sheets and
update the specified google sheets
'''
from __future__ import print_function

import os.path
import logging
import logger

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google.oauth2 import service_account

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

def update_g_sheet(
data,
meta,
spreadsheet_id,
range,
append_mode = False,
log_to_sheet = False,
):

creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
# credentials = service_account.Credentials.from_service_account_file('credentials/service-account-credentials.json', scopes=SCOPES)

# Get script path
script_dir = os.path.dirname(os.path.abspath(__file__))

credentials_path = os.path.join(script_dir, "credentials/service-account-credentials-live.json")
'''LIVE CREDENTIALS'''
credentials = service_account.Credentials.from_service_account_file(credentials_path, scopes=SCOPES)

try:
service = build('sheets', 'v4', credentials=credentials)

# Call the Sheets API
sheet = service.spreadsheets()

if not append_mode:
# Clear the sheet
print("Clearing old values...")
sheet.values().clear(
spreadsheetId=spreadsheet_id,
range=range
).execute()

values = data
body = {"values": values}

if not values:
if log_to_sheet:
body = {'values': [
['Status: FAIL'],
['Reason: no data to upload']
]}
result = (
sheet
.values()
.append(
spreadsheetId=spreadsheet_id,
range=range,
valueInputOption='USER_ENTERED',
body=body,
)
.execute()
)

print('No data to upload.')
logger.log_message('No data to upload.', level=logging.WARNING)
return

# Call the Sheets API
result = (
sheet
.values()
.update(
spreadsheetId=spreadsheet_id,
range=range,
valueInputOption='USER_ENTERED',
body=body,
)
.execute()
)
# time.sleep(2)
if(result):
update_range = result["updatedRange"].split('!', 2)[1]
update_row_count = result["updatedRows"]
logger.log_message(f"google spreadsheet updated")
logger.log_message(f"range: {update_range}, rows updated: {update_row_count}")

print("Updating new values...")
# time.sleep(2)
print("\nUpdate Done!")
print("\tUpdated Range: %s" % (update_range))
print("\tUpdated Rows: %s" % update_row_count)
body = {'values': [
# [f'Rows Range: {update_range}'],
# [f'Rows Updated: {update_row_count}'],
['Status: SUCCESS'],
[f"Script Execution began at: {meta['script_start_time']} {meta['timezone']}"],
]}
if log_to_sheet:
result = (
sheet
.values()
.append(
spreadsheetId=spreadsheet_id,
range=range,
valueInputOption='USER_ENTERED',
body=body,
)
.execute()
)
elif log_to_sheet:
body = {'values': [
['Status: FAIL'],
['Reason: unable to upload data']
]}
result = (
sheet
.values()
.append(
spreadsheetId=spreadsheet_id,
range=range,
valueInputOption='USER_ENTERED',
body=body,
)
.execute()
)
except HttpError as err:
logger.log_message(err, level=logging.ERROR)
print(err)
16 changes: 16 additions & 0 deletions logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import logging
import os

def setup_logger(log_file="app.log"):
if not os.path.exists(log_file):
os.makedirs(os.path.dirname(log_file), exist_ok=True)

# Configure the logging system
logging.basicConfig(filename=log_file,
level=logging.INFO,
format="%(asctime)s - %(levelname)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S")

def log_message(message, level=logging.INFO):
# Log a message with the specified level
logging.log(level, message)
Loading

0 comments on commit d50ac2f

Please sign in to comment.