Skip to content

Commit

Permalink
Done google sheet parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Impervguin committed Oct 14, 2024
1 parent f73c26a commit 8041f21
Show file tree
Hide file tree
Showing 8 changed files with 556 additions and 0 deletions.
8 changes: 8 additions & 0 deletions googleimport/achievement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@


class Achievement:
def __init__(self, count : str, description : str):
self.count = count
self.description = description


58 changes: 58 additions & 0 deletions googleimport/googleloader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseDownload
import os

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ["https://www.googleapis.com/auth/drive.readonly"]

class GoogleFile:
def __init__(self, id: str, name: str, mimeType: str):
self.Id = id
self.Name = name
self.MimeType = mimeType

class GoogleLoader:
def __init__(self, creds):
self.service = build("drive", "v3", credentials=creds)

def DownloadBlobFile(self, googleFileId, filename):
req = self.service.files().get_media(
fileId = googleFileId,
supportsAllDrives=True,
)
with open(filename, 'wb') as saveFile:
downloader = MediaIoBaseDownload(saveFile, req)
done = False
while not done:
_, done = downloader.next_chunk()

def GetFileInfo(self, googleFileId) -> GoogleFile:
req = self.service.files().get(
fileId=googleFileId,
supportsAllDrives=True,
).execute()
return GoogleFile(
id=req["id"],
name=req["name"],
mimeType=req["mimeType"]
)

def GetSharedDriveFiles(self, googleDriveId) -> list[GoogleFile] :
req = (self.service.files()
.list(q=f"'{googleDriveId}' in parents", supportsAllDrives=True, includeItemsFromAllDrives=True,)
.execute())
files = req.get("files", [])
resFiles = []
for f in files:
resFiles.append(GoogleFile(
id=f['id'],
name=f['name'],
mimeType=f['mimeType']
))
return resFiles



138 changes: 138 additions & 0 deletions googleimport/googlesheet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from googleapiclient.discovery import build
import os.path
import utils
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

SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"]
ALPHABET = {chr(i): i - ord('A') + 1 for i in range(ord('A'), ord('Z') + 1)}
REVERSE_ALPHABET = {i + 1: chr(i + ord('A')) for i in range(26)}
class GoogleCellAddress:
def __init__(self, addr : str):
addr = addr.upper()
self.column = 0
self.row = 0
columnPart = ""
for i in range(len(addr)):
if addr[i] in ALPHABET:
columnPart += addr[i]
else:
self.row = int(addr[i:])
break
pow = 26 ** (len(columnPart) - 1)
for el in columnPart:
self.column += pow * ALPHABET[el]
pow //= 26


def ToGoogleCell(self):
column = self.column
addr = ""
while column > 0:
if column % 26 == 0:
addr = REVERSE_ALPHABET[26] + addr
column //= 26
column -= 1
else:
addr = REVERSE_ALPHABET[column % 26] + addr
column //= 26
addr += str(self.row)
return addr

def GetColumn(self):
return self.column

def GetRow(self):
return self.row

@staticmethod
def Difference(cell1, cell2):
return cell1.column - cell2.column, cell1.row - cell2.row

def __str__(self):
return f"{'{'}Column: {self.column}, Row: {self.row}.{'}'}"

class GoogleSheetRange:
def __init__(self, values, cellStart: GoogleCellAddress, cellEnd: GoogleCellAddress):
self. valuesMatrix = values
if values == None:
raise ValueError("values must be specified")
self.cellStart = cellStart
self.cellEnd = cellEnd
self.cols, self.rows = GoogleCellAddress.Difference(self.cellEnd, self.cellStart)
self.cols += 1
self.rows += 1
if self.cols <= 0 or self.rows <= 0:
raise ValueError("Incorrect range values")

def Rows(self):
return self.rows

def Cols(self):
return self.cols

def NonEmptyRows(self):
return len(self.valuesMatrix)

def GetCell(self, address: str) -> str:
googleAddress = GoogleCellAddress(address)
col, row = GoogleCellAddress.Difference(googleAddress, self.cellStart)
if row < 0 or row >= self.rows or col < 0 or col >= self.cols:
raise IndexError(f"Address out of range: {address}")
if row >= len(self.valuesMatrix):
return ""
if col >= len(self.valuesMatrix[row]):
return ""
return self.valuesMatrix[row][col]

def __getitem__(self, index: str):
return self.GetCell(index)

class GoogleSpreadsheet:
def __init__(self, spreadsheetId, creds):
self.service = build("sheets", "v4", credentials=creds)
self.spreadsheetGoogleID = spreadsheetId

def GetTableSizes(self, tableName: str) -> tuple[int, int]:
spreadsheets = self.service.spreadsheets().get(spreadsheetId=self.spreadsheetGoogleID).execute()
for spreadsheet in spreadsheets['sheets']:
if spreadsheet['properties']['title'] == tableName:
sheet = spreadsheet
break
else:
raise ValueError(f"No {tableName} table found.")

rowCount = sheet['properties']['gridProperties']['rowCount']
colCount = sheet['properties']['gridProperties']['columnCount']
return rowCount, colCount

def GetTableRange(self, tableName: str, cellStart: str, cellEnd: str):
cellS = GoogleCellAddress(cellStart)
cellE = GoogleCellAddress(cellEnd)
if any([el < 0 for el in GoogleCellAddress.Difference(cellE, cellS)]):
raise ValueError(f"invalid range {cellS.ToGoogleCell()}:{cellE.ToGoogleCell()}")

dataRange = f"{tableName}!{cellS.ToGoogleCell()}:{cellE.ToGoogleCell()}"

data = self.service.spreadsheets().values().get(
spreadsheetId=self.spreadsheetGoogleID,
range=dataRange).execute()

if data == None:
raise RuntimeError(f"can't get table {dataRange} from spreadsheet {self.spreadsheetGoogleID}")

return GoogleSheetRange(values=data['values'], cellStart=cellS, cellEnd=cellE)











23 changes: 23 additions & 0 deletions googleimport/member.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import utils
class Member:
def __init__(self, name, photoUrl, telegram, vk, roleName, roleSpec, roleField):
try:
self.photoGoogleId = utils.ParseSharedFileID(photoUrl)
except ValueError: # Incorrect photo url
self.photoGoogleId = None
self.osPhotoPath = None
self.name = name
self.telegram = telegram
self.vk = vk
self.roleName = roleName
self.roleSpec = roleSpec
self.roleField = roleField

def GetPhotoGoogleId(self):
return self.photoGoogleId

def SetOsPhotoPath(self, path):
self.osPhotoPath = path

def GetName(self):
return self.name
35 changes: 35 additions & 0 deletions googleimport/organisation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import os.path
import utils
from member import Member
from achievement import Achievement

class Organization:
def __init__(self):
self.ClubId = None
self.ClubType = ""
self.Name = ""
self.ShortName = ""
self.ShortDescription = ""
self.Description = ""
self.Telegram = ""
self.Vk = ""
self.PhotoFolderGoogleID = ""
self.LogoGoogleID = None
self.OsLogoPath = None
self.OsPhotosPath = None
self.Members = []
self.Achievements = []

def AddMember(self, member: Member):
self.Members.append(member)

def AddAchievement(self, achievement: Achievement):
self.Achievements.append(achievement)

def DeleteMember(self, member: Member):
self.Members.remove(member)

def DeleteAchievement(self, achievement: Achievement):
self.Achievements.remove(achievement)


Loading

0 comments on commit 8041f21

Please sign in to comment.