Skip to content

Commit

Permalink
Updated the project structure, fixed code
Browse files Browse the repository at this point in the history
  • Loading branch information
ujjwal-ibm committed Dec 10, 2024
1 parent 03f47bb commit 85f9d4b
Show file tree
Hide file tree
Showing 18 changed files with 1,425 additions and 663 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,4 @@ cython_debug/

path/*
*.docx
.pypirc
28 changes: 28 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[build-system]
requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 88
include = '\.pyi?$'
extend-exclude = '''
# Add files to exclude from formatting
'''

[tool.isort]
profile = "black"
multi_line_output = 3

[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
check_untyped_defs = true

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = [
"tests",
]
15 changes: 7 additions & 8 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
-r requirements.txt
pytest>=7.0.0
black>=22.3.0
isort>=5.10.1
mypy>=0.981
pytest>=7.1.3
pytest-cov>=3.0.0
black>=22.0.0
isort>=5.10.0
flake8>=4.0.0
mypy>=0.950
tox>=3.24.0
build>=0.7.0
twine>=3.8.0
flake8>=4.0.1
tox>=3.24.5
pre-commit>=2.20.0
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
beautifulsoup4>=4.9.3
beautifulsoup4>=4.9.3,<5.0.0
python-docx>=0.8.11
requests>=2.25.1
click>=8.0.0
Expand Down
35 changes: 20 additions & 15 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
"""Package configuration for boxtodocx."""
from setuptools import setup, find_packages

with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()

with open("requirements.txt", "r", encoding="utf-8") as fh:
requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")]

setup(
name="boxtodocx",
version="1.0.0",
version="0.1.0",
author="Ujjwal Kumar",
author_email="[email protected]",
description="Convert Box Notes to Microsoft Word (docx) documents",
description="Convert Box documents to HTML and DOCX formats",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/ujjwal-ibm/boxtodocx",
url="https://github.ibm.com/Ujjwal-Kumar1/boxtodocx",
project_urls={
"Bug Tracker": "https://github.com/ujjwal-ibm/boxtodocx/issues",
"Documentation": "https://github.com/ujjwal-ibm/boxtodocx",
"Bug Tracker": "https://github.ibm.com/Ujjwal-Kumar1/boxtodocx/issues",
},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: End Users",
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
Expand All @@ -30,17 +27,25 @@
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Office/Business",
"Topic :: Text Processing",
"Topic :: Text Processing :: Markup :: HTML",
],
package_dir={"": "src"},
packages=find_packages(where="src"),
python_requires=">=3.8",
install_requires=requirements,
install_requires=[
"beautifulsoup4>=4.9.3",
"python-docx>=0.8.11",
"requests>=2.25.1",
"click>=8.0.0",
"typing-extensions>=4.0.0",
"colorlog>=6.7.0",
"Pillow>=10.0.0",
"yattag>=1.16.0",
"selenium>=4.0.0",
],
entry_points={
"console_scripts": [
"boxtodocx=boxtodocx.cli:main",
],
},
include_package_data=True,
)

)
7 changes: 0 additions & 7 deletions src/boxtodocx/__main__.py

This file was deleted.

159 changes: 132 additions & 27 deletions src/boxtodocx/cli.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,142 @@
"""Command-line interface for Box document conversion."""
from typing import Optional
import click
import os
from pathlib import Path
from .converter import BoxNoteConverter
from .utils.logger import get_logger

logger = get_logger(__name__)
from .convertor import BoxNoteConverter
from .utils.logger import setup_logger
from .utils.constants import DEFAULT_OUTPUT_DIR

@click.command()
@click.version_option()
@click.argument('input_path', type=click.Path(exists=True))
@click.option('-d', '--dir', help='Work directory for temporary files')
@click.option('-t', '--token', help='Box access token')
@click.option('-o', '--output', help='Output file name')
@click.option('-u', '--user', help='Box user id')
@click.option('-v', '--verbose', is_flag=True, help='Enable verbose logging')
def main(input_path, dir, token, output, user, verbose):
logger = setup_logger()

@click.argument(
"input_path",
type=click.Path(exists=True, path_type=Path)
)
@click.option(
"--dest-dir", "-d",
type=click.Path(path_type=Path),
default=DEFAULT_OUTPUT_DIR,
help="Destination directory for output files"
)
@click.option(
"--export-images",
is_flag=True,
default=False,
help="Export images from Box documents"
)
@click.option(
"--box-id",
help="Box login email"
)
@click.option(
"--box-pwd",
help="Box login password"
)
@click.option(
"--link",
help="Div ID for additional login step"
)
@click.option(
"--id",
help="User ID field for Box login"
)
@click.option(
"--pwd",
help="Password field for Box login"
)
@click.option(
"--mfa-link",
help="Div ID to click for MFA"
)
@click.option(
"--mfa-otp-id",
help="ID of input field for MFA code"
)
@click.option(
"--mfa-btn-id",
help="ID of button to submit MFA code"
)
@click.option(
"--mfa-otp",
help="MFA code (one-time password)"
)
@click.option(
"--directory",
is_flag=True,
default=False,
help="Process all Box documents in a directory"
)
@click.command(help="Convert Box documents to HTML and DOCX formats with image support.")
def main(
input_path: Path,
dest_dir: Path,
export_images: bool,
box_id: Optional[str],
box_pwd: Optional[str],
link: Optional[str],
id: Optional[str],
pwd: Optional[str],
mfa_link: Optional[str],
mfa_otp_id: Optional[str],
mfa_btn_id: Optional[str],
mfa_otp: Optional[str],
directory: bool
) -> None:
"""
Convert Box documents to HTML and DOCX formats.
Args:
input_path: Path to Box document or directory
"""
try:
converter = BoxNoteConverter()
input_path = Path(input_path)
credentials = None
if export_images:
if not all([box_id, box_pwd, link, id, pwd]):
raise click.UsageError(
"All Box login parameters must be provided when exporting images"
)
credentials = {
"user_id": box_id,
"password": box_pwd,
"link_id": link,
"user_field_id": id,
"password_field_id": pwd,
"mfa_link": mfa_link,
"mfa_otp_id": mfa_otp_id,
"mfa_btn_id": mfa_btn_id,
"mfa_otp": mfa_otp
}

if input_path.is_file():
_convert_file(converter, input_path, output or dir)
else:
_convert_directory(converter, input_path)
converter = BoxNoteConverter(dest_dir)

if directory:
if not input_path.is_dir():
raise click.BadParameter(f"Not a directory: {input_path}")

results = converter.convert_directory(input_path, credentials)
logger.info(f"Processed {len(results)} files in {input_path}")

else:
if not input_path.is_file():
raise click.BadParameter(f"Not a file: {input_path}")

if not BoxNoteConverter.validate_boxnote(input_path):
raise click.BadParameter(f"Invalid Box document: {input_path}")

html_path, docx_path, image_paths = converter.convert(
input_path,
credentials
)
logger.info(f"Converted {input_path} to:")
logger.info(f" HTML: {html_path}")
logger.info(f" DOCX: {docx_path}")
if image_paths:
logger.info(f" Images: {len(image_paths)} files")

except Exception as e:
logger.error(f"Error: {str(e)}")
logger.error(str(e))
raise click.Abort()

def _convert_file(converter, file_path, output_dir=None):
output_dir = output_dir or file_path.parent
converter.convert(str(file_path), str(output_dir))

def _convert_directory(converter, dir_path):
for file in dir_path.glob('**/*.boxnote'):
_convert_file(converter, file)
if __name__ == "__main__":
main()
34 changes: 0 additions & 34 deletions src/boxtodocx/converter.py

This file was deleted.

Loading

0 comments on commit 85f9d4b

Please sign in to comment.