{"action":"created","comment":{"url":"https://api.github.com/repos/borgbackup/borg-import/pulls/comments/93707863","pull_request_review_id":14239981,"id":93707863,"diff_hunk":"@@ -1,17 +1,160 @@\n import argparse\n+import logging\n+import shutil\n+import shlex\n+import subprocess\n+import sys\n+from pathlib import Path\n \n from .rsnapshots import get_snapshots\n \n+log = logging.getLogger(__name__)\n+\n+\n+def borg_import(args, archive_name, path, timestamp=None):\n+    borg_cmdline = ['borg', 'create']\n+    if timestamp:\n+        borg_cmdline += '--timestamp', timestamp.isoformat()\n+    if args.create_options:\n+        borg_cmdline.append(args.create_options)\n+\n+    repository = args.repository.resolve()\n+    location = '{}::{}'.format(repository, archive_name)\n+    borg_cmdline.append(location)\n+    borg_cmdline.append('.')\n+\n+    log.debug('Borg command line: %r', borg_cmdline)\n+    log.debug('Borg working directory: %s', path)\n+    subprocess.check_call(borg_cmdline, cwd=str(path))\n+\n+\n+def list_borg_archives(args):\n+    borg_cmdline = ['borg', 'list', '--short']\n+    repository = args.repository.resolve()\n+    borg_cmdline.append(str(repository))\n+    return subprocess.check_output(borg_cmdline).decode().split('\\n')\n+\n+\n+class Importer:\n+    name = 'name-of-command'\n+    description = 'descriptive description describing this importer'\n+\n+    def populate_parser(self, parser):\n+        \"\"\"\n+        Add arguments to argparse *parser*.\n+\n+        Specify the callback for the importer like so::\n+\n+            parser.set_defaults(function=self.import_something)\n+\n+        Then you can define *import_something* like this in the class::\n+\n+            def import_something(self, args):\n+                ...  # do something!\n+        \"\"\"\n+\n+\n+class rsnapshotImporter(Importer):\n+    name = 'rsnapshot'\n+    description = 'import rsnapshot backups'\n+\n+    def populate_parser(self, parser):\n+        parser.add_argument('--backup-set', help='Only consider given backup set (can be given multiple times).',\n+                            action='append', dest='backup_sets')\n+        parser.add_argument('rsnapshot_root', metavar='RSNAPSHOT_ROOT',\n+                            help='Path to rsnapshot root directory', type=Path)\n+        # TODO: support the full wealth of borg possibilities\n+        parser.add_argument('repository', metavar='REPOSITORY', help='Borg repository', type=Path)\n+        parser.set_defaults(function=self.import_rsnapshot)\n+\n+    def import_rsnapshot(self, args):\n+        existing_archives = list_borg_archives(args)\n+\n+        import_path = args.rsnapshot_root / 'borg-import-dir'\n+        import_journal = args.rsnapshot_root / 'borg-import-dir.snapshot'\n+\n+        if import_path.exists():\n+            print('{} exists. Cannot continue.'.format(import_path))\n+            return 1\n+\n+        for rsnapshot in get_snapshots(args.rsnapshot_root):\n+            timestamp = rsnapshot['timestamp'].replace(microsecond=0)\n+            snapshot_original_path = rsnapshot['path']\n+            name = rsnapshot['name']\n+            archive_name = args.prefix + name\n+\n+            if args.backup_sets and rsnapshot['backup_set'] not in args.backup_sets:\n+                print('Skipping (backup set is not selected):', name)\n+                continue\n+\n+            if archive_name in existing_archives:\n+                print('Skipping (already exists in repository):', name)\n+                continue\n+\n+            print('Importing {} (timestamp {}) '.format(name, timestamp), end='')\n+            if archive_name != name:\n+                print('as', archive_name)\n+            else:\n+                print()\n+            log.debug('  Moving {} -> {}'.format(rsnapshot['path'], import_path))\n+\n+            with import_journal.open('w') as fd:\n+                fd.write('Current snapshot: %s\\n' % rsnapshot['name'])\n+                fd.write('Original path: %s\\n' % snapshot_original_path)\n+\n+            snapshot_original_path.rename(import_path)","path":"src/borg_import/main.py","position":105,"original_position":105,"commit_id":"68fce0d0f5da7aa4e0e081617bd97e4a509c2741","original_commit_id":"68fce0d0f5da7aa4e0e081617bd97e4a509c2741","user":{"login":"ThomasWaldmann","id":356103,"avatar_url":"https://avatars.githubusercontent.com/u/356103?v=3","gravatar_id":"","url":"https://api.github.com/users/ThomasWaldmann","html_url":"https://github.com/ThomasWaldmann","followers_url":"https://api.github.com/users/ThomasWaldmann/followers","following_url":"https://api.github.com/users/ThomasWaldmann/following{/other_user}","gists_url":"https://api.github.com/users/ThomasWaldmann/gists{/gist_id}","starred_url":"https://api.github.com/users/ThomasWaldmann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ThomasWaldmann/subscriptions","organizations_url":"https://api.github.com/users/ThomasWaldmann/orgs","repos_url":"https://api.github.com/users/ThomasWaldmann/repos","events_url":"https://api.github.com/users/ThomasWaldmann/events{/privacy}","received_events_url":"https://api.github.com/users/ThomasWaldmann/received_events","type":"User","site_admin":false},"body":"add a comment about why you do this rename?","created_at":"2016-12-22T22:39:16Z","updated_at":"2016-12-22T22:53:59Z","html_url":"https://github.com/borgbackup/borg-import/pull/8#discussion_r93707863","pull_request_url":"https://api.github.com/repos/borgbackup/borg-import/pulls/8","_links":{"self":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/comments/93707863"},"html":{"href":"https://github.com/borgbackup/borg-import/pull/8#discussion_r93707863"},"pull_request":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/8"}}},"pull_request":{"url":"https://api.github.com/repos/borgbackup/borg-import/pulls/8","id":99137761,"html_url":"https://github.com/borgbackup/borg-import/pull/8","diff_url":"https://github.com/borgbackup/borg-import/pull/8.diff","patch_url":"https://github.com/borgbackup/borg-import/pull/8.patch","issue_url":"https://api.github.com/repos/borgbackup/borg-import/issues/8","number":8,"state":"open","locked":false,"title":"Implement importer","user":{"login":"enkore","id":1330164,"avatar_url":"https://avatars.githubusercontent.com/u/1330164?v=3","gravatar_id":"","url":"https://api.github.com/users/enkore","html_url":"https://github.com/enkore","followers_url":"https://api.github.com/users/enkore/followers","following_url":"https://api.github.com/users/enkore/following{/other_user}","gists_url":"https://api.github.com/users/enkore/gists{/gist_id}","starred_url":"https://api.github.com/users/enkore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/enkore/subscriptions","organizations_url":"https://api.github.com/users/enkore/orgs","repos_url":"https://api.github.com/users/enkore/repos","events_url":"https://api.github.com/users/enkore/events{/privacy}","received_events_url":"https://api.github.com/users/enkore/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-12-22T17:03:55Z","updated_at":"2016-12-22T22:53:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7a38ff9b43c649cc5e3693fa735ed27d21d8ecd4","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/borgbackup/borg-import/pulls/8/commits","review_comments_url":"https://api.github.com/repos/borgbackup/borg-import/pulls/8/comments","review_comment_url":"https://api.github.com/repos/borgbackup/borg-import/pulls/comments{/number}","comments_url":"https://api.github.com/repos/borgbackup/borg-import/issues/8/comments","statuses_url":"https://api.github.com/repos/borgbackup/borg-import/statuses/68fce0d0f5da7aa4e0e081617bd97e4a509c2741","head":{"label":"enkore:master","ref":"master","sha":"68fce0d0f5da7aa4e0e081617bd97e4a509c2741","user":{"login":"enkore","id":1330164,"avatar_url":"https://avatars.githubusercontent.com/u/1330164?v=3","gravatar_id":"","url":"https://api.github.com/users/enkore","html_url":"https://github.com/enkore","followers_url":"https://api.github.com/users/enkore/followers","following_url":"https://api.github.com/users/enkore/following{/other_user}","gists_url":"https://api.github.com/users/enkore/gists{/gist_id}","starred_url":"https://api.github.com/users/enkore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/enkore/subscriptions","organizations_url":"https://api.github.com/users/enkore/orgs","repos_url":"https://api.github.com/users/enkore/repos","events_url":"https://api.github.com/users/enkore/events{/privacy}","received_events_url":"https://api.github.com/users/enkore/received_events","type":"User","site_admin":false},"repo":{"id":77158908,"name":"borg-import","full_name":"enkore/borg-import","owner":{"login":"enkore","id":1330164,"avatar_url":"https://avatars.githubusercontent.com/u/1330164?v=3","gravatar_id":"","url":"https://api.github.com/users/enkore","html_url":"https://github.com/enkore","followers_url":"https://api.github.com/users/enkore/followers","following_url":"https://api.github.com/users/enkore/following{/other_user}","gists_url":"https://api.github.com/users/enkore/gists{/gist_id}","starred_url":"https://api.github.com/users/enkore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/enkore/subscriptions","organizations_url":"https://api.github.com/users/enkore/orgs","repos_url":"https://api.github.com/users/enkore/repos","events_url":"https://api.github.com/users/enkore/events{/privacy}","received_events_url":"https://api.github.com/users/enkore/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/enkore/borg-import","description":"importer for rsync+hardlink based backups / rsnapshot","fork":true,"url":"https://api.github.com/repos/enkore/borg-import","forks_url":"https://api.github.com/repos/enkore/borg-import/forks","keys_url":"https://api.github.com/repos/enkore/borg-import/keys{/key_id}","collaborators_url":"https://api.github.com/repos/enkore/borg-import/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/enkore/borg-import/teams","hooks_url":"https://api.github.com/repos/enkore/borg-import/hooks","issue_events_url":"https://api.github.com/repos/enkore/borg-import/issues/events{/number}","events_url":"https://api.github.com/repos/enkore/borg-import/events","assignees_url":"https://api.github.com/repos/enkore/borg-import/assignees{/user}","branches_url":"https://api.github.com/repos/enkore/borg-import/branches{/branch}","tags_url":"https://api.github.com/repos/enkore/borg-import/tags","blobs_url":"https://api.github.com/repos/enkore/borg-import/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/enkore/borg-import/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/enkore/borg-import/git/refs{/sha}","trees_url":"https://api.github.com/repos/enkore/borg-import/git/trees{/sha}","statuses_url":"https://api.github.com/repos/enkore/borg-import/statuses/{sha}","languages_url":"https://api.github.com/repos/enkore/borg-import/languages","stargazers_url":"https://api.github.com/repos/enkore/borg-import/stargazers","contributors_url":"https://api.github.com/repos/enkore/borg-import/contributors","subscribers_url":"https://api.github.com/repos/enkore/borg-import/subscribers","subscription_url":"https://api.github.com/repos/enkore/borg-import/subscription","commits_url":"https://api.github.com/repos/enkore/borg-import/commits{/sha}","git_commits_url":"https://api.github.com/repos/enkore/borg-import/git/commits{/sha}","comments_url":"https://api.github.com/repos/enkore/borg-import/comments{/number}","issue_comment_url":"https://api.github.com/repos/enkore/borg-import/issues/comments{/number}","contents_url":"https://api.github.com/repos/enkore/borg-import/contents/{+path}","compare_url":"https://api.github.com/repos/enkore/borg-import/compare/{base}...{head}","merges_url":"https://api.github.com/repos/enkore/borg-import/merges","archive_url":"https://api.github.com/repos/enkore/borg-import/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/enkore/borg-import/downloads","issues_url":"https://api.github.com/repos/enkore/borg-import/issues{/number}","pulls_url":"https://api.github.com/repos/enkore/borg-import/pulls{/number}","milestones_url":"https://api.github.com/repos/enkore/borg-import/milestones{/number}","notifications_url":"https://api.github.com/repos/enkore/borg-import/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/enkore/borg-import/labels{/name}","releases_url":"https://api.github.com/repos/enkore/borg-import/releases{/id}","deployments_url":"https://api.github.com/repos/enkore/borg-import/deployments","created_at":"2016-12-22T16:17:56Z","updated_at":"2016-12-22T16:17:59Z","pushed_at":"2016-12-22T19:25:33Z","git_url":"git://github.com/enkore/borg-import.git","ssh_url":"git@github.com:enkore/borg-import.git","clone_url":"https://github.com/enkore/borg-import.git","svn_url":"https://github.com/enkore/borg-import","homepage":null,"size":34,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"borgbackup:master","ref":"master","sha":"871fa349c139cdd3a65a584ec26f3a6fefacab3f","user":{"login":"borgbackup","id":12418060,"avatar_url":"https://avatars.githubusercontent.com/u/12418060?v=3","gravatar_id":"","url":"https://api.github.com/users/borgbackup","html_url":"https://github.com/borgbackup","followers_url":"https://api.github.com/users/borgbackup/followers","following_url":"https://api.github.com/users/borgbackup/following{/other_user}","gists_url":"https://api.github.com/users/borgbackup/gists{/gist_id}","starred_url":"https://api.github.com/users/borgbackup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/borgbackup/subscriptions","organizations_url":"https://api.github.com/users/borgbackup/orgs","repos_url":"https://api.github.com/users/borgbackup/repos","events_url":"https://api.github.com/users/borgbackup/events{/privacy}","received_events_url":"https://api.github.com/users/borgbackup/received_events","type":"Organization","site_admin":false},"repo":{"id":71938021,"name":"borg-import","full_name":"borgbackup/borg-import","owner":{"login":"borgbackup","id":12418060,"avatar_url":"https://avatars.githubusercontent.com/u/12418060?v=3","gravatar_id":"","url":"https://api.github.com/users/borgbackup","html_url":"https://github.com/borgbackup","followers_url":"https://api.github.com/users/borgbackup/followers","following_url":"https://api.github.com/users/borgbackup/following{/other_user}","gists_url":"https://api.github.com/users/borgbackup/gists{/gist_id}","starred_url":"https://api.github.com/users/borgbackup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/borgbackup/subscriptions","organizations_url":"https://api.github.com/users/borgbackup/orgs","repos_url":"https://api.github.com/users/borgbackup/repos","events_url":"https://api.github.com/users/borgbackup/events{/privacy}","received_events_url":"https://api.github.com/users/borgbackup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/borgbackup/borg-import","description":"importer for rsync+hardlink based backups / rsnapshot","fork":false,"url":"https://api.github.com/repos/borgbackup/borg-import","forks_url":"https://api.github.com/repos/borgbackup/borg-import/forks","keys_url":"https://api.github.com/repos/borgbackup/borg-import/keys{/key_id}","collaborators_url":"https://api.github.com/repos/borgbackup/borg-import/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/borgbackup/borg-import/teams","hooks_url":"https://api.github.com/repos/borgbackup/borg-import/hooks","issue_events_url":"https://api.github.com/repos/borgbackup/borg-import/issues/events{/number}","events_url":"https://api.github.com/repos/borgbackup/borg-import/events","assignees_url":"https://api.github.com/repos/borgbackup/borg-import/assignees{/user}","branches_url":"https://api.github.com/repos/borgbackup/borg-import/branches{/branch}","tags_url":"https://api.github.com/repos/borgbackup/borg-import/tags","blobs_url":"https://api.github.com/repos/borgbackup/borg-import/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/borgbackup/borg-import/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/borgbackup/borg-import/git/refs{/sha}","trees_url":"https://api.github.com/repos/borgbackup/borg-import/git/trees{/sha}","statuses_url":"https://api.github.com/repos/borgbackup/borg-import/statuses/{sha}","languages_url":"https://api.github.com/repos/borgbackup/borg-import/languages","stargazers_url":"https://api.github.com/repos/borgbackup/borg-import/stargazers","contributors_url":"https://api.github.com/repos/borgbackup/borg-import/contributors","subscribers_url":"https://api.github.com/repos/borgbackup/borg-import/subscribers","subscription_url":"https://api.github.com/repos/borgbackup/borg-import/subscription","commits_url":"https://api.github.com/repos/borgbackup/borg-import/commits{/sha}","git_commits_url":"https://api.github.com/repos/borgbackup/borg-import/git/commits{/sha}","comments_url":"https://api.github.com/repos/borgbackup/borg-import/comments{/number}","issue_comment_url":"https://api.github.com/repos/borgbackup/borg-import/issues/comments{/number}","contents_url":"https://api.github.com/repos/borgbackup/borg-import/contents/{+path}","compare_url":"https://api.github.com/repos/borgbackup/borg-import/compare/{base}...{head}","merges_url":"https://api.github.com/repos/borgbackup/borg-import/merges","archive_url":"https://api.github.com/repos/borgbackup/borg-import/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/borgbackup/borg-import/downloads","issues_url":"https://api.github.com/repos/borgbackup/borg-import/issues{/number}","pulls_url":"https://api.github.com/repos/borgbackup/borg-import/pulls{/number}","milestones_url":"https://api.github.com/repos/borgbackup/borg-import/milestones{/number}","notifications_url":"https://api.github.com/repos/borgbackup/borg-import/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/borgbackup/borg-import/labels{/name}","releases_url":"https://api.github.com/repos/borgbackup/borg-import/releases{/id}","deployments_url":"https://api.github.com/repos/borgbackup/borg-import/deployments","created_at":"2016-10-25T20:51:27Z","updated_at":"2016-11-28T12:55:23Z","pushed_at":"2016-12-22T19:25:34Z","git_url":"git://github.com/borgbackup/borg-import.git","ssh_url":"git@github.com:borgbackup/borg-import.git","clone_url":"https://github.com/borgbackup/borg-import.git","svn_url":"https://github.com/borgbackup/borg-import","homepage":null,"size":25,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":5,"forks":4,"open_issues":5,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/8"},"html":{"href":"https://github.com/borgbackup/borg-import/pull/8"},"issue":{"href":"https://api.github.com/repos/borgbackup/borg-import/issues/8"},"comments":{"href":"https://api.github.com/repos/borgbackup/borg-import/issues/8/comments"},"review_comments":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/8/comments"},"review_comment":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/borgbackup/borg-import/pulls/8/commits"},"statuses":{"href":"https://api.github.com/repos/borgbackup/borg-import/statuses/68fce0d0f5da7aa4e0e081617bd97e4a509c2741"}}}}
{"actor":{"display_login":"ThomasWaldmann"}}