Skip to main content

Synchronization folders package

PyPI

Hello everyone! This is the repository of my package on Python "sync-folders".

Table of contents

Motivation

Someday I made the script, that synchronizes two folders by date of theirs files. After time I've wanted to create package on PyPi. Also I've added some new features for work with files, in addition to syncing.

Build status

Here you can see build status of continuous integration/continuous deployment:

Python package Lint Code Base Upload Python Package PyPI - Downloads

Code style

I'm using Codacy for automate my code quality.

Codacy Badge

Dependencies

You can see all dependencies from requirements.txt here.

Features

With my package you can sync two folders, manage logs files, delete empty folders and old files, read and create zip-archives.

Installation

First install Python.

If you don't have pip, install it.

Then type in terminal:

pip install sync-folders --upgrade

Importing

# Import module
from sync_folders import main, purgelog, cleaner

Fast usage

Example of usage this module

Synchronization

main.sync('./test_a', './test_b')
# Expected creation of `logs.txt`

Files output

main.files('./')
""" Expected output

.gitattributes   Last Modified: 18 Jun 2020, 08 52
.gitignore       Last Modified: 10 Jun 2020, 06 39
CONTRIBUTING.md  Last Modified: 23 Jun 2020, 12 26
LICENSE  Last Modified: 09 Jun 2020, 18 10
README.md        Last Modified: 23 Jun 2020, 18 20
requirements.txt         Last Modified: 10 Jun 2020, 15 00
setup.cfg        Last Modified: 10 Jun 2020, 07 08
setup.py         Last Modified: 21 Jun 2020, 14 03
_config.yml      Last Modified: 10 Jun 2020, 09 28
"""

Dirs output

main.dirs('./tests')
""" Expected output

.venv
test_a
test_b
"""

Reading the file data

print(main.read_file('./index.py'))
""" Expected output

from sync_folders import main, purgelog, cleaner

print(main.read_file('./index.py'))
"""

Write in the file

Not an appending

main.write_file('./test.txt', 'your text')

List of the dirs

main.list_dir('./')
""" Expected result

['.git', '.github', '.venv', 'sync_folders', 'tests', 'util']
"""

List of the files

main.get_files('./')
""" Expected result

[
  {'name': 'python-package.yml', 'date': 1592564708.6109703, 'date_str': '19 Jun 2020, 11 05'}, 
  {'name': 'python-publish.yml', 'date': 1591772746.2324488, 'date_str': '10 Jun 2020, 07 05'}
]
"""

Read zip-archive

main.read_zip('./test.zip')
""" Expected output

test_a/
            Compress size: 0.0 in KB
            Filesize: 0.0 in KB
test_a/test.docx
            Compress size: 8.490234375 in KB
            Filesize: 11.1572265625 in KB
test_b/
            Compress size: 0.0 in KB
            Filesize: 0.0 in KB
"""

List of the elements in archive

main.files_in_zip('test.zip')
""" Expected result

['test_a/', 'test_a/test.docx', 'test_b/']
"""

Extract element from archive

main.extract('test.zip', 'test_a/test.docx')
# Expected creation of `test_a/test.docx`

Create archive

main.create_zip(['_config.yml', 'LICENSE', 'setup.py'], './test.zip')
# Expected creation of `test.zip`

Cleaner

cleaner.cleaner(['./test_a', './test_a/test_c', './test_b'], 5)
# Expected creation of `logs.txt`
""" Expected output

START TIME: Tue Jun 23 22:01:00 2020
Total deleted size: 0.0 MB
Total deleted files: 0
Total deleted empty folders: 3
FINISH TIME: Tue Jun 23 22:01:00 2020
"""

Purgelog

purgelog.purgelog('./logs.txt', 5, 2)
""" Expected output
Copied: logs.txt to 1_logs.txt
"""
# Expected creation of `1_logs.txt`

API

main.sync( path_a, path_b )

Name Type Argument Default Description
path_a string <required> None the path to the directory
path_b string <required> None the path to the directory

main.files( path )

Name Type Argument Default Description
path string <required> None the path to the directory

main.dirs( path )

Name Type Argument Default Description
path string <required> None the path to the directory

main.read_file( path )

Name Type Argument Default Description
path string <required> None the path to the file

main.write_file( path, data )

Name Type Argument Default Description
path string <required> None the path to the file
data string <required> None the content

main.list_dir( path )

Name Type Argument Default Description
path string <required> None the path to the directory

main.get_files( path )

Name Type Argument Default Description
path string <required> None the path to the directory

main.read_zip( path )

Name Type Argument Default Description
path string <required> None the path to the archive

main.files_in_zip( path )

Name Type Argument Default Description
path string <required> None the path to the archive

main.extract( path_to_zip, path_to_file )

Name Type Argument Default Description
path_to_zip string <required> None the path to the archive
path_to_file string <not required> None the path to the need file for extracting

main.create_zip( files, path)

Name Type Argument Default Description
files list <required> None the list of pathes to the files for archiving
path string <required> None the path to the new archive

cleaner.cleaner( folders, limit )

Name Type Argument Default Description
folders list <required> None the array of the folders
days int <required> None the limit of the days for comparing

purgelog.purgelog( log-file, limit, number )

Name Type Argument Default Description
log-file string <required> None the path to the log-file
limit int <required> None the limit of the maximum memory
number int <required> None the number of the maximum available number of the logs file

Code Example

Here you can see the function, that syncs two folders

# Main function for synchronize two folders
def sync(path_a=None, path_b=None):
    if not path_a or not path_b:
        raise NameError('Required path to both dirs')
    logs = ''
    files_in_a = get_files(path_a)
    files_in_b = get_files(path_b)
    same_files = []
    for file_a in files_in_a:
        for file_b in files_in_b:
            if file_b['name'] == file_a['name']:
                # compare dates
                if file_b['date'] < file_a['date']:
                    # change
                    shutil.copy2(path_a + '/' + file_a['name'], path_b)
                    logs += f"Change {file_a['name']} in {path_b}" + '\n'
            same_files.append(file_b['name'])
    for file_a in files_in_a:
        if not file_a['name'] in same_files:
            # move to b
            shutil.copy2(path_a + '/' + file_a['name'], path_b)
            logs += f"Create {file_a['name']} in {path_b}" + '\n'

    write_file('./logs.txt', logs)

Tests

Unit-testing with pytest:

😄I give you the link to GitHub Actions, where you can see all my tests.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Also look at the CONTRIBUTING.md.

Credits

Links to videos and articles which helped me to build this project:

License

GitHub

MIT © mezgoodle

Metadata

Release files for sync-folders 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sync-folders 1.2.1
File Size Uploaded Provenance Actions
sync-folders-1.2.1.tar.gz 10.4 kB Without provenance Details for sync-folders-1.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sync-folders 1.2.1
File Interpreter ABI Platform Actions
sync_folders-1.2.1-py3-none-any.whl Python 3 none any Details for sync_folders-1.2.1-py3-none-any.whl

Total release size: 19.0 kB

Release files / sync-folders-1.2.1.tar.gz

Download URL sync-folders-1.2.1.tar.gz
Size 10.4 kB
Tags Source
SHA-256 checksum
How to use checksums
955d5c3f9e2eaf01f4b1e399d834f1ddf286c253e77d78ef24af346da336c119
BLAKE2b-256 checksum
How to use checksums
06b593955b065f0794693797a1e8ba184631a128c5101ce3c757253e642d7ef1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

Release files / sync_folders-1.2.1-py3-none-any.whl

Download URL sync_folders-1.2.1-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2640f90c8d7a8153fee072155b158d9a20d0bcbf806950ca60d031f7967f93aa
BLAKE2b-256 checksum
How to use checksums
0155a8fc1225e9f5262a21c0b831397c2beb9a6776d1a6c135be8f00c18eeb89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.4

Security for sync-folders 1.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page