diff options
-rw-r--r-- | Offlink.app/Contents/Info.plist | 63 | ||||
-rwxr-xr-x | Offlink.app/Contents/MacOS/droplet | bin | 0 -> 25028 bytes | |||
-rwxr-xr-x | Offlink.app/Contents/MacOS/helper.py | 100 | ||||
-rw-r--r-- | Offlink.app/Contents/PkgInfo | 1 | ||||
-rw-r--r-- | Offlink.app/Contents/Resources/Scripts/main.scpt | bin | 0 -> 5042 bytes | |||
-rw-r--r-- | Offlink.app/Contents/Resources/description.rtfd/TXT.rtf | 4 | ||||
-rw-r--r-- | Offlink.app/Contents/Resources/droplet.icns | bin | 0 -> 74052 bytes | |||
-rw-r--r-- | Offlink.app/Contents/Resources/droplet.rsrc | bin | 0 -> 362 bytes | |||
-rw-r--r-- | README.md | 35 |
9 files changed, 203 insertions, 0 deletions
diff --git a/Offlink.app/Contents/Info.plist b/Offlink.app/Contents/Info.plist new file mode 100644 index 0000000..ec06067 --- /dev/null +++ b/Offlink.app/Contents/Info.plist @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleAllowMixedLocalizations</key> + <true/> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDocumentTypes</key> + <array> + <dict> + <key>CFBundleTypeExtensions</key> + <array> + <string>*</string> + </array> + <key>CFBundleTypeOSTypes</key> + <array> + <string>****</string> + </array> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + </dict> + </array> + <key>CFBundleExecutable</key> + <string>droplet</string> + <key>CFBundleIconFile</key> + <string>droplet</string> + <key>CFBundleIdentifier</key> + <string>com.apple.ScriptEditor.id.App</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>App</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>dplt</string> + <key>LSMinimumSystemVersionByArchitecture</key> + <dict> + <key>x86_64</key> + <string>10.6</string> + </dict> + <key>LSRequiresCarbon</key> + <true/> + <key>WindowState</key> + <dict> + <key>dividerCollapsed</key> + <false/> + <key>eventLogLevel</key> + <integer>-1</integer> + <key>name</key> + <string>ScriptWindowState</string> + <key>positionOfDivider</key> + <real>422.5</real> + <key>savedFrame</key> + <string>62 116 1228 736 0 0 1440 878 </string> + <key>selectedTabView</key> + <string>event log</string> + </dict> +</dict> +</plist> diff --git a/Offlink.app/Contents/MacOS/droplet b/Offlink.app/Contents/MacOS/droplet Binary files differnew file mode 100755 index 0000000..4f7d67b --- /dev/null +++ b/Offlink.app/Contents/MacOS/droplet diff --git a/Offlink.app/Contents/MacOS/helper.py b/Offlink.app/Contents/MacOS/helper.py new file mode 100755 index 0000000..686c194 --- /dev/null +++ b/Offlink.app/Contents/MacOS/helper.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +import os.path +import plistlib +import subprocess + +PREF = os.path.expanduser("~/Library/Preferences/com.github.filipp.offlink.plist") + +def open_plist(): + try: + return plistlib.readPlist(PREF) + except Exception: + d = dict(folders=[]) + return plistlib.writePlist(d, PREF) + +def is_linked(path): + """ + Returns True if path is in the linked list + + >>> is_linked("/tmp2") + False + """ + plist = open_plist() + for x in plist['folders']: + if x['source'] == path: + return True + return False + +def add_path(source, target): + """ + Adds source and target to list of synced folders + + >>> add_path('/blaa', '/bluu') #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + ValueError... + >>> add_path('/var', '/tmp') + /var linked with /tmp + """ + plist = open_plist() + for path in (source, target,): + if not os.path.exists(path): + raise ValueError("%s is not a valid path" % path) + f = dict(source=source, target=target) + plist['folders'] = plist['folders'] + [f] + plistlib.writePlist(plist, PREF) + + print("%s linked with %s" % (source, target)) + +def forget_path(path): + """ + Removes this source from the linked folders list + + >>> forget_path("/var") + /var removed from synced list + """ + plist = open_plist() + newlist = [] + + for x in plist['folders']: + if x['source'] != path: + newlist.append(x) + plist['folders'] = newlist + plistlib.writePlist(plist, PREF) + + print("%s removed from synced list" % path) + +def sync(source, target): + subprocess.call(["/usr/bin/rsync", "-auE", source, target]) + print("%s synced with %s" % (source, target)) + +def source_to_target(): + plist = open_plist() + + for x in plist['folders']: + sync(x['source'], x['target']) + +def target_to_source(): + plist = open_plist() + + for x in plist['folders']: + sync(x['target'], x['source']) + + +if __name__ == '__main__': + import sys + import doctest + + if len(sys.argv) == 1: + doctest.testmod() + sys.exit() + + if sys.argv[1] == 'add': + add_path(sys.argv[2], sys.argv[3]) + if sys.argv[1] == 'forget': + forget_path(sys.argv[2]) + if sys.argv[1] == 'check': + sys.exit(255) if is_linked(sys.argv[2]) else sys.exit(0) + if sys.argv[1] == 'sync': + source_to_target() diff --git a/Offlink.app/Contents/PkgInfo b/Offlink.app/Contents/PkgInfo new file mode 100644 index 0000000..b999e99 --- /dev/null +++ b/Offlink.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLdplt
\ No newline at end of file diff --git a/Offlink.app/Contents/Resources/Scripts/main.scpt b/Offlink.app/Contents/Resources/Scripts/main.scpt Binary files differnew file mode 100644 index 0000000..d060e2d --- /dev/null +++ b/Offlink.app/Contents/Resources/Scripts/main.scpt diff --git a/Offlink.app/Contents/Resources/description.rtfd/TXT.rtf b/Offlink.app/Contents/Resources/description.rtfd/TXT.rtf new file mode 100644 index 0000000..116a631 --- /dev/null +++ b/Offlink.app/Contents/Resources/description.rtfd/TXT.rtf @@ -0,0 +1,4 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210 +{\fonttbl} +{\colortbl;\red255\green255\blue255;} +}
\ No newline at end of file diff --git a/Offlink.app/Contents/Resources/droplet.icns b/Offlink.app/Contents/Resources/droplet.icns Binary files differnew file mode 100644 index 0000000..4783f3f --- /dev/null +++ b/Offlink.app/Contents/Resources/droplet.icns diff --git a/Offlink.app/Contents/Resources/droplet.rsrc b/Offlink.app/Contents/Resources/droplet.rsrc Binary files differnew file mode 100644 index 0000000..a091d9e --- /dev/null +++ b/Offlink.app/Contents/Resources/droplet.rsrc diff --git a/README.md b/README.md new file mode 100644 index 0000000..41f3b18 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +### Introduction + +This tool synchronizes shared folders for offline editing. It may come in useful if you have some folders on a file server that you would like to "take with you" - you then simply drag those folders to + +It has 3 modes of operation: + +- Dragging new folder: create "link" between source and target and sync +- Dragging previously synced folder: "unlink" source and target +- Launch without drag/drop: sync folders + +### How to + +- Drag your source items onto the Offlink droplet +- Run the Offlink droplet before you go "offline" +- To remove items from the "linked list", just drag the source file/folders onto it again + +### Bugs + +It would be nice to be able to sync files back to the source directory as well and the rsync code is in there, but I don't know how to trigger that behaviour (alt-clicking would be an option, but stock AppleScript cannot detect that). + +### License + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2016 Filipp Lepalaan <filipp@mac.com> + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. |