iman
Advanced tools
+232
| from docx import Document | ||
| from docx.shared import Pt, RGBColor | ||
| from docx.shared import Cm, Inches | ||
| from docx.enum.text import WD_ALIGN_PARAGRAPH | ||
| from docx.oxml import OxmlElement | ||
| from docx.oxml.ns import qn | ||
| import os | ||
| import xml.etree.ElementTree as ET | ||
| # Try to import win32com for page counting | ||
| try: | ||
| import win32com.client | ||
| import pythoncom | ||
| WIN32COM_AVAILABLE = True | ||
| except ImportError: | ||
| WIN32COM_AVAILABLE = False | ||
| print("Warning: win32com not available. Install with: pip install pywin32") | ||
| def apply_rtl_style(p, intext, color_is, font_is, size_is, isbold=False, add_bullet=False): | ||
| """ | ||
| Apply RTL style to a paragraph with the given text and formatting | ||
| """ | ||
| p._p.get_or_add_pPr().append(OxmlElement('w:bidi')) | ||
| if add_bullet: | ||
| run_bullet = p.add_run('• ') | ||
| run_bullet.font.color.rgb = RGBColor(0, 0, 255) # blue bullet | ||
| rPr = run_bullet._element.get_or_add_rPr() | ||
| rFonts = rPr.get_or_add_rFonts() | ||
| rFonts.set(qn('w:cs'), font_is) | ||
| rFonts.set(qn('w:eastAsia'), font_is) | ||
| szCs = OxmlElement('w:szCs') | ||
| szCs.set(qn('w:val'), size_is) | ||
| rPr.append(szCs) | ||
| rtl = OxmlElement('w:rtl') | ||
| rPr.append(rtl) | ||
| run_fa = p.add_run(intext) | ||
| run_fa.font.color.rgb = color_is | ||
| rPr = run_fa._element.get_or_add_rPr() | ||
| rFonts = rPr.get_or_add_rFonts() | ||
| rFonts.set(qn('w:cs'), font_is) | ||
| rFonts.set(qn('w:eastAsia'), font_is) | ||
| szCs = OxmlElement('w:szCs') | ||
| szCs.set(qn('w:val'), size_is) | ||
| rPr.append(szCs) | ||
| rtl = OxmlElement('w:rtl') | ||
| rPr.append(rtl) | ||
| if isbold: | ||
| b = OxmlElement('w:b') | ||
| rPr.append(b) | ||
| bCs = OxmlElement('w:bCs') | ||
| rPr.append(bCs) | ||
| def convert_to_persian_numbers(text): | ||
| """Convert English/Arabic numerals to Persian numerals""" | ||
| if not isinstance(text, str): | ||
| text = str(text) | ||
| persian_numerals = { | ||
| '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴', | ||
| '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹' | ||
| } | ||
| for eng, per in persian_numerals.items(): | ||
| text = text.replace(eng, per) | ||
| return text | ||
| def add_persian_page_number_to_footer(footer, start_number=None, section=None): | ||
| """Add Persian page number to a specific footer""" | ||
| # Create a new paragraph for page number | ||
| paragraph = footer.add_paragraph() | ||
| paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER | ||
| # Set RTL for the paragraph | ||
| pPr = paragraph._p.get_or_add_pPr() | ||
| pPr.append(OxmlElement('w:bidi')) | ||
| # Add run with Persian text and page number field | ||
| run = paragraph.add_run() | ||
| # Set font for Persian support | ||
| run.font.name = 'B Zar' | ||
| rPr = run._r.get_or_add_rPr() | ||
| rFonts = OxmlElement('w:rFonts') | ||
| rFonts.set(qn('w:cs'), 'B Zar') | ||
| rFonts.set(qn('w:eastAsia'), 'B Zar') | ||
| rPr.append(rFonts) | ||
| # Add RTL | ||
| rtl = OxmlElement('w:rtl') | ||
| rPr.append(rtl) | ||
| # Add page number field | ||
| fldChar_begin = OxmlElement('w:fldChar') | ||
| fldChar_begin.set(qn('w:fldCharType'), 'begin') | ||
| run._r.append(fldChar_begin) | ||
| instrText = OxmlElement('w:instrText') | ||
| instrText.set(qn('xml:space'), 'preserve') | ||
| instrText.text = "PAGE" | ||
| run._r.append(instrText) | ||
| fldChar_end = OxmlElement('w:fldChar') | ||
| fldChar_end.set(qn('w:fldCharType'), 'end') | ||
| run._r.append(fldChar_end) | ||
| # Set starting page number if section is provided | ||
| if section and start_number: | ||
| sectPr = section._sectPr | ||
| pgNumType = OxmlElement('w:pgNumType') | ||
| pgNumType.set(qn('w:start'), str(start_number)) | ||
| existing_pgNumType = sectPr.find(qn('w:pgNumType')) | ||
| if existing_pgNumType is not None: | ||
| sectPr.remove(existing_pgNumType) | ||
| sectPr.append(pgNumType) | ||
| def get_docx_page_count_win32(docx_filename): | ||
| """Get actual page count using Microsoft Word (Windows only)""" | ||
| if not WIN32COM_AVAILABLE: | ||
| print("win32com not available, using fallback page count method") | ||
| return None | ||
| try: | ||
| pythoncom.CoInitialize() | ||
| abs_path = os.path.abspath(docx_filename) | ||
| word = win32com.client.Dispatch("Word.Application") | ||
| word.Visible = False | ||
| doc = word.Documents.Open(abs_path) | ||
| page_count = doc.ComputeStatistics(2) # 2 = wdStatisticPages | ||
| doc.Close() | ||
| word.Quit() | ||
| return page_count | ||
| except Exception as e: | ||
| print(f"Error getting page count with win32com: {e}") | ||
| return None | ||
| finally: | ||
| pythoncom.CoUninitialize() | ||
| def docx_to_pdf(docx_path , pdf_path): | ||
| try: | ||
| cmd = f'docx2pdf "{docx_path}" "{pdf_path}" ' | ||
| os.system(cmd) | ||
| return (pdf_path) | ||
| except: | ||
| print("install docx2pdf") | ||
| def merge_pdfs(pdf_files, output_filename): | ||
| try: | ||
| from PyPDF2 import PdfMerger | ||
| merger = PdfMerger() | ||
| for pdf_file in pdf_files: | ||
| merger.append(pdf_file) | ||
| merger.write(output_filename) | ||
| merger.close() | ||
| return output_filename | ||
| except: | ||
| print("install PyPDF2") | ||
| #add section | ||
| def adds(document , top_margin = 4 , bottom_margin=4 , start_page =1): | ||
| for section in document.sections: | ||
| section.top_margin = Cm(top_margin) | ||
| section.bottom_margin = Cm(bottom_margin) | ||
| section = document.sections[0] | ||
| section.different_first_page_header_footer = True | ||
| if not section.first_page_footer: | ||
| section.first_page_footer = section.footer | ||
| add_persian_page_number_to_footer(section.first_page_footer, start_number=start_page, section=section) | ||
| add_persian_page_number_to_footer(section.footer, start_number=start_page, section=section) | ||
| #add picture | ||
| def addpic(document , image_path , width , align = "c"): | ||
| pic = document.add_picture(str(image_path), width=width) | ||
| if (align.lower() == "l"): | ||
| document.paragraphs[-1].alignment= WD_ALIGN_PARAGRAPH.LEFT | ||
| elif (align.lower() == "r"): | ||
| document.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.RIGHT | ||
| elif (align.lower() == "j"): | ||
| document.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.JUSTIFY | ||
| else: | ||
| document.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER | ||
| #add paragraph | ||
| def addp(document , text , rtl = True , align="J" , font = "B Nazanin" , size = 12 , bold = False , color = RGBColor(0, 0, 0) , line_spacing = 0.8, right_indent= 0 , left_indent= 0 , space_after=0, bullet = False ): | ||
| p = document.add_paragraph() | ||
| if (rtl): | ||
| p.paragraph_format.right_to_left = True | ||
| else: | ||
| p.paragraph_format.right_to_left = False | ||
| if (align.lower() == "l"): | ||
| p.alignment = WD_ALIGN_PARAGRAPH.LEFT | ||
| elif (align.lower() == "r"): | ||
| p.alignment = WD_ALIGN_PARAGRAPH.RIGHT | ||
| elif (align.lower() == "j"): | ||
| p.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY | ||
| else: | ||
| p.alignment = WD_ALIGN_PARAGRAPH.CENTER | ||
| p.paragraph_format.line_spacing = line_spacing | ||
| p.paragraph_format.right_indent = Inches(right_indent) | ||
| p.paragraph_format.left_indent = Inches(left_indent) | ||
| p.paragraph_format.space_after = Pt(space_after) | ||
| apply_rtl_style(p,text, color,font,str(size*2),bold , bullet) | ||
+13
-11
| Metadata-Version: 2.1 | ||
| Name: iman | ||
| Version: 2.0.3 | ||
| Version: 2.0.4 | ||
| Summary: Python package for daily Tasks | ||
@@ -351,2 +351,14 @@ Author: Iman Sarraf | ||
| iman.word | ||
| ~~~~~~~~~~ | ||
| - ``documnet = Documnet()``: Create New Documnet | ||
| - ``adds(document , top_margin = 4 , bottom_margin=4 , start_page =1)``: Add Section with footer page number | ||
| - ``addpic(document , image_path , width , align = "c")``: Add picture to document | ||
| - ``addp(document , text , rtl = True , align="J" , font = "B Nazanin" , size = 12 , bold = False , color = RGBColor(0, 0, 0) , line_spacing = 0.8, right_indent= 0 , left_indent= 0 , space_after=0, bullet = False )``: Add paragraph to documnet | ||
| - ``get_docx_page_count_win32(docx_filename)``: Count Page Number | ||
| - ``convert_to_persian_numbers(text)``: Convert numbers in text to persian format | ||
| - ``docx_to_pdf(docx_path , pdf_path)``: Convet docx to pdf | ||
| - ``merge_pdfs(pdf_files, output_filename)``: merge pdf files | ||
| Dependencies | ||
@@ -363,12 +375,2 @@ ------------ | ||
| Documentation | ||
| ------------- | ||
| For detailed usage, refer to the source code or use the built-in help system: | ||
| .. code-block:: python | ||
| from iman import examples | ||
| examples.help("Audio") # Get help on the Audio module | ||
| Contributing | ||
@@ -375,0 +377,0 @@ ------------ |
@@ -24,2 +24,3 @@ MANIFEST.in | ||
| iman/web.py | ||
| iman/word.py | ||
| iman/xvector.py | ||
@@ -26,0 +27,0 @@ iman/yt.py |
| from .model import load_silero_vad | ||
| import wave | ||
| import numpy as np | ||
| vad_model = load_silero_vad() | ||
@@ -25,2 +28,47 @@ print("silero_vad jit model Loaded") | ||
| ) | ||
| return(speech_timestamps , wav) | ||
| return(speech_timestamps , wav) | ||
| def svadw(wav , sampling_rate=16000 , min_speech_duration_ms=250 , max_speech_duration_s=float('inf'),min_silence_duration_ms=100): | ||
| speech_timestamps = get_speech_timestamps( | ||
| wav, | ||
| vad_model, | ||
| return_seconds=True, # Return speech timestamps in seconds (default is samples) | ||
| sampling_rate=sampling_rate, | ||
| min_speech_duration_ms=min_speech_duration_ms, | ||
| max_speech_duration_s=max_speech_duration_s, | ||
| min_silence_duration_ms=min_silence_duration_ms, | ||
| ) | ||
| return(speech_timestamps , filter_wav_by_intervals(wav,speech_timestamps,sampling_rate)) | ||
| import numpy as np | ||
| def filter_wav_by_intervals(wav_data, intervals, framerate=16000, sampwidth=2, nchannels=1): | ||
| # Convert to numpy array if bytes | ||
| if isinstance(wav_data, bytes): | ||
| dtype = np.int16 if sampwidth == 2 else np.int8 | ||
| audio_data = np.frombuffer(wav_data, dtype=dtype) | ||
| else: | ||
| audio_data = wav_data | ||
| # Reshape for multi-channel | ||
| if nchannels > 1: | ||
| audio_data = audio_data.reshape(-1, nchannels) | ||
| # Extract segments | ||
| filtered_segments = [] | ||
| for interval in intervals: | ||
| start_frame = int(interval['start'] * framerate) | ||
| end_frame = int(interval['end'] * framerate) | ||
| segment = audio_data[start_frame:end_frame] | ||
| filtered_segments.append(segment) | ||
| # Concatenate all segments | ||
| if len(filtered_segments) > 0: | ||
| filtered_audio = np.concatenate(filtered_segments) | ||
| else: | ||
| filtered_audio = np.array([], dtype=audio_data.dtype) | ||
| return filtered_audio | ||
+13
-11
| Metadata-Version: 2.1 | ||
| Name: iman | ||
| Version: 2.0.3 | ||
| Version: 2.0.4 | ||
| Summary: Python package for daily Tasks | ||
@@ -351,2 +351,14 @@ Author: Iman Sarraf | ||
| iman.word | ||
| ~~~~~~~~~~ | ||
| - ``documnet = Documnet()``: Create New Documnet | ||
| - ``adds(document , top_margin = 4 , bottom_margin=4 , start_page =1)``: Add Section with footer page number | ||
| - ``addpic(document , image_path , width , align = "c")``: Add picture to document | ||
| - ``addp(document , text , rtl = True , align="J" , font = "B Nazanin" , size = 12 , bold = False , color = RGBColor(0, 0, 0) , line_spacing = 0.8, right_indent= 0 , left_indent= 0 , space_after=0, bullet = False )``: Add paragraph to documnet | ||
| - ``get_docx_page_count_win32(docx_filename)``: Count Page Number | ||
| - ``convert_to_persian_numbers(text)``: Convert numbers in text to persian format | ||
| - ``docx_to_pdf(docx_path , pdf_path)``: Convet docx to pdf | ||
| - ``merge_pdfs(pdf_files, output_filename)``: merge pdf files | ||
| Dependencies | ||
@@ -363,12 +375,2 @@ ------------ | ||
| Documentation | ||
| ------------- | ||
| For detailed usage, refer to the source code or use the built-in help system: | ||
| .. code-block:: python | ||
| from iman import examples | ||
| examples.help("Audio") # Get help on the Audio module | ||
| Contributing | ||
@@ -375,0 +377,0 @@ ------------ |
+12
-10
@@ -340,2 +340,14 @@ iman | ||
| iman.word | ||
| ~~~~~~~~~~ | ||
| - ``documnet = Documnet()``: Create New Documnet | ||
| - ``adds(document , top_margin = 4 , bottom_margin=4 , start_page =1)``: Add Section with footer page number | ||
| - ``addpic(document , image_path , width , align = "c")``: Add picture to document | ||
| - ``addp(document , text , rtl = True , align="J" , font = "B Nazanin" , size = 12 , bold = False , color = RGBColor(0, 0, 0) , line_spacing = 0.8, right_indent= 0 , left_indent= 0 , space_after=0, bullet = False )``: Add paragraph to documnet | ||
| - ``get_docx_page_count_win32(docx_filename)``: Count Page Number | ||
| - ``convert_to_persian_numbers(text)``: Convert numbers in text to persian format | ||
| - ``docx_to_pdf(docx_path , pdf_path)``: Convet docx to pdf | ||
| - ``merge_pdfs(pdf_files, output_filename)``: merge pdf files | ||
| Dependencies | ||
@@ -352,12 +364,2 @@ ------------ | ||
| Documentation | ||
| ------------- | ||
| For detailed usage, refer to the source code or use the built-in help system: | ||
| .. code-block:: python | ||
| from iman import examples | ||
| examples.help("Audio") # Get help on the Audio module | ||
| Contributing | ||
@@ -364,0 +366,0 @@ ------------ |
+1
-1
@@ -11,3 +11,3 @@ import os | ||
| name="iman", | ||
| version='2.0.3', | ||
| version='2.0.4', | ||
| author="Iman Sarraf", | ||
@@ -14,0 +14,0 @@ author_email="imansarraf@gmail.com", |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
2891378
0.37%120
0.84%13168
1.68%