CoolFace
Apppublic

Almaatla/Standard_Intelligence_Dev

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
scrape_3gpp.py612 linesDownload Raw Back to root
1import os2import requests3from bs4 import BeautifulSoup4from urllib.parse import urljoin5import pandas as pd6import numpy as np7import zipfile8import textract9import gradio as gr10import shutil11from pypdf import PdfReader12 13def browse_folder(url):14    if url.lower().endswith(('docs', 'docs/')):15      return gr.update(choices=[])16    response = requests.get(url)17    response.raise_for_status()  # This will raise an exception if there's an error18 19    soup = BeautifulSoup(response.text, 'html.parser')20 21    excel_links = [a['href'] + '/' for a in soup.find_all('a', href=True) if a['href'].startswith(url)]22 23    return gr.update(choices=excel_links)24 25 26 27def extract_statuses(url):28    # Send a GET request to the webpage29    response = requests.get(url)30 31    # Parse the webpage content32    soup = BeautifulSoup(response.content, 'html.parser')33 34    # Find all links in the webpage35    links = soup.find_all('a')36 37    # Identify and download the Excel file38    for link in links:39        href = link.get('href')40        if href and (href.endswith('.xls') or href.endswith('.xlsx')):41            excel_url = href if href.startswith('http') else url + href42            excel_response = requests.get(excel_url)43            file_name = 'guide_status.xlsx' #excel_url.split('/')[-1]44 45            # Save the file46            with open(file_name, 'wb') as f:47                f.write(excel_response.content)48 49            # Read the Excel file50            df = pd.read_excel(file_name)51 52            # Check if 'TDoc Status' column exists and extract unique statuses53            if 'TDoc Status' in df.columns:54                unique_statuses = df['TDoc Status'].unique().tolist()55                print(f'Downloaded {file_name} and extracted statuses: {unique_statuses}')56 57 58                if 'withdrawn' in unique_statuses:59                    unique_statuses.remove('withdrawn')60                return gr.update(choices=unique_statuses, value=unique_statuses)61            else:62                print(f"'TDoc Status' column not found in {file_name}")63                return []64 65 66import os67import requests68from bs4 import BeautifulSoup69import pandas as pd70import gradio as gr71 72 73def scrape(url, folder_name, status_list, sorted_files, progress=gr.Progress()):74    filenames = []75    status_filenames = []76    df = pd.DataFrame()  # Initialize df to ensure it's always defined77    excel_file = "guide_status.xlsx"78 79    print("Downloading zip files directly from the URL...")80    response = requests.get(url)81    soup = BeautifulSoup(response.content, 'html.parser')82 83    # Select all zip files84    zip_links = [a['href'] for a in soup.find_all('a', href=True) if a['href'].endswith('.zip') ]85 86    sorted_files_tab = []87    # Check if the user selected some filters88    if len(sorted_files) != 0:89        for link in zip_links:90            for file in sorted_files:91                if file in link:92                    sorted_files_tab.append(link)93 94    if len(sorted_files_tab) != 0:95        zip_links = sorted_files_tab96 97    # Construct absolute URLs for zip files98    status_filenames = [url + link if not link.startswith('http') else link for link in zip_links]99    print(f"Filenames from URL: {status_filenames}")100 101    download_directory = folder_name102    if not os.path.exists(download_directory):103        os.makedirs(download_directory)104 105    pourcentss = 0.05106 107 108 109    # Proceed with downloading files110    for file_url in status_filenames:111 112 113        filename = os.path.basename(file_url)114        save_path = os.path.join(download_directory, filename)115        progress(pourcentss, desc='Downloading')116        pourcentss += 0.4 / max(len(status_filenames), 1)  # Ensure non-zero division117 118 119 120        try:121            with requests.get(file_url, stream=True) as r:122                r.raise_for_status()123                with open(save_path, 'wb') as f:124                    for chunk in r.iter_content(chunk_size=8192):125                        f.write(chunk)126        except requests.exceptions.HTTPError as e:127            print(f"HTTP error occurred while downloading {file_url}: {e}")128 129    return True, len(status_filenames)130 131 132 133 134 135 136def extractZip(url):137    # Répertoire où les fichiers zip sont déjà téléchargés138    nom_extract = url.split("/")[-3] + "_extraction"139    if os.path.exists(nom_extract):    140        shutil.rmtree(nom_extract)141    extract_directory = nom_extract142 143    download_directory = url.split("/")[-3] + "_downloads"144      # Répertoire où le contenu des fichiers zip sera extrait145 146    # Extraire le contenu de tous les fichiers zip dans le répertoire de téléchargement147    for zip_file in os.listdir(download_directory):148        zip_path = os.path.join(download_directory, zip_file)149        # Vérifier si le fichier est un fichier zip150        if zip_file.endswith(".zip"):151            extract_dir = os.path.join(extract_directory, os.path.splitext(zip_file)[0])  # Supprimer l'extension .zip152 153            # Vérifier si le fichier zip existe154            if os.path.exists(zip_path):155                # Créer un répertoire pour extraire le contenu s'il n'existe pas156                if not os.path.exists(extract_dir):157                    os.makedirs(extract_dir)158 159                # Extraire le contenu du fichier zip160                try:161                    with zipfile.ZipFile(zip_path, 'r') as zip_ref:162                        zip_ref.extractall(extract_dir)163    164                    print(f"Extraction terminée pour {zip_file}")165                except:166                    print(f"Erreur: Extraction {zip_file}")167            else:168                print(f"Fichier zip {zip_file} introuvable")169 170    print("Toutes les extractions sont terminées !")171 172 173def excel3gpp(url):174    response = requests.get(url)175    response.raise_for_status()  # This will raise an exception if there's an error176 177    # Use BeautifulSoup to parse the HTML content178    soup = BeautifulSoup(response.text, 'html.parser')179 180    # Look for Excel file links; assuming they have .xlsx or .xls extensions181    excel_links = [a['href'] for a in soup.find_all('a', href=True) if a['href'].endswith(('.xlsx', '.xls'))]182 183    # Download the first Excel file found (if any)184    if excel_links:185        excel_url = excel_links[0]  # Assuming you want the first Excel file186        if not excel_url.startswith('http'):187            excel_url = os.path.join(url, excel_url)  # Handle relative URLs188 189        # Download the Excel file190        excel_response = requests.get(excel_url)191        excel_response.raise_for_status()192 193        # Define the path where you want to save the file194        # Replace 'path_to_save_directory' with your desired path195 196        # Write the content of the Excel file to a local file197        # Write the content of the Excel file to a local file named 'guide.xlsx'198 199        nom_guide = 'guide.xlsx'  # Directly specify the filename200        if os.path.exists(nom_guide):201            os.remove(nom_guide)202        filepath = nom_guide203 204 205        with open(filepath, 'wb') as f:206            f.write(excel_response.content)207        print(f'Excel file downloaded and saved as: {filepath}')208 209 210 211def replace_line_breaks(text):212    return text.replace("\n", "/n")213 214def remod_text(text):215    return text.replace("/n", "\n")216 217def update_excel(data, excel_file, url):218    new_df_columns = ["URL", "File", "Type", "Title", "Source", "Related WIs", "Status", "Content"]219    temp_df = pd.DataFrame(data, columns=new_df_columns)220    221    try:222        # Check if the Excel file already exists and append data to it223        if os.path.exists(excel_file):224            old_df = pd.read_excel(excel_file)225            df = pd.concat([old_df, temp_df], axis=0, ignore_index=True)226        else:227            df = temp_df228 229        # Save the updated data back to the Excel file230        df.to_excel(excel_file, index=False)231    except Exception as e:232        print(f"Error updating Excel file: {e}")233 234def extractionPrincipale(url, excel_file=None, status_list=None, progress=gr.Progress()):235    nom_download = url.split("/")[-3] + "_downloads"236    if os.path.exists(nom_download):    237        shutil.rmtree(nom_download)238    folder_name = nom_download239 240    nom_status = url.split("/")[-3] + "_status.xlsx"241    if os.path.exists(nom_status):242        os.remove(nom_status)243    temp_excel = nom_status244 245    progress(0.0,desc='Downloading')246 247    #Sorting files, downloading only files which have the status selected by the user248    sorted_files = []249 250    try:251        guide_file = 'guide.xlsx'252        if os.path.exists(guide_file):253            dfStatus = pd.read_excel(guide_file)254 255            # Look if the user selected some filter status256            if len(dfStatus['TDoc Status'].unique().tolist()) != len (status_list):257 258 259                keys_statuses_filename = dfStatus['TDoc'].tolist()260                values_unique_statuses = dfStatus['TDoc Status'].tolist()261 262                doc_statuses = dict(zip(keys_statuses_filename, values_unique_statuses))263                for key in doc_statuses.keys():264                    if doc_statuses[key] in status_list:265                        sorted_files.append(key)266 267            print(sorted_files)268    except Exception as e:269        print(f"Not able to retrieve informations from 'guide.xlsx' ")270 271    result, count = scrape(url, folder_name, status_list, sorted_files)272    if result:273        print("Success")274    else:275        return(None)276 277    progress(0.4,desc='Extraction')278    extractZip(url)279    progress(0.5,desc='Extraction 2')280    excel3gpp(url)281    progress(0.6,desc='Creating Excel File')282 283 284    extract_directory = url.split("/")[-3] + "_extraction"285    TabCategories = ["URL", "File", "Title", "Source", "Related WIs", "Content"]286    categories = {287        "Other": TabCategories,288        "CR": TabCategories,289        "pCR": TabCategories,290        "LS": TabCategories,291        "WID": TabCategories,292        "SID": TabCategories,293        "DISCUSSION": TabCategories,294        "pdf": TabCategories,295        "ppt": TabCategories,296        "pptx": TabCategories297    }298 299    pourcents2=0.6300    data = []301    errors_count = 0302    processed_count = 0   # Counter for processed files303 304    pre_title_section = None305 306    try:307        df = pd.read_excel(temp_excel)308    except Exception as e:309        print(f"Initializing a new DataFrame because: {e}")310        df = pd.DataFrame(columns=["URL", "File", "Type", "Title", "Source", "Related WIs","Status", "Content"])311 312    for folder in os.listdir(extract_directory):313        folder_path = os.path.join(extract_directory, folder)314        if os.path.isdir(folder_path):315            for file in os.listdir(folder_path):316                progress(min(pourcents2,0.99),desc='Creating Excel File')317                pourcents2+=0.4/count318 319 320                if file == "__MACOSX":321                    continue322                file_path = os.path.join(folder_path, file)323                if file.endswith((".pptx", ".ppt", ".pdf", ".docx", ".doc", ".DOCX")):324                    try:325                        text = textract.process(file_path).decode('utf-8')326                        if file.endswith((".pdf")):327                            pdfReader = PdfReader(file_path)328                    except Exception as e:329                        print(f"Error processing {file_path}: {e}")330                        errors_count += 1331                        continue332 333                    cleaned_text_lines = text.split('\n')334                    cleaned_text = '\n'.join([line.strip('|').strip() for line in cleaned_text_lines if line.strip()])335 336                    title = ""337                    debut = ""338                    sections = cleaned_text.split("Title:")339                    if len(sections) > 1:340                        pre_title_section = sections[0].strip().split()341                        title = sections[1].strip().split("\n")[0].strip()342                        debut = sections[0].strip()343 344                    category = "Other"345                    if file.endswith(".pdf"):346                        category = "pdf"347                    elif file.endswith((".ppt", ".pptx")):348                        category = "ppt"  # assuming all ppt and pptx files go into the same category349                    elif "CHANGE REQUEST" in debut:350                        category = "CR"351                    elif "Discussion" in title:352                        category = "DISCUSSION"353                    elif "WID" in title:354                        category = "WID"355                    elif "SID" in title:356                        category = "SID"357                    elif "LS" in title:358                        category = "LS"359                    elif pre_title_section and pre_title_section[-1] == 'pCR':360                        category = "pCR"361                    elif "Pseudo-CR" in title:362                        category = "pCR"363 364 365                    contenu = ""  # This will hold the concatenated content for 'Contenu' column366                    if category in categories:367                        columns = categories[category]368                        extracted_content = []369                        if category == "CR":370                            reason_for_change = ""371                            summary_of_change = ""372                            if len(sections) > 1:373                                reason_for_change = sections[1].split("Reason for change", 1)[-1].split("Summary of change")[0].strip()374                                summary_of_change = sections[1].split("Summary of change", 1)[-1].split("Consequences if not")[0].strip()375                            extracted_content.append(f"Reason for change: {reason_for_change}")376                            extracted_content.append(f"Summary of change: {summary_of_change}")377                        elif category == "pCR":378                            if len(sections) > 1:# Handle 'pCR' category-specific content extraction379                                pcr_specific_content = sections[1].split("Introduction", 1)[-1].split("First Change")[0].strip()380                            extracted_content.append(f"Introduction: {pcr_specific_content}")381                        elif category == "LS":382                            overall_review = ""383                            if len(sections) > 1:384                                overall_review = sections[1].split("Overall description", 1)[-1].strip()385                            extracted_content.append(f"Overall review: {overall_review}")386                        elif category in ["WID", "SID"]:387                            objective = ""388                            start_index = cleaned_text.find("Objective")389                            end_index = cleaned_text.find("Expected Output and Time scale")390                            if start_index != -1 and end_index != -1:391                                objective = cleaned_text[start_index + len("Objective"):end_index].strip()392                            extracted_content.append(f"Objective: {objective}")393                        elif category == "DISCUSSION":394                            Discussion = ""395                            extracted_text = replace_line_breaks(cleaned_text)396                            start_index_doc_for = extracted_text.find("Document for:")397                            if start_index_doc_for != -1:398                                start_index_word_after_doc_for = start_index_doc_for + len("Document for:")399                                end_index_word_after_doc_for = start_index_word_after_doc_for + extracted_text[start_index_word_after_doc_for:].find("/n")400                                word_after_doc_for = extracted_text[start_index_word_after_doc_for:end_index_word_after_doc_for].strip()401                                result_intro = ''402                                result_conclusion = ''403                                result_info = ''404                                if word_after_doc_for.lower() == "discussion":405                                    start_index_intro = extracted_text.find("Introduction")406                                    end_index_intro = extracted_text.find("Discussion", start_index_intro)407 408                                    intro_text = ""409                                    if start_index_intro != -1 and end_index_intro != -1:410                                        intro_text = extracted_text[start_index_intro + len("Introduction"):end_index_intro].strip()411                                        result_intro = remod_text(intro_text)  # Convert back line breaks412                                    else:413                                        result_intro = "Introduction section not found."414 415                                    # Attempt to find "Conclusion"416                                    start_index_conclusion = extracted_text.find("Conclusion", end_index_intro)417                                    end_index_conclusion = extracted_text.find("Proposal", start_index_conclusion if start_index_conclusion != -1 else end_index_intro)418 419                                    conclusion_text = ""420                                    if start_index_conclusion != -1 and end_index_conclusion != -1:421                                        conclusion_text = extracted_text[start_index_conclusion + len("Conclusion"):end_index_conclusion].strip()422                                        result_conclusion = remod_text(conclusion_text)423                                    elif start_index_conclusion == -1:  # Conclusion not found, look for Proposal directly424                                        start_index_proposal = extracted_text.find("Proposal", end_index_intro)425                                        if start_index_proposal != -1:426                                            end_index_proposal = len(extracted_text)  # Assuming "Proposal" section goes till the end if present427                                            proposal_text = extracted_text[start_index_proposal + len("Proposal"):end_index_proposal].strip()428                                            result_conclusion = remod_text(proposal_text)  # Using "Proposal" content as "Conclusion"429                                        else:430                                            result_conclusion = "Conclusion/Proposal section not found."431                                    else:432                                        # Handle case where "Conclusion" exists but no "Proposal" to mark its end433                                        conclusion_text = extracted_text[start_index_conclusion + len("Conclusion"):].strip()434                                        result_conclusion = remod_text(conclusion_text)435                                    Discussion=f"Introduction: {result_intro}\nConclusion/Proposal: {result_conclusion}"436                                elif word_after_doc_for.lower() == "information":437                                    start_index_info = extracted_text.find(word_after_doc_for)438                                    if start_index_info != -1:439                                        info_to_end = extracted_text[start_index_info + len("Information"):].strip()440                                        result_info = remod_text(info_to_end)441                                    Discussion = f"Discussion:{result_info}"442                                else:443                                    Discussion = "The word after 'Document for:' is not 'Discussion', 'DISCUSSION', 'Information', or 'INFORMATION'."444                            else:445                                Discussion = "The phrase 'Document for:' was not found."446                            # Since DISCUSSION category handling requires more specific processing, adapt as necessary447                            # Here's a simplified example448                            discussion_details = Discussion449                            extracted_content.append(discussion_details)450 451                        elif category == "pdf":452                            try:453                                tabLine = []454                                file = pdfReader455                                pdfNumberPages = len(file.pages)456                                words_limit = 1000457                                for pdfPage in range(0, pdfNumberPages):458                        459                                    load_page = file.get_page(pdfPage)460                                    text = load_page.extract_text()461                                    lines = text.split("\n")462                                    sizeOfLines = len(lines) - 1463                                    keyword = ["objective", "introduction", "summary", "scope"]464                        465                                    for index, line in enumerate(lines):466                                        print(line)467                                        for key in keyword:468                                            line = line.lower()469                        470                                            if key in line:471                                                print("Found keyword")472                                                lineBool = True473                                                lineIndex = index474                                                previousSelectedLines = []475                                                stringLength = 0476                                                linesForSelection = lines477                                                loadOnce = True478                                                selectedPdfPage = pdfPage479                        480                                                while lineBool:481                                                    print(lineIndex)482                                                    if stringLength > words_limit or lineIndex < 0:483                                                        lineBool = False484                                                    else:485                                                        if lineIndex == 0:486                                                            print(f"Line index == 0")487                        488                                                            if pdfPage == 0:489                                                                lineBool = False490                        491                                                            else:492                                                                try:493                                                                    selectedPdfPage -= 1494                                                                    newLoad_page = file.get_page(selectedPdfPage)495                                                                    newText = newLoad_page.extract_text()496                                                                    newLines = newText.split("\n")497                                                                    linesForSelection = newLines498                                                                    print(f"len newLines{len(newLines)}")499                                                                    lineIndex = len(newLines) - 1500                                                                except Exception as e:501                                                                    print(f"Loading previous PDF page failed")502                                                                    lineBool = False503                        504                                                        previousSelectedLines.append(linesForSelection[lineIndex])505                                                        stringLength += len(linesForSelection[lineIndex])506                        507                                                        lineIndex -= 1508                                                previousSelectedLines = ' '.join(previousSelectedLines[::-1])509                        510                                                lineBool = True511                                                lineIndex = index + 1512                                                nextSelectedLines = ""513                                                linesForSelection = lines514                                                loadOnce = True515                                                selectedPdfPage = pdfPage516                        517                                                while lineBool:518                        519                                                    if len(nextSelectedLines.split()) > words_limit:520                                                        lineBool = False521                                                    else:522                                                        if lineIndex > sizeOfLines:523                                                            lineBool = False524                        525                                                            if pdfPage == pdfNumberPages - 1:526                                                                lineBool = False527                        528                                                            else:529                                                                try:530                                                                    selectedPdfPage += 1531                                                                    newLoad_page = file.get_page(selectedPdfPage)532                                                                    newText = newLoad_page.extract_text()533                                                                    newLines = newText.split("\n")534                                                                    linesForSelection = newLines535                                                                    lineIndex = 0536                                                                except Exception as e:537                                                                    print(f"Loading next PDF page failed")538                                                                    lineBool = False539                                                        else:540                                                            nextSelectedLines += " " + linesForSelection[lineIndex]541                                                        lineIndex += 1542                        543                                                print(f"Previous Lines : {previousSelectedLines}")544                                                print(f"Next Lines : {nextSelectedLines}")545                                                selectedText = previousSelectedLines + ' ' + nextSelectedLines546                                                print(selectedText)547                                                tabLine.append([pdfPage, selectedText, key])548                                                print(f"Selected line in keywords is: {line}")549                        550                                for r in tabLine:551                                    extracted_content.append(f'PDF Page number {r[0]} extracted text from the KEYWORD {r[2]} : \n')552                                    extracted_content.append(''.join(r[1])) 553                            except Exception as e:554                                print(f"Error occured while extracting PDF content : {e}")555                        # Add more categories as needed556                        contenu = "\n".join(extracted_content)557 558                    # Assuming 'source' needs to be filled from the guide.xlsx mapping559                    # Placeholder for source value calculation560                    source = ""  # Update this with actual source determination logic561                    RelatedWIs = ""562                    status = ""563                    data.append([url+ "/" + folder + '.zip', folder , category, title, source, RelatedWIs, status, contenu])564 565                    guide_file = 'guide.xlsx'566                    if os.path.exists(guide_file):567                        # If guide.xlsx exists, proceed with operations that require it568                        try:569                            guide_df = pd.read_excel(guide_file, usecols=['Source', 'TDoc', 'Related WIs', 'TDoc Status'])570                            # Continue with the operations that require guide.xlsx571                            # For example, reading the file, processing the data, etc.572                            tdoc_source_map = {row['TDoc']: row['Source'] for index, row in guide_df.iterrows()}573                            tdoc_relatedWIs_map = {row['TDoc']: row['Related WIs'] for index, row in guide_df.iterrows()}574                            tdoc_status_map = {row['TDoc']: row['TDoc Status'] for index, row in guide_df.iterrows()}575                            # Update the 'Source' in your data based on matching 'Nom du fichier' with 'TDoc'576                            for item in data:577                                nom_du_fichier = item[1]  # Assuming 'Nom du fichier' is the first item in your data list578                                if nom_du_fichier in tdoc_source_map:579                                    item[4] = tdoc_source_map[nom_du_fichier]  # Update the 'Source' field, assuming it's the fourth item580                                    item[5] = tdoc_relatedWIs_map[nom_du_fichier]581                                    item[6] = tdoc_status_map[nom_du_fichier]582                            # Your code that depends on guide.xlsx goes here583                            584                        except Exception as e:585                            print(f"An error occurred while processing {guide_file}: {e}")586                            # Handle any errors that arise during processing587                    else:588                        print(f"File {guide_file} not found. Skipping operations that require this file.")589                        # Since guide.xlsx is not found, skip the related operations590                        591                        592                    593 594 595                    processed_count += 1596 597                # Check if it's time to update the Excel file598                    if processed_count % 20 == 0:599                        update_excel(data, temp_excel, url)600                        print(f"Updated after processing {processed_count} files.")601                        data = []  # Clear the data list after updating602 603    if data:604    # This final call ensures that any remaining data is processed and saved.605        update_excel(data, temp_excel, url)606        print(f"Final update after processing all files.")607 608    file_name = temp_excel609    # Save the updated DataFrame to Excel610    return file_name611 612