1+ import smartsheet
2+ from datetime import datetime , timedelta
3+
4+ # Configuration
5+ SMARTSHEET_TOKEN = 'j4fc01RK42GEZuxlRP49zCBYnlwMr3HwjYXsz'
6+ SMARTSHEET_ID = '5CRwhFxhPX7pfvcQ6PVRx7VX8ggpW7JPfh4xfHx1'
7+
8+ def get_week_range (date ):
9+ """
10+ Get the start (Monday) and end (Sunday) of the week for a given date
11+ """
12+ start = date - timedelta (days = date .weekday ())
13+ end = start + timedelta (days = 6 )
14+ return start , end
15+
16+ def validate_credentials (access_token , sheet_id ):
17+ """
18+ Validate Smartsheet credentials before proceeding
19+ """
20+ try :
21+ print ("Validating Smartsheet credentials..." )
22+ smartsheet_client = smartsheet .Smartsheet (access_token )
23+ smartsheet_client .errors_as_exceptions (True )
24+
25+ # Try to get current user info to validate token
26+ current_user = smartsheet_client .Users .get_current_user ()
27+ print (f"✓ Access token valid - Authenticated as: { current_user .email } " )
28+
29+ # Try to access the sheet to validate sheet ID
30+ sheet = smartsheet_client .Sheets .get_sheet (sheet_id )
31+ print (f"✓ Sheet ID valid - Sheet name: { sheet .name } " )
32+ print (f"✓ Sheet has { sheet .total_row_count } rows and { len (sheet .columns )} columns" )
33+
34+ return True
35+
36+ except smartsheet .exceptions .ApiError as e :
37+ if e .error .result .status_code == 401 :
38+ print ("✗ Authentication failed - Invalid access token" )
39+ elif e .error .result .status_code == 404 :
40+ print ("✗ Sheet not found - Invalid sheet ID or no access" )
41+ else :
42+ print (f"✗ API Error: { e .error .result .message } " )
43+ return False
44+ except Exception as e :
45+ print (f"✗ Unexpected error: { str (e )} " )
46+ return False
47+
48+ def get_smartsheet_releases (access_token , sheet_id ):
49+ """
50+ Fetch release version, start date, and end date from Smartsheet
51+ Filter for current week and next week only
52+ """
53+ # Initialize Smartsheet client
54+ smartsheet_client = smartsheet .Smartsheet (access_token )
55+ smartsheet_client .errors_as_exceptions (True )
56+
57+ # Get the sheet
58+ sheet = smartsheet_client .Sheets .get_sheet (sheet_id )
59+
60+ # Extract column names and find target columns
61+ columns = {col .id : col .title for col in sheet .columns }
62+ column_ids = {title .lower (): col_id for col_id , title in columns .items ()}
63+
64+ # Debug: Print all column names
65+ print ("\n 📋 Available columns in sheet:" )
66+ for col_id , col_title in columns .items ():
67+ print (f" - Column Name : { col_title } " )
68+ print ()
69+
70+ # Get current date and week ranges
71+ today = datetime .now ().date ()
72+ current_week_start , current_week_end = get_week_range (today )
73+ next_week_start = current_week_start + timedelta (days = 7 )
74+ next_week_end = current_week_end + timedelta (days = 7 )
75+
76+ print (f"Today: { today } " )
77+ print (f"Current Week: { current_week_start } to { current_week_end } " )
78+ print (f"Next Week: { next_week_start } to { next_week_end } " )
79+ print ("=" * 60 )
80+
81+ # Extract row data
82+ releases = []
83+ rows_processed = 0
84+
85+ for row in sheet .rows :
86+ # Skip row if all cells are empty
87+ if all (
88+ (getattr (cell , "display_value" , None ) in [None , "" ] and getattr (cell , "value" , None ) in [None , "" ])
89+ for cell in row .cells
90+ ):
91+ continue
92+
93+ rows_processed += 1
94+ row_data = {}
95+ for cell in row .cells :
96+ column_name = columns [cell .column_id ].lower ()
97+ print (f" { column_name } : { getattr (cell , 'display_value' , None )} | { getattr (cell , 'value' , None )} " )
98+
99+ # Look for release version, start date, and end date columns
100+ if 'release' in column_name or 'version' in column_name :
101+ row_data ['release_version' ] = cell .display_value if cell .display_value else cell .value
102+ row_data ['release_column' ] = columns [cell .column_id ]
103+ elif 'start' in column_name and 'date' in column_name :
104+ row_data ['start_date' ] = cell .value
105+ row_data ['start_column' ] = columns [cell .column_id ]
106+ elif 'end' in column_name and 'date' in column_name :
107+ row_data ['end_date' ] = cell .value
108+ row_data ['end_column' ] = columns [cell .column_id ]
109+
110+ # Only process rows that have all required fields
111+ if all (key in row_data for key in ['release_version' , 'start_date' , 'end_date' ]):
112+ try :
113+ # Parse dates - handle different date formats
114+ if isinstance (row_data ['start_date' ], str ):
115+ # Try different date formats
116+ for date_format in ['%Y-%m-%d' , '%m/%d/%Y' , '%d/%m/%Y' , '%Y-%m-%dT%H:%M:%S' ]:
117+ try :
118+ start_date = datetime .strptime (row_data ['start_date' ], date_format ).date ()
119+ break
120+ except ValueError :
121+ continue
122+ else :
123+ print (f"⚠️ Could not parse start_date: { row_data ['start_date' ]} " )
124+ continue
125+ else :
126+ start_date = row_data ['start_date' ]
127+
128+ if isinstance (row_data ['end_date' ], str ):
129+ for date_format in ['%Y-%m-%d' , '%m/%d/%Y' , '%d/%m/%Y' , '%Y-%m-%dT%H:%M:%S' ]:
130+ try :
131+ end_date = datetime .strptime (row_data ['end_date' ], date_format ).date ()
132+ break
133+ except ValueError :
134+ continue
135+ else :
136+ print (f"⚠️ Could not parse end_date: { row_data ['end_date' ]} " )
137+ continue
138+ else :
139+ end_date = row_data ['end_date' ]
140+
141+ # Check if the release falls in current week or next week
142+ if (current_week_start <= start_date <= next_week_end ) or \
143+ (current_week_start <= end_date <= next_week_end ) or \
144+ (start_date <= current_week_start and end_date >= next_week_end ):
145+ releases .append ({
146+ 'release_version' : row_data ['release_version' ],
147+ 'start_date' : start_date ,
148+ 'end_date' : end_date
149+ })
150+ print (f"✓ Matched release: { row_data ['release_version' ]} " )
151+ except (ValueError , TypeError ) as e :
152+ # Skip rows with invalid dates
153+ print (f"⚠️ Error processing row: { e } " )
154+ continue
155+
156+ print (f"\n 📊 Processed { rows_processed } rows total" )
157+ return releases
158+
159+ def main ():
160+ """
161+ Main function to fetch and display releases for current and next week
162+ """
163+ try :
164+ # Validate credentials first
165+ if not validate_credentials (SMARTSHEET_TOKEN , SMARTSHEET_ID ):
166+ print ("\n ❌ Credential validation failed. Please check your access token and sheet ID." )
167+ return
168+
169+ print ("\n " + "=" * 60 )
170+ print ("Fetching releases from Smartsheet...\n " )
171+ releases = get_smartsheet_releases (SMARTSHEET_TOKEN , SMARTSHEET_ID )
172+
173+ if not releases :
174+ print ("No releases found for current week or next week." )
175+ else :
176+ print (f"\n Found { len (releases )} release(s) for current and next week:\n " )
177+ for i , release in enumerate (releases , 1 ):
178+ print (f"{ i } . Release Version: { release ['release_version' ]} " )
179+ print (f" Start Date: { release ['start_date' ]} " )
180+ print (f" End Date: { release ['end_date' ]} " )
181+ print ("-" * 60 )
182+
183+ except Exception as e :
184+ print (f"Error: { str (e )} " )
185+ raise
186+
187+ if __name__ == "__main__" :
188+ main ()
0 commit comments