File size: 10,717 Bytes
de01ad6
79491a7
de01ad6
 
 
 
02315b3
de01ad6
 
79491a7
de01ad6
 
 
25c6fdf
 
 
 
 
de01ad6
 
 
 
 
 
 
 
 
 
 
 
3e0537a
26e101f
3e0537a
26e101f
3e0537a
26e101f
3e0537a
26e101f
de01ad6
 
 
 
d296363
de01ad6
 
 
 
 
 
 
 
e87d72f
de01ad6
 
e87d72f
 
 
 
4d3ac9f
 
 
 
 
 
 
 
e87d72f
 
 
4d3ac9f
e87d72f
 
 
 
 
 
79491a7
 
 
 
 
 
e87d72f
de01ad6
e87d72f
30740d5
02315b3
 
4d3ac9f
 
02315b3
 
 
 
 
78977a5
02315b3
 
9c2f520
79491a7
 
 
 
 
 
 
02315b3
dcbf4f3
ac50c2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d3ac9f
167b29b
190fcf3
167b29b
 
 
 
 
 
 
 
 
 
 
02315b3
167b29b
4e03c68
167b29b
 
 
da15a76
167b29b
 
be64d63
167b29b
2e46553
 
 
 
 
 
 
 
 
 
190fcf3
2e46553
 
 
de01ad6
 
 
 
1f8073d
 
 
 
 
 
02315b3
 
 
 
 
1f8073d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
de01ad6
02315b3
e87d72f
 
 
02315b3
dcbf4f3
79491a7
e87d72f
02315b3
e87d72f
 
02315b3
e87d72f
30740d5
e87d72f
 
 
dcbf4f3
e87d72f
78977a5
b30536e
5844e99
 
 
 
 
 
ac50c2d
 
 
 
 
 
 
5844e99
ac50c2d
5844e99
ac50c2d
 
 
 
 
 
 
 
 
 
 
5844e99
de01ad6
 
 
 
c99fc58
9c2f520
02315b3
dcbf4f3
79491a7
25c6fdf
5844e99
ac50c2d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import os
import zipfile
import pandas as pd
import gradio as gr
from helper import assign_main_accounts, generate_schedule, save_processed_files

# Global Constants
UPLOAD_FOLDER = "uploads"
PROCESSED_FOLDER = "processed"
ZIP_FILE = "processed_files.zip"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(PROCESSED_FOLDER, exist_ok=True)

# Create an empty ZIP file if it doesn't exist
if not os.path.exists(ZIP_FILE):
    with zipfile.ZipFile(ZIP_FILE, "w") as zipf:
        pass

USERNAME = "admin"
PASSWORD = "password123"

# Helper Functions
def login(username, password):
    if username == USERNAME and password == PASSWORD:
        return "Login Successful!", True
    else:
        return "Invalid credentials. Try again.", False

def upload_files(creators_file, overnight_file, day_file, prime_file):
    try:
        with open(os.path.join(UPLOAD_FOLDER, "creators_file.xlsx"), "wb") as f:
            f.write(creators_file)
        with open(os.path.join(UPLOAD_FOLDER, "overnight_file.xlsx"), "wb") as f:
            f.write(overnight_file)
        with open(os.path.join(UPLOAD_FOLDER, "day_file.xlsx"), "wb") as f:
            f.write(day_file)
        with open(os.path.join(UPLOAD_FOLDER, "prime_file.xlsx"), "wb") as f:
            f.write(prime_file)
        return "Files uploaded successfully!"
    except Exception as e:
        return f"Error uploading files: {e}"

def generate_main_accounts():
    creators_file = os.path.join(UPLOAD_FOLDER, "creators_file.xlsx")
    chatter_files = [
        os.path.join(UPLOAD_FOLDER, "overnight_file.xlsx"),
        os.path.join(UPLOAD_FOLDER, "day_file.xlsx"),
        os.path.join(UPLOAD_FOLDER, "prime_file.xlsx"),
    ]

    if not all(os.path.exists(path) for path in [creators_file] + chatter_files):
        return "Missing required files. Please upload all necessary files.", None, None

    try:
        updated_chatter_files, processed_creator_file, combined_assignments = assign_main_accounts(
            creators_file, chatter_files
        )

        # Add the `Shift` column to the combined assignments
        shifts = ["Overnight", "Day", "Prime"]
        for idx, chatter_df in enumerate(updated_chatter_files):
            chatter_df["Shift"] = shifts[idx]
            updated_chatter_files[idx] = chatter_df

        combined_assignments = pd.concat(updated_chatter_files)

        # Save updated files
        for idx, chatter_df in enumerate(updated_chatter_files):
            chatter_df.to_excel(
                os.path.join(PROCESSED_FOLDER, f"Updated_{shifts[idx].lower()}_file.xlsx"),
                index=False
            )
        processed_creator_file.to_excel(
            os.path.join(PROCESSED_FOLDER, "creators_file.xlsx"), index=False
        )

        # Create a zip file containing all processed files
        with zipfile.ZipFile(ZIP_FILE, "w") as zipf:
            for root, _, files in os.walk(PROCESSED_FOLDER):
                for file in files:
                    zipf.write(os.path.join(root, file), arcname=file)

        return "Main accounts generated successfully!", combined_assignments, processed_creator_file
    except Exception as e:
        return f"Error during main account generation: {e}", None, None

def update_assignments(assignments_df, creators_df):
    try:
        print("DEBUG: Assignments DataFrame Columns:", assignments_df.columns)

        shifts = ["Overnight", "Day", "Prime"]
        for shift in shifts:
            shift_data = assignments_df[assignments_df["Shift"] == shift]
            shift_file_path = os.path.join(PROCESSED_FOLDER, f"Updated_{shift.lower()}_file.xlsx")
            shift_data.to_excel(shift_file_path, index=False)

        creators_file_path = os.path.join(PROCESSED_FOLDER, "creators_file.xlsx")
        creators_df.to_excel(creators_file_path, index=False)

        # Update the ZIP file with the latest files
        with zipfile.ZipFile(ZIP_FILE, "w") as zipf:
            for root, _, files in os.walk(PROCESSED_FOLDER):
                for file in files:
                    zipf.write(os.path.join(root, file), arcname=file)

        return "Assignments and Creator File updated successfully!", ZIP_FILE
    except Exception as e:
        return f"Error updating assignments: {e}", None
        
def update_and_download_schedule(overnight_df, day_df, prime_df):
    try:
        # Save updated schedules to the processed folder
        overnight_path = os.path.join(PROCESSED_FOLDER, "Updated_Overnight_Schedule.xlsx")
        day_path = os.path.join(PROCESSED_FOLDER, "Updated_Day_Schedule.xlsx")
        prime_path = os.path.join(PROCESSED_FOLDER, "Updated_Prime_Schedule.xlsx")
        
        overnight_df.to_excel(overnight_path, index=False)
        day_df.to_excel(day_path, index=False)
        prime_df.to_excel(prime_path, index=False)

        # Zip the updated files for download
        with zipfile.ZipFile(ZIP_FILE, "w") as zipf:
            zipf.write(overnight_path, arcname="Updated_Overnight_Schedule.xlsx")
            zipf.write(day_path, arcname="Updated_Day_Schedule.xlsx")
            zipf.write(prime_path, arcname="Updated_Prime_Schedule.xlsx")

        return "Schedules updated and saved successfully!", ZIP_FILE
    except Exception as e:
        return f"Error updating schedules: {e}", None

def generate_full_schedule(creators_file_path, overnight_file_path, day_file_path, prime_file_path):
    try:
        # Log file paths for debugging
        print(f"DEBUG: Creators File Path: {creators_file_path}")
        print(f"DEBUG: Overnight File Path: {overnight_file_path}")
        print(f"DEBUG: Day File Path: {day_file_path}")
        print(f"DEBUG: Prime File Path: {prime_file_path}")

        # Read files
        creators_data = pd.read_excel(creators_file_path)
        overnight_data = pd.read_excel(overnight_file_path)
        day_data = pd.read_excel(day_file_path)
        prime_data = pd.read_excel(prime_file_path)

        print("DEBUG: Creators File Columns:", creators_data.columns)

        # Validate structure
        if not {"Creator", "ActiveFans"}.issubset(creators_data.columns):
            raise KeyError("The account data must contain 'Creator' and 'ActiveFans' columns.")

        # Pass data to generate_schedule
        chatter_files = [overnight_data, day_data, prime_data]
        full_schedule = generate_schedule(chatter_files, creators_data)

        # Extract individual schedules
        overnight_schedule = full_schedule["Overnight"]
        day_schedule = full_schedule["Day"]
        prime_schedule = full_schedule["Prime"]

        print("DEBUG: Overnight Schedule:", overnight_schedule.head())
        print("DEBUG: Day Schedule:", day_schedule.head())
        print("DEBUG: Prime Schedule:", prime_schedule.head())

        return overnight_schedule, day_schedule, prime_schedule
    except Exception as e:
        print(f"DEBUG: Error in generate_full_schedule: {e}")
        return f"Error generating schedule: {e}", None, None


# Gradio Interface
def app():
    with gr.Blocks() as interface:
        with gr.Tab("Login"):
            username = gr.Textbox(label="Username")
            password = gr.Textbox(label="Password", type="password")
            login_btn = gr.Button("Login")
            login_status = gr.Textbox(label="Login Status", interactive=False)

            login_btn.click(
                login,
                inputs=[username, password],
                outputs=[login_status],
            )

        with gr.Tab("Upload Files"):
            creators_file = gr.File(label="Creators File", type="binary")
            overnight_file = gr.File(label="Overnight File", type="binary")
            day_file = gr.File(label="Day File", type="binary")
            prime_file = gr.File(label="Prime File", type="binary")
            upload_btn = gr.Button("Upload Files")
            upload_status = gr.Textbox(label="Upload Status", interactive=False)

            upload_btn.click(
                upload_files,
                inputs=[creators_file, overnight_file, day_file, prime_file],
                outputs=[upload_status],
            )

        with gr.Tab("Generate Main Accounts"):
            generate_main_status = gr.Textbox(label="Status", interactive=False)
            assignments_preview = gr.Dataframe(label="Main Account Assignments Preview", interactive=True)
            creators_preview = gr.Dataframe(label="Processed Creator File Preview", interactive=True)

            generate_main_btn = gr.Button("Generate Main Accounts")
            update_btn = gr.Button("Update and Download Files")
            download_zip_btn = gr.File(label="Download Processed Files", value=ZIP_FILE)

            generate_main_btn.click(
                generate_main_accounts,
                inputs=[],
                outputs=[generate_main_status, assignments_preview, creators_preview],
            )

            update_btn.click(
                update_assignments,
                inputs=[assignments_preview, creators_preview],
                outputs=[generate_main_status, download_zip_btn],
            )

        with gr.Tab("Generate Full Schedule"):
            creators_file = gr.File(label="Creators File", type="binary")
            overnight_file = gr.File(label="Overnight File", type="binary")
            day_file = gr.File(label="Day File", type="binary")
            prime_file = gr.File(label="Prime File", type="binary")

            generate_schedule_btn = gr.Button("Generate Full Schedule")
            overnight_schedule_output = gr.Dataframe(label="Overnight Schedule", interactive=True)
            day_schedule_output = gr.Dataframe(label="Day Schedule", interactive=True)
            prime_schedule_output = gr.Dataframe(label="Prime Schedule", interactive=True)

            update_schedule_btn = gr.Button("Update and Download Schedule")
            download_schedule_btn = gr.File(label="Download Updated Schedules", value=ZIP_FILE)
            update_status = gr.Textbox(label="Update Status", interactive=False)

            # Generate Schedule
            generate_schedule_btn.click(
                generate_full_schedule,
                inputs=[creators_file, overnight_file, day_file, prime_file],
                outputs=[overnight_schedule_output, day_schedule_output, prime_schedule_output]
            )

            # Update and Download Schedule
            update_schedule_btn.click(
                update_and_download_schedule,
                inputs=[overnight_schedule_output, day_schedule_output, prime_schedule_output],
                outputs=[update_status, download_schedule_btn]
            )

    return interface

if __name__ == "__main__":
    app().launch()